<div><div>Hello Nginx Developers,</div><div> </div><div>There was a problem that we encountered: proxy_bind option is sometimes ignored when keepalive enabled in target upstream.</div><div>In search for connection in cache the only comparison is with target address and local address set by proxy_bind is ignored.</div><div>I'd like to propose the following change to fix this issue.</div><div>Would like to receive your comments.</div><div> </div><div>Best Regards,</div><div>Andrei</div><div> </div><div># HG changeset patch</div><div># User Andrei Bich <dronimal@yandex-team.ru></div><div># Date 1611236106 -10800</div><div># Thu Jan 21 16:35:06 2021 +0300</div><div># Node ID 937fb90a4f43f22213e489a280e54686b85389ec</div><div># Parent 61d0df8fcc7c630da35e832ba8e983db0061a3be</div><div>Fix proxy_bind with upstreams with keepalive.</div><div>While search connection in keepalive cache check local sockaddr in addition to destination sockaddr.</div><div> </div><div>diff -r 61d0df8fcc7c -r 937fb90a4f43 src/http/modules/ngx_http_upstream_keepalive_module.c</div><div>--- a/src/http/modules/ngx_http_upstream_keepalive_module.c Tue Jan 19 20:35:17 2021 +0300</div><div>+++ b/src/http/modules/ngx_http_upstream_keepalive_module.c Thu Jan 21 16:35:06 2021 +0300</div><div>@@ -33,6 +33,9 @@</div><div>socklen_t socklen;</div><div>ngx_sockaddr_t sockaddr;</div><div> </div><div>+ ngx_flag_t local_set;</div><div>+ socklen_t local_socklen;</div><div>+ ngx_sockaddr_t local_sockaddr;</div><div>} ngx_http_upstream_keepalive_cache_t;</div><div> </div><div> </div><div>@@ -259,6 +262,23 @@</div><div>item->socklen, pc->socklen)</div><div>== 0)</div><div>{<!-- --></div><div>+ if (!pc->local && item->local_set) {<!-- --></div><div>+ /*</div><div>+ * Actually this item is good for this pc</div><div>+ * but usign it will drop item->local_set flag for this</div><div>+ * connection during ngx_http_upstream_free_keepalive_peer</div><div>+ * since pc->local wiil be NULL.</div><div>+ */</div><div>+ continue;</div><div>+ }</div><div>+ if (pc->local && !(item->local_set</div><div>+ && ngx_memn2cmp((u_char *) &item->local_sockaddr,</div><div>+ (u_char *) pc->local->sockaddr,</div><div>+ item->local_socklen, pc->local->socklen) == 0))</div><div>+ {<!-- --></div><div>+ continue;</div><div>+ }</div><div>+</div><div>ngx_queue_remove(q);</div><div>ngx_queue_insert_head(&kp->conf->free, q);</div><div> </div><div>@@ -387,6 +407,16 @@</div><div>item->socklen = pc->socklen;</div><div>ngx_memcpy(&item->sockaddr, pc->sockaddr, pc->socklen);</div><div> </div><div>+ if (pc->local) {<!-- --></div><div>+ item->local_set = 1;</div><div>+ item->local_socklen = pc->local->socklen;</div><div>+ ngx_memcpy(&item->local_sockaddr,</div><div>+ pc->local->sockaddr,</div><div>+ pc->local->socklen);</div><div>+ } else {<!-- --></div><div>+ item->local_set = 0;</div><div>+ }</div><div>+</div><div>if (c->read->ready) {<!-- --></div><div>ngx_http_upstream_keepalive_close_handler(c->read);</div><div>}</div><div> </div><div> </div><div> </div></div>