diff --git a/lib/libwebsockets.c b/lib/libwebsockets.c index cf814ec7..f94b11c0 100644 --- a/lib/libwebsockets.c +++ b/lib/libwebsockets.c @@ -20,6 +20,7 @@ */ #include "private-libwebsockets.h" +#include /* * In-place str to lower case @@ -101,6 +102,33 @@ libwebsockets_decode_ssl_error(void) } #endif + +static int +interface_to_sa(const char* ifname, struct sockaddr_in *addr, size_t addrlen) +{ + int rc = -1; + struct ifaddrs *ifr; + struct ifaddrs *ifc; + struct sockaddr_in *sin; + + getifaddrs(&ifr); + for (ifc = ifr; ifc != NULL; ifc = ifc->ifa_next) { + if (strcmp(ifc->ifa_name, ifname)) + continue; + if (ifc->ifa_addr == NULL) + continue; + sin = (struct sockaddr_in *)ifc->ifa_addr; + if (sin->sin_family != AF_INET) + continue; + memcpy(addr, sin, addrlen); + rc = 0; + } + + freeifaddrs(ifr); + + return rc; +} + void libwebsocket_close_and_free_session(struct libwebsocket_context *this, struct libwebsocket *wsi) @@ -1201,7 +1229,8 @@ libwebsocket_service(struct libwebsocket_context *this, int timeout_ms) * libwebsocket_callback_on_writable() - Request a callback when this socket * becomes able to be written to without * blocking - * * + * + * @this: libwebsockets context * @wsi: Websocket connection instance to get callback for */ @@ -1366,6 +1395,8 @@ static void sigpipe_handler(int x) * @port: Port to listen on... you can use 0 to suppress listening on * any port, that's what you want if you are not running a * websocket server at all but just using it as a client + * @interface: NULL to bind the listen socket to all interfaces, or the + * interface name, eg, "eth2" * @protocols: Array of structures listing supported protocols and a protocol- * specific callback for each one. The list is ended with an * entry that has a NULL callback pointer. @@ -1406,7 +1437,7 @@ static void sigpipe_handler(int x) */ struct libwebsocket_context * -libwebsocket_create_context(int port, +libwebsocket_create_context(int port, const char *interface, struct libwebsocket_protocols *protocols, const char *ssl_cert_filepath, const char *ssl_private_key_filepath, @@ -1622,7 +1653,11 @@ libwebsocket_create_context(int port, bzero((char *) &serv_addr, sizeof(serv_addr)); serv_addr.sin_family = AF_INET; - serv_addr.sin_addr.s_addr = INADDR_ANY; + if (interface == NULL) + serv_addr.sin_addr.s_addr = INADDR_ANY; + else + interface_to_sa(interface, &serv_addr, + sizeof(serv_addr)); serv_addr.sin_port = htons(port); n = bind(sockfd, (struct sockaddr *) &serv_addr, diff --git a/lib/libwebsockets.h b/lib/libwebsockets.h index 927d93df..acb27b13 100644 --- a/lib/libwebsockets.h +++ b/lib/libwebsockets.h @@ -125,7 +125,7 @@ struct libwebsocket_context; /* document the generic callback (it's a fake prototype under this) */ /** * callback() - User server actions - * @this: Websockets context + * @context: Websockets context * @wsi: Opaque websocket instance pointer * @reason: The reason for the call * @user: Pointer to per-session user data allocated by library @@ -289,7 +289,7 @@ struct libwebsocket_protocols { }; extern struct libwebsocket_context * -libwebsocket_create_context(int port, +libwebsocket_create_context(int port, const char * interface, struct libwebsocket_protocols *protocols, const char *ssl_cert_filepath, const char *ssl_private_key_filepath, int gid, int uid, diff --git a/libwebsockets-api-doc.html b/libwebsockets-api-doc.html index e351ab87..cd3e70d0 100644 --- a/libwebsockets-api-doc.html +++ b/libwebsockets-api-doc.html @@ -120,13 +120,15 @@ would call it with a timeout_ms of 0, so it returns immediately if nothing is pending, or as soon as it services whatever was pending.
-

libwebsocket_callback_on_writable - Request a callback when this socket becomes able to be written to without blocking *

+

libwebsocket_callback_on_writable - Request a callback when this socket becomes able to be written to without blocking

int libwebsocket_callback_on_writable (struct libwebsocket_context * this, struct libwebsocket * wsi)

Arguments

+
this +
libwebsockets context
wsi
Websocket connection instance to get callback for
@@ -217,6 +219,7 @@ has been created. struct libwebsocket_context * libwebsocket_create_context (int port, +const char * interface, struct libwebsocket_protocols * protocols, const char * ssl_cert_filepath, const char * ssl_private_key_filepath, @@ -229,6 +232,9 @@ has been created.
Port to listen on... you can use 0 to suppress listening on any port, that's what you want if you are not running a websocket server at all but just using it as a client +
interface +
NULL to bind the listen socket to all interfaces, or the +interface name, eg, "eth2"
protocols
Array of structures listing supported protocols and a protocol- specific callback for each one. The list is ended with an @@ -469,6 +475,8 @@ This function creates a connection to a remote server size_t len)

