mirror of
git://xwords.git.sourceforge.net/gitroot/xwords/xwords
synced 2025-02-06 20:45:54 +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;
|
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
|
void
|
||||||
CRefMgr::RemoveSocketRefs( const AddrInfo* addr )
|
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()
|
SafeCref::~SafeCref()
|
||||||
{
|
{
|
||||||
if ( m_cinfo != NULL ) {
|
if ( m_cinfo != NULL ) {
|
||||||
|
|
|
@ -129,6 +129,7 @@ class CRefMgr {
|
||||||
bool isPublic, bool* isDead );
|
bool isPublic, bool* isDead );
|
||||||
|
|
||||||
CidInfo* getMakeCookieRef( const char* const connName, HostID hid, 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( CookieID cid, bool failOk = false );
|
||||||
CidInfo* getCookieRef( const AddrInfo* addr );
|
CidInfo* getCookieRef( const AddrInfo* addr );
|
||||||
|
@ -182,6 +183,7 @@ class SafeCref {
|
||||||
SafeCref( const char* const connName, HostID hid );
|
SafeCref( const char* const connName, HostID hid );
|
||||||
SafeCref( CookieID cid, bool failOk = false );
|
SafeCref( CookieID cid, bool failOk = false );
|
||||||
SafeCref( const AddrInfo* addr );
|
SafeCref( const AddrInfo* addr );
|
||||||
|
SafeCref( const AddrInfo::ClientToken clientToken, HostID srcID );
|
||||||
/* SafeCref( CookieRef* cref ); */
|
/* SafeCref( CookieRef* cref ); */
|
||||||
~SafeCref();
|
~SafeCref();
|
||||||
|
|
||||||
|
|
|
@ -185,6 +185,41 @@ DBMgr::FindGame( const char* connName, HostID hid, char* roomBuf, int roomBufLen
|
||||||
return cid;
|
return cid;
|
||||||
} /* FindGame */
|
} /* 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
|
bool
|
||||||
DBMgr::FindPlayer( DevIDRelay relayID, AddrInfo::ClientToken token,
|
DBMgr::FindPlayer( DevIDRelay relayID, AddrInfo::ClientToken token,
|
||||||
string& connName, HostID* hidp, unsigned short* seed )
|
string& connName, HostID* hidp, unsigned short* seed )
|
||||||
|
|
|
@ -76,6 +76,10 @@ class DBMgr {
|
||||||
CookieID FindGame( const char* connName, HostID hid, char* cookieBuf, int bufLen,
|
CookieID FindGame( const char* connName, HostID hid, char* cookieBuf, int bufLen,
|
||||||
int* langP, int* nPlayersTP, int* nPlayersHP,
|
int* langP, int* nPlayersTP, int* nPlayersHP,
|
||||||
bool* isDead );
|
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,
|
bool FindGameFor( const char* connName, char* cookieBuf, int bufLen,
|
||||||
unsigned short seed, HostID hid,
|
unsigned short seed, HostID hid,
|
||||||
|
|
|
@ -996,13 +996,13 @@ processReconnect( const uint8_t* bufp, int bufLen, const AddrInfo* addr )
|
||||||
} /* processReconnect */
|
} /* processReconnect */
|
||||||
|
|
||||||
static bool
|
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;
|
bool success = false;
|
||||||
const uint8_t* end = bufp + bufLen;
|
const uint8_t* end = bufp + bufLen;
|
||||||
HostID srcID;
|
HostID srcID;
|
||||||
if ( getNetByte( &bufp, end, &srcID ) ) {
|
if ( getNetByte( &bufp, end, &srcID ) ) {
|
||||||
SafeCref scr( addr );
|
SafeCref scr( clientToken, srcID );
|
||||||
success = scr.HandleAck( srcID );
|
success = scr.HandleAck( srcID );
|
||||||
}
|
}
|
||||||
return success;
|
return success;
|
||||||
|
@ -1092,7 +1092,8 @@ forwardMessage( const uint8_t* buf, int buflen, const AddrInfo* addr )
|
||||||
} /* forwardMessage */
|
} /* forwardMessage */
|
||||||
|
|
||||||
static bool
|
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 */
|
bool success = false; /* default is failure */
|
||||||
XWRELAY_Cmd cmd = *buf;
|
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 );
|
success = processReconnect( buf+1, bufLen-1, addr );
|
||||||
break;
|
break;
|
||||||
case XWRELAY_ACK:
|
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;
|
break;
|
||||||
case XWRELAY_GAME_DISCONNECT:
|
case XWRELAY_GAME_DISCONNECT:
|
||||||
success = processDisconnect( buf+1, bufLen-1, addr );
|
success = processDisconnect( buf+1, bufLen-1, addr );
|
||||||
|
@ -1468,7 +1473,7 @@ handleProxyMsgs( int sock, const AddrInfo* addr, const uint8_t* bufp,
|
||||||
static void
|
static void
|
||||||
game_thread_proc( UdpThreadClosure* utc )
|
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() );
|
XWThreadPool::GetTPool()->CloseSocket( utc->addr() );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1756,7 +1761,7 @@ handle_udp_packet( UdpThreadClosure* utc )
|
||||||
clientToken = ntohl( clientToken );
|
clientToken = ntohl( clientToken );
|
||||||
if ( AddrInfo::NULL_TOKEN != clientToken ) {
|
if ( AddrInfo::NULL_TOKEN != clientToken ) {
|
||||||
AddrInfo addr( g_udpsock, clientToken, utc->saddr() );
|
AddrInfo addr( g_udpsock, clientToken, utc->saddr() );
|
||||||
(void)processMessage( ptr, end - ptr, &addr );
|
(void)processMessage( ptr, end - ptr, &addr, clientToken );
|
||||||
} else {
|
} else {
|
||||||
logf( XW_LOGERROR, "%s: dropping packet with token of 0",
|
logf( XW_LOGERROR, "%s: dropping packet with token of 0",
|
||||||
__func__ );
|
__func__ );
|
||||||
|
|
Loading…
Add table
Reference in a new issue