summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--listen.c7
-rw-r--r--main.c18
-rw-r--r--uhttpd.h2
3 files changed, 21 insertions, 6 deletions
diff --git a/listen.c b/listen.c
index 2a54888..908127a 100644
--- a/listen.c
+++ b/listen.c
@@ -128,7 +128,7 @@ void uh_setup_listeners(void)
}
}
-int uh_socket_bind(const char *host, const char *port, bool tls)
+int uh_socket_bind(const char *host, const char *port, const char *device, bool tls)
{
int sock = -1;
int yes = 1;
@@ -169,6 +169,11 @@ int uh_socket_bind(const char *host, const char *port, bool tls)
goto error;
}
+ if (device && setsockopt(sock, SOL_SOCKET, SO_BINDTODEVICE, device, strlen(device)) < 0) {
+ perror("setsockopt()");
+ goto error;
+ }
+
/* bind */
if (bind(sock, p->ai_addr, p->ai_addrlen) < 0) {
perror("bind()");
diff --git a/main.c b/main.c
index 73e3d42..8f51813 100644
--- a/main.c
+++ b/main.c
@@ -103,7 +103,7 @@ static void uh_config_parse(void)
fclose(c);
}
-static int add_listener_arg(char *arg, bool tls)
+static int add_listener_arg(char *arg, const char *device, bool tls)
{
char *host = NULL;
char *port = arg;
@@ -125,7 +125,7 @@ static int add_listener_arg(char *arg, bool tls)
}
}
- return uh_socket_bind(host, port, tls);
+ return uh_socket_bind(host, port, device, tls);
}
static int usage(const char *name)
@@ -134,6 +134,8 @@ static int usage(const char *name)
"Usage: %s -p [addr:]port -h docroot\n"
" -f Do not fork to background\n"
" -c file Configuration file, default is '/etc/httpd.conf'\n"
+ " -b interface Bind subsequent ports (and addresses) to specified"
+ " network interface with SO_BINDTODEVICE\n"
" -p [addr:]port Bind to specified address and port, multiple allowed\n"
#ifdef HAVE_TLS
" -s [addr:]port Like -p but provide HTTPS on this port\n"
@@ -256,6 +258,7 @@ int main(int argc, char **argv)
#ifdef HAVE_LUA
const char *lua_prefix = NULL, *lua_handler = NULL;
#endif
+ char *device = NULL;
BUILD_BUG_ON(sizeof(uh_buf) < PATH_MAX);
@@ -263,7 +266,7 @@ int main(int argc, char **argv)
init_defaults_pre();
signal(SIGPIPE, SIG_IGN);
- while ((ch = getopt(argc, argv, "A:aC:c:Dd:E:e:fh:H:I:i:K:k:L:l:m:N:n:P:p:qRr:Ss:T:t:U:u:Xx:y:")) != -1) {
+ while ((ch = getopt(argc, argv, "A:abC:c:Dd:E:e:fh:H:I:i:K:k:L:l:m:N:n:P:p:qRr:Ss:T:t:U:u:Xx:y:")) != -1) {
switch(ch) {
#ifdef HAVE_TLS
case 'C':
@@ -282,6 +285,13 @@ int main(int argc, char **argv)
conf.tls_redirect = 1;
break;
+ case 'b':
+ if (optarg[0] == '\0')
+ device = NULL;
+ else
+ device = optarg;
+ break;
+
case 's':
n_tls++;
/* fall through */
@@ -297,7 +307,7 @@ int main(int argc, char **argv)
#endif
case 'p':
optarg = strdup(optarg);
- bound += add_listener_arg(optarg, (ch == 's'));
+ bound += add_listener_arg(optarg, device, (ch == 's'));
break;
case 'h':
diff --git a/uhttpd.h b/uhttpd.h
index e61e176..77273a7 100644
--- a/uhttpd.h
+++ b/uhttpd.h
@@ -289,7 +289,7 @@ bool uh_accept_client(int fd, bool tls);
void uh_unblock_listeners(void);
void uh_setup_listeners(void);
-int uh_socket_bind(const char *host, const char *port, bool tls);
+int uh_socket_bind(const char *host, const char *port, const char *device, bool tls);
int uh_first_tls_port(int family);