Arguments

+
context +
Websockets context
wsi
Opaque websocket instance pointer
reason diff --git a/test-server/test-client.c b/test-server/test-client.c index e8879718..09528c29 100644 --- a/test-server/test-client.c +++ b/test-server/test-client.c @@ -224,7 +224,7 @@ int main(int argc, char **argv) * For this client-only demo, we tell it to not listen on any port. */ - context = libwebsocket_create_context(CONTEXT_PORT_NO_LISTEN, + context = libwebsocket_create_context(CONTEXT_PORT_NO_LISTEN, NULL, protocols, NULL, NULL, -1, -1, 0); if (context == NULL) { fprintf(stderr, "Creating libwebsocket context failed\n"); diff --git a/test-server/test-ping.c b/test-server/test-ping.c index c04bb872..1ecfb4de 100644 --- a/test-server/test-ping.c +++ b/test-server/test-ping.c @@ -400,7 +400,7 @@ int main(int argc, char **argv) if (w.ws_col > 0) screen_width = w.ws_col; - context = libwebsocket_create_context(CONTEXT_PORT_NO_LISTEN, + context = libwebsocket_create_context(CONTEXT_PORT_NO_LISTEN, NULL, protocols, NULL, NULL, -1, -1, 0); if (context == NULL) { fprintf(stderr, "Creating libwebsocket context failed\n"); diff --git a/test-server/test-server-extpoll.c b/test-server/test-server-extpoll.c index 74b1c02d..29595a18 100644 --- a/test-server/test-server-extpoll.c +++ b/test-server/test-server-extpoll.c @@ -419,6 +419,7 @@ static struct option options[] = { { "port", required_argument, NULL, 'p' }, { "ssl", no_argument, NULL, 's' }, { "killmask", no_argument, NULL, 'k' }, + { "interface", required_argument, NULL, 'i' }, { NULL, 0, 0, 0 } }; @@ -436,13 +437,15 @@ int main(int argc, char **argv) struct libwebsocket_context *context; int opts = 0; unsigned int oldus = 0; + char interface_name[128] = ""; + const char * interface = NULL; fprintf(stderr, "libwebsockets test server with external poll()\n" "(C) Copyright 2010-2011 Andy Green " "licensed under LGPL2.1\n"); while (n >= 0) { - n = getopt_long(argc, argv, "khsp:", options, NULL); + n = getopt_long(argc, argv, "i:khsp:", options, NULL); if (n < 0) continue; switch (n) { @@ -455,6 +458,11 @@ int main(int argc, char **argv) case 'p': port = atoi(optarg); break; + case 'i': + strncpy(interface_name, optarg, sizeof interface_name); + interface_name[(sizeof interface_name) - 1] = '\0'; + interface = interface_name; + break; case 'h': fprintf(stderr, "Usage: test-server " "[--port=

] [--ssl]\n"); @@ -465,8 +473,8 @@ int main(int argc, char **argv) if (!use_ssl) cert_path = key_path = NULL; - context = libwebsocket_create_context(port, protocols, cert_path, - key_path, -1, -1, opts); + context = libwebsocket_create_context(port, interface, protocols, + cert_path, key_path, -1, -1, opts); if (context == NULL) { fprintf(stderr, "libwebsocket init failed\n"); return -1; diff --git a/test-server/test-server.c b/test-server/test-server.c index db22868f..26209088 100644 --- a/test-server/test-server.c +++ b/test-server/test-server.c @@ -369,6 +369,7 @@ static struct option options[] = { { "port", required_argument, NULL, 'p' }, { "ssl", no_argument, NULL, 's' }, { "killmask", no_argument, NULL, 'k' }, + { "interface", required_argument, NULL, 'i' }, { NULL, 0, 0, 0 } }; @@ -385,6 +386,8 @@ int main(int argc, char **argv) int use_ssl = 0; struct libwebsocket_context *context; int opts = 0; + char interface_name[128] = ""; + const char * interface = NULL; #ifdef LWS_NO_FORK unsigned int oldus = 0; #endif @@ -394,7 +397,7 @@ int main(int argc, char **argv) "licensed under LGPL2.1\n"); while (n >= 0) { - n = getopt_long(argc, argv, "khsp:", options, NULL); + n = getopt_long(argc, argv, "i:khsp:", options, NULL); if (n < 0) continue; switch (n) { @@ -407,6 +410,11 @@ int main(int argc, char **argv) case 'p': port = atoi(optarg); break; + case 'i': + strncpy(interface_name, optarg, sizeof interface_name); + interface_name[(sizeof interface_name) - 1] = '\0'; + interface = interface_name; + break; case 'h': fprintf(stderr, "Usage: test-server " "[--port=

] [--ssl]\n"); @@ -417,8 +425,8 @@ int main(int argc, char **argv) if (!use_ssl) cert_path = key_path = NULL; - context = libwebsocket_create_context(port, protocols, cert_path, - key_path, -1, -1, opts); + context = libwebsocket_create_context(port, interface, protocols, + cert_path, key_path, -1, -1, opts); if (context == NULL) { fprintf(stderr, "libwebsocket init failed\n"); return -1;