mirror of
git://xwords.git.sourceforge.net/gitroot/xwords/xwords
synced 2025-01-30 08:34:16 +01:00
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:
parent
3e9381d946
commit
7c22d1fdf8
5 changed files with 107 additions and 6 deletions
|
@ -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 ) {
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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 )
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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__ );
|
||||
|
|
Loading…
Add table
Reference in a new issue