Added randomization to the checking for success of outgoing connections and the arrival of incoming connections
This commit is contained in:
parent
7edcf5f36e
commit
e8e751c2fd
1 changed files with 96 additions and 82 deletions
178
sim_tmxr.c
178
sim_tmxr.c
|
@ -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,95 +863,108 @@ 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 (lp->connecting) { /* connecting? */
|
/* If two simulators are configured with symmetric virtual null modem
|
||||||
char *sockname, *peername;
|
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? */
|
||||||
|
char *sockname, *peername;
|
||||||
|
|
||||||
switch (sim_check_conn(lp->connecting, FALSE))
|
switch (sim_check_conn(lp->connecting, FALSE))
|
||||||
{
|
{
|
||||||
case 1: /* successful connection */
|
case 1: /* successful connection */
|
||||||
lp->conn = TRUE; /* record connection */
|
lp->conn = TRUE; /* record connection */
|
||||||
lp->sock = lp->connecting; /* it now looks normal */
|
lp->sock = lp->connecting; /* it now looks normal */
|
||||||
lp->connecting = 0;
|
lp->connecting = 0;
|
||||||
lp->ipad = realloc (lp->ipad, 1+strlen (lp->destination));
|
lp->ipad = realloc (lp->ipad, 1+strlen (lp->destination));
|
||||||
strcpy (lp->ipad, lp->destination);
|
strcpy (lp->ipad, lp->destination);
|
||||||
lp->cnms = sim_os_msec ();
|
lp->cnms = sim_os_msec ();
|
||||||
sim_getnames_sock (lp->sock, &sockname, &peername);
|
sim_getnames_sock (lp->sock, &sockname, &peername);
|
||||||
sprintf (msg, "tmxr_poll_conn() - Outgoing Line Connection to %s (%s->%s) established", lp->destination, sockname, peername);
|
sprintf (msg, "tmxr_poll_conn() - Outgoing Line Connection to %s (%s->%s) established", lp->destination, sockname, peername);
|
||||||
tmxr_debug_connect_line (lp, msg);
|
tmxr_debug_connect_line (lp, msg);
|
||||||
free (sockname);
|
free (sockname);
|
||||||
free (peername);
|
free (peername);
|
||||||
break;
|
break;
|
||||||
case -1: /* failed connection */
|
case -1: /* failed connection */
|
||||||
sprintf (msg, "tmxr_poll_conn() - Outgoing Line Connection to %s failed", lp->destination);
|
sprintf (msg, "tmxr_poll_conn() - Outgoing Line Connection to %s failed", lp->destination);
|
||||||
tmxr_debug_connect_line (lp, msg);
|
tmxr_debug_connect_line (lp, msg);
|
||||||
tmxr_reset_ln (lp); /* retry */
|
tmxr_reset_ln (lp); /* retry */
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check for a pending Telnet/tcp connection */
|
|
||||||
|
|
||||||
if (lp->master) {
|
|
||||||
|
|
||||||
while (INVALID_SOCKET != (newsock = sim_accept_conn (lp->master, &address))) {/* got a live one? */
|
|
||||||
char *sockname, *peername;
|
|
||||||
|
|
||||||
sim_getnames_sock (newsock, &sockname, &peername);
|
|
||||||
sprintf (msg, "tmxr_poll_conn() - Incoming Line Connection from %s (%s->%s)", address, peername, sockname);
|
|
||||||
tmxr_debug_connect_line (lp, msg);
|
|
||||||
free (sockname);
|
|
||||||
free (peername);
|
|
||||||
++mp->sessions; /* count the new session */
|
|
||||||
|
|
||||||
if (lp->destination) { /* Virtual Null Modem Cable? */
|
|
||||||
char host[CBUFSIZE];
|
|
||||||
|
|
||||||
if (sim_parse_addr (lp->destination, host, sizeof(host), NULL, NULL, 0, NULL, address)) {
|
|
||||||
tmxr_msg (newsock, "Rejecting connection from unexpected source\r\n");
|
|
||||||
sprintf (msg, "tmxr_poll_conn() - Rejecting line connection from: %s, Expected: %s", address, host);
|
|
||||||
tmxr_debug_connect_line (lp, msg);
|
|
||||||
sim_close_sock (newsock, 0);
|
|
||||||
free (address);
|
|
||||||
continue; /* Try for another connection */
|
|
||||||
}
|
|
||||||
if (lp->connecting) {
|
|
||||||
sprintf (msg, "tmxr_poll_conn() - aborting outgoing line connection attempt to: %s", lp->destination);
|
|
||||||
tmxr_debug_connect_line (lp, msg);
|
|
||||||
sim_close_sock (lp->connecting, 0); /* abort our as yet unconnnected socket */
|
|
||||||
lp->connecting = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (lp->conn == FALSE) { /* is the line available? */
|
|
||||||
if ((!lp->modem_control) || (lp->modembits & TMXR_MDM_DTR)) {
|
|
||||||
tmxr_init_line (lp); /* init line */
|
|
||||||
lp->conn = TRUE; /* record connection */
|
|
||||||
lp->sock = newsock; /* save socket */
|
|
||||||
lp->ipad = address; /* ip address */
|
|
||||||
if (!lp->notelnet) {
|
|
||||||
sim_write_sock (newsock, (char *)mantra, sizeof(mantra));
|
|
||||||
tmxr_debug (TMXR_DBG_XMT, lp, "Sending", (char *)mantra, sizeof(mantra));
|
|
||||||
}
|
}
|
||||||
tmxr_report_connection (mp, lp);
|
|
||||||
lp->cnms = sim_os_msec (); /* time of connection */
|
|
||||||
return i;
|
|
||||||
}
|
}
|
||||||
else {
|
break;
|
||||||
tmxr_msg (newsock, "Line connection not available\r\n");
|
case 1:
|
||||||
tmxr_debug_connect_line (lp, "tmxr_poll_conn() - Line connection not available");
|
if (lp->master) { /* Check for a pending Telnet/tcp connection */
|
||||||
sim_close_sock (newsock, 0);
|
while (INVALID_SOCKET != (newsock = sim_accept_conn (lp->master, &address))) {/* got a live one? */
|
||||||
free (address);
|
char *sockname, *peername;
|
||||||
|
|
||||||
|
sim_getnames_sock (newsock, &sockname, &peername);
|
||||||
|
sprintf (msg, "tmxr_poll_conn() - Incoming Line Connection from %s (%s->%s)", address, peername, sockname);
|
||||||
|
tmxr_debug_connect_line (lp, msg);
|
||||||
|
free (sockname);
|
||||||
|
free (peername);
|
||||||
|
++mp->sessions; /* count the new session */
|
||||||
|
|
||||||
|
if (lp->destination) { /* Virtual Null Modem Cable? */
|
||||||
|
char host[CBUFSIZE];
|
||||||
|
|
||||||
|
if (sim_parse_addr (lp->destination, host, sizeof(host), NULL, NULL, 0, NULL, address)) {
|
||||||
|
tmxr_msg (newsock, "Rejecting connection from unexpected source\r\n");
|
||||||
|
sprintf (msg, "tmxr_poll_conn() - Rejecting line connection from: %s, Expected: %s", address, host);
|
||||||
|
tmxr_debug_connect_line (lp, msg);
|
||||||
|
sim_close_sock (newsock, 0);
|
||||||
|
free (address);
|
||||||
|
continue; /* Try for another connection */
|
||||||
|
}
|
||||||
|
if (lp->connecting) {
|
||||||
|
sprintf (msg, "tmxr_poll_conn() - aborting outgoing line connection attempt to: %s", lp->destination);
|
||||||
|
tmxr_debug_connect_line (lp, msg);
|
||||||
|
sim_close_sock (lp->connecting, 0); /* abort our as yet unconnnected socket */
|
||||||
|
lp->connecting = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (lp->conn == FALSE) { /* is the line available? */
|
||||||
|
if ((!lp->modem_control) || (lp->modembits & TMXR_MDM_DTR)) {
|
||||||
|
tmxr_init_line (lp); /* init line */
|
||||||
|
lp->conn = TRUE; /* record connection */
|
||||||
|
lp->sock = newsock; /* save socket */
|
||||||
|
lp->ipad = address; /* ip address */
|
||||||
|
if (!lp->notelnet) {
|
||||||
|
sim_write_sock (newsock, (char *)mantra, sizeof(mantra));
|
||||||
|
tmxr_debug (TMXR_DBG_XMT, lp, "Sending", (char *)mantra, sizeof(mantra));
|
||||||
|
}
|
||||||
|
tmxr_report_connection (mp, lp);
|
||||||
|
lp->cnms = sim_os_msec (); /* time of connection */
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
tmxr_msg (newsock, "Line connection not available\r\n");
|
||||||
|
tmxr_debug_connect_line (lp, "tmxr_poll_conn() - Line connection not available");
|
||||||
|
sim_close_sock (newsock, 0);
|
||||||
|
free (address);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
tmxr_msg (newsock, "Line connection busy\r\n");
|
||||||
|
tmxr_debug_connect_line (lp, "tmxr_poll_conn() - Line connection busy");
|
||||||
|
sim_close_sock (newsock, 0);
|
||||||
|
free (address);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
break;
|
||||||
else {
|
|
||||||
tmxr_msg (newsock, "Line connection busy\r\n");
|
|
||||||
tmxr_debug_connect_line (lp, "tmxr_poll_conn() - Line connection busy");
|
|
||||||
sim_close_sock (newsock, 0);
|
|
||||||
free (address);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/* Check for pending serial port connection notification */
|
/* Check for pending serial port connection notification */
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue