components/proftpd/patches/proftpd-retry.patch
author Tomas Klacko <tomas.klacko@oracle.com>
Mon, 12 Aug 2013 02:14:11 -0700
branchs11-update
changeset 2724 90c18e89db60
parent 554 0ed48135019d
child 1952 edbaa9c65514
permissions -rw-r--r--
16191277 problem in SERVICE/FTP-SERVER 16761173 proftpd in inetd mode, randomly fails to accept connections
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
2724
90c18e89db60 16191277 problem in SERVICE/FTP-SERVER
Tomas Klacko <tomas.klacko@oracle.com>
parents: 554
diff changeset
     1
--- a/src/data.c
90c18e89db60 16191277 problem in SERVICE/FTP-SERVER
Tomas Klacko <tomas.klacko@oracle.com>
parents: 554
diff changeset
     2
+++ b/src/data.c
90c18e89db60 16191277 problem in SERVICE/FTP-SERVER
Tomas Klacko <tomas.klacko@oracle.com>
parents: 554
diff changeset
     3
@@ -333,6 +333,7 @@ static int data_pasv_open(char *reason, off_t size) {
554
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;
2724
90c18e89db60 16191277 problem in SERVICE/FTP-SERVER
Tomas Klacko <tomas.klacko@oracle.com>
parents: 554
diff changeset
     8
   pr_netaddr_t *bind_addr;
554
0ed48135019d 7095498 Unable to build data connection: Address already in use
Milan Jurik <Milan.Jurik@oracle.com>
parents:
diff changeset
     9
 
0ed48135019d 7095498 Unable to build data connection: Address already in use
Milan Jurik <Milan.Jurik@oracle.com>
parents:
diff changeset
    10
   if (!reason && session.xfer.filename)
2724
90c18e89db60 16191277 problem in SERVICE/FTP-SERVER
Tomas Klacko <tomas.klacko@oracle.com>
parents: 554
diff changeset
    11
@@ -348,45 +349,55 @@ static int data_active_open(char *reason, off_t size) {
90c18e89db60 16191277 problem in SERVICE/FTP-SERVER
Tomas Klacko <tomas.klacko@oracle.com>
parents: 554
diff changeset
    12
     bind_addr = pr_netaddr_v6tov4(session.xfer.p, session.c->local_addr);
90c18e89db60 16191277 problem in SERVICE/FTP-SERVER
Tomas Klacko <tomas.klacko@oracle.com>
parents: 554
diff changeset
    13
   }
554
0ed48135019d 7095498 Unable to build data connection: Address already in use
Milan Jurik <Milan.Jurik@oracle.com>
parents:
diff changeset
    14
 
2724
90c18e89db60 16191277 problem in SERVICE/FTP-SERVER
Tomas Klacko <tomas.klacko@oracle.com>
parents: 554
diff changeset
    15
-  session.d = pr_inet_create_conn(session.pool, -1, bind_addr,
90c18e89db60 16191277 problem in SERVICE/FTP-SERVER
Tomas Klacko <tomas.klacko@oracle.com>
parents: 554
diff changeset
    16
-    session.c->local_port-1, TRUE);
554
0ed48135019d 7095498 Unable to build data connection: Address already in use
Milan Jurik <Milan.Jurik@oracle.com>
parents:
diff changeset
    17
+  for (;;) {
2724
90c18e89db60 16191277 problem in SERVICE/FTP-SERVER
Tomas Klacko <tomas.klacko@oracle.com>
parents: 554
diff changeset
    18
+    session.d = pr_inet_create_conn(session.pool, -1, bind_addr,
90c18e89db60 16191277 problem in SERVICE/FTP-SERVER
Tomas Klacko <tomas.klacko@oracle.com>
parents: 554
diff changeset
    19
+      session.c->local_port-1, TRUE);
554
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
-  /* 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
    22
-   * 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
    23
-   */
2724
90c18e89db60 16191277 problem in SERVICE/FTP-SERVER
Tomas Klacko <tomas.klacko@oracle.com>
parents: 554
diff changeset
    24
-  if (timeout_stalled) {
554
0ed48135019d 7095498 Unable to build data connection: Address already in use
Milan Jurik <Milan.Jurik@oracle.com>
parents:
diff changeset
    25
-    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
    26
-      "TimeoutStalled");
2724
90c18e89db60 16191277 problem in SERVICE/FTP-SERVER
Tomas Klacko <tomas.klacko@oracle.com>
parents: 554
diff changeset
    27
-  }
554
0ed48135019d 7095498 Unable to build data connection: Address already in use
Milan Jurik <Milan.Jurik@oracle.com>
parents:
diff changeset
    28
+    /* 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
    29
+     * 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
    30
+     */
2724
90c18e89db60 16191277 problem in SERVICE/FTP-SERVER
Tomas Klacko <tomas.klacko@oracle.com>
parents: 554
diff changeset
    31
+    if (timeout_stalled) {
554
0ed48135019d 7095498 Unable to build data connection: Address already in use
Milan Jurik <Milan.Jurik@oracle.com>
parents:
diff changeset
    32
+      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
    33
+        "TimeoutStalled");
2724
90c18e89db60 16191277 problem in SERVICE/FTP-SERVER
Tomas Klacko <tomas.klacko@oracle.com>
parents: 554
diff changeset
    34
+    }
554
0ed48135019d 7095498 Unable to build data connection: Address already in use
Milan Jurik <Milan.Jurik@oracle.com>
parents:
diff changeset
    35
 
