summaryrefslogtreecommitdiffhomepage
path: root/netio.c
diff options
context:
space:
mode:
Diffstat (limited to 'netio.c')
-rw-r--r--netio.c19
1 files changed, 18 insertions, 1 deletions
diff --git a/netio.c b/netio.c
index 0d69d3a..50d1e23 100644
--- a/netio.c
+++ b/netio.c
@@ -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);