change relay connect message format to include client version (meaning

of which is TBD).  When a new-version client connects, store the value
it's passed. At first this will let me track how quickly people
upgrade.  Later I can use it to let different clients have different
formats to their messages e.g. to proxy.
This commit is contained in:
Eric House 2012-01-26 05:43:54 -08:00
parent af26ebfff9
commit 866aeb2387
11 changed files with 74 additions and 36 deletions

View file

@ -35,6 +35,10 @@
#ifndef XWFEATURE_STANDALONE_ONLY
#ifndef INITIAL_CLIENT_VERS
# define INITIAL_CLIENT_VERS 1
#endif
#ifdef COMMS_HEARTBEAT
/* It might make sense for this to be a parameter or somehow tied to the
platform and transport. But in that case it'd have to be passed across
@ -2009,6 +2013,7 @@ msg_to_stream( CommsCtxt* comms, XWRELAY_Cmd cmd, XWHostID destID,
break;
case XWRELAY_GAME_CONNECT:
stream_putU8( stream, XWRELAY_PROTO_VERSION );
stream_putU16( stream, INITIAL_CLIENT_VERS );
stringToStream( stream, addr.u.ip_relay.invite );
stream_putU8( stream, addr.u.ip_relay.seeksPublicRoom );
stream_putU8( stream, addr.u.ip_relay.advertiseRoom );
@ -2027,6 +2032,7 @@ msg_to_stream( CommsCtxt* comms, XWRELAY_Cmd cmd, XWHostID destID,
case XWRELAY_GAME_RECONNECT:
stream_putU8( stream, XWRELAY_PROTO_VERSION );
stream_putU16( stream, INITIAL_CLIENT_VERS );
stringToStream( stream, addr.u.ip_relay.invite );
stream_putU8( stream, addr.u.ip_relay.seeksPublicRoom );
stream_putU8( stream, addr.u.ip_relay.advertiseRoom );

View file

@ -179,7 +179,7 @@ CookieRef::Unlock() {
}
bool
CookieRef::_Connect( int socket, int nPlayersH, int nPlayersS, int seed,
CookieRef::_Connect( int socket, int clientVersion, int nPlayersH, int nPlayersS, int seed,
bool seenSeed, in_addr& addr )
{
bool connected = false;
@ -199,7 +199,7 @@ CookieRef::_Connect( int socket, int nPlayersH, int nPlayersS, int seed,
if ( !connected ) {
set<int> sockets = GetSockets();
if ( sockets.end() == sockets.find( socket ) ) {
pushConnectEvent( socket, nPlayersH, nPlayersS, seed, addr );
pushConnectEvent( socket, clientVersion, nPlayersH, nPlayersS, seed, addr );
handleEvents();
connected = HasSocket_locked( socket );
} else {
@ -210,7 +210,8 @@ CookieRef::_Connect( int socket, int nPlayersH, int nPlayersS, int seed,
}
bool
CookieRef::_Reconnect( int socket, HostID hid, int nPlayersH, int nPlayersS,
CookieRef::_Reconnect( int socket, int clientVersion, HostID hid,
int nPlayersH, int nPlayersS,
int seed, in_addr& addr, bool gameDead )
{
bool spotTaken = false;
@ -222,7 +223,7 @@ CookieRef::_Reconnect( int socket, HostID hid, int nPlayersH, int nPlayersS,
logf( XW_LOGINFO, "%s: dropping because already here",
__func__ );
} else {
pushReconnectEvent( socket, hid, nPlayersH, nPlayersS, seed, addr );
pushReconnectEvent( socket, clientVersion, hid, nPlayersH, nPlayersS, seed, addr );
}
if ( gameDead ) {
pushGameDead( socket );
@ -512,12 +513,13 @@ CookieRef::_Remove( int socket )
} /* Forward */
void
CookieRef::pushConnectEvent( int socket, int nPlayersH, int nPlayersS,
CookieRef::pushConnectEvent( int socket, int clientVersion, int nPlayersH, int nPlayersS,
int seed, in_addr& addr )
{
CRefEvent evt;
evt.type = XWE_DEVCONNECT;
evt.u.con.socket = socket;
evt.u.con.clientVersion = clientVersion;
evt.u.con.srcID = HOST_ID_NONE;
evt.u.con.nPlayersH = nPlayersH;
evt.u.con.nPlayersS = nPlayersS;
@ -527,11 +529,13 @@ CookieRef::pushConnectEvent( int socket, int nPlayersH, int nPlayersS,
} /* pushConnectEvent */
void
CookieRef::pushReconnectEvent( int socket, HostID srcID, int nPlayersH,
int nPlayersS, int seed, in_addr& addr )
CookieRef::pushReconnectEvent( int socket, int clientVersion, HostID srcID,
int nPlayersH, int nPlayersS, int seed,
in_addr& addr )
{
CRefEvent evt( XWE_RECONNECT );
evt.u.con.socket = socket;
evt.u.con.clientVersion = clientVersion;
evt.u.con.srcID = srcID;
evt.u.con.nPlayersH = nPlayersH;
evt.u.con.nPlayersS = nPlayersS;
@ -872,9 +876,10 @@ CookieRef::increasePlayerCounts( CRefEvent* evt, bool reconn, HostID* hidp )
assert( m_nPlayersHere <= m_nPlayersSought );
}
evt->u.con.srcID = DBMgr::Get()->AddDevice( ConnName(), evt->u.con.srcID,
nPlayersH, seed,
evt->u.con.addr, reconn );
evt->u.con.srcID =
DBMgr::Get()->AddDevice( ConnName(), evt->u.con.srcID,
evt->u.con.clientVersion, nPlayersH, seed,
evt->u.con.addr, reconn );
HostID hostid = evt->u.con.srcID;
if ( NULL != hidp ) {

View file

@ -119,9 +119,10 @@ class CookieRef {
static void Delete( CookieID cid );
static void Delete( const char* name );
bool _Connect( int socket, int nPlayersH, int nPlayersS, int seed,
bool seenSeed, in_addr& addr );
bool _Reconnect( int socket, HostID srcID, int nPlayersH, int nPlayersS,
bool _Connect( int socket, int clientVersion, int nPlayersH, int nPlayersS,
int seed, bool seenSeed, in_addr& addr );
bool _Reconnect( int socket, int clientVersion, HostID srcID,
int nPlayersH, int nPlayersS,
int seed, in_addr& addr, bool gameDead );
void _HandleAck( HostID hostID );
void _PutMsg( HostID srcID, in_addr& addr, HostID destID, unsigned char* buf, int buflen );
@ -155,6 +156,7 @@ class CookieRef {
} fwd;
struct {
int socket;
int clientVersion;
int nPlayersH;
int nPlayersS;
int seed;
@ -193,9 +195,9 @@ class CookieRef {
bool cascade );
void send_msg( int socket, HostID id, XWRelayMsg msg, XWREASON why,
bool cascade );
void pushConnectEvent( int socket, int nPlayersH, int nPlayersS,
void pushConnectEvent( int socket, int clientVersion, int nPlayersH, int nPlayersS,
int seed, in_addr& addr );
void pushReconnectEvent( int socket, HostID srcID,
void pushReconnectEvent( int socket, int clientVersion, HostID srcID,
int nPlayersH, int nPlayersS,
int seed, in_addr& addr );
void pushHeartbeatEvent( HostID id, int socket );

View file

@ -589,11 +589,13 @@ CookieMapIterator::Next()
//////////////////////////////////////////////////////////////////////////////
/* connect case */
SafeCref::SafeCref( const char* cookie, int socket, int nPlayersH, int nPlayersS,
SafeCref::SafeCref( const char* cookie, int socket, int clientVersion,
int nPlayersH, int nPlayersS,
unsigned short gameSeed, int langCode, bool wantsPublic,
bool makePublic )
: m_cinfo( NULL )
, m_mgr( CRefMgr::Get() )
, m_clientVersion( clientVersion )
, m_isValid( false )
, m_seenSeed( false )
{
@ -613,11 +615,12 @@ SafeCref::SafeCref( const char* cookie, int socket, int nPlayersH, int nPlayersS
/* REconnect case */
SafeCref::SafeCref( const char* connName, const char* cookie, HostID hid,
int socket, int nPlayersH, int nPlayersS,
int socket, int clientVersion, int nPlayersH, int nPlayersS,
unsigned short gameSeed, int langCode,
bool wantsPublic, bool makePublic )
: m_cinfo( NULL )
, m_mgr( CRefMgr::Get() )
, m_clientVersion( clientVersion )
, m_isValid( false )
{
CidInfo* cinfo;

View file

@ -171,12 +171,13 @@ class SafeCref {
public:
/* for connect */
SafeCref( const char* cookie, int socket, int nPlayersH, int nPlayersS,
SafeCref( const char* cookie, int socket, int clientVersion,
int nPlayersH, int nPlayersS,
unsigned short gameSeed, int langCode, bool wantsPublic,
bool makePublic );
/* for reconnect */
SafeCref( const char* connName, const char* cookie, HostID hid,
int socket, int nPlayersH, int nPlayersS,
int socket, int clientVersion, int nPlayersH, int nPlayersS,
unsigned short gameSeed, int langCode,
bool wantsPublic, bool makePublic );
SafeCref( const char* const connName );
@ -209,7 +210,7 @@ class SafeCref {
if ( IsValid() ) {
CookieRef* cref = m_cinfo->GetRef();
assert( 0 != cref->GetCid() );
return cref->_Connect( socket, nPlayersH, nPlayersS, seed,
return cref->_Connect( socket, m_clientVersion, nPlayersH, nPlayersS, seed,
m_seenSeed, addr );
} else {
return false;
@ -225,7 +226,7 @@ class SafeCref {
if ( m_dead ) {
*errp = XWRELAY_ERROR_DEADGAME;
} else {
success = cref->_Reconnect( socket, srcID, nPlayersH,
success = cref->_Reconnect( socket, m_clientVersion, srcID, nPlayersH,
nPlayersS, seed, addr, m_dead );
}
}
@ -385,6 +386,7 @@ class SafeCref {
private:
CidInfo* m_cinfo;
CRefMgr* m_mgr;
int m_clientVersion;
bool m_isValid;
bool m_locked;
bool m_dead;

View file

@ -238,7 +238,7 @@ DBMgr::AllDevsAckd( const char* const connName )
}
HostID
DBMgr::AddDevice( const char* connName, HostID curID, int nToAdd,
DBMgr::AddDevice( const char* connName, HostID curID, int clientVersion, int nToAdd,
unsigned short seed, const in_addr& addr, bool ackd )
{
HostID newID = curID;
@ -255,11 +255,12 @@ DBMgr::AddDevice( const char* connName, HostID curID, int nToAdd,
assert( newID <= 4 );
const char* fmt = "UPDATE " GAMES_TABLE " SET nPerDevice[%d] = %d,"
" clntVers[%d] = %d,"
" seeds[%d] = %d, addrs[%d] = \'%s\', mtimes[%d]='now', ack[%d]=\'%c\'"
" WHERE connName = '%s'";
char query[256];
snprintf( query, sizeof(query), fmt, newID, nToAdd, newID, seed,
newID, inet_ntoa(addr), newID,
snprintf( query, sizeof(query), fmt, newID, nToAdd, newID, clientVersion,
newID, seed, newID, inet_ntoa(addr), newID,
newID, ackd?'A':'a', connName );
logf( XW_LOGINFO, "%s: query: %s", __func__, query );

View file

@ -55,7 +55,7 @@ class DBMgr {
char* connNameBuf, int bufLen, int* nPlayersHP );
bool AllDevsAckd( const char* const connName );
HostID AddDevice( const char* const connName, HostID curID,
HostID AddDevice( const char* const connName, HostID curID, int clientVersion,
int nToAdd, unsigned short seed, const in_addr& addr, bool unAckd );
void NoteAckd( const char* const connName, HostID id );
HostID HIDForSeed( const char* const connName, unsigned short seed );

View file

@ -26,7 +26,7 @@ QUERY="WHERE NOT -NTOTAL = sum_array(nperdevice)"
echo "Device (pid) count: $(pidof xwords | wc | awk '{print $2}')"
echo "Row count:" $(psql -t xwgames -c "select count(*) FROM games $QUERY;")
echo "SELECT dead,connname,cid,room,lang,ntotal,nperdevice,seeds,ack,nsent "\
echo "SELECT dead,connname,cid,room,lang,ntotal,clntVers,nperdevice,seeds,ack,nsent "\
"FROM games $QUERY ORDER BY NOT dead, connname LIMIT $LIMIT;" \
| psql xwgames

View file

@ -267,10 +267,27 @@ readStr( unsigned char** bufp, const unsigned char* end,
} /* readStr */
static XWREASON
flagsOK( unsigned char flags )
flagsOK( unsigned char** bufp, unsigned char const* end,
unsigned short* clientVersion )
{
return flags == XWRELAY_PROTO_VERSION ?
XWRELAY_ERROR_NONE : XWRELAY_ERROR_OLDFLAGS;
XWREASON err = XWRELAY_ERROR_OLDFLAGS;
unsigned char flags;
if ( getNetByte( bufp, end, &flags ) ) {
switch ( flags ) {
case XWRELAY_PROTO_VERSION_CLIENTVERS:
if ( getNetShort( bufp, end, clientVersion ) ) {
err = XWRELAY_ERROR_NONE;
}
break;
case XWRELAY_PROTO_VERSION_NOCLIENT:
*clientVersion = 0;
err = XWRELAY_ERROR_NONE;
break;
default:
break;
}
}
return err;
} /* flagsOK */
void
@ -328,8 +345,8 @@ processConnect( unsigned char* bufp, int bufLen, int socket, in_addr& addr )
cookie[0] = '\0';
unsigned char flags = *bufp++;
XWREASON err = flagsOK( flags );
unsigned short clientVersion;
XWREASON err = flagsOK( &bufp, end, &clientVersion );
if ( err == XWRELAY_ERROR_NONE ) {
/* HostID srcID; */
unsigned char nPlayersH;
@ -354,7 +371,7 @@ processConnect( unsigned char* bufp, int bufLen, int socket, in_addr& addr )
static pthread_mutex_t s_newCookieLock = PTHREAD_MUTEX_INITIALIZER;
MutexLock ml( &s_newCookieLock );
SafeCref scr( cookie, socket, nPlayersH, nPlayersT,
SafeCref scr( cookie, socket, clientVersion, nPlayersH, nPlayersT,
seed, langCode, wantsPublic, makePublic );
/* nPlayersT etc could be slots in SafeCref to avoid passing
here */
@ -378,8 +395,8 @@ processReconnect( unsigned char* bufp, int bufLen, int socket, in_addr& addr )
logf( XW_LOGINFO, "%s()", __func__ );
unsigned char flags = *bufp++;
XWREASON err = flagsOK( flags );
unsigned short clientVersion;
XWREASON err = flagsOK( &bufp, end, &clientVersion );
if ( err == XWRELAY_ERROR_NONE ) {
char cookie[MAX_INVITE_LEN+1];
char connName[MAX_CONNNAME_LEN+1] = {0};
@ -401,7 +418,7 @@ processReconnect( unsigned char* bufp, int bufLen, int socket, in_addr& addr )
&& readStr( &bufp, end, connName, sizeof(connName) ) ) {
SafeCref scr( connName[0]? connName : NULL,
cookie, srcID, socket, nPlayersH,
cookie, srcID, socket, clientVersion, nPlayersH,
nPlayersT, gameSeed, langCode,
wantsPublic, makePublic );
success = scr.Reconnect( socket, srcID, nPlayersH, nPlayersT,

View file

@ -120,7 +120,8 @@ typedef unsigned char XWRELAY_Cmd;
#define XWRELAY_PROTO_VERSION_LATE_NAME 0x02
#define XWRELAY_PROTO_VERSION_LATE_COOKIEID 0x03
#define XWRELAY_PROTO_VERSION_NOCLIENT 0x04
#define XWRELAY_PROTO_VERSION XWRELAY_PROTO_VERSION_NOCLIENT
#define XWRELAY_PROTO_VERSION_CLIENTVERS 0x05
#define XWRELAY_PROTO_VERSION XWRELAY_PROTO_VERSION_CLIENTVERS
/* Errors passed with denied */
#ifndef CANT_DO_TYPEDEF

View file

@ -50,6 +50,7 @@ cid integer
,pub BOOLEAN
,connName VARCHAR(64) UNIQUE PRIMARY KEY
,nTotal INTEGER
,clntVers INTEGER[]
,nPerDevice INTEGER[]
,seeds INTEGER[]
,ack VARCHAR(1)[]