# HG changeset patch # User Igor Sysoev # Date 1257175442 0 # Node ID fcd98af88df3313db0c1b23aace8bfe30f2dd54a # Parent 7d1a04259e3fa7f6bb6c68482ff28705e60aba17 proxy_bind, fastcgi_bind, and memcached_bind diff -r 7d1a04259e3f -r fcd98af88df3 src/event/ngx_event_connect.c --- a/src/event/ngx_event_connect.c Mon Nov 02 15:20:42 2009 +0000 +++ b/src/event/ngx_event_connect.c Mon Nov 02 15:24:02 2009 +0000 @@ -54,15 +54,7 @@ { 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_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); + + goto failed; } - - return NGX_ERROR; } c->recv = ngx_recv; @@ -127,7 +121,7 @@ if (ngx_add_conn) { if (ngx_add_conn(c) == NGX_ERROR) { - return NGX_ERROR; + goto failed; } } @@ -199,7 +193,7 @@ 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 @@ } if (ngx_add_event(rev, NGX_READ_EVENT, event) != NGX_OK) { - return NGX_ERROR; + goto failed; } if (rc == -1) { @@ -237,7 +231,7 @@ /* 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 @@ 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; } diff -r 7d1a04259e3f -r fcd98af88df3 src/event/ngx_event_connect.h --- a/src/event/ngx_event_connect.h Mon Nov 02 15:20:42 2009 +0000 +++ b/src/event/ngx_event_connect.h Mon Nov 02 15:24:02 2009 +0000 @@ -55,6 +55,8 @@ ngx_atomic_t *lock; #endif + ngx_addr_t *local; + int rcvbuf; ngx_log_t *log; diff -r 7d1a04259e3f -r fcd98af88df3 src/http/modules/ngx_http_fastcgi_module.c --- a/src/http/modules/ngx_http_fastcgi_module.c Mon Nov 02 15:20:42 2009 +0000 +++ b/src/http/modules/ngx_http_fastcgi_module.c Mon Nov 02 15:24:02 2009 +0000 @@ -240,6 +240,13 @@ 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, diff -r 7d1a04259e3f -r fcd98af88df3 src/http/modules/ngx_http_memcached_module.c --- a/src/http/modules/ngx_http_memcached_module.c Mon Nov 02 15:20:42 2009 +0000 +++ b/src/http/modules/ngx_http_memcached_module.c Mon Nov 02 15:24:02 2009 +0000 @@ -63,6 +63,13 @@ 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, diff -r 7d1a04259e3f -r fcd98af88df3 src/http/modules/ngx_http_proxy_module.c --- a/src/http/modules/ngx_http_proxy_module.c Mon Nov 02 15:20:42 2009 +0000 +++ b/src/http/modules/ngx_http_proxy_module.c Mon Nov 02 15:24:02 2009 +0000 @@ -229,6 +229,13 @@ 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, diff -r 7d1a04259e3f -r fcd98af88df3 src/http/ngx_http_upstream.c --- a/src/http/ngx_http_upstream.c Mon Nov 02 15:20:42 2009 +0000 +++ b/src/http/ngx_http_upstream.c Mon Nov 02 15:24:02 2009 +0000 @@ -479,6 +479,8 @@ 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 @@ } +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, diff -r 7d1a04259e3f -r fcd98af88df3 src/http/ngx_http_upstream.h --- a/src/http/ngx_http_upstream.h Mon Nov 02 15:20:42 2009 +0000 +++ b/src/http/ngx_http_upstream.h Mon Nov 02 15:24:02 2009 +0000 @@ -152,6 +152,8 @@ 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 @@ 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);