When guest connects, check if providing too many players before

reponding to connection request so that we just deny the request (with
new error code) rather than revoking it later.
This commit is contained in:
ehouse 2009-12-14 04:10:23 +00:00
parent 35f068e05c
commit fc17df2a7e
5 changed files with 71 additions and 24 deletions

View file

@ -490,6 +490,22 @@ CookieRef::pushLastSocketGoneEvent()
m_eventQueue.push_back( evt );
}
void
CookieRef::checkHaveRoom( const CRefEvent* evt )
{
CRefEvent newEvt;
assert ( m_nPlayersSought > 0 );
if ( m_nPlayersSought < m_nPlayersHere + evt->u.con.nPlayersH ) {
newEvt.type = XWE_TOO_MANY;
newEvt.u.rmsock.socket = evt->u.con.socket;
} else {
newEvt = *evt;
newEvt.type = XWE_HAVE_ROOM;
}
m_eventQueue.push_back( newEvt );
}
void
CookieRef::handleEvents()
{
@ -511,6 +527,10 @@ CookieRef::handleEvents()
switch( takeAction ) {
case XWA_CHECK_HAVE_ROOM:
checkHaveRoom( &evt );
break;
case XWA_SEND_HOST_RSP:
case XWA_SEND_GUEST_RSP:
case XWA_SEND_1ST_RERSP:
@ -535,6 +555,10 @@ CookieRef::handleEvents()
send_denied( &evt, XWRELAY_ERROR_DUP_ROOM );
removeSocket( evt.u.rmsock.socket );
break;
case XWA_SEND_TOO_MANY:
send_denied( &evt, XWRELAY_ERROR_TOO_MANY );
removeSocket( evt.u.rmsock.socket );
break;
case XWA_FWD:
forward_or_store( &evt );
@ -574,20 +598,27 @@ CookieRef::handleEvents()
notifyDisconn( &evt );
break;
case XWA_REMOVESOCKET:
case XWA_REMOVESOCK_2:
setAllConnectedTimer();
/* fallthru */
case XWA_REMOVESOCK_1:
reducePlayerCounts( evt.u.rmsock.socket );
notifyOthers( evt.u.rmsock.socket, XWRELAY_DISCONNECT_OTHER,
XWRELAY_ERROR_LOST_OTHER );
if ( XWA_REMOVESOCK_2 == takeAction ) {
notifyOthers( evt.u.rmsock.socket, XWRELAY_DISCONNECT_OTHER,
XWRELAY_ERROR_LOST_OTHER );
}
removeSocket( evt.u.rmsock.socket );
break;
case XWA_SENDALLHERE:
case XWA_SNDALLHERE_2:
cancelAllConnectedTimer();
assignHostIds();
assignConnName();
sendAllHere();
sendAllHere( true );
break;
case XWA_SNDALLHERE_2:
sendAllHere( false );
break;
case XWA_NOTE_EMPTY:
@ -822,8 +853,8 @@ CookieRef::sendResponse( const CRefEvent* evt, bool initial )
*bufp++ = initial ? XWRELAY_CONNECT_RESP : XWRELAY_RECONNECT_RESP;
putNetShort( &bufp, GetHeartbeat() );
*bufp++ = GetPlayersHere();
*bufp++ = GetPlayersSought();
*bufp++ = GetPlayersHere();
send_with_length( socket, buf, bufp - buf, true );
logf( XW_LOGVERBOSE0, "sent %s", cmdToStr( XWRELAY_Cmd(buf[0]) ) );
@ -923,7 +954,7 @@ CookieRef::moveSockets( void )
}
void
CookieRef::sendAllHere( void )
CookieRef::sendAllHere( bool initial )
{
unsigned char buf[1 + 1 /* hostID */
+ sizeof(CookieID)
@ -932,7 +963,7 @@ CookieRef::sendAllHere( void )
unsigned char* bufp = buf;
unsigned char* idLoc;
*bufp++ = XWRELAY_ALLHERE;
*bufp++ = initial? XWRELAY_ALLHERE : XWRELAY_ALLBACK;
idLoc = bufp++; /* space for hostId, remembering address */
putNetShort( &bufp, GetCookieID() );

View file

@ -181,6 +181,7 @@ class CookieRef {
int buflen );
void pushDestBadEvent();
void pushLastSocketGoneEvent();
void checkHaveRoom( const CRefEvent* evt );
void pushRemoveSocketEvent( int socket );
void pushNotifyDisconEvent( int socket, XWREASON why );
@ -204,7 +205,7 @@ class CookieRef {
void noteHeartbeat(const CRefEvent* evt);
void notifyDisconn(const CRefEvent* evt);
void removeSocket( int socket );
void sendAllHere( void );
void sendAllHere( bool initial );
void moveSockets( void );
bool SeedBelongs( int gameSeed );
bool SeedsBelong( const char* connName );

View file

@ -65,13 +65,15 @@ StateTable g_stateTable[] = {
{ XWS_INITED, XWE_HOSTCONNECT, XWA_SEND_HOST_RSP, XWS_WAITGUESTS },
{ XWS_INITED, XWE_GUESTCONNECT, XWA_SEND_NO_ROOM, XWS_DEAD },
{ XWS_WAITGUESTS, XWE_GUESTCONNECT, XWA_SEND_GUEST_RSP, XWS_CHK_ALLHERE },
{ XWS_WAITGUESTS, XWE_HOSTCONNECT, XWA_SEND_DUP_ROOM, XWS_WAITGUESTS },
{ XWS_WAITGUESTS, XWE_GUESTCONNECT, XWA_CHECK_HAVE_ROOM,XWS_ROOMCHK },
{ XWS_ROOMCHK, XWE_HAVE_ROOM, XWA_SEND_GUEST_RSP, XWS_CHK_ALLHERE },
{ XWS_ROOMCHK, XWE_TOO_MANY, XWA_SEND_TOO_MANY, XWS_WAITGUESTS },
{ XWS_CHK_ALLHERE, XWE_ALLHERE, XWA_SENDALLHERE, XWS_ALLCONND },
{ XWS_CHK_ALLHERE, XWE_SOMEMISSING, XWA_NONE, XWS_WAITGUESTS },
{ XWS_CHK_ALLHERE, XWE_TOO_MANY, XWA_SEND_TOO_MANY, XWS_WAITGUESTS },
{ XWS_WAITGUESTS, XWE_HOSTCONNECT, XWA_SEND_DUP_ROOM, XWS_WAITGUESTS },
{ XWS_ALLCONND, XWE_DISCONN, XWA_DISCONNECT, XWS_MISSING },
{ XWS_WAITGUESTS, XWE_DISCONN, XWA_DISCONNECT, XWS_WAITGUESTS },
@ -93,9 +95,9 @@ StateTable g_stateTable[] = {
{ XWS_CHK_ALLHERE_2, XWE_ALLHERE, XWA_SNDALLHERE_2, XWS_ALLCONND },
{ XWS_CHK_ALLHERE_2, XWE_SOMEMISSING, XWA_NONE, XWS_MISSING },
{ XWS_WAITGUESTS, XWE_REMOVESOCKET, XWA_REMOVESOCKET, XWS_WAITGUESTS },
{ XWS_ALLCONND, XWE_REMOVESOCKET, XWA_REMOVESOCKET, XWS_MISSING },
{ XWS_MISSING, XWE_REMOVESOCKET, XWA_REMOVESOCKET, XWS_MISSING },
{ XWS_WAITGUESTS, XWE_REMOVESOCKET, XWA_REMOVESOCK_1, XWS_WAITGUESTS },
{ XWS_ALLCONND, XWE_REMOVESOCKET, XWA_REMOVESOCK_2, XWS_MISSING },
{ XWS_MISSING, XWE_REMOVESOCKET, XWA_REMOVESOCK_2, XWS_MISSING },
#ifdef RELAY_HEARTBEAT
{ XWS_ALLCONND, XWE_HEARTFAILED, XWA_HEARTDISCONN, XWS_MISSING },
@ -122,7 +124,7 @@ StateTable g_stateTable[] = {
{ XWS_ALLCONND, XWE_FORWARDMSG, XWA_FWD, XWS_ALLCONND },
{ XWS_MISSING, XWE_FORWARDMSG, XWA_FWD, XWS_MISSING },
{ XWS_DEAD, XWE_REMOVESOCKET, XWA_REMOVESOCKET, XWS_DEAD }
{ XWS_DEAD, XWE_REMOVESOCKET, XWA_REMOVESOCK_1, XWS_DEAD }
};
@ -168,13 +170,12 @@ stateString( XW_RELAY_STATE state )
CASESTR(XWS_ALLCONND);
CASESTR(XWS_DEAD);
CASESTR(XWS_CHECKING_CONN);
CASESTR(XWS_CHECKINGDEST);
CASESTR(XWS_CHECKING_CAN_LOCK);
CASESTR(XWS_MISSING);
CASESTR(XWS_MSGONLY);
CASESTR(XWS_CHK_ALLHERE);
CASESTR(XWS_CHK_ALLHERE_2);
CASESTR(XWS_CHKCOUNTS_INIT);
CASESTR(XWS_ROOMCHK);
default:
assert(0);
}
@ -209,6 +210,8 @@ eventString( XW_RELAY_EVENT evt )
CASESTR(XWE_ALLHERE);
CASESTR(XWE_SOMEMISSING);
CASESTR(XWE_TOO_MANY);
CASESTR(XWE_HAVE_ROOM);
CASESTR(XWE_SHUTDOWN);
default:
assert(0);
@ -236,9 +239,11 @@ actString( XW_RELAY_ACTION act )
CASESTR(XWA_TIMERDISCONN);
CASESTR(XWA_DISCONNECT);
CASESTR(XWA_NOTIFYDISCON);
CASESTR(XWA_REMOVESOCKET);
CASESTR(XWA_REMOVESOCK_1);
CASESTR(XWA_REMOVESOCK_2);
CASESTR(XWA_HEARTDISCONN);
CASESTR(XWA_SHUTDOWN);
CASESTR(XWA_CHECK_HAVE_ROOM);
CASESTR(XWA_NOTE_EMPTY);
default:
assert(0);

View file

@ -64,10 +64,8 @@ enum {
,XWS_MSGONLY /* We have no connections but still messages to
send */
,XWS_CHECKINGDEST /* Checking for valid socket */
,XWS_CHECKING_CAN_LOCK /* Is this message one that implies all
players are present? */
,XWS_ROOMCHK /* do we have room for as many players as are
being provided */
,XWS_DEAD /* About to kill the object */
} XW_RELAY_STATE;
@ -79,8 +77,10 @@ typedef enum {
,XWE_ALLHERE /* notify that all expected players are arrived */
,XWE_SOMEMISSING /* notify that some expected players are still missing */
,XWE_HAVE_ROOM
,XWE_TOO_MANY
,XWE_GUESTCONNECT /* A device is connecting using the cookie for */
,XWE_HOSTCONNECT /* this object, as host or guest */
@ -125,6 +125,8 @@ typedef enum {
,XWA_SEND_RERSP
,XWA_CHECK_HAVE_ROOM /* check for number of players still sought */
,XWA_SENDALLHERE /* Let all devices know we're in business */
,XWA_SNDALLHERE_2 /* Ditto, but for a reconnect */
@ -140,7 +142,8 @@ typedef enum {
,XWA_NOTIFYDISCON
,XWA_REMOVESOCKET
,XWA_REMOVESOCK_1 /* remove when not yet in allcond state */
,XWA_REMOVESOCK_2 /* remove after have reached allCond */
,XWA_HEARTDISCONN

View file

@ -65,6 +65,12 @@ enum { XWRELAY_NONE /* 0 is an illegal value */
Format: hostID: 1; connectionID: 2; connNameLen: 1;
connName<connNameLen>; */
, XWRELAY_ALLBACK
/* Like XWRELAY_ALLHERE, but indicates a return to all devices being
present rather than the first time that's achieved. Has no real
purpose now that the relay does store-and-forward, but at least lets
devices tell users everybody's home. */
, XWRELAY_DISCONNECT_YOU
/* Sent from relay when existing connection is terminated.
Format: errorCode: 1 */
@ -126,6 +132,7 @@ enum {
a new game? */
,XWRELAY_ERROR_NO_ROOM
,XWRELAY_ERROR_DUP_ROOM
,XWRELAY_ERROR_TOO_MANY
,XWRELAY_ERROR_LASTERR
}
#ifndef CANT_DO_TYPEDEF