Socket.io: Remote address (IP) is always undefined

Created on 19 Jun 2017  Â·  16Comments  Â·  Source: socketio/socket.io

After upgrading socket.io from 1.x.x to 2.0.3 I can't get client's IP address — it's always undefined.

Test environment:
Ubuntu 14.04.5 LTS
Node.js 8.1.2
Socket.io 2.0.3

Server:

require('socket.io')(8888).on('connection', socket => {
    console.log('socket.client.conn.remoteAddress', socket.client.conn.remoteAddress);
    console.log('socket.request.connection.remoteAddress', socket.request.connection.remoteAddress);
    console.log('socket.handshake.address', socket.handshake.address);
});

Client:

<script src="http://192.168.13.13:8888/socket.io/socket.io.js"></script>
<script>
    var socket = io('http://192.168.13.13:8888', { transports: [ 'websocket' ] });
    socket.on('connect', function(){
        console.log('connected');
    });
</script>

Aaaaand it's gone.

daniil@ubuntu:/var/srv/node-test# node server.js
socket.client.conn.remoteAddress undefined
socket.request.connection.remoteAddress undefined
socket.handshake.address undefined

When I remove { transports: [ 'websocket' ] } from client's code, I got this:

socket.client.conn.remoteAddress ::ffff:192.168.13.12
socket.request.connection.remoteAddress ::ffff:192.168.13.12
socket.handshake.address ::ffff:192.168.13.12

Socket.io 1.7.4 works fine. Socket.io >=2.0.1 is not.

Most helpful comment

@Serveurperso You can also turn off IPv6 if you http.listen(port, '0.0.0.0'). This way your server won't be IPv6-compatible, but also you will have remote addresses in IPv4 format. Given the fact you were going to convert IPv6 address to IPv4, IPv6 connectivity shouldn't be an issue for you.

All 16 comments

@kirick13 I am experiencing the exact same behavior with { transports: [ 'websocket' ] }

We also experience this issue on 2.x and are unable to upgrade for now.

https://github.com/thelounge/lounge/pull/1143
https://travis-ci.org/thelounge/lounge/builds/241839980

Was this fixed? As i'm having the same issue.

@burstpay I think its still not fixed.
Here you have the solution to obtain remoteAddress in Socket.io 2.x

Same problem here, always undefined... major issue !

Could you please try with engine.io v3.1.3?

@darrachequesne How do you access that remoteAddress in context of socket.io itself? socket.remoteAddress is undefined in connect callback.

Is it correct that it should be socket.request.connection.remoteAddress?

@xPaw it should be socket.handshake.address (ref)

Sorry, what is the proper way to upgrade my engine.io dependency from 3.1.0 to 3.1.3 ?
Can I edit the package.json from my socket.io 2.0.3 and how to refresh the dependency ?

I installed engine.io inside my own project and it's clean:)
npm install engine.io

Now "socket.handshake.address" work but I get an ipv4-mapped IPv6address. I must parse the string (or better, upgrade my log display to ipv6)
::ffff:127.0.0.

Issue close...

@Serveurperso You can also turn off IPv6 if you http.listen(port, '0.0.0.0'). This way your server won't be IPv6-compatible, but also you will have remote addresses in IPv4 format. Given the fact you were going to convert IPv6 address to IPv4, IPv6 connectivity shouldn't be an issue for you.

io.on('connection', function(socket){
  const address = socket.handshake.headers["x-forwarded-for"].split(",")[0];
  console.log(address);
});

@Serveurperso You can also turn off IPv6 if you http.listen(port, '0.0.0.0'). This way your server won't be IPv6-compatible, but also you will have remote addresses in IPv4 format. Given the fact you were going to convert IPv6 address to IPv4, IPv6 connectivity shouldn't be an issue for you.

@polkovnikov-ph Thanks for this great solution. Is this option somewhere documented?

It was a long time ago, but I'm pretty sure I just made a google search with something like "http listen force ipv4" and opened first link that lead to stackoverflow.

The issue is not actually related to Node.js. It's platform-specific socket behavior. Listening on :: meta-address might or might not listen also on 0.0.0.0. The choice of :: as default address in listen call on IPv6-enabled systems was quite arbitrary and misleading though. This is why good API design generally implies functions take no default parameters (as enforced language-wide in Haskell and several other languages, for example).

Thanks for your prompt response.

socket Object SERVER SIDE !

const sha_last_index_colon = socket.handshake.address.lastIndexOf(':');
if (sha_last_index_colon > -1) {
    if (socket.handshake.address.lastIndexOf('.') > -1) {
        socket.this_is_a_demo = {
            ipv4: socket.handshake.address.slice(sha_last_index_colon + 1),
            ipv6: socket.handshake.address.slice(0, sha_last_index_colon)
        }
    } else {
        socket.this_is_a_demo = {
            ipv6: socket.handshake.address
        }
    }
} else {
    socket.this_is_a_demo = {
        ipv4: socket.handshake.address
    }
}
console.log(socket.this_is_a_demo.ipv4);
console.log(socket.this_is_a_demo.ipv6);
Was this page helpful?
0 / 5 - 0 ratings