From 063b01d3d81f679af7b7aa97afca3d19589a6ca1 Mon Sep 17 00:00:00 2001 From: Eric House Date: Sun, 25 Aug 2013 21:20:26 -0700 Subject: [PATCH] change most len-as-short+bytes strings to vli+bytes; add device model to what's passed for device registration, and store it in a new column in devices table. --- .../org/eehouse/android/xw4/RelayService.java | 35 +++--- xwords4/linux/relaycon.c | 46 +++++--- xwords4/relay/dbmgr.cpp | 18 +-- xwords4/relay/dbmgr.h | 5 +- xwords4/relay/xwrelay.cpp | 110 +++++++++--------- xwords4/relay/xwrelay.sh | 1 + 6 files changed, 116 insertions(+), 99 deletions(-) diff --git a/xwords4/android/XWords4/src/org/eehouse/android/xw4/RelayService.java b/xwords4/android/XWords4/src/org/eehouse/android/xw4/RelayService.java index 00d8ce936..e4d1c0631 100644 --- a/xwords4/android/XWords4/src/org/eehouse/android/xw4/RelayService.java +++ b/xwords4/android/XWords4/src/org/eehouse/android/xw4/RelayService.java @@ -24,14 +24,15 @@ import android.app.Service; import android.content.Context; import android.content.Intent; import android.os.AsyncTask; +import android.os.Build; import android.os.Handler; import android.os.IBinder; import java.io.ByteArrayInputStream; -import java.io.InputStream; -import java.io.OutputStream; import java.io.ByteArrayOutputStream; import java.io.DataInputStream; import java.io.DataOutputStream; +import java.io.InputStream; +import java.io.OutputStream; import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.InetAddress; @@ -494,24 +495,24 @@ public class RelayService extends XWService int unavail = dis.readInt(); DbgUtils.logf( "relay unvailable for another %d seconds", unavail ); - String str = getStringWithLength( dis ); + String str = getVLIString( dis ); sendResult( MultiEvent.RELAY_ALERT, str ); break; case XWPDEV_ALERT: - str = getStringWithLength( dis ); + str = getVLIString( dis ); Intent intent = GamesList.makeAlertIntent( this, str ); Utils.postNotification( this, intent, R.string.relay_alert_title, str, str.hashCode() ); break; case XWPDEV_BADREG: - str = getStringWithLength( dis ); + str = getVLIString( dis ); DbgUtils.logf( "bad relayID \"%s\" reported", str ); XWPrefs.clearRelayDevID( this ); registerWithRelay(); break; case XWPDEV_REGRSP: - str = getStringWithLength( dis ); + str = getVLIString( dis ); m_maxIntervalSeconds = dis.readShort(); DbgUtils.logf( "got relayid %s, maxInterval %d", str, m_maxIntervalSeconds ); @@ -553,12 +554,11 @@ public class RelayService extends XWService try { DataOutputStream out = addProtoAndCmd( bas, XWRelayReg.XWPDEV_REG ); out.writeByte( typ[0] ); - out.writeShort( devid.length() ); - out.writeBytes( devid ); + writeVLIString( out, devid ); out.writeShort( GitVersion.CLIENT_VERS_RELAY ); - out.writeShort( GitVersion.VERS.length() ); - out.writeBytes( GitVersion.VERS ); + writeVLIString( out, GitVersion.VERS ); + writeVLIString( out, Build.MODEL ); postPacket( bas ); } catch ( java.io.IOException ioe ) { @@ -572,8 +572,7 @@ public class RelayService extends XWService try { DataOutputStream out = addProtoAndCmd( bas, reg ); String devid = getDevID( null ); - out.writeShort( devid.length() ); - out.writeBytes( devid ); + writeVLIString( out, devid ); postPacket( bas ); } catch ( java.io.IOException ioe ) { DbgUtils.loge( ioe ); @@ -656,10 +655,10 @@ public class RelayService extends XWService return result; } - private String getStringWithLength( DataInputStream dis ) + private String getVLIString( DataInputStream dis ) throws java.io.IOException { - short len = dis.readShort(); + int len = vli2un( dis ); byte[] tmp = new byte[len]; dis.read( tmp ); String result = new String( tmp ); @@ -1000,6 +999,14 @@ public class RelayService extends XWService return result; } + private static void writeVLIString( DataOutputStream os, String str ) + throws java.io.IOException + { + int len = str.length(); + un2vli( len, os ); + os.writeBytes( str ); + } + /* Timers: * * Two goals: simulate the GCM experience for those who don't have diff --git a/xwords4/linux/relaycon.c b/xwords4/linux/relaycon.c index 33692fcf6..6916da722 100644 --- a/xwords4/linux/relaycon.c +++ b/xwords4/linux/relaycon.c @@ -42,7 +42,7 @@ static RelayConStorage* getStorage( LaunchParams* params ); static XP_U32 hostNameToIP( const XP_UCHAR* name ); static void relaycon_receive( void* closure, int socket ); static ssize_t sendIt( RelayConStorage* storage, const XP_U8* msgbuf, XP_U16 len ); -static size_t addStrWithLength( XP_U8* buf, XP_U8* end, const XP_UCHAR* str ); +static size_t addVLIStr( XP_U8* buf, size_t len, const XP_UCHAR* str ); static void getNetString( const XP_U8** ptr, XP_U16 len, XP_UCHAR* buf ); static XP_U16 getNetShort( const XP_U8** ptr ); static XP_U32 getNetLong( const XP_U8** ptr ); @@ -90,7 +90,8 @@ relaycon_reg( LaunchParams* params, const XP_UCHAR* devID, DevIDType typ ) indx += writeDevID( &tmpbuf[indx], sizeof(tmpbuf) - indx, devID ); indx += writeShort( &tmpbuf[indx], sizeof(tmpbuf) - indx, INITIAL_CLIENT_VERS ); - indx += addStrWithLength( &tmpbuf[indx], tmpbuf + sizeof(tmpbuf), SVN_REV ); + indx += addVLIStr( &tmpbuf[indx], sizeof(tmpbuf) - indx, SVN_REV ); + indx += addVLIStr( &tmpbuf[indx], sizeof(tmpbuf) - indx, "linux box" ); sendIt( storage, tmpbuf, indx ); } @@ -158,7 +159,7 @@ relaycon_requestMsgs( LaunchParams* params, const XP_UCHAR* devID ) XP_U8 tmpbuf[128]; int indx = 0; indx += writeHeader( storage, tmpbuf, XWPDEV_RQSTMSGS ); - indx += addStrWithLength( &tmpbuf[indx], tmpbuf + sizeof(tmpbuf), devID ); + indx += addVLIStr( &tmpbuf[indx], sizeof(tmpbuf) - indx, devID ); sendIt( storage, tmpbuf, indx ); } @@ -218,7 +219,10 @@ relaycon_receive( void* closure, int socket ) sendAckIf( storage, &header ); switch( header.cmd ) { case XWPDEV_REGRSP: { - XP_U16 len = getNetShort( &ptr ); + uint32_t len; + if ( !vli2un( &ptr, &len ) ) { + assert(0); + } XP_UCHAR devID[len+1]; getNetString( &ptr, len, devID ); XP_U16 maxInterval = getNetShort( &ptr ); @@ -241,9 +245,13 @@ relaycon_receive( void* closure, int socket ) case XWPDEV_UNAVAIL: { XP_U32 unavail = getNetLong( &ptr ); XP_LOGF( "%s: unavail = %lu", __func__, unavail ); - XP_U16 len = getNetShort( &ptr ); + uint32_t len; + if ( !vli2un( &ptr, &len ) ) { + assert(0); + } XP_UCHAR buf[len+1]; getNetString( &ptr, len, buf ); + (*storage->procs.msgErrorMsg)( storage->procsClosure, buf ); break; } @@ -257,11 +265,12 @@ relaycon_receive( void* closure, int socket ) break; } case XWPDEV_ALERT: { - XP_U16 len = getNetShort( &ptr ); - unsigned char buf[len + 1]; - memcpy( buf, ptr, len ); - ptr += len; - buf[len] = '\0'; + uint32_t len; + if ( !vli2un( &ptr, &len ) ) { + assert(0); + } + XP_UCHAR buf[len + 1]; + getNetString( &ptr, len, buf ); XP_LOGF( "%s: got message: %s", __func__, buf ); break; } @@ -323,22 +332,23 @@ sendIt( RelayConStorage* storage, const XP_U8* msgbuf, XP_U16 len ) } static size_t -addStrWithLength( XP_U8* buf, XP_U8* end, const XP_UCHAR* str ) +addVLIStr( XP_U8* buf, size_t buflen, const XP_UCHAR* str ) { - XP_U16 len = !!str? XP_STRLEN( str ) : 0; - if ( buf + len + sizeof(len) <= end ) { - XP_U16 lenNBO = htons( len ); - XP_MEMCPY( buf, &lenNBO, sizeof(lenNBO) ); - buf += sizeof(lenNBO); + uint32_t len = !!str? strlen( str ) : 0; + uint8_t nbuf[5]; + size_t nsize = un2vli( len, nbuf ); + if ( nsize + len <= buflen ) { + memcpy( buf, nbuf, nsize ); + buf += nsize; XP_MEMCPY( buf, str, len ); } - return len + sizeof(len); + return nsize + len; } static size_t writeDevID( XP_U8* buf, size_t len, const XP_UCHAR* str ) { - return addStrWithLength( buf, buf + len, str ); + return addVLIStr( buf, len, str ); } static size_t diff --git a/xwords4/relay/dbmgr.cpp b/xwords4/relay/dbmgr.cpp index 8f0fa958c..a63b9673b 100644 --- a/xwords4/relay/dbmgr.cpp +++ b/xwords4/relay/dbmgr.cpp @@ -340,7 +340,7 @@ DBMgr::AllDevsAckd( const char* const connName ) // already there. DevIDRelay DBMgr::RegisterDevice( const DevID* host, int clientVersion, - const char* const desc ) + const char* const desc, const char* const model ) { DevIDRelay devID; assert( host->m_devIDType != ID_TYPE_NONE ); @@ -368,14 +368,14 @@ DBMgr::RegisterDevice( const DevID* host, int clientVersion, const char* command = "INSERT INTO " DEVICES_TABLE " (id, devType, devid, clntVers, versDesc)" " VALUES( $1, $2, $3, $4, $5 )"; - int nParams = 5; + int nParams = 6; char* paramValues[nParams]; char buf[1024]; formatParams( paramValues, nParams, - "%d"DELIM"%d"DELIM"%s"DELIM"%d"DELIM"%s", + "%d"DELIM"%d"DELIM"%s"DELIM"%d"DELIM"%s"DELIM"%s", buf, sizeof(buf), devID, host->m_devIDType, host->m_devIDString.c_str(), clientVersion, - desc ); + desc, model ); PGresult* result = PQexecParams( getThreadConn(), command, nParams, NULL, @@ -396,12 +396,13 @@ DBMgr::RegisterDevice( const DevID* host, int clientVersion, DevIDRelay DBMgr::RegisterDevice( const DevID* host ) { - return RegisterDevice( host, 0, "" ); + return RegisterDevice( host, 0, NULL, NULL ); } bool DBMgr::UpdateDevice( DevIDRelay relayID, int clientVersion, - const char* const desc, bool check ) + const char* const desc, const char* const model, + bool check ) { bool exists = !check; if ( !exists ) { @@ -417,6 +418,9 @@ DBMgr::UpdateDevice( DevIDRelay relayID, int clientVersion, string_printf( query, ", clntVers=%d, versDesc='%s'", clientVersion, desc ); } + if ( NULL != model && '\0' != model[0] ) { + string_printf( query, ", model='%s'", model ); + } string_printf( query, " WHERE id = %d", relayID ); execSql( query ); } @@ -426,7 +430,7 @@ DBMgr::UpdateDevice( DevIDRelay relayID, int clientVersion, bool DBMgr::UpdateDevice( DevIDRelay relayID ) { - return UpdateDevice( relayID, 0, NULL, false ); + return UpdateDevice( relayID, 0, NULL, NULL, false ); } HostID diff --git a/xwords4/relay/dbmgr.h b/xwords4/relay/dbmgr.h index 33a31db09..7dfcaf001 100644 --- a/xwords4/relay/dbmgr.h +++ b/xwords4/relay/dbmgr.h @@ -82,9 +82,10 @@ class DBMgr { DevIDRelay RegisterDevice( const DevID* host ); DevIDRelay RegisterDevice( const DevID* host, int clientVersion, - const char* const desc ); + const char* const desc, const char* const model ); bool UpdateDevice( DevIDRelay relayID, int clientVersion, - const char* const desc, bool check ); + const char* const desc, const char* const model, + bool check ); HostID AddDevice( const char* const connName, HostID curID, int clientVersion, int nToAdd, unsigned short seed, const AddrInfo* addr, diff --git a/xwords4/relay/xwrelay.cpp b/xwords4/relay/xwrelay.cpp index 6a4fcfa96..8f2097f9a 100644 --- a/xwords4/relay/xwrelay.cpp +++ b/xwords4/relay/xwrelay.cpp @@ -294,23 +294,6 @@ getNetString( const unsigned char** bufpp, const unsigned char* end, string& out return success; } -static bool -getShortInitString( const unsigned char** bufpp, const unsigned char* end, - string& out ) -{ - bool success; - uint16_t len; - success = getNetShort( bufpp, end, &len ); - if ( success ) { - success = *bufpp + len <= end; - if ( success ) { - out.append( (const char*)*bufpp, len ); - *bufpp += len; - } - } - return success; -} - static bool vli2un( const unsigned char** bufpp, const unsigned char* end, uint32_t* out ) { @@ -338,11 +321,26 @@ vli2un( const unsigned char** bufpp, const unsigned char* end, uint32_t* out ) return success; } +static bool +getVLIString( const unsigned char** bufpp, const unsigned char* end, + string& out ) +{ + bool success = false; + uint32_t len; + if ( vli2un( bufpp, end, &len ) && *bufpp + len <= end ) { + out.append( (const char*)*bufpp, len ); + *bufpp += len; + success = true; + logf( XW_LOGINFO, "%s=>%s", __func__, out.c_str() ); + } + return success; +} + static bool getRelayDevID( const unsigned char** bufpp, const unsigned char* end, DevID& devID ) { - return getShortInitString( bufpp, end, devID.m_devIDString ); + return getVLIString( bufpp, end, devID.m_devIDString ); } static bool @@ -719,11 +717,12 @@ post_message( DevIDRelay devid, const char* message, OnMsgAckProc proc, vector packet; uint32_t packetID; XWRelayReg cmd = XWPDEV_ALERT; - short len = strlen( message ); - short netLen = htons( len ); - assemble_packet( packet, &packetID, cmd, &netLen, sizeof(netLen), - message, strlen(message), - NULL ); + + uint32_t len = strlen( message ); + uint8_t lenbuf[5]; + size_t lenlen = un2vli( len, lenbuf ); + assemble_packet( packet, &packetID, cmd, lenbuf, lenlen, + message, len, NULL ); const AddrInfo::AddrUnion* addru = DevMgr::Get()->get( devid ); bool canSendNow = !!addru; @@ -1427,33 +1426,36 @@ proxy_thread_proc( UdpThreadClosure* utc ) XWThreadPool::GetTPool()->CloseSocket( addr ); } // proxy_thread_proc +static size_t +addVLIStr( uint8_t* ptr, const char* str ) +{ + uint32_t len = strlen( str ); + size_t indx = un2vli( len, ptr ); + memcpy( &ptr[indx], str, len ); + return indx + len; +} + static short addRegID( unsigned char* ptr, DevIDRelay relayID ) { - short used = 0; char idbuf[9]; - int idLen = snprintf( idbuf, sizeof(idbuf), "%.8X", relayID ); - short lenNBO = htons(idLen); - memcpy( &ptr[used], &lenNBO, sizeof(lenNBO) ); - used += sizeof(lenNBO); - memcpy( &ptr[used], idbuf, idLen ); - used += idLen; - return used; + (void)snprintf( idbuf, sizeof(idbuf), "%.8X", relayID ); + return addVLIStr( ptr, idbuf ); } static void registerDevice( const DevID* devID, const AddrInfo* addr, int clientVers, - string devDesc ) + string& devDesc, string& model ) { DevIDRelay relayID; DBMgr* dbMgr = DBMgr::Get(); short indx = 0; - unsigned char buf[32]; + uint8_t buf[32]; if ( ID_TYPE_RELAY == devID->m_devIDType ) { // known to us; just update the time relayID = devID->asRelayID(); if ( dbMgr->UpdateDevice( relayID, clientVers, devDesc.c_str(), - true ) ) { + model.c_str(), true ) ) { int nMsgs = dbMgr->CountStoredMessages( relayID ); if ( 0 < nMsgs ) { send_havemsgs( addr ); @@ -1465,7 +1467,8 @@ registerDevice( const DevID* devID, const AddrInfo* addr, int clientVers, relayID = DBMgr::DEVID_NONE; } } else { - relayID = dbMgr->RegisterDevice( devID, clientVers, devDesc.c_str() ); + relayID = dbMgr->RegisterDevice( devID, clientVers, devDesc.c_str(), + model.c_str() ); } if ( DBMgr::DEVID_NONE != relayID ) { @@ -1573,9 +1576,12 @@ handle_udp_packet( UdpThreadClosure* utc ) if ( getRelayDevID( &ptr, end, devID ) ) { uint16_t clientVers; string devDesc; + string model; if ( getNetShort( &ptr, end, &clientVers ) - && getShortInitString( &ptr, end, devDesc ) ) { - registerDevice( &devID, utc->addr(), clientVers, devDesc ); + && getVLIString( &ptr, end, devDesc ) + && getVLIString( &ptr, end, model ) ) { + registerDevice( &devID, utc->addr(), clientVers, + devDesc, model ); } } break; @@ -1620,23 +1626,14 @@ handle_udp_packet( UdpThreadClosure* utc ) } case XWPDEV_KEEPALIVE: case XWPDEV_RQSTMSGS: { - unsigned short idLen; - if ( !getNetShort( &ptr, end, &idLen ) ) { - break; - } - if ( end - ptr > idLen ) { - logf( XW_LOGERROR, "full devID not received" ); - break; - } DevID devID( ID_TYPE_RELAY ); - devID.m_devIDString.append( (const char*)ptr, idLen ); - ptr += idLen; + if ( getVLIString( &ptr, end, devID.m_devIDString ) ) { + const AddrInfo* addr = utc->addr(); + DevMgr::Get()->rememberDevice( devID.asRelayID(), addr ); - const AddrInfo* addr = utc->addr(); - DevMgr::Get()->rememberDevice( devID.asRelayID(), addr ); - - if ( XWPDEV_RQSTMSGS == header.cmd ) { - retrieveMessages( devID, addr ); + if ( XWPDEV_RQSTMSGS == header.cmd ) { + retrieveMessages( devID, addr ); + } } break; } @@ -1793,11 +1790,8 @@ maint_str_loop( int udpsock, const char* str ) { logf( XW_LOGINFO, "%s()", __func__ ); assert( -1 != udpsock ); - short len = strlen(str); - unsigned char outbuf[sizeof(len) + len]; - short lenNS = htons( len ); - memcpy( &outbuf[0], &lenNS, sizeof(lenNS) ); - memcpy( &outbuf[0+sizeof(len)], str, len ); + uint8_t outbuf[1024]; + size_t indx = addVLIStr( &outbuf[0], str ); fd_set rfds; for ( ; ; ) { @@ -1825,7 +1819,7 @@ maint_str_loop( int udpsock, const char* str ) if ( getHeader( &ptr, ptr + nRead, &header ) ) { send_via_udp( udpsock, &saddr.u.addr, NULL, XWPDEV_UNAVAIL, &unavail, sizeof(unavail), - outbuf, sizeof(outbuf), + outbuf, indx, NULL ); } else { logf( XW_LOGERROR, "unexpected data" ); diff --git a/xwords4/relay/xwrelay.sh b/xwords4/relay/xwrelay.sh index 169a59a5c..a3652548a 100755 --- a/xwords4/relay/xwrelay.sh +++ b/xwords4/relay/xwrelay.sh @@ -85,6 +85,7 @@ id INTEGER UNIQUE PRIMARY KEY ,clntVers INTEGER ,versDesc TEXT ,devid TEXT +,model TEXT ,ctime TIMESTAMP DEFAULT CURRENT_TIMESTAMP ,mtime TIMESTAMP ,unreg BOOLEAN DEFAULT FALSE