]> git.kaiwu.me - nginx.git/commitdiff
proxy_bind, fastcgi_bind, and memcached_bind
authorIgor Sysoev <igor@sysoev.ru>
Mon, 2 Nov 2009 15:24:02 +0000 (15:24 +0000)
committerIgor Sysoev <igor@sysoev.ru>
Mon, 2 Nov 2009 15:24:02 +0000 (15:24 +0000)
src/event/ngx_event_connect.c
src/event/ngx_event_connect.h
src/http/modules/ngx_http_fastcgi_module.c
src/http/modules/ngx_http_memcached_module.c
src/http/modules/ngx_http_proxy_module.c
src/http/ngx_http_upstream.c
src/http/ngx_http_upstream.h

index 839bb6ca43240b73146677d610db2117355855e1..dc1407563df619d63f135ff5998357b27397618d 100644 (file)
@@ -54,15 +54,7 @@ ngx_event_connect_peer(ngx_peer_connection_t *pc)
         {
             ngx_log_error(NGX_LOG_ALERT, pc->log, ngx_socket_errno,
                           "setsockopt(SO_RCVBUF) failed");
-
-            ngx_free_connection(c);
-
-            if (ngx_close_socket(s) == -1) {
-                ngx_log_error(NGX_LOG_ALERT, pc->log, ngx_socket_errno,
-                              ngx_close_socket_n " failed");
-            }
-
-            return NGX_ERROR;
+            goto failed;
         }
     }
 
@@ -70,14 +62,16 @@ ngx_event_connect_peer(ngx_peer_connection_t *pc)
         ngx_log_error(NGX_LOG_ALERT, pc->log, ngx_socket_errno,
                       ngx_nonblocking_n " failed");
 
-        ngx_free_connection(c);
+        goto failed;
+    }
 
-        if (ngx_close_socket(s) == -1) {
-            ngx_log_error(NGX_LOG_ALERT, pc->log, ngx_socket_errno,
-                          ngx_close_socket_n " failed");
-        }
+    if (pc->local) {
+        if (bind(s, pc->local->sockaddr, pc->local->socklen) == -1) {
+            ngx_log_error(NGX_LOG_CRIT, pc->log, ngx_socket_errno,
+                          "bind(%V) failed", &pc->local->name);
 
-        return NGX_ERROR;
+            goto failed;
+        }
     }
 
     c->recv = ngx_recv;
@@ -127,7 +121,7 @@ ngx_event_connect_peer(ngx_peer_connection_t *pc)
 
     if (ngx_add_conn) {
         if (ngx_add_conn(c) == NGX_ERROR) {
-            return NGX_ERROR;
+            goto failed;
         }
     }
 
@@ -199,7 +193,7 @@ ngx_event_connect_peer(ngx_peer_connection_t *pc)
         if (ngx_blocking(s) == -1) {
             ngx_log_error(NGX_LOG_ALERT, pc->log, ngx_socket_errno,
                           ngx_blocking_n " failed");
-            return NGX_ERROR;
+            goto failed;
         }
 
         /*
@@ -229,7 +223,7 @@ ngx_event_connect_peer(ngx_peer_connection_t *pc)
     }
 
     if (ngx_add_event(rev, NGX_READ_EVENT, event) != NGX_OK) {
-        return NGX_ERROR;
+        goto failed;
     }
 
     if (rc == -1) {
@@ -237,7 +231,7 @@ ngx_event_connect_peer(ngx_peer_connection_t *pc)
         /* NGX_EINPROGRESS */
 
         if (ngx_add_event(wev, NGX_WRITE_EVENT, event) != NGX_OK) {
-            return NGX_ERROR;
+            goto failed;
         }
 
         return NGX_AGAIN;
@@ -248,6 +242,17 @@ ngx_event_connect_peer(ngx_peer_connection_t *pc)
     wev->ready = 1;
 
     return NGX_OK;
+
+failed:
+
+    ngx_free_connection(c);
+
+    if (ngx_close_socket(s) == -1) {
+        ngx_log_error(NGX_LOG_ALERT, pc->log, ngx_socket_errno,
+                      ngx_close_socket_n " failed");
+    }
+
+    return NGX_ERROR;
 }
 
 
