1

I'm struggling to understand how I'm supposed to capture the client IP address when using libwebsockets as a server.

From what I understand of the documentation, libwebsockets_get_peer_addresses is only available for use in the LWS_CALLBACK_FILTER_NETWORK_CONNECTION callback, but at that point the user data struct is seemingly not initialized, so any attempt to store here will segfault.

I would have expected the IP address to be in the request headers, as per other web servers such as Apache or nginx, but in this library it seems to be only available for a certain portion of the request process and is not copied into the headers.

This is what I'm attempting inside LWS_CALLBACK_FILTER_NETWORK_CONNECTION:

char client_name [IP_SIZE];
char client_ip   [IP_SIZE];

libwebsockets_get_peer_addresses(context, wsi, (int)(long)in, 
                                 client_name, sizeof(client_name),
                                 client_ip, sizeof(client_ip));

strncpy(pss->ip, client_ip, sizeof(client_ip)); // segfault

I've tested the strncpy inside another callback (LWS_CALLBACK_HTTP) so I know that it should work when that pss has been initialized.

Any help would be appreciated because I find the documentation for the library very difficult to comprehend.

GMemory
  • 137
  • 9

2 Answers2

2

You almost had it.

If you replace the (int)(long)in with libwebsocket_get_socket_fd(wsi) you can use it in other callbacks.

switch (reason) {
    case LWS_CALLBACK_HTTP:
             int IP_SIZE = 50;
             char client_name [IP_SIZE];
             char client_ip   [IP_SIZE];
             libwebsockets_get_peer_addresses(context, wsi, libwebsocket_get_socket_fd(wsi), 
                      client_name, sizeof(client_name), 
                      client_ip, sizeof(client_ip));

             fprintf(stderr, "Received network connect from %s (%s)\n",
                                    client_name, client_ip);
             ...
}

Output:

Received network connect from xxxxxxxx.dip0.t-ipconnect.de (93.208.91.xxx)

Kame Graf
  • 36
  • 4
  • Thanks! I knew there had to be something more sane than the workaround I have been using. I just wish I didn't have such trouble getting my head around the documentation... – GMemory Apr 08 '15 at 14:24
0

Okay, it appears I can work around this by getting the descriptor using libwebsocket_get_socket_fd in a later callback (such as LWS_CALLBACK_HTTP)

It concerns me that the documentation says " You will not need this unless you are doing something special " regarding this particular function, but it seems to work correctly after running a few tests.

I wonder if there's a less obtuse way of doing this.

GMemory
  • 137
  • 9