# HG changeset patch # User Jiri Sasek # Date 1466688111 25200 # Node ID 3d1d422367d41c3cecfb15bd14efbaf4805587d4 # Parent 4e700eaededa4533a2d1ab58d0fa1417c407b02b 23536514 ftp randomly could not build data connection diff -r 4e700eaededa -r 3d1d422367d4 components/proftpd/patches/004.proftpd-retry.patch --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/components/proftpd/patches/004.proftpd-retry.patch Thu Jun 23 06:21:51 2016 -0700 @@ -0,0 +1,67 @@ +Source: In-House +Reason: Solaris leave socket in TIME_WAIT status +Reasonable to upstream?: Not much for Linux. + +Note: This patch do not look "pretty" but its code +is re-used from the original patch which colided +with the proftpd-1.3.6 code. During proftpd update +the binaries were tested on huge # of small files +(!passive) it looked good so the original patch was +removed. +Now it has returned as regression from supercluster +testing. +Final fix of this problem on Solaris will need further +discussion with community then it will be probably fixed +by a proftpd update. + +--- a//src/data.c 2016-03-10 17:04:32.000000000 -0800 ++++ b/src/data.c 2016-06-23 05:41:37.547107933 -0700 +@@ -337,6 +337,7 @@ + static int data_active_open(char *reason, off_t size) { + conn_t *c; + int bind_port, rev; ++ int retries = 0; + pr_netaddr_t *bind_addr; + unsigned char *root_revoke = NULL; + +@@ -384,6 +385,7 @@ + } + } + ++ for(;;) { /* begin of endless loop */ + session.d = pr_inet_create_conn(session.pool, -1, bind_addr, bind_port, TRUE); + if (session.d == NULL) { + int xerrno = errno; +@@ -425,7 +427,7 @@ + pr_inet_set_socket_opts(session.d->pool, session.d, + (main_server->tcp_rcvbuf_override ? main_server->tcp_rcvbuf_len : 0), 0, + main_server->tcp_keepalive); +- ++ + } else { + pr_inet_set_socket_opts(session.d->pool, session.d, + 0, (main_server->tcp_sndbuf_override ? main_server->tcp_sndbuf_len : 0), +@@ -442,6 +444,13 @@ + + if (pr_inet_connect(session.d->pool, session.d, &session.data_addr, + session.data_port) == -1) { ++ if (session.d->xerrno == EADDRINUSE && retries < 16) { ++ destroy_pool(session.d->pool); ++ pr_signals_handle(); ++ /* Wait up to MSL to avoid TIME_WAIT. */ ++ sleep(retries++); ++ continue; /* continue in endless loop */ ++ } + pr_log_debug(DEBUG6, + "Error connecting to %s#%u for active data transfer: %s", + pr_netaddr_get_ipstr(&session.data_addr), session.data_port, +@@ -453,7 +462,8 @@ + destroy_pool(session.d->pool); + session.d = NULL; + return -1; +- } ++ } else break; /* finish the endless loop */ ++ } /* end of endless loop */ + + c = pr_inet_openrw(session.pool, session.d, NULL, PR_NETIO_STRM_DATA, + session.d->listen_fd, -1, -1, TRUE);