index 4f09524dd119e81a2814c4c26585c2899a8d183c..d64f1bb101ea3c9b9fb542167afffafe062e71e0 100644 (file)
@@ -55,6 +55,8 @@ struct ngx_peer_connection_s {
     ngx_atomic_t                    *lock;
 #endif
 
+    ngx_addr_t                      *local;
+
     int                              rcvbuf;
 
     ngx_log_t                       *log;
index a4a62e4cc48a8decdf426c200dac440a4f135fad..ba79cea0f6a192750dc3e711d084047d7932f24f 100644 (file)
@@ -240,6 +240,13 @@ static ngx_command_t  ngx_http_fastcgi_commands[] = {
       offsetof(ngx_http_fastcgi_loc_conf_t, upstream.ignore_client_abort),
       NULL },
 
+    { ngx_string("fastcgi_bind"),
+      NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
+      ngx_http_upsteam_bind_set_slot,
+      NGX_HTTP_LOC_CONF_OFFSET,
+      offsetof(ngx_http_fastcgi_loc_conf_t, upstream.local),
+      NULL },
+
     { ngx_string("fastcgi_connect_timeout"),
       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
       ngx_conf_set_msec_slot,
index 6cf58815bd08dd3027067b061a0684a3e3060fe0..92052153d0d0bbd12f104f3d1a9725bbe8852d9b 100644 (file)
@@ -63,6 +63,13 @@ static ngx_command_t  ngx_http_memcached_commands[] = {
       0,
       NULL },
 
+    { ngx_string("memcached_bind"),
+      NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
+      ngx_http_upsteam_bind_set_slot,
+      NGX_HTTP_LOC_CONF_OFFSET,
+      offsetof(ngx_http_memcached_loc_conf_t, upstream.local),
+      NULL },
+
     { ngx_string("memcached_connect_timeout"),
       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
       ngx_conf_set_msec_slot,
index 88530e1db3ca7ebf4fdc059dfab6acfc6c8b2c7c..8f169fe4368e9b9644045569df8c6629887c7173 100644 (file)
@@ -229,6 +229,13 @@ static ngx_command_t  ngx_http_proxy_commands[] = {
       offsetof(ngx_http_proxy_loc_conf_t, upstream.ignore_client_abort),
       NULL },
 
+    { ngx_string("proxy_bind"),
+      NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
+      ngx_http_upsteam_bind_set_slot,
+      NGX_HTTP_LOC_CONF_OFFSET,
+      offsetof(ngx_http_proxy_loc_conf_t, upstream.local),
+      NULL },
+
     { ngx_string("proxy_connect_timeout"),
       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
       ngx_conf_set_msec_slot,
index b95db57a7264bf3e16ea15c69d328aac2d9fd38e..a04aad3232a569168bf2449ba2a2fcac81f6e613 100644 (file)
@@ -479,6 +479,8 @@ ngx_http_upstream_init_request(ngx_http_request_t *r)
         return;
     }
 
+    u->peer.local = u->conf->local;
+
     clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
 
     u->output.alignment = clcf->directio_alignment;
@@ -4196,6 +4198,31 @@ ngx_http_upstream_add(ngx_conf_t *cf, ngx_url_t *u, ngx_uint_t flags)
 }
 
 
+char *
+ngx_http_upsteam_bind_set_slot(ngx_conf_t *cf, ngx_command_t *cmd,
+    void *conf)
+{
+    char  *p = conf;
+
+    ngx_str_t    *value;
+    ngx_addr_t  **paddr;
+
+    paddr = (ngx_addr_t **) (p + cmd->offset);
+
+    value = cf->args->elts;
+
+    *paddr = ngx_parse_addr(cf->pool, &value[1]);
+    if (*paddr) {
+        return NGX_CONF_OK;
+    }
+
+    ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+                       "invalid address \"%V\"", &value[1]);
+
+    return NGX_CONF_ERROR;
+}
+
+
 ngx_int_t
 ngx_http_upstream_hide_headers_hash(ngx_conf_t *cf,
     ngx_http_upstream_conf_t *conf, ngx_http_upstream_conf_t *prev,
index 2d3bc2000bd8c30c086ee53aad96115fd0760ef3..09fab00e6f3b650d9218abbdae21075d5d327b89 100644 (file)
@@ -152,6 +152,8 @@ typedef struct {
     ngx_array_t                     *hide_headers;
     ngx_array_t                     *pass_headers;
 
+    ngx_addr_t                      *local;
+
 #if (NGX_HTTP_CACHE)
     ngx_shm_zone_t                  *cache;
 
@@ -321,6 +323,8 @@ ngx_int_t ngx_http_upstream_create(ngx_http_request_t *r);
 void ngx_http_upstream_init(ngx_http_request_t *r);
 ngx_http_upstream_srv_conf_t *ngx_http_upstream_add(ngx_conf_t *cf,
     ngx_url_t *u, ngx_uint_t flags);
+char *ngx_http_upsteam_bind_set_slot(ngx_conf_t *cf, ngx_command_t *cmd,
+    void *conf);
 ngx_int_t ngx_http_upstream_hide_headers_hash(ngx_conf_t *cf,
     ngx_http_upstream_conf_t *conf, ngx_http_upstream_conf_t *prev,
     ngx_str_t *default_hide_headers, ngx_hash_init_t *hash);