Skip to content

Commit 46a0a02

Browse files
committed
Test to fix some connect timeouts #3
1 parent 9179aef commit 46a0a02

File tree

12 files changed

+139
-20
lines changed

12 files changed

+139
-20
lines changed

MTA10/core/CConnectManager.cpp

Lines changed: 34 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,7 @@ bool CConnectManager::Connect ( const char* szHost, unsigned short usPort, const
130130

131131
m_bIsConnecting = true;
132132
m_tConnectStarted = time ( NULL );
133-
m_bHasSentTcpRequest = false;
133+
m_bHasTriedSecondConnect = false;
134134

135135
// Load server password
136136
if ( m_strPassword.empty () )
@@ -141,6 +141,7 @@ bool CConnectManager::Connect ( const char* szHost, unsigned short usPort, const
141141
m_pServerItem = new CServerListItem ( m_Address, m_usPort );
142142
m_pServerItem->m_iTimeoutLength = 2000;
143143
m_bIsDetectingVersion = true;
144+
OpenServerFirewall( m_Address );
144145

145146
// Display the status box
146147
SString strBuffer ( _("Connecting to %s:%u ..."), m_strHost.c_str(), m_usPort );
@@ -248,19 +249,18 @@ void CConnectManager::DoPulse ( void )
248249
}
249250
}
250251

251-
if ( !m_bHasSentTcpRequest )
252+
int iConnectTimeDelta = time ( NULL ) - m_tConnectStarted;
253+
254+
// Try connect again if no response after 4 seconds
255+
if ( iConnectTimeDelta >= 4 && !m_bHasTriedSecondConnect && g_pCore->GetNetwork()->GetExtendedErrorCode() == 0 )
252256
{
253-
if ( time ( NULL ) >= m_tConnectStarted + 2 )
254-
{
255-
// Handle possible IP rejection by proving we exist with a TCP connection
256-
g_pCore->GetNetwork()->GetHTTPDownloadManager( EDownloadMode::CORE_UPDATER )->QueueFile( m_strHost.c_str(), NULL, 0, "", 0, true, NULL, NULL, false, 1, 2000 );
257-
m_bHasSentTcpRequest = true;
258-
AddReportLog( 9401, SString( "ConnectManager sent TCP connection request to %s", m_strHost.c_str() ) );
259-
}
257+
m_bHasTriedSecondConnect = true;
258+
SString strAddress = inet_ntoa ( m_Address );
259+
g_pCore->GetNetwork()->StartNetwork ( strAddress, m_usPort, CVARS_GET_VALUE < bool > ( "packet_tag" ) );
260260
}
261261

262262
// Time to timeout the connection?
263-
if ( time ( NULL ) >= m_tConnectStarted + 8 )
263+
if ( iConnectTimeDelta >= 8 )
264264
{
265265
// Show a message that the connection timed out and abort
266266
g_pCore->ShowNetErrorMessageBox ( _("Error")+_E("CC23"), _("Connection timed out"), "connect-timed-out", true );
@@ -455,3 +455,27 @@ void CConnectManager::OnServerExists ( void )
455455
CServerBrowser::GetSingletonPtr()->NotifyServerExists ( m_Address, m_usPort );
456456
}
457457
}
458+
459+
//
460+
// Some server firewalls block UDP packets unless a TCP connection has previously been established
461+
//
462+
void CConnectManager::OpenServerFirewall( in_addr Address, ushort usHttpPort, bool bHighPriority )
463+
{
464+
if ( usHttpPort == 0 )
465+
usHttpPort = 80;
466+
467+
uint uiTimeOut;
468+
if ( bHighPriority )
469+
{
470+
// Clear previously queued requests if this is high priority
471+
g_pCore->GetNetwork()->GetHTTPDownloadManager( EDownloadMode::CONNECT_TCP_SEND )->Reset();
472+
uiTimeOut = 2000;
473+
}
474+
else
475+
{
476+
uiTimeOut = 1000;
477+
}
478+
479+
SString strDummyUrl( "http://%s:%d/.dummy/", inet_ntoa( Address ), usHttpPort );
480+
g_pCore->GetNetwork()->GetHTTPDownloadManager( EDownloadMode::CONNECT_TCP_SEND )->QueueFile( strDummyUrl, NULL, 0, "", 0, true, NULL, NULL, false, 1, uiTimeOut );
481+
}

MTA10/core/CConnectManager.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ class CConnectManager
3434
void OnServerExists ( void );
3535

3636
bool ShouldUseInternalHTTPServer ( void ) { return m_bForceInternalHTTPServer; }
37+
static void OpenServerFirewall ( in_addr Address, ushort usHttpPort = 80, bool bHighPriority = false );
3738

