With curl it works:
root@server:~/server-scripts# curl --interface enp1s0 https://v6.ident.me/ && echo && echo
2001:470:1f1b:5b5:9ade:d0ff:fe04:23c3
root@server:~/server-scripts# curl --interface enp2s0 https://v6.ident.me/ && echo && echo
2001:470:1f1b:5b3:eeaa:a0ff:fe1b:4d84
With Nodejs, just one request, it works:
/* The request
{ url: 'https://v6.ident.me/.json',
localAddress: '2001:470:1f1b:5b3:eeaa:a0ff:fe1b:4d84' }
*/
utils.http.request(getRequest({
url: 'https://v6.ident.me/.json',
//family: 6,
localAddress: getIpV6(interfaces.enp2s0).address
})),
result:
{ address: '2001:470:1f1b:5b3:eeaa:a0ff:fe1b:4d84' }
With 2 request, it is stuck:
/* 2 Request - 2 different functions
{ url: 'https://v6.ident.me/.json',
localAddress: '2001:470:1f1b:5b3:eeaa:a0ff:fe1b:4d84' }
{ url: 'https://v6.ident.me/.json',
localAddress: '2001:470:1f1b:5b5:9ade:d0ff:fe04:23c3' }
*/
I get no results. If i change 2nd with IPV4, it works of works.
Can you post a complete test case with no third-party dependencies? I.e., no dependencies on npm packages.
The error :-1:
{ message: 'connect ETIMEDOUT 2a01:7e00::f03c:91ff:fe70:2b9d:443',
stack: 'Error: connect ETIMEDOUT 2a01:7e00::f03c:91ff:fe70:2b9d:443\n at Object.exports._errnoException (util.js:1016:11)\n at exports._exceptionWithHostPort (util.js:1039:20)\n at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1138:14)' }
No idea where this 2a01:7e00::f03c:91ff:fe70:2b9d:443' comes from. But it is a NodeJs issue, because I have to revert to curl for now.
there is no thrid party dependencies, a simple request, a wrapper. pure node request.
Then please post that complete test case I asked for. If I can't run it, I'm not going to look at it.
#!/usr/bin/env node
const os = require('os');
const interfaces = os.networkInterfaces();
const https = require('https');
const url = require('url');
const getIpV6 = (items) => {
const result = items.find(item => {
return item.family === 'IPv6' && !item.address.startsWith('f');
})
return result;
}
const parsed = url.parse('https://v6.ident.me/.json');
const option1 = Object.assign({
localAddress: getIpV6(interfaces.enp2s0).address,
}, parsed)
const option2 = Object.assign({
localAddress: getIpV6(interfaces.enp1s0).address,
}, parsed)
console.log(`start options1 ${option1.localAddress}`);
https.get(option1 , (res) => {
console.log();
console.log('got option1 result');
console.log('option1 local address', option1.localAddress);
res.on('data', (chunk) => {
console.log(`${option1.localAddress} option1 chunk`, chunk.toString());
});
})
console.log(`start options2 ${option2.localAddress}`);
https.get(option2, (res) => {
console.log();
console.log('got option2 result');
console.log('option2 local address', option2.localAddress);
res.on('data', (chunk) => {
console.log(`${option2.localAddress} option2 chunk`, chunk.toString());
});
})
const exec = require('child_process').exec
exec('curl -ssk --interface enp2s0 https://v6.ident.me/.json', (err, stdout, stderr) => {
console.log();
console.log('curl enp2s0 stderr', stderr)
console.log('curl enp2s0 stdout', stdout)
console.log('curl enp2s0 stderr', stderr)
});
exec('curl -ssk --interface enp1s0 https://v6.ident.me/.json', (err, stdout, stderr) => {
console.log();
console.log('curl enp1s0 stderr', stderr)
console.log('curl enp1s0 stdout', stdout)
console.log('curl enp1s0 stderr', stderr)
});
Output:
root@server:~/server-scripts# ./test.js
start options1 2001:470:1f1b:5b3:eeaa:a0ff:fe1b:4d84
start options2 2001:470:1f1b:5b5:9ade:d0ff:fe04:23c3
got option1 result
option1 local address 2001:470:1f1b:5b3:eeaa:a0ff:fe1b:4d84
2001:470:1f1b:5b3:eeaa:a0ff:fe1b:4d84 option1 chunk {"address": "2001:470:1f1b:5b3:eeaa:a0ff:fe1b:4d84"}
curl enp2s0 stderr
curl enp2s0 stdout {"address": "2001:470:1f1b:5b3:eeaa:a0ff:fe1b:4d84"}
curl enp2s0 stderr
curl enp1s0 stderr
curl enp1s0 stdout {"address": "2001:470:1f1b:5b5:9ade:d0ff:fe04:23c3"}
curl enp1s0 stderr
You can see, the 2nd interface is not working wiith NodeJs, but everywhere it is working wget and curl.
Here are the interfaces, but it is only with NodeJs. C, PHP works.
```
{ lo:
[ { address: '127.0.0.1',
netmask: '255.0.0.0',
family: 'IPv4',
mac: '00:00:00:00:00:00',
internal: true },
{ address: '::1',
netmask: 'ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff',
family: 'IPv6',
mac: '00:00:00:00:00:00',
scopeid: 0,
internal: true } ],
enp1s0:
[ { address: '192.168.81.20',
netmask: '255.255.255.0',
family: 'IPv4',
mac: '00:00:00:00:9a:de',
internal: false },
{ address: '2001:470:1f1b:5b5:9ade:d0ff:fe04:23c3',
netmask: 'ffff:ffff:ffff:ffff::',
family: 'IPv6',
mac: '00:00:00:00:9a:de',
scopeid: 0,
internal: false },
{ address: 'fe80::9ade:d0ff:fe04:23c3',
netmask: 'ffff:ffff:ffff:ffff::',
family: 'IPv6',
mac: '00:00:00:00:9a:de',
scopeid: 2,
internal: false } ],
enp2s0:
[ { address: '192.168.78.20',
netmask: '255.255.255.0',
family: 'IPv4',
mac: '00:00:00:00:ee:aa',
internal: false },
{ address: '2001:470:1f1b:5b3:eeaa:a0ff:fe1b:4d84',
netmask: 'ffff:ffff:ffff:ffff::',
family: 'IPv6',
mac: '00:00:00:00:ee:aa',
scopeid: 0,
internal: false },
{ address: 'fe80::eeaa:a0ff:fe1b:4d84',
netmask: 'ffff:ffff:ffff:ffff::',
family: 'IPv6',
mac: '00:00:00:00:ee:aa',
scopeid: 3,
internal: false } ] }
````
thanks for helping!
Seems to be working for me locally. Does it make a difference if you pass in a link-local address, like 2001:470:1f1b:5b3:eeaa:a0ff:fe1b:4d84%enp2s0? (Note the %enps20 suffix.)
Ciao!
How are you?
Do you have 2 interfaces? I use 2 interfaces for the server. How do you make it to work with NodeJS?
I tested, but the same result. And only with NodeJs. PHP is good. Look the settings. they seem good.
Code:'
#!/usr/bin/env node
const os = require('os');
const https = require('https');
const url = require('url');
const exec = require('child_process').exec
const interfaces = os.networkInterfaces();
delete interfaces.lo;
console.log('interfaces')
console.log(interfaces);
const parsedUrl = url.parse('https://v6.ident.me/.json');
Object.keys(interfaces).forEach(_interface => {
const curlUrl = `curl -ssk --interface ${_interface} https://v6.ident.me/.json`;
console.log()
console.log('CURL', curlUrl);
exec(curlUrl, (err, stdout, stderr) => {
console.log();
console.log(`CURL RESULT ${_interface} err`, err)
console.log(`CURL RESULT ${_interface} stdout`, stdout)
console.log(`CURL RESULT ${_interface} stderr`, stderr)
});
const ipv6 = interfaces[_interface].find(info => {
return info.family === 'IPv6' && !info.address.startsWith('f');
});
const httpRequest = Object.assign({
localAddress: `${ipv6.address}%${_interface}`,
family: 6,
}, parsedUrl);
Object.keys(httpRequest).forEach((key) => (httpRequest[key] == null) && delete httpRequest[key]);
console.log();
console.log('NODE Request', httpRequest);
const req = https.get(httpRequest, (res) => {
res.on('data', (chunk) => {
console.log();
console.log(`NODE RESULT ${ipv6.address}` + '%%' + `${_interface}`, chunk.toString());
});
})
req.end();
})
Result;
oot@server:~/server-scripts# ./test.js
interfaces
{ enp1s0:
[ { address: '192.168.81.20',
netmask: '255.255.255.0',
family: 'IPv4',
mac: '00:00:00:00:9a:de',
internal: false },
{ address: '2001:470:1f1b:5b5:9ade:d0ff:fe04:23c3',
netmask: 'ffff:ffff:ffff:ffff::',
family: 'IPv6',
mac: '00:00:00:00:9a:de',
scopeid: 0,
internal: false },
{ address: 'fe80::9ade:d0ff:fe04:23c3',
netmask: 'ffff:ffff:ffff:ffff::',
family: 'IPv6',
mac: '00:00:00:00:9a:de',
scopeid: 2,
internal: false } ],
enp2s0:
[ { address: '192.168.78.20',
netmask: '255.255.255.0',
family: 'IPv4',
mac: '00:00:00:00:ee:aa',
internal: false },
{ address: '2001:470:1f1b:5b3:eeaa:a0ff:fe1b:4d84',
netmask: 'ffff:ffff:ffff:ffff::',
family: 'IPv6',
mac: '00:00:00:00:ee:aa',
scopeid: 0,
internal: false },
{ address: 'fe80::eeaa:a0ff:fe1b:4d84',
netmask: 'ffff:ffff:ffff:ffff::',
family: 'IPv6',
mac: '00:00:00:00:ee:aa',
scopeid: 3,
internal: false } ] }
CURL curl -ssk --interface enp1s0 https://v6.ident.me/.json
NODE Request { localAddress: '2001:470:1f1b:5b5:9ade:d0ff:fe04:23c3%enp1s0',
family: 6,
protocol: 'https:',
slashes: true,
host: 'v6.ident.me',
hostname: 'v6.ident.me',
pathname: '/.json',
path: '/.json',
href: 'https://v6.ident.me/.json' }
CURL curl -ssk --interface enp2s0 https://v6.ident.me/.json
NODE Request { localAddress: '2001:470:1f1b:5b3:eeaa:a0ff:fe1b:4d84%enp2s0',
family: 6,
protocol: 'https:',
slashes: true,
host: 'v6.ident.me',
hostname: 'v6.ident.me',
pathname: '/.json',
path: '/.json',
href: 'https://v6.ident.me/.json' }
NODE RESULT 2001:470:1f1b:5b3:eeaa:a0ff:fe1b:4d84%enp2s0 {"address": "2001:470:1f1b:5b3:eeaa:a0ff:fe1b:4d84"}
CURL RESULT enp1s0 err null
CURL RESULT enp1s0 stdout {"address": "2001:470:1f1b:5b5:9ade:d0ff:fe04:23c3"}
CURL RESULT enp1s0 stderr
CURL RESULT enp2s0 err null
CURL RESULT enp2s0 stdout {"address": "2001:470:1f1b:5b3:eeaa:a0ff:fe1b:4d84"}
CURL RESULT enp2s0 stderr
events.js:182
throw er; // Unhandled 'error' event
^
Error: connect ETIMEDOUT 2a01:7e00::f03c:91ff:fe70:2b9d:443
at Object.exports._errnoException (util.js:1016:11)
at exports._exceptionWithHostPort (util.js:1039:20)
at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1138:14)
There is a timeout, I waited, but I have no idea this IPv6 address comes, because it only with NodeJs.
Do you know how can do it? The routes are good, nothing like that anywere.
PHP, CURL, working.
Yes, two interfaces. I didn't need to do anything special (except use the right interface names), it just worked.
Perhaps try strace'ing node and curl to see what they do differently. Look for bind, connect, ioctl, setsockopt, etc. system calls. If I had to venture a guess, it's that curl binds to the interface (with an ioctl) while node binds to the address.
I'm going to close this for now because so far it seems to be an issue with your local environment. I can reopen if it does turn out to be a bug in node.
If you want to debug this further, open an issue over at https://github.com/nodejs/help/issues and we'll take it from there.
can you show works with 2 interfaces? you code, please! where i am doing something wrong and you already got it.
please you are using 2 ipv6, 1ipv6 works, it is deffirent ndoejs error, since with work it works!
how can my entirvonrnemt bad is everything works (mail server, https,)
only in nodejs not working with 2 ipv6 adress.
curl works!!!
why is my entinvornment bad!!!!
this weird!
The only changes I made to your script were the interface names.
i see, end nodejs cannot select the interface? only bind to an address?
Correct. Node calls bind(2). I suspect curl calls an ioctl or setsockopt(SO_BINDTODEVICE).
proposal to solve this issue #35769