-
Notifications
You must be signed in to change notification settings - Fork 30.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
http.get option localAddress not working #3625
Comments
IIRC routing on Linux uses the route with the lowest metric value when multiple routes match, which in this case would agree with what you're experiencing. |
Of cause it uses the route with the lowest metric! But that's the question! In C language it is a simplest question to resolve with SO_BINDTODEVICE socket option. And I thought nodejs do this also in some intellectual way like //convert localAddress to the Interface name
#ifdef __linux__
//SO_BINDTODEVICE to the interface
#elif __APPLE__
//IP_BOUND_IF to the interface
#endif No problemo |
Perhaps it's stating the obvious but the
With script.js looking something like this: var socket = require('net').Socket({ fd: 3, readable: true, writable: true });
var req = require('http').get({
createConnection: () => socket,
headers: { Host: 'example.com' },
}, res => res.pipe(process.stdout)); |
I've found another workaround that works. Using ffi and call to setsockopt. But I wish I could do that with nodejs only. var http = require('http'),
net = require('net'),
util = require('util'),
ffi = require('ffi');
var SOL_SOCKET = 1;
var SO_BINDTODEVICE = 25;
var current = ffi.Library(null, {
'setsockopt': ['int', ['int', 'int', 'int', 'string', 'int']]
});
var remoteIp = "192.168.0.1";
var ourIp = "192.168.0.182";
var ourInterface = "eth1";
function bindingAgent(options) {
http.Agent.call(this, options);
this.createConnection = bindingCreateConnection;
}
util.inherits(bindingAgent, http.Agent);
function bindingCreateConnection(port, host, options) {
var socket;
socket = new net.Socket({handle: net._createServerHandle(ourIp)});
var iface = ourInterface;
var r = current.setsockopt(socket._handle.fd, SOL_SOCKET, SO_BINDTODEVICE, iface, 6);
if (r === -1)
throw new Error("getsockopt(SO_BINDTODEVICE) error");
socket.connect(port, host);
return socket;
}
var optionsAgent = {};
var ourBindingAgent = new bindingAgent(optionsAgent);
var httpReq = {};
httpReq.port = 80;
httpReq.host = remoteIp;
httpReq.path = '/index.html';
httpReq.headers = {'Referer': 'http://' + remoteIp + ':' + httpReq.port + '/index.html'};
httpReq.agent = ourBindingAgent;
var body = '';
var creq = http.get(httpReq);
creq.on('response', function (res) {
res.setEncoding('utf8');
res.on('data', function (chunk) {
console.log(chunk);
});
}); |
Hello! The binding to Local interface option is not working at all.
The case: Arch Linux system with two different ethernet interfaces.
eth0: 192.168.0.173/24
eth1: 192.168.0.182/24
routing table is
default via 192.168.0.1 dev eth0 metric 280
default via 192.168.0.1 dev eth1 metric 281
Every interface has a listening http server on other end with the address: 192.168.0.1
So I'm trying to send a request to each of them with nodejs.
Sample code:
I've even tried creating a socket for that request with new net.Socket({ handle: net._createServerHandle( '192.168.0.182')}); and requests kept going from the wrong address.
There's workaround with 'curl --interface eth1 ...' that works, but it's not a good solution.
The text was updated successfully, but these errors were encountered: