Patch to enable SO_BINDTODEVICE
Ben Greear
greearb at candelatech.com
Wed Jan 9 23:19:57 UTC 2013
In order to play some tricks and send requests to myself
over external network interfaces, I need to enable the
SO_BINDTODEVICE socket option.
Here's the patch that I'm trying out. If there is a better patch format
or place to send this, please let me know.
Thanks,
Ben
From fe7226036848bd1f4f74dd8186a176b17f974614 Mon Sep 17 00:00:00 2001
From: Ben Greear <greearb at candelatech.com>
Date: Wed, 9 Jan 2013 15:01:35 -0800
Subject: [PATCH] Support bind_dev=[ifname] in accept configuration clause.
If this option is enabled, nginx will call SO_BINDTODEVICE
on the particular device name. This can be helpful for
some types of firewalling, and routing setups.
Signed-off-by: Ben Greear <greearb at candelatech.com>
---
src/core/ngx_connection.c | 21 +++++++++++++++++++++
src/core/ngx_connection.h | 1 +
src/http/ngx_http.c | 13 +++++++++++++
src/http/ngx_http_core_module.c | 6 ++++++
src/http/ngx_http_core_module.h | 1 +
5 files changed, 42 insertions(+)
diff --git a/src/core/ngx_connection.c b/src/core/ngx_connection.c
index c818114..a3a8101 100644
--- a/src/core/ngx_connection.c
+++ b/src/core/ngx_connection.c
@@ -397,6 +397,27 @@ ngx_open_listening_sockets(ngx_cycle_t *cycle)
continue;
}
+ if (ls[i].dev_name[0]) {
+#ifdef SO_BINDTODEVICE
+ if (setsockopt(s, SOL_SOCKET, SO_BINDTODEVICE,
+ ls[i].dev_name, strlen(ls[i].dev_name))) {
+ ngx_log_error(NGX_LOG_EMERG, log, errno, "setsockopt (%i, BINDTODEVICE, %s) failed",
+ s, ls[i].dev_name);
+ return NGX_ERROR;
+ }
+ else {
+ ngx_log_error(NGX_LOG_EMERG, log, 0, "setsockopt (%i, BINDTODEVICE, %s) succeeded!",
+ s, ls[i].dev_name);
+ }
+#else
+ ngx_log_error(NGX_LOG_EMERG, log, 0,
+ "setsockopt (%i, BINDTODEVICE, %s) not supported on this platform. Please remove the bind_dev= option for 'listen' directive.",
+ s, ls[i].dev_name);
+ return NGX_ERROR;
+#endif
+ }
+
+
#if (NGX_HAVE_UNIX_DOMAIN)
if (ls[i].sockaddr->sa_family == AF_UNIX) {
diff --git a/src/core/ngx_connection.h b/src/core/ngx_connection.h
index 87fd087..e5c030c 100644
--- a/src/core/ngx_connection.h
+++ b/src/core/ngx_connection.h
@@ -18,6 +18,7 @@ typedef struct ngx_listening_s ngx_listening_t;
struct ngx_listening_s {
ngx_socket_t fd;
+ char dev_name[32]; /* Use SO_BINDTODEVICE if this is not zero-length */
struct sockaddr *sockaddr;
socklen_t socklen; /* size of sockaddr */
size_t addr_text_max_len;
diff --git a/src/http/ngx_http.c b/src/http/ngx_http.c
index f1f8a48..9aa732b 100644
--- a/src/http/ngx_http.c
+++ b/src/http/ngx_http.c
@@ -1618,6 +1618,16 @@ ngx_http_cmp_conf_addrs(const void *one, const void *two)
return -1;
}
+ if (first->opt.dev_name[0] && !second->opt.dev_name[0]) {
+ /* shift explicit bind_dev()ed addresses to the start */
+ return -1;
+ }
+
+ if (!first->opt.dev_name[0] && second->opt.dev_name[0]) {
+ /* shift explicit bind_dev()ed addresses to the start */
+ return 1;
+ }
+
if (first->opt.bind && !second->opt.bind) {
/* shift explicit bind()ed addresses to the start */
return -1;
@@ -1768,6 +1778,9 @@ ngx_http_add_listening(ngx_conf_t *cf, ngx_http_conf_addr_t *addr)
ls->rcvbuf = addr->opt.rcvbuf;
ls->sndbuf = addr->opt.sndbuf;
+ strncpy(ls->dev_name, addr->opt.dev_name, sizeof(ls->dev_name));
+ ls->dev_name[sizeof(ls->dev_name) - 1] = 0;
+
ls->keepalive = addr->opt.so_keepalive;
#if (NGX_HAVE_KEEPALIVE_TUNABLE)
ls->keepidle = addr->opt.tcp_keepidle;
diff --git a/src/http/ngx_http_core_module.c b/src/http/ngx_http_core_module.c
index 27f082e..664f9b7 100644
--- a/src/http/ngx_http_core_module.c
+++ b/src/http/ngx_http_core_module.c
@@ -3937,6 +3937,12 @@ ngx_http_core_listen(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
continue;
}
+ if (ngx_strncmp(value[n].data, "bind_dev=", 9) == 0) {
+ strncpy(lsopt.dev_name, (char*)(value[n].data + 9), sizeof(lsopt.dev_name));
+ lsopt.dev_name[sizeof(lsopt.dev_name) - 1] = 0;
+ continue;
+ }
+
#if (NGX_HAVE_SETFIB)
if (ngx_strncmp(value[n].data, "setfib=", 7) == 0) {
lsopt.setfib = ngx_atoi(value[n].data + 7, value[n].len - 7);
diff --git a/src/http/ngx_http_core_module.h b/src/http/ngx_http_core_module.h
index ff1c2df..8ac0a7a 100644
--- a/src/http/ngx_http_core_module.h
+++ b/src/http/ngx_http_core_module.h
@@ -67,6 +67,7 @@ typedef struct {
} u;
socklen_t socklen;
+ char dev_name[32]; /* for use with bind_dev */
unsigned set:1;
unsigned default_server:1;
--
1.7.11.7
--
Ben Greear <greearb at candelatech.com>
Candela Technologies Inc http://www.candelatech.com
More information about the nginx-devel
mailing list