--- a/components/proftpd/patches/proftpd-retry.patch Fri Jul 25 13:25:28 2014 -0700
+++ b/components/proftpd/patches/proftpd-retry.patch Mon Jul 28 03:27:16 2014 -0700
@@ -1,97 +1,47 @@
--- a/src/data.c
+++ b/src/data.c
-@@ -333,6 +333,7 @@ static int data_pasv_open(char *reason, off_t size) {
+@@ -337,6 +337,7 @@ static int data_pasv_open(char *reason, off_t size) {
static int data_active_open(char *reason, off_t size) {
conn_t *c;
- int rev;
+ int bind_port, rev;
+ int retries = 0;
pr_netaddr_t *bind_addr;
+ unsigned char *root_revoke = NULL;
- if (!reason && session.xfer.filename)
-@@ -348,45 +349,55 @@ static int data_active_open(char *reason, off_t size) {
- bind_addr = pr_netaddr_v6tov4(session.xfer.p, session.c->local_addr);
+@@ -368,7 +369,9 @@ static int data_active_open(char *reason, off_t size) {
+ bind_port = INPORT_ANY;
}
-- session.d = pr_inet_create_conn(session.pool, -1, bind_addr,
-- session.c->local_port-1, TRUE);
+- session.d = pr_inet_create_conn(session.pool, -1, bind_addr, bind_port, TRUE);
+ for (;;) {
-+ session.d = pr_inet_create_conn(session.pool, -1, bind_addr,
-+ session.c->local_port-1, TRUE);
++ session.d = pr_inet_create_conn(session.pool, -1, bind_addr, bind_port,
++ TRUE);
-- /* Set the "stalled" timer, if any, to prevent the connection
-- * open from taking too long
-- */
-- if (timeout_stalled) {
-- pr_timer_add(timeout_stalled, PR_TIMER_STALLED, NULL, stalled_timeout_cb,
-- "TimeoutStalled");
-- }
-+ /* Set the "stalled" timer, if any, to prevent the connection
-+ * open from taking too long
-+ */
-+ if (timeout_stalled) {
-+ pr_timer_add(timeout_stalled, PR_TIMER_STALLED, NULL, stalled_timeout_cb,
-+ "TimeoutStalled");
-+ }
-
-- rev = pr_netaddr_set_reverse_dns(ServerUseReverseDNS);
-+ rev = pr_netaddr_set_reverse_dns(ServerUseReverseDNS);
-
-- /* Protocol and socket options should be set before handshaking. */
-+ /* Protocol and socket options should be set before handshaking. */
+ /* Default remote address to which to connect for an active transfer,
+ * if the client has not specified a different address via PORT/EPRT,
+@@ -416,6 +419,15 @@ static int data_active_open(char *reason, off_t size) {
-- if (session.xfer.direction == PR_NETIO_IO_RD) {
-- pr_inet_set_socket_opts(session.d->pool, session.d,
-- (main_server->tcp_rcvbuf_override ? main_server->tcp_rcvbuf_len : 0), 0);
-+ if (session.xfer.direction == PR_NETIO_IO_RD) {
-+ pr_inet_set_socket_opts(session.d->pool, session.d,
-+ (main_server->tcp_rcvbuf_override ? main_server->tcp_rcvbuf_len : 0), 0);
-
-- } else {
-- pr_inet_set_socket_opts(session.d->pool, session.d,
-- 0, (main_server->tcp_sndbuf_override ? main_server->tcp_sndbuf_len : 0));
-- }
-+ } else {
-+ pr_inet_set_socket_opts(session.d->pool, session.d,
-+ 0, (main_server->tcp_sndbuf_override ? main_server->tcp_sndbuf_len : 0));
+ 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;
+ }
-
-- /* Make sure that the necessary socket options are set on the socket prior
-- * to the call to connect(2).
-- */
-- pr_inet_set_proto_opts(session.pool, session.d, main_server->tcp_mss_len, 0,
-- IPTOS_THROUGHPUT, 1);
-- pr_inet_generate_socket_event("core.data-connect", main_server,
-- session.d->local_addr, session.d->listen_fd);
-+ /* Make sure that the necessary socket options are set on the socket prior
-+ * to the call to connect(2).
-+ */
-+ pr_inet_set_proto_opts(session.pool, session.d, main_server->tcp_mss_len, 0,
-+ IPTOS_THROUGHPUT, 1);
-+ pr_inet_generate_socket_event("core.data-connect", main_server,
-+ session.d->local_addr, session.d->listen_fd);
-
-- if (pr_inet_connect(session.d->pool, session.d, &session.data_addr,
-+ if (pr_inet_connect(session.d->pool, session.d, &session.data_addr,
- session.data_port) == -1) {
-- pr_response_add_err(R_425, _("Unable to build data connection: %s"),
-- strerror(session.d->xerrno));
-- destroy_pool(session.d->pool);
-- session.d = NULL;
-- return -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;
-+ }
-+ pr_response_add_err(R_425, _("Unable to build data connection: %s"),
-+ strerror(session.d->xerrno));
-+ destroy_pool(session.d->pool);
-+ session.d = NULL;
-+ return -1;
-+ } else
-+ break;
++
+ pr_log_debug(DEBUG6,
+ "Error connecting to %s#%u for active data transfer: %s",
+ pr_netaddr_get_ipstr(&session.data_addr), session.data_port,
+@@ -427,6 +439,9 @@ static int data_active_open(char *reason, off_t size) {
+ destroy_pool(session.d->pool);
+ session.d = NULL;
+ return -1;
++ } else
++ break;
++
}
c = pr_inet_openrw(session.pool, session.d, NULL, PR_NETIO_STRM_DATA,