3839
static bool StaticProcessPacket ( unsigned char ucPacketID, class NetBitStreamInterface& bitStream );
3940

@@ -54,7 +55,7 @@ class CConnectManager
5455
bool m_bSave;
5556
bool m_bForceInternalHTTPServer;
5657
time_t m_tConnectStarted;
57-
bool m_bHasSentTcpRequest;
58+
bool m_bHasTriedSecondConnect;
5859

5960
GUI_CALLBACK* m_pOnCancelClick;
6061

MTA10/core/CServerBrowser.RemoteMasterServer.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -388,6 +388,8 @@ bool CRemoteMasterServer::ParseListVer2 ( CServerListItemList& itemList )
388388
bool bHasRestrictionFlags = ( uiFlags & ASE_FLAG_RESTRICTIONS ) != 0;
389389
bool bHasSearchIgnoreSections = ( uiFlags & ASE_FLAG_SEARCH_IGNORE_SECTIONS ) != 0;
390390
bool bHasKeepFlag = ( uiFlags & ASE_FLAG_KEEP ) != 0;
391+
bool bHasHttpPort = ( uiFlags & ASE_FLAG_HTTP_PORT ) != 0;
392+
bool bHasSpecialFlags = ( uiFlags & ASE_FLAG_SPECIAL_FLAGS ) != 0;
391393

392394
// Rate quality of data supplied here
393395
uint uiDataQuality = SERVER_INFO_ASE_2;
@@ -496,6 +498,16 @@ bool CRemoteMasterServer::ParseListVer2 ( CServerListItemList& itemList )
496498
pItem->bKeepFlag = ucKeepFlag ? true : false;
497499
}
498500

501+
if ( bHasHttpPort )
502+
{
503+
stream.Read ( pItem->m_usHttpPort );
504+
}
505+
506+
if ( bHasSpecialFlags )
507+
{
508+
stream.Read ( pItem->m_ucSpecialFlags );
509+
}
510+
499511
pItem->PostChange ();
500512

501513
#if MTA_DEBUG

MTA10/core/CServerCache.cpp

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@ namespace
3737
CValueInt bPassworded; // Password protected
3838
CValueInt bKeepFlag;
3939
CValueInt uiCacheNoReplyCount;
40+
CValueInt usHttpPort;
41+
CValueInt ucSpecialFlags;
4042
SString strName; // Server name
4143
SString strGameMode; // Game mode
4244
SString strMap; // Map name
@@ -168,6 +170,8 @@ bool CServerCache::LoadServerCache ( void )
168170
if ( const SString* pString = MapFind ( item.attributeMap, "bPassworded" ) ) info.bPassworded.SetFromString ( *pString );
169171
if ( const SString* pString = MapFind ( item.attributeMap, "bKeepFlag" ) ) info.bKeepFlag.SetFromString ( *pString );
170172
if ( const SString* pString = MapFind ( item.attributeMap, "uiNoReplyCount" ) ) info.uiCacheNoReplyCount.SetFromString ( *pString );
173+
if ( const SString* pString = MapFind ( item.attributeMap, "httpPort" ) ) info.usHttpPort.SetFromString ( *pString );
174+
if ( const SString* pString = MapFind ( item.attributeMap, "flags" ) ) info.ucSpecialFlags.SetFromString ( *pString );
171175
if ( const SString* pString = MapFind ( item.attributeMap, "strName" ) ) info.strName = *pString;
172176
if ( const SString* pString = MapFind ( item.attributeMap, "strGameMode" ) ) info.strGameMode = *pString;
173177
if ( const SString* pString = MapFind ( item.attributeMap, "strMap" ) ) info.strMap = *pString;
@@ -281,6 +285,8 @@ void CServerCache::StaticSaveServerCache ( void )
281285
MapSet ( item.attributeMap, "bPassworded", info.bPassworded.ToString () );
282286
MapSet ( item.attributeMap, "bKeepFlag", info.bKeepFlag.ToString () );
283287
MapSet ( item.attributeMap, "uiNoReplyCount", info.uiCacheNoReplyCount.ToString () );
288+
MapSet ( item.attributeMap, "httpPort", info.usHttpPort.ToString () );
289+
MapSet ( item.attributeMap, "flags", info.ucSpecialFlags.ToString () );
284290
MapSet ( item.attributeMap, "strName", info.strName );
285291
MapSet ( item.attributeMap, "strGameMode", info.strGameMode );
286292
MapSet ( item.attributeMap, "strMap", info.strMap );
@@ -324,7 +330,8 @@ void CServerCache::GetServerCachedInfo ( CServerListItem* pItem )
324330
pItem->strMap = pInfo->strMap;
325331
pItem->strVersion = pInfo->strVersion;
326332
pItem->uiCacheNoReplyCount = pInfo->uiCacheNoReplyCount;
327-
333+
pItem->m_usHttpPort = pInfo->usHttpPort;
334+
pItem->m_ucSpecialFlags = pInfo->ucSpecialFlags;
328335
pItem->PostChange ();
329336
}
330337
else
@@ -335,6 +342,8 @@ void CServerCache::GetServerCachedInfo ( CServerListItem* pItem )
335342
if ( pItem->strMap.empty () ) pItem->strMap = pInfo->strMap;
336343
if ( pItem->strVersion.empty () ) pItem->strVersion = pInfo->strVersion;
337344
if ( pItem->nPing == 9999 ) pItem->nPing = pInfo->nPing;
345+
if ( pItem->m_usHttpPort == 0 ) pItem->m_usHttpPort = pInfo->usHttpPort;
346+
if ( pItem->m_ucSpecialFlags == 0 ) pItem->m_ucSpecialFlags = pInfo->ucSpecialFlags;
338347
}
339348
}
340349
}
@@ -370,7 +379,9 @@ void CServerCache::SetServerCachedInfo ( const CServerListItem* pItem )
370379
&& pInfo->strGameMode == pItem->strGameMode
371380
//&& pInfo->strMap == pItem->strMap
372381
&& pInfo->strVersion == pItem->strVersion
373-
&& pInfo->uiCacheNoReplyCount == pItem->uiCacheNoReplyCount )
382+
&& pInfo->uiCacheNoReplyCount == pItem->uiCacheNoReplyCount
383+
&& pInfo->usHttpPort == pItem->m_usHttpPort
384+
&& pInfo->ucSpecialFlags == pItem->m_ucSpecialFlags )
374385
{
375386
return;
376387
}
@@ -386,6 +397,8 @@ void CServerCache::SetServerCachedInfo ( const CServerListItem* pItem )
386397
pInfo->strMap = pItem->strMap;
387398
pInfo->strVersion = pItem->strVersion;
388399
pInfo->uiCacheNoReplyCount = pItem->uiCacheNoReplyCount;
400+
pInfo->usHttpPort = pItem->m_usHttpPort;
401+
pInfo->ucSpecialFlags = pItem->m_ucSpecialFlags;
389402
}
390403