0ed48135019d 7095498 Unable to build data connection: Address already in use
Milan Jurik <Milan.Jurik@oracle.com>
parents:
diff changeset
    36
-  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
    37
+    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
    38
 
0ed48135019d 7095498 Unable to build data connection: Address already in use
Milan Jurik <Milan.Jurik@oracle.com>
parents:
diff changeset
    39
-  /* 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
    40
+    /* 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
    41
 
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
+    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
    46
+      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
    47
+        (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
    48
     
0ed48135019d 7095498 Unable to build data connection: Address already in use
Milan Jurik <Milan.Jurik@oracle.com>
parents:
diff changeset
    49
-  } else {
0ed48135019d 7095498 Unable to build data connection: Address already in use
Milan Jurik <Milan.Jurik@oracle.com>
parents:
diff changeset
    50
-    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
    51
-      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
    52
-  }
0ed48135019d 7095498 Unable to build data connection: Address already in use
Milan Jurik <Milan.Jurik@oracle.com>
parents:
diff changeset
    53
+    } else {
0ed48135019d 7095498 Unable to build data connection: Address already in use
Milan Jurik <Milan.Jurik@oracle.com>
parents:
diff changeset
    54
+      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
    55
+        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
    56
+    }
0ed48135019d 7095498 Unable to build data connection: Address already in use
Milan Jurik <Milan.Jurik@oracle.com>
parents:
diff changeset
    57
 
2724
90c18e89db60 16191277 problem in SERVICE/FTP-SERVER
Tomas Klacko <tomas.klacko@oracle.com>
parents: 554
diff changeset
    58
-  /* Make sure that the necessary socket options are set on the socket prior
90c18e89db60 16191277 problem in SERVICE/FTP-SERVER
Tomas Klacko <tomas.klacko@oracle.com>
parents: 554
diff changeset
    59
-   * to the call to connect(2).
90c18e89db60 16191277 problem in SERVICE/FTP-SERVER
Tomas Klacko <tomas.klacko@oracle.com>
parents: 554
diff changeset
    60
-   */
90c18e89db60 16191277 problem in SERVICE/FTP-SERVER
Tomas Klacko <tomas.klacko@oracle.com>
parents: 554
diff changeset
    61
-  pr_inet_set_proto_opts(session.pool, session.d, main_server->tcp_mss_len, 0,
90c18e89db60 16191277 problem in SERVICE/FTP-SERVER
Tomas Klacko <tomas.klacko@oracle.com>
parents: 554
diff changeset
    62
-    IPTOS_THROUGHPUT, 1);
90c18e89db60 16191277 problem in SERVICE/FTP-SERVER
Tomas Klacko <tomas.klacko@oracle.com>
parents: 554
diff changeset
    63
-  pr_inet_generate_socket_event("core.data-connect", main_server,
90c18e89db60 16191277 problem in SERVICE/FTP-SERVER
Tomas Klacko <tomas.klacko@oracle.com>
parents: 554
diff changeset
    64
-    session.d->local_addr, session.d->listen_fd);
90c18e89db60 16191277 problem in SERVICE/FTP-SERVER
Tomas Klacko <tomas.klacko@oracle.com>
parents: 554
diff changeset
    65
