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-- |
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, |