introduce listen on specific interface
Signed-off-by: Andy Green <andy@warmcat.com>
diff --git a/lib/libwebsockets.c b/lib/libwebsockets.c
index cf814ec..f94b11c 100644
--- a/lib/libwebsockets.c
+++ b/lib/libwebsockets.c
@@ -20,6 +20,7 @@
*/
#include "private-libwebsockets.h"
+#include <ifaddrs.h>
/*
* In-place str to lower case
@@ -101,6 +102,33 @@
}
#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_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 @@
* @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 @@
*/
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 @@
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 927d93d..acb27b1 100644
--- a/lib/libwebsockets.h
+++ b/lib/libwebsockets.h
@@ -125,7 +125,7 @@
/* 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 @@
};
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 e351ab8..cd3e70d 100644
--- a/libwebsockets-api-doc.html
+++ b/libwebsockets-api-doc.html
@@ -120,13 +120,15 @@
nothing is pending, or as soon as it services whatever was pending.
</blockquote>
<hr>
-<h2>libwebsocket_callback_on_writable - Request a callback when this socket becomes able to be written to without blocking *</h2>
+<h2>libwebsocket_callback_on_writable - Request a callback when this socket becomes able to be written to without blocking</h2>
<i>int</i>
<b>libwebsocket_callback_on_writable</b>
(<i>struct libwebsocket_context *</i> <b>this</b>,
<i>struct libwebsocket *</i> <b>wsi</b>)
<h3>Arguments</h3>
<dl>
+<dt><b>this</b>
+<dd>libwebsockets context
<dt><b>wsi</b>
<dd>Websocket connection instance to get callback for
</dl>
@@ -217,6 +219,7 @@
<i>struct libwebsocket_context *</i>
<b>libwebsocket_create_context</b>
(<i>int</i> <b>port</b>,
+<i>const char *</i> <b>interface</b>,
<i>struct libwebsocket_protocols *</i> <b>protocols</b>,
<i>const char *</i> <b>ssl_cert_filepath</b>,
<i>const char *</i> <b>ssl_private_key_filepath</b>,
@@ -229,6 +232,9 @@
<dd>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
+<dt><b>interface</b>
+<dd>NULL to bind the listen socket to all interfaces, or the
+interface name, eg, "eth2"
<dt><b>protocols</b>
<dd>Array of structures listing supported protocols and a protocol-
specific callback for each one. The list is ended with an
@@ -469,6 +475,8 @@
<i>size_t</i> <b>len</b>)
<h3>Arguments</h3>
<dl>
+<dt><b>context</b>
+<dd>Websockets context
<dt><b>wsi</b>
<dd>Opaque websocket instance pointer
<dt><b>reason</b>
diff --git a/test-server/test-client.c b/test-server/test-client.c
index e887971..09528c2 100644
--- a/test-server/test-client.c
+++ b/test-server/test-client.c
@@ -224,7 +224,7 @@
* 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 c04bb87..1ecfb4d 100644
--- a/test-server/test-ping.c
+++ b/test-server/test-ping.c
@@ -400,7 +400,7 @@
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 74b1c02..29595a1 100644
--- a/test-server/test-server-extpoll.c
+++ b/test-server/test-server-extpoll.c
@@ -419,6 +419,7 @@
{ "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 @@
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 <andy@warmcat.com> "
"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 @@
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=<p>] [--ssl]\n");
@@ -465,8 +473,8 @@
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 db22868..2620908 100644
--- a/test-server/test-server.c
+++ b/test-server/test-server.c
@@ -369,6 +369,7 @@
{ "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 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 @@
"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 @@
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=<p>] [--ssl]\n");
@@ -417,8 +425,8 @@
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;