391404

MTA10/core/CServerList.cpp

Lines changed: 40 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -390,7 +390,34 @@ std::string CServerListItem::Pulse ( bool bCanSendQuery, bool bRemoveNonRespondi
390390
}
391391
}
392392

393-
if ( m_ElapsedTime.Get () > SERVER_LIST_ITEM_TIMEOUT )
393+
/////////////////////////////////////////////////////////////////////////////////////////
394+
// TCP send to servers that the master server can see, but this client can't
395+
uint uiQueryAge = (uint)m_ElapsedTime.Get();
396+
if ( uiQueryAge > 2000 )
397+
{
398+
if ( !m_bDoneTcpSend && GetMaxRetries() > 0 )
399+
{
400+
m_bDoneTcpSend = true;
401+
if ( ( m_ucSpecialFlags & ASE_SPECIAL_FLAG_DENY_TCP_SEND ) == 0 )
402+
{
403+
CConnectManager::OpenServerFirewall( Address, m_usHttpPort, false );
404+
m_bDoPostTcpQuery = 1;
405+
}
406+
}
407+
}
408+
if ( uiQueryAge > 4000 )
409+
{
410+
if ( m_bDoPostTcpQuery )
411+
{
412+
// Do another query if we just tried to open this server's firewall
413+
m_bDoPostTcpQuery = false;
414+
Query ();
415+
return "ResentQuery";
416+
}
417+
}
418+
/////////////////////////////////////////////////////////////////////////////////////////
419+
420+
if ( uiQueryAge > SERVER_LIST_ITEM_TIMEOUT )
394421
{
395422
if ( bKeepFlag )
396423
bRemoveNonResponding = false;
@@ -401,9 +428,8 @@ std::string CServerListItem::Pulse ( bool bCanSendQuery, bool bRemoveNonRespondi
401428
nPlayers = 0; // We don't have player names, so zero this now
402429
}
403430
uiRevision++; // To flag browser gui update
404-
uint uiMaxRetries = GetDataQuality () <= SERVER_INFO_ASE_0 || MaybeWontRespond () ? 0 : 1;
405431

406-
if ( uiQueryRetryCount < uiMaxRetries )
432+
if ( uiQueryRetryCount < GetMaxRetries() )
407433
{
408434
// Try again
409435
uiQueryRetryCount++;
@@ -600,6 +626,13 @@ bool CServerListItem::ParseQuery ( const char * szBuffer, unsigned int nLength )
600626
const SString strPingStatus = strBuildNumber.Right ( strBuildNumber.length () - strlen ( strBuildNumber ) - 1 );
601627
CCore::GetSingleton ().GetNetwork ()->UpdatePingStatus ( *strPingStatus, nPlayers );
602628

629+
// Recover server http port if present
630+
const SString strNetRoute = strPingStatus.Right ( strPingStatus.length () - strlen ( strPingStatus ) - 1 );
631+
const SString strUpTime = strNetRoute.Right ( strNetRoute.length () - strlen ( strNetRoute ) - 1 );
632+
const SString strHttpPort = strUpTime.Right ( strUpTime.length () - strlen ( strUpTime ) - 1 );
633+
if ( !strHttpPort.empty () )
634+
m_usHttpPort = atoi ( strHttpPort );
635+
603636
// Get player nicks
604637
vecPlayers.clear ();
605638
while ( i < nLength )
@@ -770,6 +803,10 @@ CServerListItem::CServerListItem ( in_addr _Address, unsigned short _usGamePort,
770803
Address = _Address;
771804
usGamePort = _usGamePort;
772805
m_pItemList = pItemList;
806+
m_bDoneTcpSend = false;
807+
m_bDoPostTcpQuery = false;
808+
m_usHttpPort = 0;
809+
m_ucSpecialFlags = 0;
773810
Init ();
774811
if ( m_pItemList )
775812
{

MTA10/core/CServerList.h

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,15 @@ enum
6363
ASE_FLAG_RESTRICTIONS = 0x2000,
6464
ASE_FLAG_SEARCH_IGNORE_SECTIONS = 0x4000,
6565
ASE_FLAG_KEEP = 0x8000,
66+
ASE_FLAG_HTTP_PORT = 0x080000,
67+
ASE_FLAG_SPECIAL_FLAGS = 0x100000,
68+
};
69+
70+
enum
71+
{
72+
ASE_SPECIAL_FLAG_VALID = 0x01,
73+
ASE_SPECIAL_FLAG_DENY_TCP_SEND = 0x02,
74+
ASE_SPECIAL_FLAG_FORCE_KEEP = 0x04,
6675
};
6776

6877
enum
@@ -86,6 +95,10 @@ class CServerListItem
8695
Address.S_un.S_addr = 0;
8796
usGamePort = 0;
8897
m_pItemList = NULL;
98+
m_bDoneTcpSend = false;
99+
m_bDoPostTcpQuery = false;
100+
m_usHttpPort = 0;
101+
m_ucSpecialFlags = 0;
89102
Init ();
90103
}
91104
CServerListItem ( in_addr _Address, unsigned short _usGamePort, CServerListItemList* pItemList = NULL, bool bAtFront = false );
@@ -204,6 +217,8 @@ class CServerListItem
204217

205218
int m_iBuildType; // 9=release
206219
int m_iBuildNumber; // 00000 and up
220+
ushort m_usHttpPort;
221+
uchar m_ucSpecialFlags;
207222

208223
SString strNameSortKey; // Server name as a sortable string
209224
SString strVersionSortKey; // Game version as a sortable string
@@ -300,11 +315,18 @@ class CServerListItem
300315
return m_iDataQuality;
301316
}
302317

318+
uint GetMaxRetries ( void ) const
319+
{
320+
return GetDataQuality () <= SERVER_INFO_ASE_0 || MaybeWontRespond () ? 0 : 1;
321+
}
322+
303323
static bool StaticIsValid ( CServerListItem* pServer )
304324
{
305325
return MapContains ( ms_ValidServerListItemMap, pServer );
306326
}
307327

328+
bool m_bDoneTcpSend;
329+
bool m_bDoPostTcpQuery;
308330
int m_iTimeoutLength;
309331
CServerListItemList* m_pItemList;
310332
protected:

MTA10/core/CVersionUpdater.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2234,7 +2234,7 @@ void CVersionUpdater::_ProcessPatchFileQuery ( void )
22342234
if ( strNotifyMasterRevision.length () && strNotifyMasterRevision > m_MasterConfig.master.strRevision )
22352235
{
22362236
// Only do next bit when 'notify revision' increases (prevents superfluous downloads when notify revision is (incorrectly) higher than actual revision)
2237-
if ( m_VarConfig.master_highestNotifyRevision.empty () || strNotifyMasterRevision < m_VarConfig.master_highestNotifyRevision )
2237+
if ( m_VarConfig.master_highestNotifyRevision.empty () || strNotifyMasterRevision > m_VarConfig.master_highestNotifyRevision )
22382238
{
22392239
m_VarConfig.master_highestNotifyRevision = strNotifyMasterRevision;
22402240

MTA10/sdk/net/CNet.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ namespace EDownloadMode
2828
RESOURCE_SINGULAR_FILES,
2929
CALL_REMOTE,
3030
WEBBROWSER_LISTS,
31+
CONNECT_TCP_SEND,
3132
};
3233
}
3334
using EDownloadMode::EDownloadModeType;

MTA10/sdk/net/CNetHTTPDownloadManagerInterface.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@ class CNetHTTPDownloadManagerInterface
3434

3535
// Limit number of concurrent http client connections
3636
virtual void SetMaxConnections ( int iMaxConnections ) = 0;
37+
38+
virtual void Reset ( void ) = 0;
3739
};
3840

