Added randomization to the checking for success of outgoing connections and the arrival of incoming connections

This commit is contained in:
Mark Pizzolato 2013-05-15 15:34:45 -07:00
parent 7edcf5f36e
commit e8e751c2fd

View file

@ -807,6 +807,7 @@ if (mp->last_poll_time == 0) { /* first poll initializa
if ((poll_time - mp->last_poll_time) < TMXR_CONNECT_POLL_INTERVAL) if ((poll_time - mp->last_poll_time) < TMXR_CONNECT_POLL_INTERVAL)
return -1; /* too soon to try */ return -1; /* too soon to try */
srand((unsigned int)poll_time);
tmxr_debug_trace (mp, "tmxr_poll_conn()"); tmxr_debug_trace (mp, "tmxr_poll_conn()");
mp->last_poll_time = poll_time; mp->last_poll_time = poll_time;
@ -862,8 +863,21 @@ if (mp->master) {
/* Look for per line listeners or outbound connecting sockets */ /* Look for per line listeners or outbound connecting sockets */
for (i = 0; i < mp->lines; i++) { /* check each line in sequence */ for (i = 0; i < mp->lines; i++) { /* check each line in sequence */
int j, r = rand();
lp = mp->ldsc + i; /* get pointer to line descriptor */ lp = mp->ldsc + i; /* get pointer to line descriptor */
/* If two simulators are configured with symmetric virtual null modem
cables pointing at each other, there may be a problem establishing
a connection if both systems happen to be checking for the success
of their connections in the exact same order. They can each observe
success in their respective outgoing connections, which haven't
actually been 'accept'ed on the peer end of the connection.
We address this issue by checking for the success of an outgoing
connection and the arrival of an incoming one in a random order.
*/
for (j=0; j<2; j++)
switch ((j+r)&1) {
case 0:
if (lp->connecting) { /* connecting? */ if (lp->connecting) { /* connecting? */
char *sockname, *peername; char *sockname, *peername;
@ -889,11 +903,9 @@ for (i = 0; i < mp->lines; i++) { /* check each line in se
break; break;
} }
} }
break;
/* Check for a pending Telnet/tcp connection */ case 1:
if (lp->master) { /* Check for a pending Telnet/tcp connection */
if (lp->master) {
while (INVALID_SOCKET != (newsock = sim_accept_conn (lp->master, &address))) {/* got a live one? */ while (INVALID_SOCKET != (newsock = sim_accept_conn (lp->master, &address))) {/* got a live one? */
char *sockname, *peername; char *sockname, *peername;
@ -951,6 +963,8 @@ for (i = 0; i < mp->lines; i++) { /* check each line in se
} }
} }
} }
break;
}
/* Check for pending serial port connection notification */ /* Check for pending serial port connection notification */