diff options
Diffstat (limited to 'netio.c')
-rw-r--r-- | netio.c | 19 |
1 files changed, 18 insertions, 1 deletions
@@ -350,6 +350,18 @@ void set_sock_nodelay(int sock) { setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, (void*)&val, sizeof(val)); } +int set_sock_bindtodevice(int sock, const char* device) { +#ifdef SO_BINDTODEVICE + if (device && setsockopt(sock, SOL_SOCKET, SO_BINDTODEVICE, device, strlen(device)) < 0) { + TRACE(("set_sock_bindtodevice(%s) failed for socket %d: %s", device, sock ,strerror(errno))) + } + return 0; +#else + TRACE(("set_sock_bindtodevice not supported")) + return -1; +#endif /* SO_BINDTODEVICE */ +} + #if DROPBEAR_SERVER_TCP_FAST_OPEN void set_listen_fast_open(int sock) { int qlen = MAX(MAX_UNAUTH_PER_IP, 5); @@ -451,7 +463,7 @@ int get_sock_port(int sock) { * Returns the number of sockets bound on success, or -1 on failure. On * failure, if errstring wasn't NULL, it'll be a newly malloced error * string.*/ -int dropbear_listen(const char* address, const char* port, +int dropbear_listen(const char* address, const char* port, const char* device, int *socks, unsigned int sockcount, char **errstring, int *maxfd) { struct addrinfo hints, *res = NULL, *res0 = NULL; @@ -551,6 +563,11 @@ int dropbear_listen(const char* address, const char* port, #endif set_sock_nodelay(sock); + if (device && set_sock_bindtodevice(sock, device) < 0) { + close(sock); + continue; + } + if (bind(sock, res->ai_addr, res->ai_addrlen) < 0) { err = errno; close(sock); |