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.
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)