diff options
author | Mikael Magnusson <mikma@users.sourceforge.net> | 2021-09-02 01:10:43 +0200 |
---|---|---|
committer | Mikael Magnusson <mikma@users.sourceforge.net> | 2021-09-08 02:01:24 +0200 |
commit | 553ebab10f3ae777a55b10e2da0595c82cb06819 (patch) | |
tree | 4e5616e810925c25a3ff3e24cc5d996826605a02 | |
parent | 15346de8d3ba422002496526ee24c62a3601ab8c (diff) |
uhttpd: add SO_BINDTODEVICE support
Add command line option "-b <interface>" which binds the ports
(and addresses) in the following "-p" and "-s" options to the specified
network interface with SO_BINDTODEVICE.
Using SO_BINDTODEVICE means uhttpd will only accept incoming traffic from
the specified network interface.
Signed-off-by: Mikael Magnusson <mikma@users.sourceforge.net>
-rw-r--r-- | listen.c | 7 | ||||
-rw-r--r-- | main.c | 18 | ||||
-rw-r--r-- | uhttpd.h | 2 |
3 files changed, 21 insertions, 6 deletions
@@ -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()"); @@ -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': @@ -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); |