+    /* Make sure that the necessary socket options are set on the socket prior
90c18e89db60 16191277 problem in SERVICE/FTP-SERVER
Tomas Klacko <tomas.klacko@oracle.com>
parents: 554
diff changeset
    66
+     * to the call to connect(2).
90c18e89db60 16191277 problem in SERVICE/FTP-SERVER
Tomas Klacko <tomas.klacko@oracle.com>
parents: 554
diff changeset
    67
+     */
90c18e89db60 16191277 problem in SERVICE/FTP-SERVER
Tomas Klacko <tomas.klacko@oracle.com>
parents: 554
diff changeset
    68
+    pr_inet_set_proto_opts(session.pool, session.d, main_server->tcp_mss_len, 0,
90c18e89db60 16191277 problem in SERVICE/FTP-SERVER
Tomas Klacko <tomas.klacko@oracle.com>
parents: 554
diff changeset
    69
+      IPTOS_THROUGHPUT, 1);
90c18e89db60 16191277 problem in SERVICE/FTP-SERVER
Tomas Klacko <tomas.klacko@oracle.com>
parents: 554
diff changeset
    70
+    pr_inet_generate_socket_event("core.data-connect", main_server,
90c18e89db60 16191277 problem in SERVICE/FTP-SERVER
Tomas Klacko <tomas.klacko@oracle.com>
parents: 554
diff changeset
    71
+      session.d->local_addr, session.d->listen_fd);
90c18e89db60 16191277 problem in SERVICE/FTP-SERVER
Tomas Klacko <tomas.klacko@oracle.com>
parents: 554
diff changeset
    72
 
554
0ed48135019d 7095498 Unable to build data connection: Address already in use
Milan Jurik <Milan.Jurik@oracle.com>
parents:
diff changeset
    73
-  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
    74
+    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
    75
       session.data_port) == -1) {
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
+      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
    82
+        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
    83
+        pr_signals_handle();
0ed48135019d 7095498 Unable to build data connection: Address already in use
Milan Jurik <Milan.Jurik@oracle.com>
parents:
diff changeset
    84
+        /* 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
    85
+        sleep(retries++);
0ed48135019d 7095498 Unable to build data connection: Address already in use
Milan Jurik <Milan.Jurik@oracle.com>
parents:
diff changeset
    86
+        continue;
0ed48135019d 7095498 Unable to build data connection: Address already in use
Milan Jurik <Milan.Jurik@oracle.com>
parents:
diff changeset
    87
+      }
0ed48135019d 7095498 Unable to build data connection: Address already in use
Milan Jurik <Milan.Jurik@oracle.com>
parents:
diff changeset
    88
+      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
    89
+        strerror(session.d->xerrno));
0ed48135019d 7095498 Unable to build data connection: Address already in use
Milan Jurik <Milan.Jurik@oracle.com>
parents:
diff changeset
    90
+      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
    91
+      session.d = NULL;
0ed48135019d 7095498 Unable to build data connection: Address already in use
Milan Jurik <Milan.Jurik@oracle.com>
parents:
diff changeset
    92
+      return -1;
0ed48135019d 7095498 Unable to build data connection: Address already in use
Milan Jurik <Milan.Jurik@oracle.com>
parents:
diff changeset
    93
+    } else
0ed48135019d 7095498 Unable to build data connection: Address already in use
Milan Jurik <Milan.Jurik@oracle.com>
parents:
diff changeset
    94
+      break;
0ed48135019d 7095498 Unable to build data connection: Address already in use
Milan Jurik <Milan.Jurik@oracle.com>
parents:
diff changeset
    95
   }
0ed48135019d 7095498 Unable to build data connection: Address already in use
Milan Jurik <Milan.Jurik@oracle.com>
parents:
diff changeset
    96
 
0ed48135019d 7095498 Unable to build data connection: Address already in use
Milan Jurik <Milan.Jurik@oracle.com>
parents:
diff changeset
    97
   c = pr_inet_openrw(session.pool, session.d, NULL, PR_NETIO_STRM_DATA,
2724
90c18e89db60 16191277 problem in SERVICE/FTP-SERVER
Tomas Klacko <tomas.klacko@oracle.com>
parents: 554
diff changeset
    98