Open ghost opened 4 years ago
Hi @TheBrainEscaped,
Super thank you for the feedback :heart:
I haven't yet be able to reproduce the bug. However, it looks like the problem is related to PMP.
So I have added an option on the last version (0.1.3
) of nat-api
to force PMP. This means that if you update your version you shouldn't have any more problems because it is not using PMP by default.
Please check it out and let me know how it went :)
I can confirm that with nat-api@0.1.3
the issue mentioned above is gone the way of the Dodo bird.
Thanks for the update!
Let me take that back.
I distinctively remember creating a quick test project on Windows 10 and testing some of the above code against 0.1.3 and had my ports appearing on the router's "UPNP "page without issues.
However, testing on a Linux distribution I started running into issues again so I decided to re-test on Windows and managed to replicate the issues encountered on Linux.
This code
const clientTCP = new NatAPI({ autoUpdate: true, enablePMP: false });
clientTCP.map({ publicPort: 10000, privatePort: 10000, ttl: 1200, protocol: 'TCP', description: 'Nat-Api TCP' },function (err) {
if (err) {
console.log('Error', err);
} else {
console.log('TCP port mapped!');
}
});
const clientUDP = new NatAPI({ autoUpdate: true, enablePMP: false });
clientUDP.map({ publicPort: 10000, privatePort: 10000, ttl: 1200, protocol: 'UDP', description: 'Nat-Api UDP' },function (err) {
if (err) {
console.log('Error', err);
} else {
console.log('UDP port mapped!');
}
});
leads to
Error Error: UPnP port mapping failed
at C:\Users\XXX\Desktop\nat-test-2\node_modules\nat-api\index.js:226:25
at C:\Users\XXX\Desktop\nat-test-2\node_modules\nat-api\index.js:293:16
at C:\Users\XXX\Desktop\nat-test-2\node_modules\nat-api\lib\upnp\index.js:24:23
at Timeout._onTimeout (C:\Users\Cos\Desktop\nat-test-2\node_modules\nat-api\lib\upnp\index.js:193:7)
at listOnTimeout (internal/timers.js:531:17)
at processTimers (internal/timers.js:475:7)
Error Error: UPnP port mapping failed
at C:\Users\XXX\Desktop\nat-test-2\node_modules\nat-api\index.js:226:25
at C:\Users\XXX\Desktop\nat-test-2\node_modules\nat-api\index.js:293:16
at C:\Users\XXX\Desktop\nat-test-2\node_modules\nat-api\lib\upnp\index.js:24:23
at Timeout._onTimeout (C:\Users\Cos\Desktop\nat-test-2\node_modules\nat-api\lib\upnp\index.js:193:7)
at listOnTimeout (internal/timers.js:531:17)
at processTimers (internal/timers.js:475:7)
and no ports mapped.
I have come to realize that my router only supports NAT-PMP, therefore the exceptions above are unavoidable due to nat-api attemtping UPNP mapping by default. To test this assumption, I went ahead and commented out all UPNP related code and re-tested with
const NatAPI = require('nat-api');
const clientTCP = new NatAPI({ autoUpdate: true, enablePMP: true });
clientTCP.map({ publicPort: 10000, privatePort: 10000, ttl: 1200, protocol: 'TCP', description: 'Nat-Api TCP' },function (err) {
if (err) {
console.log('Error', err);
} else {
console.log('TCP port mapped!');
}
});
const clientUDP = new NatAPI({ autoUpdate: true, enablePMP: true });
clientUDP.map({ publicPort: 10000, privatePort: 10000, ttl: 1200, protocol: 'UDP', description: 'Nat-Api UDP' },function (err) {
if (err) {
console.log('Error', err);
} else {
console.log('UDP port mapped!');
}
});
The above maps both ports, however it bombs with
C:\Users\XXX\Desktop\nat-test-2\node_modules\nat-api\lib\pmp\index.js:257
parsed.vers = msg.readUInt8(0)
^
TypeError: Cannot read property 'readUInt8' of undefined
at Client.onMessage (C:\Users\XXX\Desktop\nat-test-2\node_modules\nat-api\lib\pmp\index.js:257:23)
at Socket.<anonymous> (C:\Users\XXX\Desktop\nat-test-2\node_modules\nat-api\lib\pmp\index.js:50:42)
at Socket.emit (events.js:210:5)
at UDP.onMessage [as onmessage] (dgram.js:861:8)
The culprit, line 257 in lib/pmp/index.js : parsed.vers = msg.readUInt8(0)
. Apparently msg is undefined. Adding if (!msg) return;
after line 231 ( if (this._queue.length === 0) return
) in lib/pmp/index.js fixes it: no more exceptions. Bear in mind that this is possible by commenting-out the UPNP mapping code.
Would it be possible to have the option to toggle the mapping type between UPNP and NAT-PMP ? Something along the lines of:
const clientUPNP = new NatAPI({ autoUpdate: true, mappingType: 'UPNP' });
const clientPMP = new NatAPI({ autoUpdate: true, mappingType: 'PMP' });
And of course if mappingType
is left out it should probably default to UPNP.
nat-api version: 0.1.2
Test 1:
Maps port 10000 UDP and bombs for TCP with:
Test 2 (with NULL protocol in options):
Maps port 10000 UDP and bombs for TCP with:
Test 3:
Works:
Port mapped!
Test 4:
Works:
Port mapped!
Test 5:
TCP port mapped, UDP port bombs:
Test 6:
UDP port maps, TCP port bombs:
Conclusion: dual TCP/UDP port mapping does not work as expected.