generate new mqtt devid when server reports dupe

Thanks to my use of unseeded() rand() early on to generate mqtt device
IDs, a handful of devices are using the same devIDs. The server notices
this and passes a new response which triggers generating a new id that
should be unique (rand() being seeded earlier now.) Testing says the
games that are left behind with the old devid will limp along thanks to
their relay connection while newer games will be better.
This commit is contained in:
Eric House 2020-09-13 14:48:36 -07:00
parent 4e7055d629
commit e4594f36e0
6 changed files with 78 additions and 9 deletions

View file

@ -313,6 +313,7 @@ public class MQTTUtils extends Thread implements IMqttActionListener, MqttCallba
params.put( "dbg", BuildConfig.DEBUG );
params.put( "myNow", now );
params.put( "loc", LocUtils.getCurLocale( mContext ) );
params.put( "knowsDup", true );
String fcmid = FBMService.getFCMDevID( mContext );
if ( null != fcmid ) {
@ -335,6 +336,16 @@ public class MQTTUtils extends Thread implements IMqttActionListener, MqttCallba
DBUtils.setStringFor( mContext, KEY_LAST_WRITE, BuildConfig.GIT_REV );
sLastRev = BuildConfig.GIT_REV;
}
String dupID = response.optString( "dupID", "" );
if ( dupID.equals( mDevID ) ) {
Log.e( TAG, "********** %s bad; need new devID!!! **********", dupID );
XwJNI.dvc_resetMQTTDevID();
// Force a reconnect asap
DBUtils.setLongFor( mContext, KEY_NEXT_REG, 0 );
sNextReg = 0;
clearInstance();
}
}
} else {
Log.e( TAG, "registerOnce(): null back from runConn()" );

View file

@ -138,6 +138,11 @@ public class XwJNI {
return dvc_getMQTTDevID( getJNI().m_ptrGlobals, topic );
}
public static void dvc_resetMQTTDevID()
{
dvc_resetMQTTDevID( getJNI().m_ptrGlobals );
}
public static byte[] dvc_makeMQTTInvite( NetLaunchInfo nli, String[] addrToTopic )
{
return dvc_makeMQTTInvite( getJNI().m_ptrGlobals, nli, addrToTopic );
@ -664,6 +669,7 @@ public class XwJNI {
// Private methods -- called only here
private static native long globalsInit( DUtilCtxt dutil, JNIUtils jniu, long seed );
private static native String dvc_getMQTTDevID( long jniState, String[] topic );
private static native void dvc_resetMQTTDevID( long jniState );
private static native byte[] dvc_makeMQTTInvite( long jniState, NetLaunchInfo nli,
String[] addrToTopic );
private static native byte[] dvc_makeMQTTMessage( long jniState, int gameID, byte[] buf,

View file

@ -648,6 +648,15 @@ Java_org_eehouse_android_xw4_jni_XwJNI_dvc_1getMQTTDevID
return result;
}
JNIEXPORT void JNICALL
Java_org_eehouse_android_xw4_jni_XwJNI_dvc_1resetMQTTDevID
( JNIEnv* env, jclass C, jlong jniGlobalPtr )
{
DVC_HEADER(jniGlobalPtr);
dvc_resetMQTTDevID( globalState->dutil, env );
DVC_HEADER_END();
}
static void
addrToTopic( JNIEnv* env, jobjectArray jAddrToTopic )
{

View file

@ -80,30 +80,73 @@ dvc_store( XW_DUtilCtxt* dutil, XWEnv xwe )
#endif
void
dvc_getMQTTDevID( XW_DUtilCtxt* dutil, XWEnv xwe, MQTTDevID* devID )
// #define BOGUS_ALL_SAME_DEVID
static void
getMQTTDevID( XW_DUtilCtxt* dutil, XWEnv xwe, XP_Bool forceNew, MQTTDevID* devID )
{
#ifdef BOGUS_ALL_SAME_DEVID
XP_USE(forceNew);
MQTTDevID bogusID = 0;
XP_UCHAR* str = "ABCDEF0123456789";
XP_Bool ok = strToMQTTCDevID( str, &bogusID );
XP_ASSERT( ok );
MQTTDevID tmp = 0;
XP_U16 len = sizeof(tmp);
dutil_loadPtr( dutil, xwe, MQTT_DEVID_KEY, SUFFIX_MQTT_DEVID, &tmp, &len );
if ( len != sizeof(tmp) || 0 != XP_MEMCMP( &bogusID, &tmp, sizeof(tmp) ) ) {
dutil_storePtr( dutil, xwe, MQTT_DEVID_KEY, &bogusID, sizeof(bogusID) );
}
*devID = bogusID;
// XP_LOGFF( "len: %d; sizeof(tmp): %d", len, sizeof(tmp) );
if ( len != sizeof(tmp) ) { /* not found, or bogus somehow */
#else
MQTTDevID tmp = 0;
XP_U16 len = sizeof(tmp);
if ( !forceNew ) {
dutil_loadPtr( dutil, xwe, MQTT_DEVID_KEY, SUFFIX_MQTT_DEVID, &tmp, &len );
}
XP_LOGFF( "len: %d; sizeof(tmp): %zu", len, sizeof(tmp) );
if ( forceNew || len != sizeof(tmp) ) { /* not found, or bogus somehow */
tmp = XP_RANDOM();
tmp <<= 27;
tmp ^= XP_RANDOM();
tmp <<= 27;
tmp ^= XP_RANDOM();
dutil_storePtr( dutil, xwe, MQTT_DEVID_KEY, &tmp, sizeof(tmp) );
#ifdef DEBUG
# ifdef DEBUG
XP_UCHAR buf[32];
formatMQTTDevID( &tmp, buf, VSIZE(buf) );
/* This log statement is required by discon_ok2.py!!! (keep in sync) */
XP_LOGFF( "generated id: %s; key: %s", buf, MQTT_DEVID_KEY );
#endif
# endif
}
*devID = tmp;
// LOG_RETURNF( MQTTDevID_FMT " key: %s", *devID, MQTT_DEVID_KEY );
#endif
LOG_RETURNF( MQTTDevID_FMT " key: %s", *devID, MQTT_DEVID_KEY );
}
void
dvc_getMQTTDevID( XW_DUtilCtxt* dutil, XWEnv xwe, MQTTDevID* devID )
{
getMQTTDevID( dutil, xwe, XP_FALSE, devID );
}
void
dvc_resetMQTTDevID( XW_DUtilCtxt* dutil, XWEnv xwe )
{
LOG_FUNC();
#ifdef BOGUS_ALL_SAME_DEVID
XP_LOGFF( "doing nothing" );
XP_USE( dutil );
XP_USE( xwe );
#else
MQTTDevID ignored;
getMQTTDevID( dutil, xwe, XP_TRUE, &ignored );
#endif
}
typedef enum { CMD_INVITE, CMD_MSG, CMD_DEVGONE, } MQTTCmd;

View file

@ -31,7 +31,7 @@ void dvc_store( XW_DUtilCtxt* dctxt, XWEnv xwe );
# endif
void dvc_getMQTTDevID( XW_DUtilCtxt* dutil, XWEnv xwe, MQTTDevID* devID );
void dvc_resetMQTTDevID( XW_DUtilCtxt* dutil, XWEnv xwe );
void dvc_makeMQTTInvite( XW_DUtilCtxt* dutil, XWEnv xwe, XWStreamCtxt* stream,
const NetLaunchInfo* nli );
void dvc_makeMQTTMessage( XW_DUtilCtxt* dutil, XWEnv xwe, XWStreamCtxt* stream,

View file

@ -165,7 +165,7 @@ class Device():
sTilesLeftTrayPat = re.compile('.*player \d+ now has (\d+) tiles')
sRelayIDPat = re.compile('.*UPDATE games.*seed=(\d+),.*relayid=\'([^\']+)\'.*')
sDevIDPat = re.compile('.*storing new devid: ([\da-fA-F]+).*')
sMQTTDevIDPat = re.compile('.*dvc_getMQTTDevID.*: generated id: ([\d[A-F]+).*')
sMQTTDevIDPat = re.compile('.*getMQTTDevID.*: generated id: ([\d[A-F]+).*')
sConnPat = re.compile('.*linux_util_informMissing\(isServer.*nMissing=0\).*')
sScoresDup = []