coapjs / node-coap

CoAP - Node.js style
MIT License
533 stars 156 forks source link

Multiple server instances can listen to the same port #268

Closed fillobotto closed 3 years ago

fillobotto commented 3 years ago

I'm using coap 0.25.0 and trying to listen to the same port using two separate Coap server instances and I though it would have thrown error when attempting to listen again on the same port using listen(port, address, done). It comes out I am wrong, but is it a bug or what?

Here's a minimal sample of what I mean:

const coap = require("coap");

const port = 5683;
const address = "localhost";

let server = coap.createServer();
let server2 = coap.createServer();

server.once("error", (err) => {
    throw new Error(err);
});

server2.once("error", (err) => {
    throw new Error(err);
});

server.listen(port, address, (res) => {
    console.log(`error is ${res}`);
});

server2.listen(port, address, (res) => {
    console.log(`error is ${res}`);
});

Both the done callbacks correctly return and err is undefined. Shouldn't the second call return an error? Or I just have to assume that multiple servers can listen to connections on the same port?

JKRhb commented 3 years ago

Thank you for reporting this issue! I am not actually sure if this is a feature or a bug 🤔 Also, I am not sure if there is a way to figure out which ports are currently used by CoAP servers as they are probably not sharing a global variable. Maybe this is something that has to be checked for in your application. I will also have a look into the server implementation, though, and see if it can be fixed there :)

relu91 commented 3 years ago

In my experience with TCP native sockets, you can't bind a socket on the same address and port in your local machine. So it is actually something that should be raised by the "native" side of the coap library. No global variables should be needed. I don't know if this actually applies to UDP.

JKRhb commented 3 years ago

I now found the reason why reusing the same port for two servers works: The parameter reuseAddr is set to true when the dgram.createSocket method is called:

https://github.com/mcollina/node-coap/blob/9166c3d100a3a6eafd63d27bb4190204520b7feb/lib/server.js#L256-L259

I am not sure, however, if this is actually a problem and an error should be thrown if the same address/port combination is being used. If I am not mistaken, only the first server that starts listening (edit: to message/request events apparently) will receive incoming messages anyway.