--- a/src/data.c
+++ b/src/data.c
@@ -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 bind_port, rev;
+ int retries = 0;
pr_netaddr_t *bind_addr;
unsigned char *root_revoke = NULL;
@@ -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, bind_port, TRUE);
+ for (;;) {
+ session.d = pr_inet_create_conn(session.pool, -1, bind_addr, bind_port,
+ TRUE);
/* 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 (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;
+ }
+
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,