deal with case where guest begins new game but connects to host that's

running the old game: the host may reply, but guest must not take that
as evidence of a connection having been established: don't remove sent
messages (this isn't an ACK), and don't assert later on.
This commit is contained in:
ehouse 2007-02-06 05:49:45 +00:00
parent e6315e118f
commit a762f27846

View file

@ -205,6 +205,7 @@ comms_reset( CommsCtxt* comms, XP_Bool isServer,
XP_U16 XP_UNUSED_RELAY(nPlayersHere), XP_U16 XP_UNUSED_RELAY(nPlayersHere),
XP_U16 XP_UNUSED_RELAY(nPlayersTotal) ) XP_U16 XP_UNUSED_RELAY(nPlayersTotal) )
{ {
LOG_FUNC();
#ifdef XWFEATURE_RELAY #ifdef XWFEATURE_RELAY
relayDisconnect( comms ); relayDisconnect( comms );
#endif #endif
@ -223,6 +224,7 @@ comms_reset( CommsCtxt* comms, XP_Bool isServer,
comms->r.nPlayersTotal = nPlayersTotal; comms->r.nPlayersTotal = nPlayersTotal;
relayConnect( comms ); relayConnect( comms );
#endif #endif
LOG_RETURN_VOID();
} /* comms_reset */ } /* comms_reset */
void void
@ -643,35 +645,39 @@ printQueue( CommsCtxt* comms )
/* We've received on some channel a message with a certain ID. This means /* We've received on some channel a message with a certain ID. This means
* that all messages sent on that channel with lower IDs have been received * that all messages sent on that channel with lower IDs have been received
* and can be removed from our queue. * and can be removed from our queue. BUT: if this ID is higher than any
* we've sent, don't remove. We may be starting a new game but have a server
* that's still on the old one.
*/ */
static void static void
removeFromQueue( CommsCtxt* comms, XP_PlayerAddr channelNo, MsgID msgID ) removeFromQueue( CommsCtxt* comms, XP_PlayerAddr channelNo, MsgID msgID )
{ {
XP_STATUSF( "%s: remove msgs <= " XP_LD " for channel %d (queueLen: %d)",
__func__, msgID, channelNo, comms->queueLen );
if ( (channelNo == 0) || !!getRecordFor(comms, channelNo) ) {
MsgQueueElem* elem; MsgQueueElem* elem;
MsgQueueElem* next;
MsgQueueElem* keep = NULL; MsgQueueElem* keep = NULL;
MsgQueueElem* tail = NULL; MsgQueueElem* tail = NULL;
MsgQueueElem* keepHead = NULL; MsgQueueElem* keepHead = NULL;
MsgQueueElem* next;
XP_STATUSF( "looking to remove msgs prior or equal to " XP_LD
" for channel %d (queue len now %d)",
msgID, channelNo, comms->queueLen );
for ( elem = comms->msgQueueHead; !!elem; elem = next ) { for ( elem = comms->msgQueueHead; !!elem; elem = next ) {
next = elem->next; next = elem->next;
/* remove the 0-channel message if we've established a channel number. /* remove the 0-channel message if we've established a channel
Only clients should have any 0-channel messages in the queue, and number. Only clients should have any 0-channel messages in the
receiving something from the server is an implicit ACK */ queue, and receiving something from the server is an implicit
ACK -- IFF it isn't left over from the last game. */
if ( elem->channelNo == 0 && channelNo != 0 ) { if ( (elem->channelNo == 0) && (channelNo != 0) ) {
XP_ASSERT( !comms->isServer ); /* I've seen this fail once */ XP_ASSERT( !comms->isServer ); /* I've seen this fail once */
XP_ASSERT( elem->msgID == 0 ); /* will the check below pass? */ XP_ASSERT( elem->msgID == 0 ); /* will the check below pass? */
} else if ( elem->channelNo != channelNo ) { } else if ( elem->channelNo != channelNo ) {
continue; continue;
} }
/* here */
if ( elem->msgID <= msgID ) { if ( elem->msgID <= msgID ) {
XP_FREE( comms->mpool, elem->msg ); XP_FREE( comms->mpool, elem->msg );
XP_FREE( comms->mpool, elem ); XP_FREE( comms->mpool, elem );
@ -687,11 +693,11 @@ removeFromQueue( CommsCtxt* comms, XP_PlayerAddr channelNo, MsgID msgID )
tail = elem; tail = elem;
} }
} }
comms->msgQueueHead = keepHead; comms->msgQueueHead = keepHead;
comms->msgQueueTail = tail; comms->msgQueueTail = tail;
}
XP_STATUSF( "%s: queueLen now %d", __FUNCTION__, comms->queueLen ); XP_STATUSF( "%s: queueLen now %d", __func__, comms->queueLen );
XP_ASSERT( comms->queueLen > 0 || comms->msgQueueHead == NULL ); XP_ASSERT( comms->queueLen > 0 || comms->msgQueueHead == NULL );
@ -717,7 +723,7 @@ sendMsg( CommsCtxt* comms, MsgQueueElem* elem )
result = send_via_relay( comms, XWRELAY_MSG_TORELAY, destID, result = send_via_relay( comms, XWRELAY_MSG_TORELAY, destID,
elem->msg, elem->len ); elem->msg, elem->len );
} else { } else {
XP_LOGF( "skipping message: not connected" ); XP_LOGF( "%s: skipping message: not connected", __func__ );
} }
#endif #endif
} else { } else {
@ -915,7 +921,7 @@ comms_checkIncomingStream( CommsCtxt* comms, XWStreamCtxt* stream,
if ( !done ) { if ( !done ) {
if ( stream_getSize( stream ) >= sizeof(connID) ) { if ( stream_getSize( stream ) >= sizeof(connID) ) {
connID = stream_getU32( stream ); connID = stream_getU32( stream );
XP_STATUSF( "read connID of %lx", connID ); XP_STATUSF( "%s: read connID of %lx", __func__, connID );
if ( comms->connID == connID || comms->connID == CONN_ID_NONE ) { if ( comms->connID == connID || comms->connID == CONN_ID_NONE ) {
if ( stream_getSize( stream ) >= sizeof(channelNo) if ( stream_getSize( stream ) >= sizeof(channelNo)
@ -980,7 +986,6 @@ comms_checkIncomingStream( CommsCtxt* comms, XWStreamCtxt* stream,
validMessage = XP_FALSE; validMessage = XP_FALSE;
} }
} else if ( msgID > 1 ) { } else if ( msgID > 1 ) {
XP_ASSERT( 0 );
validMessage = XP_FALSE; validMessage = XP_FALSE;
} }
#ifdef DEBUG #ifdef DEBUG
@ -1141,18 +1146,16 @@ channelToAddress( CommsCtxt* comms, XP_PlayerAddr channelNo,
static AddressRecord* static AddressRecord*
getRecordFor( CommsCtxt* comms, XP_PlayerAddr channelNo ) getRecordFor( CommsCtxt* comms, XP_PlayerAddr channelNo )
{ {
AddressRecord* recs; AddressRecord* recs = NULL;
if ( channelNo == CHANNEL_NONE ) {
return (AddressRecord*)NULL;
}
if ( channelNo != CHANNEL_NONE ) {
for ( recs = comms->recs; !!recs; recs = recs->next ) { for ( recs = comms->recs; !!recs; recs = recs->next ) {
if ( recs->channelNo == channelNo ) { if ( recs->channelNo == channelNo ) {
break;
}
}
}
return recs; return recs;
}
}
return (AddressRecord*)NULL;
} /* getRecordFor */ } /* getRecordFor */
static XP_U16 static XP_U16
@ -1276,7 +1279,7 @@ send_via_relay( CommsCtxt* comms, XWRELAY_Cmd cmd, XWHostID destID,
static void static void
relayConnect( CommsCtxt* comms ) relayConnect( CommsCtxt* comms )
{ {
XP_LOGF( "relayConnect called" ); LOG_FUNC();
if ( comms->addr.conType == COMMS_CONN_RELAY && !comms->r.connecting ) { if ( comms->addr.conType == COMMS_CONN_RELAY && !comms->r.connecting ) {
comms->r.connecting = XP_TRUE; comms->r.connecting = XP_TRUE;
send_via_relay( comms, send_via_relay( comms,