fix failure of http apps to ack relay

Change how acks are handled by adding ability to look up connname by
combination of hid and token. It's a bit of a hack, but it's already
there in the protocol and enough to find the game.
This commit is contained in:
Eric House 2017-10-28 16:29:04 -07:00
parent 3e9381d946
commit 7c22d1fdf8
5 changed files with 107 additions and 6 deletions

View file

@ -375,6 +375,48 @@ CRefMgr::getMakeCookieRef( const char* const connName, HostID hid, bool* isDead
return cinfo;
}
CidInfo*
CRefMgr::getMakeCookieRef( const AddrInfo::ClientToken clientToken, HostID srcID )
{
CookieRef* cref = NULL;
CidInfo* cinfo = NULL;
char curCookie[MAX_INVITE_LEN+1];
int curLangCode;
int nPlayersT = 0;
int nAlreadyHere = 0;
for ( ; ; ) { /* for: see comment above */
char connName[MAX_CONNNAME_LEN+1] = {0};
CookieID cid = m_db->FindGame( clientToken, srcID,
connName, sizeof(connName),
curCookie, sizeof(curCookie),
&curLangCode, &nPlayersT, &nAlreadyHere );
// &seed );
if ( 0 != cid ) { /* already open */
cinfo = m_cidlock->Claim( cid );
if ( NULL == cinfo->GetRef() ) {
m_cidlock->Relinquish( cinfo, true );
continue;
}
} else if ( nPlayersT == 0 ) { /* wasn't in the DB */
/* do nothing; insufficient info to fake it */
} else {
cinfo = m_cidlock->Claim();
if ( !m_db->AddCID( connName, cinfo->GetCid() ) ) {
m_cidlock->Relinquish( cinfo, true );
continue;
}
logf( XW_LOGINFO, "%s(): added cid???", __func__ );
cref = AddNew( curCookie, connName, cinfo->GetCid(), curLangCode,
nPlayersT, nAlreadyHere );
cinfo->SetRef( cref );
}
break;
}
logf( XW_LOGINFO, "%s() => %p", __func__, cinfo );
return cinfo;
}
void
CRefMgr::RemoveSocketRefs( const AddrInfo* addr )
{
@ -722,6 +764,19 @@ SafeCref::SafeCref( const AddrInfo* addr )
}
}
SafeCref::SafeCref( const AddrInfo::ClientToken clientToken, HostID srcID )
: m_cinfo( NULL )
, m_mgr( CRefMgr::Get() )
, m_isValid( false )
{
CidInfo* cinfo = m_mgr->getMakeCookieRef( clientToken, srcID );
if ( NULL != cinfo && NULL != cinfo->GetRef() ) {
m_locked = cinfo->GetRef()->Lock();
m_cinfo = cinfo;
m_isValid = true;
}
}
SafeCref::~SafeCref()
{
if ( m_cinfo != NULL ) {

View file

@ -129,6 +129,7 @@ class CRefMgr {
bool isPublic, bool* isDead );
CidInfo* getMakeCookieRef( const char* const connName, HostID hid, bool* isDead );
CidInfo* getMakeCookieRef( const AddrInfo::ClientToken clientToken, HostID srcID );
CidInfo* getCookieRef( CookieID cid, bool failOk = false );
CidInfo* getCookieRef( const AddrInfo* addr );
@ -182,6 +183,7 @@ class SafeCref {
SafeCref( const char* const connName, HostID hid );
SafeCref( CookieID cid, bool failOk = false );
SafeCref( const AddrInfo* addr );
SafeCref( const AddrInfo::ClientToken clientToken, HostID srcID );
/* SafeCref( CookieRef* cref ); */
~SafeCref();

View file

@ -185,6 +185,41 @@ DBMgr::FindGame( const char* connName, HostID hid, char* roomBuf, int roomBufLen
return cid;
} /* FindGame */
CookieID
DBMgr::FindGame( const AddrInfo::ClientToken clientToken, HostID hid,
char* connNameBuf, int connNameBufLen,
char* roomBuf, int roomBufLen,
int* langP, int* nPlayersTP, int* nPlayersHP )
{
CookieID cid = 0;
const char* fmt = "SELECT room, lang, nTotal, nPerDevice[%d], connname FROM "
GAMES_TABLE " WHERE tokens[%d] = %d and NOT dead";
// " LIMIT 1"
;
StrWPF query;
query.catf( fmt, hid, hid, clientToken );
logf( XW_LOGINFO, "query: %s", query.c_str() );
PGresult* result = PQexec( getThreadConn(), query.c_str() );
assert( 1 >= PQntuples( result ) );
if ( 1 == PQntuples( result ) ) {
int col = 0;
// room
snprintf( roomBuf, roomBufLen, "%s", PQgetvalue( result, 0, col++ ) );
// lang
*langP = atoi( PQgetvalue( result, 0, col++ ) );
*nPlayersTP = atoi( PQgetvalue( result, 0, col++ ) );
*nPlayersHP = atoi( PQgetvalue( result, 0, col++ ) );
snprintf( connNameBuf, connNameBufLen, "%s", PQgetvalue( result, 0, col++ ) );
cid = GetCIDImpl(connNameBuf);
}
PQclear( result );
logf( XW_LOGINFO, "%s(ct=%d,hid=%d) => %d (connname=%s)", __func__, clientToken,
hid, cid, connNameBuf );
return cid;
}
bool
DBMgr::FindPlayer( DevIDRelay relayID, AddrInfo::ClientToken token,
string& connName, HostID* hidp, unsigned short* seed )

View file

@ -76,6 +76,10 @@ class DBMgr {
CookieID FindGame( const char* connName, HostID hid, char* cookieBuf, int bufLen,
int* langP, int* nPlayersTP, int* nPlayersHP,
bool* isDead );
CookieID FindGame( const AddrInfo::ClientToken clientToken, HostID hid,
char* connNameBuf, int connNameBufLen,
char* cookieBuf, int cookieBufLen,
int* langP, int* nPlayersTP, int* nPlayersHP );
bool FindGameFor( const char* connName, char* cookieBuf, int bufLen,
unsigned short seed, HostID hid,

View file

@ -996,13 +996,13 @@ processReconnect( const uint8_t* bufp, int bufLen, const AddrInfo* addr )
} /* processReconnect */
static bool
processAck( const uint8_t* bufp, int bufLen, const AddrInfo* addr )
processAck( const uint8_t* bufp, int bufLen, AddrInfo::ClientToken clientToken )
{
bool success = false;
const uint8_t* end = bufp + bufLen;
HostID srcID;
if ( getNetByte( &bufp, end, &srcID ) ) {
SafeCref scr( addr );
SafeCref scr( clientToken, srcID );
success = scr.HandleAck( srcID );
}
return success;
@ -1092,7 +1092,8 @@ forwardMessage( const uint8_t* buf, int buflen, const AddrInfo* addr )
} /* forwardMessage */
static bool
processMessage( const uint8_t* buf, int bufLen, const AddrInfo* addr )
processMessage( const uint8_t* buf, int bufLen, const AddrInfo* addr,
AddrInfo::ClientToken clientToken )
{
bool success = false; /* default is failure */
XWRELAY_Cmd cmd = *buf;
@ -1107,7 +1108,11 @@ processMessage( const uint8_t* buf, int bufLen, const AddrInfo* addr )
success = processReconnect( buf+1, bufLen-1, addr );
break;
case XWRELAY_ACK:
success = processAck( buf+1, bufLen-1, addr );
if ( clientToken != 0 ) {
success = processAck( buf+1, bufLen-1, clientToken );
} else {
logf( XW_LOGERROR, "%s(): null client token", __func__ );
}
break;
case XWRELAY_GAME_DISCONNECT:
success = processDisconnect( buf+1, bufLen-1, addr );
@ -1468,7 +1473,7 @@ handleProxyMsgs( int sock, const AddrInfo* addr, const uint8_t* bufp,
static void
game_thread_proc( UdpThreadClosure* utc )
{
if ( !processMessage( utc->buf(), utc->len(), utc->addr() ) ) {
if ( !processMessage( utc->buf(), utc->len(), utc->addr(), 0 ) ) {
XWThreadPool::GetTPool()->CloseSocket( utc->addr() );
}
}
@ -1756,7 +1761,7 @@ handle_udp_packet( UdpThreadClosure* utc )
clientToken = ntohl( clientToken );
if ( AddrInfo::NULL_TOKEN != clientToken ) {
AddrInfo addr( g_udpsock, clientToken, utc->saddr() );
(void)processMessage( ptr, end - ptr, &addr );
(void)processMessage( ptr, end - ptr, &addr, clientToken );
} else {
logf( XW_LOGERROR, "%s: dropping packet with token of 0",
__func__ );