3941
#endif

MTA10/version.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@
7575

7676
#define _ASE_VERSION QUOTE_DEFINE(MTASA_VERSION_MAJOR) "." QUOTE_DEFINE(MTASA_VERSION_MINOR)
7777
#define _NETCODE_VERSION_BRANCH_ID 0x4 // Use 0x1 - 0xF to indicate an incompatible branch is being used (0x0 is reserved, 0x4 is trunk)
78-
#define _CLIENT_NET_MODULE_VERSION 0x092 // (0x000 - 0xfff) Lvl9 wizards only
78+
#define _CLIENT_NET_MODULE_VERSION 0x093 // (0x000 - 0xfff) Lvl9 wizards only
7979
#define _NETCODE_VERSION 0x1DA // (0x000 - 0xfff) Increment when net messages change (pre-release)
8080
#define MTA_DM_BITSTREAM_VERSION 0x063 // (0x000 - 0xfff) Increment when net messages change (post-release). (Changing will also require additional backward compatibility code).
8181

MTA10_Server/mods/deathmatch/logic/ASE.cpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -424,6 +424,11 @@ std::string ASE::QueryLight ( void )
424424
SString strPingStatus = (const char*)strPingStatusFixed;
425425
SString strNetRoute = (const char*)strNetRouteFixed;
426426
SString strUpTime( "%d", (uint)( time( NULL ) - m_tStartTime ) );
427+
SString strHttpPort( "%d", m_pMainConfig->GetHTTPPort() );
428+
429+
uint uiExtraDataLength = ( strPlayerCount.length () + 1 + strBuildType.length () + 1 + strBuildNumber.length () + 1 + strPingStatus.length () + 1 + strNetRoute.length () + 1 + strUpTime.length() + 1 + strHttpPort.length() + 1 );
430+
uint uiMaxMapNameLength = 250 - uiExtraDataLength;
431+
m_strMapName = m_strMapName.Left( uiMaxMapNameLength );
427432

