-
Notifications
You must be signed in to change notification settings - Fork 7.3k
Race condition when getting remoteAddress of connection #7566
Comments
Your analysis is correct but...
That's intentional, see commit joyent/libuv@752ac30. The kernel's copying out of the struct sockaddr has a performance cost and it's frequently unused. Besides, you'd have to store it somewhere. That's not possible without breaking the uv_tcp_t ABI. Even if libuv stored the struct sockaddr, you'd still have the getpeername() issue with outbound connections. Lastly, I bet there are people out there doing crazy things like remapping network interfaces on the fly and expecting the result of socket.remoteAddr to reflect that. |
When doing either The fact that libuv's In any, yes it's unfortunate that right now you may not get that information -- we know about it and we're working on a solution that improves the situation. |
I guess that we could fix The correct behaviour (I think) is to instead of |
It seems my issue is related #16523 Any status update on it? It's a kind of weird expectation that |
I managed to detect, that you can get |
Is there any update on this? Am seeing this happening 25% of the time in nodetunes, wondered if there is a fix due out? |
Checks that the client address variable of `socket` is set, and returns loopback interface if it isn't. Hacky, but hey, until someone fixes this nodejs/node-v0.x-archive#7566, blame node.js :)
This repo is an archive, if you're still seeing this please open an issue at nodejs/node (if there isn't one there already). |
If the connection has already been closed before the
connect
event is handled by user code, theremoteAddress
of the connection will not be available.Reproducing this is very hard but I managed to get it working sometimes with gnu netcat version 0.7.1 with the close flag, executed on another machine:
Testcase
Output
More info
Information about the socket can be provided when calling
accept
, howeverlibuv
ignores that data:https://github.com/joyent/libuv/blob/9b4f2b84f10c96efa37910f324bc66e27aec3828/src/unix/core.c#L406
Instead, when doing
c.remoteAddress
a call togetpeername
is executed.remoteAddress
https://github.com/joyent/node/blob/940974ed039d3c9a8befe608d9c95b2ffdb457d3/lib/net.js#L569_getpeername
https://github.com/joyent/node/blob/940974ed039d3c9a8befe608d9c95b2ffdb457d3/lib/net.js#L555TCPWrap::GetPeerName
https://github.com/joyent/node/blob/940974ed039d3c9a8befe608d9c95b2ffdb457d3/src/tcp_wrap.cc#L182uv_tcp_getpeername
https://github.com/joyent/libuv/blob/9b4f2b84f10c96efa37910f324bc66e27aec3828/src/unix/tcp.c#L187I think that the only reliable way to get the
remoteAddress
is to get it from theaccept
call and store it along with the connection.Additional error
In addition to the assertion error, if I only log the
c.remoteAddress
and don't terminate the process, I will get the following error. It's not emitted on the server (net.createServer
) and thus I can't trap it withserver.on('error', ...)
.The text was updated successfully, but these errors were encountered: