components/proftpd/patches/proftpd-retry.patch
author Milan Jurik <Milan.Jurik@oracle.com>
Mon, 31 Oct 2011 03:15:38 -0700
changeset 554 0ed48135019d
child 1343 a66d36656846
permissions -rw-r--r--
7095498 Unable to build data connection: Address already in use
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
554
0ed48135019d 7095498 Unable to build data connection: Address already in use
Milan Jurik <Milan.Jurik@oracle.com>
parents:
diff changeset
     1
--- proftpd-1.3.3e/src/data.c	Thu Mar  3 09:10:03 2011
0ed48135019d 7095498 Unable to build data connection: Address already in use
Milan Jurik <Milan.Jurik@oracle.com>
parents:
diff changeset
     2
+++ proftpd-1.3.3e/src/data.c	Wed Oct  5 08:07:57 2011
0ed48135019d 7095498 Unable to build data connection: Address already in use
Milan Jurik <Milan.Jurik@oracle.com>
parents:
diff changeset
     3
@@ -337,44 +337,55 @@
0ed48135019d 7095498 Unable to build data connection: Address already in use
Milan Jurik <Milan.Jurik@oracle.com>
parents:
diff changeset
     4
 static int data_active_open(char *reason, off_t size) {
0ed48135019d 7095498 Unable to build data connection: Address already in use
Milan Jurik <Milan.Jurik@oracle.com>
parents:
diff changeset
     5
   conn_t *c;
0ed48135019d 7095498 Unable to build data connection: Address already in use
Milan Jurik <Milan.Jurik@oracle.com>
parents:
diff changeset
     6
   int rev;
0ed48135019d 7095498 Unable to build data connection: Address already in use
Milan Jurik <Milan.Jurik@oracle.com>
parents:
diff changeset
     7
+  int retries = 0;
0ed48135019d 7095498 Unable to build data connection: Address already in use
Milan Jurik <Milan.Jurik@oracle.com>
parents:
diff changeset
     8
 
0ed48135019d 7095498 Unable to build data connection: Address already in use
Milan Jurik <Milan.Jurik@oracle.com>
parents:
diff changeset
     9
   if (!reason && session.xfer.filename)
0ed48135019d 7095498 Unable to build data connection: Address already in use
Milan Jurik <Milan.Jurik@oracle.com>
parents:
diff changeset
    10
     reason = session.xfer.filename;
0ed48135019d 7095498 Unable to build data connection: Address already in use
Milan Jurik <Milan.Jurik@oracle.com>
parents:
diff changeset
    11
 
0ed48135019d 7095498 Unable to build data connection: Address already in use
Milan Jurik <Milan.Jurik@oracle.com>
parents:
diff changeset
    12
-  session.d = pr_inet_create_conn(session.pool, NULL, -1,
0ed48135019d 7095498 Unable to build data connection: Address already in use
Milan Jurik <Milan.Jurik@oracle.com>
parents:
diff changeset
    13
-    session.c->local_addr, session.c->local_port-1, TRUE);
0ed48135019d 7095498 Unable to build data connection: Address already in use
Milan Jurik <Milan.Jurik@oracle.com>
parents:
diff changeset
    14
+  for (;;) {
0ed48135019d 7095498 Unable to build data connection: Address already in use
Milan Jurik <Milan.Jurik@oracle.com>
parents:
diff changeset
    15
+    session.d = pr_inet_create_conn(session.pool, NULL, -1,
0ed48135019d 7095498 Unable to build data connection: Address already in use
Milan Jurik <Milan.Jurik@oracle.com>
parents:
diff changeset
    16
+      session.c->local_addr, session.c->local_port-1, TRUE);
0ed48135019d 7095498 Unable to build data connection: Address already in use
Milan Jurik <Milan.Jurik@oracle.com>
parents:
diff changeset
    17
 
0ed48135019d 7095498 Unable to build data connection: Address already in use
Milan Jurik <Milan.Jurik@oracle.com>
parents:
diff changeset
    18
-  /* Set the "stalled" timer, if any, to prevent the connection
0ed48135019d 7095498 Unable to build data connection: Address already in use
Milan Jurik <Milan.Jurik@oracle.com>
parents:
diff changeset
    19
-   * open from taking too long
0ed48135019d 7095498 Unable to build data connection: Address already in use
Milan Jurik <Milan.Jurik@oracle.com>
parents:
diff changeset
    20
-   */
0ed48135019d 7095498 Unable to build data connection: Address already in use
Milan Jurik <Milan.Jurik@oracle.com>
parents:
diff changeset
    21
-  if (timeout_stalled)
0ed48135019d 7095498 Unable to build data connection: Address already in use
Milan Jurik <Milan.Jurik@oracle.com>
parents:
diff changeset
    22
-    pr_timer_add(timeout_stalled, PR_TIMER_STALLED, NULL, stalled_timeout_cb,
0ed48135019d 7095498 Unable to build data connection: Address already in use
Milan Jurik <Milan.Jurik@oracle.com>
parents:
diff changeset
    23
-      "TimeoutStalled");
0ed48135019d 7095498 Unable to build data connection: Address already in use
Milan Jurik <Milan.Jurik@oracle.com>
parents:
diff changeset
    24
+    /* Set the "stalled" timer, if any, to prevent the connection
0ed48135019d 7095498 Unable to build data connection: Address already in use
Milan Jurik <Milan.Jurik@oracle.com>
parents:
diff changeset
    25
+     * open from taking too long
0ed48135019d 7095498 Unable to build data connection: Address already in use
Milan Jurik <Milan.Jurik@oracle.com>
parents:
diff changeset
    26
+     */
0ed48135019d 7095498 Unable to build data connection: Address already in use
Milan Jurik <Milan.Jurik@oracle.com>
parents:
diff changeset
    27
+    if (timeout_stalled)
0ed48135019d 7095498 Unable to build data connection: Address already in use
Milan Jurik <Milan.Jurik@oracle.com>
parents:
diff changeset
    28
+      pr_timer_add(timeout_stalled, PR_TIMER_STALLED, NULL, stalled_timeout_cb,
0ed48135019d 7095498 Unable to build data connection: Address already in use
Milan Jurik <Milan.Jurik@oracle.com>
parents:
diff changeset
    29
+        "TimeoutStalled");
0ed48135019d 7095498 Unable to build data connection: Address already in use
Milan Jurik <Milan.Jurik@oracle.com>
parents:
diff changeset
    30
 
0ed48135019d 7095498 Unable to build data connection: Address already in use
Milan Jurik <Milan.Jurik@oracle.com>
parents:
diff changeset
    31
-  rev = pr_netaddr_set_reverse_dns(ServerUseReverseDNS);
0ed48135019d 7095498 Unable to build data connection: Address already in use
Milan Jurik <Milan.Jurik@oracle.com>
parents:
diff changeset
    32
+    rev = pr_netaddr_set_reverse_dns(ServerUseReverseDNS);
0ed48135019d 7095498 Unable to build data connection: Address already in use
Milan Jurik <Milan.Jurik@oracle.com>
parents:
diff changeset
    33
 
0ed48135019d 7095498 Unable to build data connection: Address already in use
Milan Jurik <Milan.Jurik@oracle.com>
parents:
diff changeset
    34
-  /* Protocol and socket options should be set before handshaking. */
0ed48135019d 7095498 Unable to build data connection: Address already in use
Milan Jurik <Milan.Jurik@oracle.com>
parents:
diff changeset
    35
+    /* Protocol and socket options should be set before handshaking. */
0ed48135019d 7095498 Unable to build data connection: Address already in use
Milan Jurik <Milan.Jurik@oracle.com>
parents:
diff changeset
    36
 
0ed48135019d 7095498 Unable to build data connection: Address already in use
Milan Jurik <Milan.Jurik@oracle.com>
parents:
diff changeset
    37
-  if (session.xfer.direction == PR_NETIO_IO_RD) {
0ed48135019d 7095498 Unable to build data connection: Address already in use
Milan Jurik <Milan.Jurik@oracle.com>
parents:
diff changeset
    38
-    pr_inet_set_socket_opts(session.d->pool, session.d,
0ed48135019d 7095498 Unable to build data connection: Address already in use
Milan Jurik <Milan.Jurik@oracle.com>
parents:
diff changeset
    39
-      (main_server->tcp_rcvbuf_override ? main_server->tcp_rcvbuf_len : 0), 0);
0ed48135019d 7095498 Unable to build data connection: Address already in use
Milan Jurik <Milan.Jurik@oracle.com>
parents:
diff changeset
    40
-    pr_inet_set_proto_opts(session.pool, session.d, main_server->tcp_mss_len, 0,
0ed48135019d 7095498 Unable to build data connection: Address already in use
Milan Jurik <Milan.Jurik@oracle.com>
parents:
diff changeset
    41
-      0, 1, 1);
0ed48135019d 7095498 Unable to build data connection: Address already in use
Milan Jurik <Milan.Jurik@oracle.com>
parents:
diff changeset
    42
+    if (session.xfer.direction == PR_NETIO_IO_RD) {
0ed48135019d 7095498 Unable to build data connection: Address already in use
Milan Jurik <Milan.Jurik@oracle.com>
parents:
diff changeset
    43
+      pr_inet_set_socket_opts(session.d->pool, session.d,
0ed48135019d 7095498 Unable to build data connection: Address already in use
Milan Jurik <Milan.Jurik@oracle.com>
parents:
diff changeset
    44
+        (main_server->tcp_rcvbuf_override ? main_server->tcp_rcvbuf_len : 0), 0);
0ed48135019d 7095498 Unable to build data connection: Address already in use
Milan Jurik <Milan.Jurik@oracle.com>
parents:
diff changeset
    45
+      pr_inet_set_proto_opts(session.pool, session.d, main_server->tcp_mss_len, 0,
0ed48135019d 7095498 Unable to build data connection: Address already in use
Milan Jurik <Milan.Jurik@oracle.com>
parents:
diff changeset
    46
+        0, 1, 1);
0ed48135019d 7095498 Unable to build data connection: Address already in use
Milan Jurik <Milan.Jurik@oracle.com>
parents:
diff changeset
    47
     
0ed48135019d 7095498 Unable to build data connection: Address already in use
Milan Jurik <Milan.Jurik@oracle.com>
parents:
diff changeset
    48
-  } else {
0ed48135019d 7095498 Unable to build data connection: Address already in use
Milan Jurik <Milan.Jurik@oracle.com>
parents:
diff changeset
    49
-    pr_inet_set_socket_opts(session.d->pool, session.d,
0ed48135019d 7095498 Unable to build data connection: Address already in use
Milan Jurik <Milan.Jurik@oracle.com>
parents:
diff changeset
    50
-      0, (main_server->tcp_sndbuf_override ? main_server->tcp_sndbuf_len : 0));
0ed48135019d 7095498 Unable to build data connection: Address already in use
Milan Jurik <Milan.Jurik@oracle.com>
parents:
diff changeset
    51
-    pr_inet_set_proto_opts(session.pool, session.d, main_server->tcp_mss_len, 0,
0ed48135019d 7095498 Unable to build data connection: Address already in use
Milan Jurik <Milan.Jurik@oracle.com>
parents:
diff changeset
    52
-      0, 1, 1);
0ed48135019d 7095498 Unable to build data connection: Address already in use
Milan Jurik <Milan.Jurik@oracle.com>
parents:
diff changeset
    53
-  }
0ed48135019d 7095498 Unable to build data connection: Address already in use
Milan Jurik <Milan.Jurik@oracle.com>
parents:
diff changeset
    54
+    } else {
0ed48135019d 7095498 Unable to build data connection: Address already in use
Milan Jurik <Milan.Jurik@oracle.com>
parents:
diff changeset
    55
+      pr_inet_set_socket_opts(session.d->pool, session.d,
0ed48135019d 7095498 Unable to build data connection: Address already in use
Milan Jurik <Milan.Jurik@oracle.com>
parents:
diff changeset
    56
+        0, (main_server->tcp_sndbuf_override ? main_server->tcp_sndbuf_len : 0));
0ed48135019d 7095498 Unable to build data connection: Address already in use
Milan Jurik <Milan.Jurik@oracle.com>
parents:
diff changeset
    57
+      pr_inet_set_proto_opts(session.pool, session.d, main_server->tcp_mss_len, 0,
0ed48135019d 7095498 Unable to build data connection: Address already in use
Milan Jurik <Milan.Jurik@oracle.com>
parents:
diff changeset
    58
+        0, 1, 1);
0ed48135019d 7095498 Unable to build data connection: Address already in use
Milan Jurik <Milan.Jurik@oracle.com>
parents:
diff changeset
    59
+    }
0ed48135019d 7095498 Unable to build data connection: Address already in use
Milan Jurik <Milan.Jurik@oracle.com>
parents:
diff changeset
    60
 
0ed48135019d 7095498 Unable to build data connection: Address already in use
Milan Jurik <Milan.Jurik@oracle.com>
parents:
diff changeset
    61
-  if (pr_inet_connect(session.d->pool, session.d, &session.data_addr,
0ed48135019d 7095498 Unable to build data connection: Address already in use
Milan Jurik <Milan.Jurik@oracle.com>
parents:
diff changeset
    62
+    if (pr_inet_connect(session.d->pool, session.d, &session.data_addr,
0ed48135019d 7095498 Unable to build data connection: Address already in use
Milan Jurik <Milan.Jurik@oracle.com>
parents:
diff changeset
    63
       session.data_port) == -1) {
0ed48135019d 7095498 Unable to build data connection: Address already in use
Milan Jurik <Milan.Jurik@oracle.com>
parents:
diff changeset
    64
-    pr_response_add_err(R_425, _("Unable to build data connection: %s"),
0ed48135019d 7095498 Unable to build data connection: Address already in use
Milan Jurik <Milan.Jurik@oracle.com>
parents:
diff changeset
    65
-      strerror(session.d->xerrno));
0ed48135019d 7095498 Unable to build data connection: Address already in use
Milan Jurik <Milan.Jurik@oracle.com>
parents:
diff changeset
    66
-    destroy_pool(session.d->pool);
0ed48135019d 7095498 Unable to build data connection: Address already in use
Milan Jurik <Milan.Jurik@oracle.com>
parents:
diff changeset
    67
-    session.d = NULL;
0ed48135019d 7095498 Unable to build data connection: Address already in use
Milan Jurik <Milan.Jurik@oracle.com>
parents:
diff changeset
    68
-    return -1;
0ed48135019d 7095498 Unable to build data connection: Address already in use
Milan Jurik <Milan.Jurik@oracle.com>
parents:
diff changeset
    69
+      if (session.d->xerrno == EADDRINUSE && retries < 16) {
0ed48135019d 7095498 Unable to build data connection: Address already in use
Milan Jurik <Milan.Jurik@oracle.com>
parents:
diff changeset
    70
+        destroy_pool(session.d->pool);
0ed48135019d 7095498 Unable to build data connection: Address already in use
Milan Jurik <Milan.Jurik@oracle.com>
parents:
diff changeset
    71
+        pr_signals_handle();
0ed48135019d 7095498 Unable to build data connection: Address already in use
Milan Jurik <Milan.Jurik@oracle.com>
parents:
diff changeset
    72
+        /* Wait up to MSL to avoid TIME_WAIT. */
0ed48135019d 7095498 Unable to build data connection: Address already in use
Milan Jurik <Milan.Jurik@oracle.com>
parents:
diff changeset
    73
+        sleep(retries++);
0ed48135019d 7095498 Unable to build data connection: Address already in use
Milan Jurik <Milan.Jurik@oracle.com>
parents:
diff changeset
    74
+        continue;
0ed48135019d 7095498 Unable to build data connection: Address already in use
Milan Jurik <Milan.Jurik@oracle.com>
parents:
diff changeset
    75
+      }
0ed48135019d 7095498 Unable to build data connection: Address already in use
Milan Jurik <Milan.Jurik@oracle.com>
parents:
diff changeset
    76
+      pr_response_add_err(R_425, _("Unable to build data connection: %s"),
0ed48135019d 7095498 Unable to build data connection: Address already in use
Milan Jurik <Milan.Jurik@oracle.com>
parents:
diff changeset
    77
+        strerror(session.d->xerrno));
0ed48135019d 7095498 Unable to build data connection: Address already in use
Milan Jurik <Milan.Jurik@oracle.com>
parents:
diff changeset
    78
+      destroy_pool(session.d->pool);
0ed48135019d 7095498 Unable to build data connection: Address already in use
Milan Jurik <Milan.Jurik@oracle.com>
parents:
diff changeset
    79
+      session.d = NULL;
0ed48135019d 7095498 Unable to build data connection: Address already in use
Milan Jurik <Milan.Jurik@oracle.com>
parents:
diff changeset
    80
+      return -1;
0ed48135019d 7095498 Unable to build data connection: Address already in use
Milan Jurik <Milan.Jurik@oracle.com>
parents:
diff changeset
    81
+    } else
0ed48135019d 7095498 Unable to build data connection: Address already in use
Milan Jurik <Milan.Jurik@oracle.com>
parents:
diff changeset
    82
+      break;
0ed48135019d 7095498 Unable to build data connection: Address already in use
Milan Jurik <Milan.Jurik@oracle.com>
parents:
diff changeset
    83
   }
0ed48135019d 7095498 Unable to build data connection: Address already in use
Milan Jurik <Milan.Jurik@oracle.com>
parents:
diff changeset
    84
 
0ed48135019d 7095498 Unable to build data connection: Address already in use
Milan Jurik <Milan.Jurik@oracle.com>
parents:
diff changeset
    85
   c = pr_inet_openrw(session.pool, session.d, NULL, PR_NETIO_STRM_DATA,