428433
reply << "EYE2";
429434
// game
@@ -439,7 +444,7 @@ std::string ASE::QueryLight ( void )
439444
reply << ( unsigned char ) ( m_strGameType.length() + 1 );
440445
reply << m_strGameType;
441446
// map name with backwardly compatible large player count, build type and build number
442-
reply << ( unsigned char ) ( m_strMapName.length() + 1 + strPlayerCount.length () + 1 + strBuildType.length () + 1 + strBuildNumber.length () + 1 + strPingStatus.length () + 1 + strNetRoute.length () + 1 + strUpTime.length() + 1 );
447+
reply << ( unsigned char ) ( m_strMapName.length() + 1 + uiExtraDataLength );
443448
reply << m_strMapName;
444449
reply << ( unsigned char ) 0;
445450
reply << strPlayerCount;
@@ -453,6 +458,8 @@ std::string ASE::QueryLight ( void )
453458
reply << strNetRoute;
454459
reply << ( unsigned char ) 0;
455460
reply << strUpTime;
461+
reply << ( unsigned char ) 0;
462+
reply << strHttpPort;
456463
// version
457464
std::string temp = MTA_DM_ASE_VERSION;
458465
reply << ( unsigned char ) ( temp.length() + 1 );

MTA10_Server/mods/deathmatch/logic/ASE.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ class ASE
9797
CPlayerManager* m_pPlayerManager;
9898

9999
std::string m_strGameType;
100-
std::string m_strMapName;
100+
SString m_strMapName;
101101
SString m_strIPList;
102102
std::string m_strPort;
103103

0 commit comments

Comments
 (0)