summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--listen.c7
-rw-r--r--main.c22
-rw-r--r--uhttpd.h2
3 files changed, 25 insertions, 6 deletions
diff --git a/listen.c b/listen.c
index c5ba16f..922f447 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 de5f2c3..1b65e5c 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\n"
+ " 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"
@@ -286,6 +288,7 @@ int main(int argc, char **argv)
#ifdef HAVE_UCODE
const char *ucode_prefix = NULL, *ucode_handler = NULL;
#endif
+ char *device = NULL;
BUILD_BUG_ON(sizeof(uh_buf) < PATH_MAX);
@@ -293,7 +296,7 @@ int main(int argc, char **argv)
init_defaults_pre();
signal(SIGPIPE, SIG_IGN);
- while ((ch = getopt(argc, argv, "A:ab:C:c:Dd:E:e:fh:H:I:i:K:k:L:l:m:N:n:O:o:P:p:qRr:Ss:T:t:U:u:Xx:y:")) != -1) {
+ while ((ch = getopt(argc, argv, "A:aB:b:C:c:Dd:E:e:fh:H:I:i:K:k:L:l:m:N:n:O:o:P:p:qRr:Ss:T:t:U:u:Xx:y:")) != -1) {
switch(ch) {
#ifdef HAVE_TLS
case 'C':
@@ -325,9 +328,17 @@ int main(int argc, char **argv)
"ignoring -%c\n", ch);
break;
#endif
+ case 'B':
+ free(device);
+ if (optarg[0] == '\0')
+ device = NULL;
+ else
+ device = strdup(optarg);
+ break;
+
case 'p':
optarg = strdup(optarg);
- bound += add_listener_arg(optarg, (ch == 's'));
+ bound += add_listener_arg(optarg, device, (ch == 's'));
free(optarg);
break;
@@ -630,6 +641,9 @@ int main(int argc, char **argv)
return 1;
#endif
+ free(device);
+ device = NULL;
+
/* fork (if not disabled) */
if (!nofork) {
switch (fork()) {
diff --git a/uhttpd.h b/uhttpd.h
index c755df6..8445c60 100644
--- a/uhttpd.h
+++ b/uhttpd.h
@@ -305,7 +305,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);