connect.cpp 76 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672
  1. /*
  2. ** Command & Conquer Renegade(tm)
  3. ** Copyright 2025 Electronic Arts Inc.
  4. **
  5. ** This program is free software: you can redistribute it and/or modify
  6. ** it under the terms of the GNU General Public License as published by
  7. ** the Free Software Foundation, either version 3 of the License, or
  8. ** (at your option) any later version.
  9. **
  10. ** This program is distributed in the hope that it will be useful,
  11. ** but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. ** GNU General Public License for more details.
  14. **
  15. ** You should have received a copy of the GNU General Public License
  16. ** along with this program. If not, see <http://www.gnu.org/licenses/>.
  17. */
  18. //
  19. // Filename: connect.cpp
  20. // Project: wwnet
  21. // Author: Tom Spencer-Smith
  22. // Date: June 1998
  23. // Description:
  24. //
  25. //------------------------------------------------------------------------------------
  26. #include "always.h"
  27. // Disable warning about exception handling not being enabled. It's used as part of STL - in a part of STL we don't use.
  28. #pragma warning(disable : 4530)
  29. #include "connect.h" // I WANNA BE FIRST!
  30. //#include <stdlib.h>
  31. #include "systimer.h"
  32. #include "systimer.h"
  33. #include "miscutil.h"
  34. #include "netutil.h"
  35. #include "singlepl.h"
  36. #include "mathutil.h"
  37. #include "wwdebug.h"
  38. #include "wwmath.h"
  39. #include "fromaddress.h"
  40. #include "crc.h"
  41. #include "msgstatlist.h"
  42. #include "wwprofile.h"
  43. #include "commando\nat.h"
  44. #include "commando\natter.h"
  45. #include "packetmgr.h"
  46. #include "bwbalance.h"
  47. #ifdef WWDEBUG
  48. #include "combat\crandom.h"
  49. int cConnection::LatencyAddLow = 0;
  50. int cConnection::LatencyAddHigh = 0;
  51. int cConnection::CurrentLatencyAdd = 0;
  52. unsigned long cConnection::LastLatencyChange = 0;
  53. #endif //WWDEBUG
  54. //
  55. // class statics
  56. //
  57. BOOL cConnection::IsFlowControlEnabled = true;
  58. UINT cConnection::TotalCompressedBytesSent = 0;
  59. UINT cConnection::TotalUncompressedBytesSent = 0;
  60. static const int INVALID_RHOST_ID = -1;
  61. //#ifdef WWDEBUG
  62. /***********************************************************************************************
  63. * Addr_As_String -- Get a human readable internet address *
  64. * *
  65. * *
  66. * *
  67. * INPUT: Address ptr *
  68. * *
  69. * OUTPUT: String representation *
  70. * *
  71. * WARNINGS: None *
  72. * *
  73. * HISTORY: *
  74. * 8/31/2001 3:48PM ST : Created *
  75. *=============================================================================================*/
  76. char * Addr_As_String(sockaddr_in *addr)
  77. {
  78. static char _string[128];
  79. sprintf(_string, "%d.%d.%d.%d ; %d", (int)(addr->sin_addr.S_un.S_un_b.s_b1),
  80. (int)(addr->sin_addr.S_un.S_un_b.s_b2),
  81. (int)(addr->sin_addr.S_un.S_un_b.s_b3),
  82. (int)(addr->sin_addr.S_un.S_un_b.s_b4),
  83. htonl((int)(addr->sin_port)));
  84. return(_string);
  85. }
  86. //#endif //WWDEBUG
  87. //------------------------------------------------------------------------------------
  88. cConnection::cConnection() :
  89. NumRHosts(0),
  90. RefusalPacketSendId(0),
  91. HighestRefusalPacketRcvId(-1),
  92. MinRHost(-1), // should be altered if IsServer
  93. //MaxRHost(0), // should be altered if IsServer
  94. MaxRHost(-2), // should be altered if IsServer
  95. InitDone(false),
  96. IsServer(false),
  97. IsDedicatedServer(false),
  98. SimulatedPacketLossPerRANDMAX(0),
  99. SimulatedPacketDuplicationPerRANDMAX(0),
  100. MaxAcceptablePacketlossPc(0),
  101. MinimumLatencyMs(0),
  102. MaximumLatencyMs(0),
  103. BandwidthBudgetOut(0),
  104. ServiceCount(0),
  105. ThisFrameTimeMs(TIMEGETTIME()),
  106. IsDestroy(false),
  107. PRHost(NULL),
  108. AcceptHandler(NULL),
  109. RefusalHandler(NULL),
  110. ServerBrokenConnectionHandler(NULL),
  111. ClientBrokenConnectionHandler(NULL),
  112. EvictionHandler(NULL),
  113. ConnHandler(NULL),
  114. ApplicationAcceptanceHandler(NULL),
  115. ServerPacketHandler(NULL),
  116. ClientPacketHandler(NULL),
  117. IsBadConnection(false),
  118. ExtraTimeoutTime(0),
  119. ExtraTimeoutTimeStarted(0),
  120. CanProcess(true)
  121. {
  122. WWDEBUG_SAY(("cConnection::cConnection\n"));
  123. //
  124. // All this stuff is common to C & S
  125. //
  126. if (!cSinglePlayerData::Is_Single_Player()) {
  127. cNetUtil::Create_Unbound_Socket(Sock);
  128. //
  129. // Make socket non-blocking
  130. //
  131. u_long arg = 1L;
  132. WSA_CHECK(ioctlsocket(Sock, FIONBIO, (u_long *) &arg));
  133. //
  134. // Increase the send and rcv buffer sizes a bit
  135. //
  136. cNetUtil::Set_Socket_Buffer_Sizes(Sock);
  137. }
  138. /*
  139. for (int rhost_id = 0; rhost_id < MAX_RHOSTS; rhost_id++) {
  140. PRHost[rhost_id] = NULL;
  141. }
  142. */
  143. //Init_Stats();
  144. PStatList = new cMsgStatList;
  145. WWASSERT(PStatList != NULL);
  146. PStatList->Init(PACKETTYPE_COUNT);
  147. for (int i = 0; i < PStatList->Get_Num_Stats(); i++) {
  148. //PStatList->Set_Name(i, Type_Translation(i));
  149. char message_trans[200];
  150. ::strcpy(message_trans, Type_Translation(i));
  151. PStatList->Set_Name(i, &message_trans[11]);
  152. }
  153. }
  154. //------------------------------------------------------------------------------------
  155. cConnection::~cConnection()
  156. {
  157. WWDEBUG_SAY(("cConnection::~cConnection\n"));
  158. //Remove_All();
  159. if (!cSinglePlayerData::Is_Single_Player()) {
  160. //
  161. // Abortively shut down the socket
  162. //
  163. WSA_CHECK(shutdown(Sock, 2)); // SD_BOTH
  164. WSA_CHECK(::closesocket(Sock));
  165. }
  166. //for (int rhost_id = 0; rhost_id < MAX_RHOSTS; rhost_id++) {
  167. //for (int rhost_id = 0; rhost_id < MaxRHost; rhost_id++) {
  168. for (int rhost_id = MinRHost; rhost_id <= MaxRHost; rhost_id++) {
  169. if (PRHost[rhost_id] != NULL) {
  170. Destroy_Connection(rhost_id);
  171. }
  172. }
  173. delete [] PRHost;
  174. PRHost = NULL;
  175. delete PStatList;
  176. PStatList = NULL;
  177. #ifdef WWDEBUG
  178. while (LaggedPackets.Count()) {
  179. delete LaggedPackets[0];
  180. LaggedPackets.Delete(0);
  181. }
  182. LaggedPacketTimes.Delete_All();
  183. #endif //WWDEBUG
  184. }
  185. //------------------------------------------------------------------------------------
  186. void cConnection::Init_Stats()
  187. {
  188. CombinedStats.Init_Net_Stats();
  189. AveragedStats.Init_Net_Stats();
  190. for (int rhost_id = MinRHost; rhost_id <= MaxRHost; rhost_id++) {
  191. if (PRHost[rhost_id] != NULL) {
  192. PRHost[rhost_id]->Init_Stats();
  193. }
  194. }
  195. ThisFrameTimeMs = TIMEGETTIME();
  196. }
  197. //------------------------------------------------------------------------------------
  198. void cConnection::Init_As_Client(LPSOCKADDR_IN p_server_address, unsigned short my_port)
  199. {
  200. WWASSERT(p_server_address != NULL);
  201. WWASSERT(!InitDone);
  202. IsServer = false;
  203. IsDedicatedServer = false;
  204. LocalId = ID_UNKNOWN;
  205. //
  206. // Now the port is supplied by the firewall negotiation code. We have to use the same port here that the firewall code
  207. // was bound to.
  208. //
  209. // The server address and port are supplied by the firewall code too.
  210. //
  211. if (!cSinglePlayerData::Is_Single_Player()) {
  212. bool is_bound;
  213. is_bound = Bind(my_port);
  214. WWASSERT(is_bound);
  215. }
  216. //
  217. // Create rhost for server
  218. //
  219. MinRHost = 0;
  220. MaxRHost = 0;
  221. typedef cRemoteHost * PcRemoteHost;
  222. PRHost = new PcRemoteHost[1];
  223. WWASSERT(PRHost != NULL);
  224. PRHost[0] = new cRemoteHost();
  225. WWASSERT(PRHost[0] != NULL);
  226. PRHost[0]->Set_Id(0);//TSS2001
  227. NumRHosts++;
  228. WWASSERT(NumRHosts == 1);
  229. if (!cSinglePlayerData::Is_Single_Player()) {
  230. PRHost[0]->Set_Address(*p_server_address);
  231. WWASSERT(cNetUtil::Is_Same_Address(&PRHost[0]->Get_Address(), p_server_address));
  232. }
  233. Init_Stats();
  234. InitDone = true;
  235. }
  236. //------------------------------------------------------------------------------------
  237. void cConnection::Init_As_Client(ULONG server_ip, USHORT server_port, unsigned short my_port)
  238. {
  239. WWDEBUG_SAY(("cConnection::Init_As_Client(%s, %d, %d)\n",
  240. cNetUtil::Address_To_String(server_ip), server_port, my_port));
  241. WWASSERT(!InitDone);
  242. WWASSERT(server_port >= MIN_SERVER_PORT && server_port <= MAX_SERVER_PORT);
  243. SOCKADDR_IN server_address;
  244. ZeroMemory(&server_address, sizeof(server_address));
  245. if (!cSinglePlayerData::Is_Single_Player()) {
  246. server_address.sin_family = AF_INET;
  247. server_address.sin_addr.s_addr = server_ip;
  248. server_address.sin_port = ::htons(server_port);
  249. }
  250. Init_As_Client(&server_address, my_port);
  251. }
  252. //------------------------------------------------------------------------------------
  253. void cConnection::Init_As_Server(USHORT server_port, int max_players,
  254. bool is_dedicated_server, ULONG addr)
  255. {
  256. WWDEBUG_SAY(("cConnection::Init_As_Server\n"));
  257. WWASSERT(!InitDone);
  258. WWASSERT(server_port >= MIN_SERVER_PORT && server_port <= MAX_SERVER_PORT);
  259. WWASSERT(max_players >= 1);
  260. //WWASSERT(max_players < MAX_RHOSTS); // because MAX_RHOSTS is an array bound
  261. MinRHost = 1;
  262. MaxRHost = max_players;
  263. typedef cRemoteHost * PcRemoteHost;
  264. PRHost = new PcRemoteHost[max_players + 1];
  265. WWASSERT(PRHost != NULL);
  266. //ZeroMemory(PRHost, sizeof(PRHost));
  267. for (int rhost_id = MinRHost; rhost_id <= MaxRHost; rhost_id++) {
  268. PRHost[rhost_id] = NULL;
  269. }
  270. Init_Stats();
  271. IsServer = true;
  272. IsDedicatedServer = is_dedicated_server;
  273. LocalId = 0;
  274. if (cSinglePlayerData::Is_Single_Player()) {
  275. IsFlowControlEnabled = false;
  276. } else {
  277. //
  278. // The server has to ::bind to his well-known port... or the nearest he can get
  279. // to it...
  280. //
  281. bool is_bound;
  282. int num_tries = 0;
  283. do {
  284. is_bound = Bind(server_port, addr);
  285. if (!is_bound) {
  286. WWDEBUG_SAY(("Failed to Bind to local port %d.\n", server_port));
  287. server_port++;
  288. num_tries++;
  289. }
  290. } while (!is_bound && num_tries < 50 && server_port <= MAX_SERVER_PORT);
  291. WWASSERT(num_tries < 50 && server_port <= MAX_SERVER_PORT);
  292. // Tell the firewall code that we started a new local server.
  293. WOLNATInterface.Set_Server(true);
  294. }
  295. InitDone = true;
  296. }
  297. //------------------------------------------------------------------------------------
  298. bool cConnection::Bind(USHORT port, ULONG addr)
  299. {
  300. WWASSERT(!cSinglePlayerData::Is_Single_Player());
  301. WWASSERT(!InitDone);
  302. //WWASSERT((!IsServer && port == 0) ||
  303. WWASSERT((!IsServer) ||
  304. (IsServer && port >= MIN_SERVER_PORT && port <= MAX_SERVER_PORT));
  305. SOCKADDR_IN address;
  306. cNetUtil::Create_Local_Address(&address, port);
  307. if (addr) address.sin_addr.s_addr = htonl(addr);
  308. if (::bind(Sock, (LPSOCKADDR) &address, sizeof(SOCKADDR_IN)) != SOCKET_ERROR) {
  309. LocalPort = port;
  310. WWDEBUG_SAY(("Bound to local port %d.\n", LocalPort));
  311. return true;
  312. } else {
  313. //
  314. // Any excuse other than address/port already used, is fatal.
  315. //
  316. if (::WSAGetLastError() != WSAEADDRINUSE) {
  317. WSA_ERROR;
  318. }
  319. return false;
  320. }
  321. //DIE; // won't get here
  322. }
  323. //------------------------------------------------------------------------------------
  324. #define ADD_CASE(exp) case exp: return #exp;
  325. LPCSTR cConnection::Type_Translation(int type)
  326. {
  327. switch (type) {
  328. ADD_CASE(PACKETTYPE_UNRELIABLE);
  329. ADD_CASE(PACKETTYPE_RELIABLE);
  330. ADD_CASE(PACKETTYPE_ACK);
  331. ADD_CASE(PACKETTYPE_KEEPALIVE);
  332. ADD_CASE(PACKETTYPE_CONNECT_CS);
  333. ADD_CASE(PACKETTYPE_ACCEPT_SC);
  334. ADD_CASE(PACKETTYPE_REFUSAL_SC);
  335. ADD_CASE(PACKETTYPE_FIREWALL_PROBE);
  336. default:
  337. DIE;
  338. return ""; // to avoid warning
  339. }
  340. }
  341. //------------------------------------------------------------------------------------
  342. bool cConnection::Sender_Id_Tests(cPacket & packet)
  343. {
  344. WWASSERT(InitDone);
  345. int sender_id = packet.Get_Sender_Id();
  346. //
  347. // Clients should only receive packets from sender_id 0
  348. //
  349. if (!IsServer && sender_id != SERVER_RHOST_ID) {
  350. WWDEBUG_SAY(("Warning: Client received packet from non-server id %d\n", sender_id));
  351. CombinedStats.Increment_Stat_Sample(STAT_DiscardCount, 1);
  352. return false;
  353. }
  354. WWASSERT(sender_id >= MinRHost && sender_id <= MaxRHost);
  355. if (sender_id < MinRHost || sender_id > MaxRHost) {
  356. WWDEBUG_SAY(("Warning: Packet with bad sender_id %d\n", sender_id));
  357. return(false);
  358. }
  359. if (PRHost[sender_id] == NULL) {
  360. //
  361. // This can happen when the connection is broken... packets in-the-air
  362. // may still arrive
  363. //
  364. BYTE packet_type;
  365. packet_type = packet.Get_Type();
  366. WWASSERT(packet_type >= PACKETTYPE_FIRST && packet_type <= PACKETTYPE_LAST);
  367. WWDEBUG_SAY(("Packet from broken connection discarded: type %d, id %d, sender %d\n",
  368. packet_type, packet.Get_Id(), sender_id));
  369. CombinedStats.StatSample[STAT_DiscardCount]++;
  370. return false;
  371. }
  372. if (!cSinglePlayerData::Is_Single_Player() &&
  373. !cNetUtil::Is_Same_Address(&(PRHost[sender_id]->Get_Address()),
  374. &packet.Get_From_Address_Wrapper()->FromAddress)) {
  375. //
  376. // This can happen under 2 known conditions:
  377. // 1. A new player reuses an id and old packets from the previous player
  378. // are still on the wire.
  379. // 2. The client has hacked the internal id field
  380. //
  381. // At this point we will just discard the packet.
  382. //
  383. WWDEBUG_SAY(("Warning: Packet sender id (%d) conflicts with actual send address\n", sender_id));
  384. CombinedStats.StatSample[STAT_DiscardCount]++;
  385. return false;
  386. }
  387. return true;
  388. }
  389. //------------------------------------------------------------------------------------
  390. USHORT cConnection::Calculate_Packet_Bits(USHORT app_bytes)
  391. {
  392. //USHORT packet_bits = 0;
  393. //
  394. // From the app bytes, work out an approximate expected number
  395. // of bits. Assume modem and PPP.
  396. //
  397. // 1. Add header bytes
  398. // 2. Assume worst case of PPP byte escaping: all of 0x00-0x1F and 0x7d, 0x7e
  399. // = 34 bytes, so multiply by (256 + 34) / 256
  400. // 3. Multiple by 10 bits/byte for modem traffic (assume serial connection,
  401. // 1 start bit and 1 stop bit)
  402. //
  403. // So we have (app bytes + header bytes) * (256 + 34) / 256 * 10
  404. //
  405. // Assumption: no IP fragmentation occurs because we are keeping the
  406. // total packet size small (less than the IP MTU of 576).
  407. //
  408. // Our application will probably be targeting a client average inbound bps
  409. // of 28800 or less.
  410. //
  411. //
  412. // Header (assuming PPP):
  413. //
  414. // IP 4.0 : 20 Bytes
  415. // UDP : 8 Bytes
  416. // PPP : 5 Bytes (typical value after negotiation)
  417. // ---------
  418. // 33 bytes
  419. //
  420. //HeaderBytes = 33;
  421. USHORT packet_bits = (USHORT)((app_bytes + 33) * 11.328125);
  422. return packet_bits;
  423. }
  424. //------------------------------------------------------------------------------------
  425. void cConnection::Set_Packet_Loss(double percent_lost)
  426. {
  427. //
  428. // This sets simultedpacketloss to a common value for all rhosts
  429. // as well as for non-established connections
  430. //
  431. WWASSERT(percent_lost >= 0 && percent_lost <= 100);
  432. SimulatedPacketLossPerRANDMAX = (UINT) cMathUtil::Round(
  433. percent_lost / 100.0 * RAND_MAX);
  434. WWDEBUG_SAY(("cConnection::Set_Packet_Loss: %d / %d\n", SimulatedPacketLossPerRANDMAX, RAND_MAX));
  435. }
  436. //------------------------------------------------------------------------------------
  437. void cConnection::Set_Packet_Duplication(double percent_duplicated)
  438. {
  439. //
  440. // This sets simultedpacketloss to a common value for all rhosts
  441. // as well as for non-established connections
  442. //
  443. WWASSERT(percent_duplicated >= -WWMATH_EPSILON &&
  444. percent_duplicated <= 100 + WWMATH_EPSILON);
  445. //
  446. // Globally:
  447. //
  448. SimulatedPacketDuplicationPerRANDMAX = (UINT) cMathUtil::Round(
  449. percent_duplicated / 100.0 * RAND_MAX);
  450. WWDEBUG_SAY(("cConnection::Set_Packet_Duplication: %d / %d\n", SimulatedPacketDuplicationPerRANDMAX, RAND_MAX));
  451. }
  452. //------------------------------------------------------------------------------------
  453. void cConnection::Set_Packet_Latency_Range(int minimum_latency_ms, int maximum_latency_ms)
  454. {
  455. WWASSERT(minimum_latency_ms >= 0);
  456. WWASSERT(maximum_latency_ms >= 0);
  457. WWASSERT(maximum_latency_ms >= minimum_latency_ms);
  458. MinimumLatencyMs = minimum_latency_ms;
  459. MaximumLatencyMs = maximum_latency_ms;
  460. }
  461. //------------------------------------------------------------------------------------
  462. int cConnection::Single_Player_recvfrom(char * data)
  463. {
  464. //WWDEBUG_SAY(("cConnection::Single_Player_recvfrom\n"));
  465. //
  466. // TSS - this relies on doing all recvs in one shot
  467. //
  468. WWASSERT(cSinglePlayerData::Is_Single_Player());
  469. int ret_code;
  470. SList<cPacket> * p_packet_list;
  471. if (IsServer) {
  472. p_packet_list = cSinglePlayerData::Get_Input_Packet_List(SERVER_LIST);
  473. } else {
  474. p_packet_list = cSinglePlayerData::Get_Input_Packet_List(CLIENT_LIST);
  475. }
  476. WWASSERT(p_packet_list != NULL);
  477. SLNode<cPacket> * objnode = p_packet_list->Head();
  478. if (objnode == NULL) {
  479. WSASetLastError(WSAEWOULDBLOCK);
  480. ret_code = SOCKET_ERROR; // no data received
  481. } else {
  482. cPacket * p_packet = objnode->Data();
  483. WWASSERT(p_packet != NULL);
  484. memcpy(data, p_packet->Get_Data(), p_packet->Get_Max_Size());
  485. ret_code = p_packet->Get_Compressed_Size_Bytes();
  486. p_packet->Flush();
  487. p_packet_list->Remove(p_packet);
  488. delete p_packet;
  489. }
  490. return ret_code;
  491. }
  492. //------------------------------------------------------------------------------------
  493. //
  494. // Return true if we receive a valid packet on this call
  495. //
  496. bool cConnection::Receive_Packet()
  497. {
  498. //WWDEBUG_SAY(("cConnection::Receive_Packet start\n"));
  499. WWASSERT(InitDone);
  500. cPacket packet;
  501. int ret_code = 0;
  502. #ifdef WWDEBUG
  503. //
  504. // See if there are any old packets with simulated lag whos time has come.
  505. //
  506. if (LaggedPacketTimes.Count()) {
  507. unsigned long time_now = TIMEGETTIME();
  508. for (int p=0 ; p<LaggedPacketTimes.Count() ; p++) {
  509. if (LaggedPacketTimes[p] <= time_now) {
  510. packet = *LaggedPackets[p];
  511. delete LaggedPackets[p];
  512. LaggedPackets.Delete(p);
  513. LaggedPacketTimes.Delete(p);
  514. ret_code = LaggedPacketRetCodes[p];
  515. LaggedPacketRetCodes.Delete(p);
  516. break;
  517. }
  518. }
  519. }
  520. #endif //WWDEBUG
  521. if (ret_code == 0) {
  522. ret_code = Receive_Wrapper(packet);
  523. if (ret_code == 0) {
  524. return(false);
  525. }
  526. if (cSinglePlayerData::Is_Single_Player() && ret_code == SOCKET_ERROR) {
  527. return(false);
  528. }
  529. #ifndef WRAPPER_CRC
  530. if (!packet.Is_Crc_Correct()) {
  531. #ifdef WWDEBUG
  532. sockaddr_in *addr_ptr = (LPSOCKADDR_IN) &packet.Get_From_Address_Wrapper()->FromAddress;
  533. #endif //WWDEBUG
  534. WWDEBUG_SAY(("*** CRC FAILURE: PACKET DISCARDED ***\n"));
  535. WWDEBUG_SAY(("*** CRC FAILURE: Packet from %s\n", Addr_As_String(addr_ptr)));
  536. packet.Flush();
  537. return true;
  538. }
  539. #endif //WRAPPER_CRC
  540. #ifdef WWDEBUG
  541. //
  542. // Add simulated latency if required.
  543. //
  544. if (LatencyAddLow || LatencyAddHigh) {
  545. cPacket *new_packet = new cPacket;
  546. *new_packet = packet;
  547. unsigned long time = TIMEGETTIME();
  548. const int latency_adjust_delay = 1000 * 10;
  549. if (time - LastLatencyChange > latency_adjust_delay) {
  550. LastLatencyChange = time;
  551. if (LatencyAddLow == LatencyAddHigh) {
  552. CurrentLatencyAdd = LatencyAddLow;
  553. } else {
  554. CurrentLatencyAdd = FreeRandom.Get_Int(LatencyAddLow, LatencyAddHigh);
  555. }
  556. }
  557. time += CurrentLatencyAdd;
  558. LaggedPackets.Add(new_packet);
  559. LaggedPacketTimes.Add(time);
  560. LaggedPacketRetCodes.Add(ret_code);
  561. packet.Flush();
  562. return(true);
  563. }
  564. #endif //WWDEBUG
  565. }
  566. //
  567. // Intercept packets intended for the firewall negotiation code.
  568. //
  569. if (packet.Get_Type() == PACKETTYPE_FIREWALL_PROBE) {
  570. WOLNATInterface.Intercept_Game_Packet(packet);
  571. packet.Flush();
  572. WWDEBUG_SAY(("cConnection:: Packet transferred to WOLNAT interface\n"));
  573. return(true);
  574. };
  575. //
  576. // A ret_code of zero indicates either:
  577. // 1. A graceful closure of the socket, or
  578. // 2. A zero-data packet.
  579. //
  580. // We are never going to attempt to recv after we have closed it, and
  581. // we never send zero-length packets, so assert this.
  582. //
  583. WWASSERT(ret_code > 0);
  584. //
  585. // Measurement stats
  586. //
  587. USHORT packet_bits = Calculate_Packet_Bits(ret_code);
  588. int addressee = Address_To_Rhostid(&packet.Get_From_Address_Wrapper()->FromAddress);
  589. if (addressee != INVALID_RHOST_ID) {
  590. PRHost[addressee]->Get_Stats().StatSample[STAT_PktRcv]++;
  591. PRHost[addressee]->Get_Stats().StatSample[STAT_AppByteRcv] += ret_code;
  592. //PRHost[addressee]->Get_Stats().StatSample[STAT_HdrByteRcv] += cNetUtil::Get_Header_Bytes();
  593. PRHost[addressee]->Get_Stats().StatSample[STAT_BitsRcv] += packet_bits;
  594. PRHost[addressee]->Set_Last_Contact_Time(TIMEGETTIME());
  595. }
  596. //
  597. // Aliases
  598. //
  599. const int packet_id = packet.Get_Id();
  600. const int sender_id = packet.Get_Sender_Id();
  601. SOCKADDR_IN * p_from_address = &packet.Get_From_Address_Wrapper()->FromAddress;
  602. WWASSERT(p_from_address != NULL);
  603. cRemoteHost * p_sender_rhost = NULL;
  604. if (sender_id != cPacket::UNDEFINED_ID) {
  605. p_sender_rhost = PRHost[sender_id];
  606. //WWASSERT(p_sender_rhost != NULL);
  607. if (p_sender_rhost == NULL) {
  608. packet.Flush();
  609. WWDEBUG_SAY(("Packet from null rhost (%d) discarded.\n", sender_id));
  610. return true;
  611. }
  612. }
  613. switch (packet.Get_Type()) {
  614. case PACKETTYPE_KEEPALIVE: {
  615. //WWDEBUG_SAY(("CONNECT: PACKETTYPE_KEEPALIVE received\n"));
  616. if (!Sender_Id_Tests(packet)) {
  617. WWDEBUG_SAY(("PACKETTYPE_KEEPALIVE flushed due to Sender_Id_Tests. Packet id = %d\n", packet_id));
  618. packet.Flush();
  619. return true;
  620. }
  621. //
  622. // TSS110201
  623. //
  624. if ( LocalId == ID_UNKNOWN) {
  625. WWDEBUG_SAY(("PACKETTYPE_KEEPALIVE flushed due to LocalId == ID_UNKNOWN. Packet id = %d\n", packet_id));
  626. packet.Flush();
  627. return true;
  628. }
  629. //
  630. // The main purpose of the keepalive is to stimulate this ack.
  631. //
  632. Send_Ack(p_from_address, packet_id);
  633. float packetloss_pc = packet.Get(packetloss_pc);
  634. WWASSERT(p_sender_rhost != NULL);
  635. cNetStats & sender_stats = p_sender_rhost->Get_Stats();
  636. sender_stats.Set_Pc_Packetloss_Sent(packetloss_pc);
  637. int remote_service_count = packet.Get(remote_service_count);
  638. sender_stats.Set_Remote_Service_Count(remote_service_count);
  639. //
  640. // We still have to process the keepalive in the rcv list so that
  641. // we step past it's reliable id. It will be discarded at that
  642. // point, and not passed up to the application level.
  643. //
  644. WWASSERT(packet.Is_Flushed());
  645. p_sender_rhost->Add_Packet(packet, RELIABLE_RCV_LIST);
  646. return true;
  647. }
  648. case PACKETTYPE_CONNECT_CS: {
  649. WWDEBUG_SAY(("CONNECT: PACKETTYPE_CONNECT_CS received\n"));
  650. WWASSERT(IsServer);
  651. WWASSERT(sender_id == ID_UNKNOWN);
  652. //
  653. // Reliable message, ack it.
  654. //
  655. Send_Ack(p_from_address, packet_id);
  656. Process_Connection_Request(packet);
  657. return true;
  658. }
  659. case PACKETTYPE_ACCEPT_SC: {
  660. //WWDEBUG_SAY(("cConnection::Receive_Packet : PACKETTYPE_ACCEPT_SC received\n"));
  661. WWDEBUG_SAY(("CONNECT: PACKETTYPE_ACCEPT_SC received\n"));
  662. WWASSERT(!IsServer);
  663. if (LocalId != ID_UNKNOWN) {
  664. //
  665. // This is a duplicate packet... discard here.
  666. //
  667. CombinedStats.StatSample[STAT_DiscardCount]++;
  668. WWDEBUG_SAY(("PACKETTYPE_ACCEPT_SC flushed due to LocalId != ID_UNKNOWN. Packet id = %d\n", packet_id));
  669. Send_Ack(p_from_address, packet_id);
  670. packet.Flush();
  671. } else {
  672. WWASSERT(sender_id == SERVER_RHOST_ID);
  673. packet.Get(LocalId); // This is where we learn our id
  674. WWDEBUG_SAY((" Received LocalId:%d\n", LocalId));
  675. Send_Ack(p_from_address, packet_id);
  676. //
  677. // Now, client may do something if he wants
  678. //
  679. //Accept_Handler();
  680. WWASSERT(AcceptHandler != NULL);
  681. AcceptHandler();
  682. //
  683. // We still have to process the accept in the rcv list so that
  684. // we step past it's reliable id. It will be discarded at that point
  685. // and not passed up to the application level.
  686. //
  687. WWASSERT(packet.Is_Flushed());
  688. WWASSERT(p_sender_rhost != NULL);
  689. p_sender_rhost->Add_Packet(packet, RELIABLE_RCV_LIST);
  690. }
  691. return true;
  692. }
  693. case PACKETTYPE_REFUSAL_SC: {
  694. WWDEBUG_SAY(("cConnection::Receive_Packet : PACKETTYPE_REFUSAL_SC received\n"));
  695. WWASSERT(!IsServer);
  696. if (LocalId == ID_UNKNOWN) {
  697. WWASSERT(sender_id == SERVER_RHOST_ID);
  698. if (packet_id > HighestRefusalPacketRcvId) {
  699. HighestRefusalPacketRcvId = packet_id;
  700. int refusal_code = packet.Get(refusal_code);
  701. //Refusal_Handler(refusal_code);
  702. WWASSERT(RefusalHandler != NULL);
  703. RefusalHandler((REFUSAL_CODE)refusal_code);
  704. IsDestroy = true;
  705. } else {
  706. //
  707. // It's a duplicate
  708. //
  709. packet.Flush();
  710. }
  711. } else {
  712. //
  713. // This is an inappropriate packet... discard here.
  714. // TSS - bug - duplicates not handled properly - sent * 5
  715. //
  716. CombinedStats.StatSample[STAT_DiscardCount]++;
  717. packet.Flush();
  718. }
  719. return true;
  720. }
  721. case PACKETTYPE_UNRELIABLE: {
  722. //WWDEBUG_SAY(("CONNECT: PACKETTYPE_UNRELIABLE received\n"));
  723. //
  724. // Discard all unreliable packets until we have an id.
  725. //
  726. if (LocalId == ID_UNKNOWN) {
  727. packet.Flush();
  728. WWDEBUG_SAY(("Unreliable packet flushed due to unknown id.\n"));
  729. return true;
  730. }
  731. //
  732. // Discard data with an address mismatch.
  733. //
  734. if (!Sender_Id_Tests(packet)) {
  735. packet.Flush();
  736. WWDEBUG_SAY(("Unreliable packet flushed due to address mismatch.\n"));
  737. return true;
  738. }
  739. //
  740. // Discard out-of-date data.
  741. //
  742. WWASSERT(p_sender_rhost != NULL);
  743. if (packet_id < p_sender_rhost->Get_Unreliable_Packet_Rcv_Id()) {
  744. packet.Flush();
  745. //WWDEBUG_SAY(("Unreliable packet flushed due to being out-of-date.\n"));
  746. return true;
  747. }
  748. //
  749. // Keep track of how many of each packet is received
  750. //
  751. cNetStats & sender_stats = p_sender_rhost->Get_Stats();
  752. sender_stats.StatSample[STAT_MsgRcv]++;
  753. sender_stats.StatSample[STAT_UPktRcv]++;
  754. sender_stats.StatSample[STAT_UByteRcv] += ret_code;
  755. if (packet_id > sender_stats.Get_Freeze_Packet_Id()) {
  756. sender_stats.StatSample[STAT_UPktRcv2]++;
  757. sender_stats.Increment_Unreliable_Count();
  758. }
  759. if (packet_id > sender_stats.Get_Last_Unreliable_Packet_Id()) {
  760. sender_stats.Set_Last_Unreliable_Packet_Id(packet_id);
  761. }
  762. p_sender_rhost->Add_Packet(packet, UNRELIABLE_RCV_LIST);
  763. return true;
  764. }
  765. case PACKETTYPE_RELIABLE: {
  766. //WWDEBUG_SAY(("CONNECT: PACKETTYPE_RELIABLE received\n"));
  767. //
  768. // Discard all reliable packets until we have an id.
  769. // We still don't have LocalId, therefore we can't Ack this.
  770. //
  771. if (LocalId == ID_UNKNOWN) {
  772. packet.Flush();
  773. WWDEBUG_SAY(("Reliable packet %d flushed due to unknown id.\n", packet_id));
  774. return true;
  775. }
  776. //
  777. // Discard data with an address mismatch.
  778. //
  779. if (!Sender_Id_Tests(packet)) {
  780. packet.Flush();
  781. WWDEBUG_SAY(("Reliable packet %d flushed due to address mismatch.\n", packet_id));
  782. return true;
  783. }
  784. Send_Ack(p_from_address, packet_id);
  785. //
  786. // Keep track of how many of each packet is received
  787. //
  788. WWASSERT(p_sender_rhost != NULL);
  789. cNetStats & sender_stats = p_sender_rhost->Get_Stats();
  790. sender_stats.StatSample[STAT_MsgRcv]++;
  791. sender_stats.StatSample[STAT_RPktRcv]++;
  792. sender_stats.StatSample[STAT_RByteRcv] += ret_code;
  793. p_sender_rhost->Add_Packet(packet, RELIABLE_RCV_LIST);
  794. return true;
  795. }
  796. case PACKETTYPE_ACK: {
  797. //WWDEBUG_SAY(("CONNECT: PACKETTYPE_ACK received\n"));
  798. //WWDEBUG_SAY(("(Received Ack for packet %d)\n", packet_id));
  799. if (!Sender_Id_Tests(packet)) {
  800. return true;
  801. }
  802. WWASSERT(p_sender_rhost != NULL);
  803. cNetStats & sender_stats = p_sender_rhost->Get_Stats();
  804. sender_stats.StatSample[STAT_AckCountRcv]++;
  805. p_sender_rhost->Remove_Packet(packet_id, RELIABLE_SEND_LIST);
  806. return true;
  807. }
  808. default:
  809. DIE;
  810. break;
  811. }
  812. DIE; // shouldn't get here
  813. return true;
  814. }
  815. //-----------------------------------------------------------------------------
  816. void cConnection::Process_Connection_Request(cPacket & packet)
  817. {
  818. LPSOCKADDR_IN p_address = &packet.Get_From_Address_Wrapper()->FromAddress;
  819. WWASSERT(InitDone);
  820. WWASSERT(IsServer);
  821. int new_rhost_id = ID_UNKNOWN;
  822. //
  823. // Make sure we don't already know him, and find him a slot
  824. //
  825. for (int player_id = MinRHost; player_id <= MaxRHost; player_id++) {
  826. if (PRHost[player_id] != NULL) {
  827. if (!cSinglePlayerData::Is_Single_Player() &&
  828. cNetUtil::Is_Same_Address(&(PRHost[player_id]->Get_Address()),
  829. p_address)) {
  830. //
  831. // He already has an id. This must be a resend or duplicate.
  832. //
  833. return;
  834. }
  835. } else if (new_rhost_id == ID_UNKNOWN) {
  836. new_rhost_id = player_id;
  837. }
  838. }
  839. if (new_rhost_id == ID_UNKNOWN) {
  840. WWDEBUG_SAY((" Warning: server cannot accept this client; no free slots\n"));
  841. Send_Refusal_Sc(p_address, REFUSAL_GAME_FULL);
  842. } else {
  843. WWASSERT(ApplicationAcceptanceHandler != NULL);
  844. REFUSAL_CODE refusal = ApplicationAcceptanceHandler(packet);
  845. if (refusal != REFUSAL_CLIENT_ACCEPTED) {
  846. packet.Flush();
  847. Send_Refusal_Sc(p_address, refusal);
  848. return;
  849. }
  850. //
  851. // TSS091701
  852. //
  853. int bbo = packet.Get(bbo);
  854. WWDEBUG_SAY(("New clients BBO is %d\n", bbo));
  855. WWASSERT(PRHost[new_rhost_id] == NULL);
  856. PRHost[new_rhost_id] = new cRemoteHost();
  857. WWASSERT(PRHost[new_rhost_id] != NULL);
  858. PRHost[new_rhost_id]->Set_Id(new_rhost_id);//TSS2001
  859. NumRHosts++;
  860. WWASSERT(NumRHosts <= MaxRHost - MinRHost + 1);
  861. PRHost[new_rhost_id]->Set_Address(*p_address);
  862. PRHost[new_rhost_id]->Set_Maximum_Bps(bbo);
  863. Send_Accept_Sc(new_rhost_id);
  864. //Connection_Handler(new_rhost_id);
  865. WWASSERT(ConnHandler != NULL);
  866. ConnHandler(new_rhost_id);
  867. //
  868. // Although processed individually, PACKETTYPE_CONNECT_CS
  869. // is essentially reliable, and we must track the id appropriately.
  870. //
  871. PRHost[new_rhost_id]->Get_Reliable_Packet_Rcv_Id();
  872. PRHost[new_rhost_id]->Increment_Reliable_Packet_Rcv_Id();
  873. }
  874. }
  875. //------------------------------------------------------------------------------------
  876. int cConnection::Single_Player_sendto(cPacket & packet)
  877. {
  878. //WWDEBUG_SAY(("cConnection::Single_Player_sendto\n"));
  879. WWASSERT(cSinglePlayerData::Is_Single_Player());
  880. SList<cPacket> * p_packet_list;
  881. if (IsServer) {
  882. p_packet_list = cSinglePlayerData::Get_Input_Packet_List(CLIENT_LIST);
  883. } else {
  884. p_packet_list = cSinglePlayerData::Get_Input_Packet_List(SERVER_LIST);
  885. }
  886. WWASSERT(p_packet_list != NULL);
  887. cPacket * p_packet = new cPacket;
  888. WWASSERT(p_packet != NULL);
  889. *p_packet = packet;
  890. p_packet_list->Add_Tail(p_packet);
  891. return packet.Get_Compressed_Size_Bytes();
  892. }
  893. //------------------------------------------------------------------------------------
  894. int cConnection::Address_To_Rhostid(const SOCKADDR_IN* p_address)
  895. {
  896. WWASSERT(p_address != NULL);
  897. if (cSinglePlayerData::Is_Single_Player()) {
  898. return INVALID_RHOST_ID;
  899. }
  900. //
  901. // TSS - this searching is very inefficient.
  902. //
  903. for (int rhost_id = MinRHost; rhost_id <= MaxRHost; rhost_id++) {
  904. if (PRHost[rhost_id] != NULL &&
  905. cNetUtil::Is_Same_Address(&(PRHost[rhost_id]->Get_Address()), p_address)) {
  906. return rhost_id;
  907. }
  908. }
  909. return INVALID_RHOST_ID;
  910. }
  911. //#include "packetmgr.h"
  912. //unsigned char last_packet[1024];
  913. //unsigned char delta_packet[1024];
  914. //unsigned char fixed_packet[1024];
  915. //int last_packet_len = 0;
  916. //------------------------------------------------------------------------------------
  917. int cConnection::Low_Level_Send_Wrapper(cPacket & packet, LPSOCKADDR_IN p_address)
  918. {
  919. WWASSERT(p_address != NULL);
  920. int ret_code = 0;
  921. #if (0)
  922. if (last_packet_len == (int)packet.Get_Compressed_Size_Bytes()) {
  923. int delta_size = PacketManagerClass::Build_Delta_Packet_Patch(last_packet, (unsigned char*)packet.Get_Data(), delta_packet, last_packet_len, last_packet_len);
  924. if (delta_size != -1) {
  925. WWDEBUG_SAY(("Packet size = %d, last packet delta = %d\n", last_packet_len, delta_size));
  926. }
  927. int bytes = PacketManagerClass::Reconstruct_From_Delta(last_packet, fixed_packet, delta_packet, last_packet_len);
  928. assert(bytes == last_packet_len);
  929. assert(memcmp(packet.Get_Data(), fixed_packet, last_packet_len) == 0);
  930. }
  931. last_packet_len = (int)packet.Get_Compressed_Size_Bytes();
  932. memcpy(last_packet, packet.Get_Data(), last_packet_len);
  933. #endif (0)
  934. if (cSinglePlayerData::Is_Single_Player()) {
  935. ret_code = Single_Player_sendto(packet);
  936. } else {
  937. //WWDEBUG_SAY(("cConnection: sendto %s\n", Addr_As_String(p_address)));
  938. //
  939. // Just pass the packet to the packet manager for deltaing and coagulation.
  940. //
  941. bool took = PacketManager.Take_Packet((unsigned char *)packet.Get_Data(), packet.Get_Compressed_Size_Bytes(), (unsigned char*)&p_address->sin_addr.s_addr, p_address->sin_port, Sock);
  942. if (!took) {
  943. WWDEBUG_SAY(("Low_Level_Send_Wrapper - Failed to pass packet to packet manager\n"));
  944. return(0);
  945. //ret_code = sendto(Sock, packet.Get_Data(),
  946. // packet.Get_Compressed_Size_Bytes(), 0,
  947. // (LPSOCKADDR) p_address, sizeof(SOCKADDR_IN));
  948. } else {
  949. PacketManager.Flush();
  950. ret_code = packet.Get_Compressed_Size_Bytes();
  951. if (ret_code < 0) {
  952. ret_code = 0;
  953. }
  954. }
  955. //unsigned long bytes;
  956. //int result = ioctlsocket(Sock, FIONREAD, &bytes);
  957. //if (result == 0 && bytes != 0) {
  958. // WWDEBUG_SAY(("ioctlsocket - bytes left to read = %d\n", bytes));
  959. //}
  960. }
  961. return ret_code;
  962. }
  963. //------------------------------------------------------------------------------------
  964. int cConnection::Send_Wrapper(cPacket & packet, LPSOCKADDR_IN p_address)
  965. {
  966. WWASSERT(p_address != NULL);
  967. cPacket full_packet;
  968. cPacket::Construct_Full_Packet(full_packet, packet);
  969. //
  970. // Update stats
  971. //
  972. BYTE packet_type = packet.Get_Type();
  973. WWASSERT(packet_type >= PACKETTYPE_FIRST && packet_type <= PACKETTYPE_LAST);
  974. PStatList->Increment_Num_Msg_Sent(packet_type);
  975. PStatList->Increment_Num_Byte_Sent(packet_type, full_packet.Get_Compressed_Size_Bytes());
  976. bool is_lost = false;
  977. #ifdef WWDEBUG
  978. is_lost = (rand() < SimulatedPacketLossPerRANDMAX);
  979. #endif
  980. int ret_code = 0;
  981. if (is_lost) {
  982. ret_code = full_packet.Get_Compressed_Size_Bytes(); // just don't send !
  983. } else {
  984. ret_code = Low_Level_Send_Wrapper(full_packet, p_address);
  985. }
  986. return ret_code;
  987. }
  988. //------------------------------------------------------------------------------------
  989. int cConnection::Send_Wrapper(cPacket & packet, int addressee)
  990. {
  991. WWASSERT(addressee >= 0);
  992. WWASSERT(addressee != ID_UNKNOWN);
  993. WWASSERT(PRHost[addressee] != NULL);
  994. return Send_Wrapper(packet, &(PRHost[addressee]->Get_Address()));//, addressee);
  995. }
  996. //------------------------------------------------------------------------------------
  997. int cConnection::Low_Level_Receive_Wrapper(cPacket & packet)
  998. {
  999. int ret_code = 0;
  1000. if (cSinglePlayerData::Is_Single_Player()) {
  1001. ret_code = Single_Player_recvfrom(packet.Get_Data());
  1002. } else {
  1003. const int max_errors = 250;
  1004. int error_count = 0;
  1005. int bytes = 0;
  1006. //
  1007. // Try getting a packet from the packet manager. Keep trying for a number of times if we get a socket error. If we don't
  1008. // do this and just fail then we fall out of the receive packet loop and no more packets are received this frame. 15 of
  1009. // these a second and we don't get any packets in at all.
  1010. //
  1011. unsigned char ip_address[4];
  1012. unsigned short port = 0;
  1013. while (error_count < max_errors) {
  1014. bytes = PacketManager.Get_Packet(Sock, (unsigned char *)packet.Get_Data(), packet.Get_Max_Size(), ip_address, port);
  1015. //
  1016. // A return value of less than 0 indicates a fatal socket error. Try and ditch the offending client.
  1017. //
  1018. if (bytes < 0) {
  1019. bytes = 0;
  1020. error_count++;
  1021. bool found_bad = false;
  1022. if (IsServer) {
  1023. //
  1024. // If we try to invoke the broken connection handler when loading a level it will access the player list
  1025. // which will cause a DataSafe access from the wrong (main) thread with potentially catastrophic effects.
  1026. // ST - 1/17/2002 11:18AM
  1027. //
  1028. if (CanProcess) {
  1029. WWASSERT(ServerBrokenConnectionHandler != NULL);
  1030. for (int i=MinRHost ; i<MaxRHost ; i++) {
  1031. cRemoteHost *rhost_ptr = PRHost[i];
  1032. if (rhost_ptr) {
  1033. SOCKADDR_IN rhost_addr = rhost_ptr->Get_Address();
  1034. if (memcmp(ip_address, &rhost_addr.sin_addr.s_addr, 4) == 0) {
  1035. if (rhost_addr.sin_port == port) {
  1036. int rhost_id = rhost_ptr->Get_Id();
  1037. Destroy_Connection(rhost_id);
  1038. ServerBrokenConnectionHandler(rhost_id);
  1039. found_bad = true;
  1040. break;
  1041. }
  1042. }
  1043. }
  1044. }
  1045. if (!found_bad) {
  1046. WWDEBUG_SAY(("WSAECONNRESET address not in host list\n"));
  1047. }
  1048. }
  1049. }
  1050. } else {
  1051. break;
  1052. }
  1053. }
  1054. if (bytes) {
  1055. sockaddr_in *addr_ptr = (LPSOCKADDR_IN) &packet.Get_From_Address_Wrapper()->FromAddress;
  1056. memcpy(&addr_ptr->sin_addr.s_addr, ip_address, 4);
  1057. addr_ptr->sin_port = port;
  1058. }
  1059. ret_code = bytes;
  1060. #if (0)
  1061. int address_size = sizeof(SOCKADDR_IN);
  1062. ret_code = recvfrom(Sock, packet.Get_Data(),
  1063. packet.Get_Max_Size(), 0,
  1064. (LPSOCKADDR) &packet.Get_From_Address_Wrapper()->FromAddress, &address_size);
  1065. if (ret_code > 0) {
  1066. //WWDEBUG_SAY(("cConnection: recvfrom %s\n", Addr_As_String((LPSOCKADDR_IN) &packet.Get_From_Address_Wrapper()->FromAddress)));
  1067. }
  1068. #endif //(0)
  1069. /*
  1070. //
  1071. // diagnostic
  1072. //
  1073. if (ret_code > 0) {
  1074. ULONG ip = packet.Get_From_Address_Wrapper()->FromAddress.sin_addr.s_addr;
  1075. WWDEBUG_SAY(("cConnection::Low_Level_Receive_Wrapper: %s\n",
  1076. cNetUtil::Address_To_String(ip)));
  1077. }
  1078. /**/
  1079. }
  1080. return ret_code;
  1081. }
  1082. //------------------------------------------------------------------------------------
  1083. int cConnection::Receive_Wrapper(cPacket & packet)
  1084. {
  1085. cPacket full_packet;
  1086. int ret_code = Low_Level_Receive_Wrapper(full_packet);
  1087. if (ret_code > 0) {
  1088. //
  1089. // We won't be able to read the header from the full packet unless we
  1090. // set the bit length (approximately).
  1091. // The returned packet object will have the exact bit length set correctly.
  1092. //
  1093. full_packet.Set_Bit_Length(ret_code * 8);
  1094. cPacket::Construct_App_Packet(packet, full_packet);
  1095. #ifndef WRAPPER_CRC
  1096. if (packet.Is_Crc_Correct()) {
  1097. #endif //WRAPPER_CRC
  1098. //
  1099. // Update receive stats
  1100. //
  1101. BYTE packet_type = packet.Get_Type();
  1102. WWASSERT(packet_type >= PACKETTYPE_FIRST && packet_type <= PACKETTYPE_LAST);
  1103. PStatList->Increment_Num_Msg_Recd(packet_type);
  1104. PStatList->Increment_Num_Byte_Recd(packet_type, ret_code);
  1105. #ifndef WRAPPER_CRC
  1106. }
  1107. #endif //WRAPPER_CRC
  1108. }
  1109. return ret_code;
  1110. }
  1111. /*
  1112. //------------------------------------------------------------------------------------
  1113. void cConnection::Handle_Send_Resource_Failure(int rhost_id)
  1114. {
  1115. if (rhost_id != INVALID_RHOST_ID) {
  1116. WWASSERT(PRHost[rhost_id] != NULL);
  1117. PRHost[rhost_id]->Get_Stats().StatSample[STAT_SendFailureCount]++;
  1118. }
  1119. int orgbuffersize;
  1120. int newbuffersize;
  1121. int len;
  1122. len = sizeof(int);
  1123. WSA_CHECK(::getsockopt(Sock, SOL_SOCKET, SO_SNDBUF,
  1124. (char *)&orgbuffersize, &len));
  1125. static int time_of_last_reset = 0;
  1126. int time_now = TIMEGETTIME();
  1127. Clear_Resend_Counts();
  1128. if (time_now - time_of_last_reset > 5000) {
  1129. failcount++;
  1130. float failure_ratio;
  1131. if (succcount == 0) {
  1132. failure_ratio = 1;
  1133. } else {
  1134. failure_ratio = failcount / (float) succcount;
  1135. }
  1136. succcount = 0;
  1137. failcount = 0;
  1138. extern int g_c_wouldblock;
  1139. extern int g_c_nobufs;
  1140. g_c_wouldblock = 0;
  1141. g_c_nobufs = 0;
  1142. if (orgbuffersize < 1000000) {
  1143. //
  1144. // 2-pronged approach. Firstly, increase send buffer size.
  1145. // Secondly, if it was a significant failure, immediately
  1146. // reduce bw out.
  1147. //
  1148. newbuffersize = 4 * orgbuffersize;
  1149. len = sizeof(int);
  1150. WSA_CHECK(setsockopt(Sock, SOL_SOCKET, SO_SNDBUF,
  1151. (char *)&newbuffersize, len));
  1152. len = sizeof(int);
  1153. WSA_CHECK(::getsockopt(Sock, SOL_SOCKET, SO_SNDBUF,
  1154. (char *)&newbuffersize, &len));
  1155. WWDEBUG_SAY(("SO_SNDBUF %d -> %d\n",
  1156. orgbuffersize, newbuffersize));
  1157. if (failure_ratio > 0.05f) {
  1158. time_of_last_reset = time_now;
  1159. }
  1160. } else {
  1161. //
  1162. // If we max out the send buffer and are still getting fails here
  1163. // then we need to throttle back our output through this socket.
  1164. //
  1165. if (failure_ratio > 0.05f) {
  1166. time_of_last_reset = time_now;
  1167. }
  1168. }
  1169. }
  1170. }
  1171. */
  1172. //------------------------------------------------------------------------------------
  1173. void cConnection::Send_Packet_To_Address(cPacket & packet, LPSOCKADDR_IN p_address)
  1174. {
  1175. WWASSERT(p_address != NULL);
  1176. WWASSERT(InitDone);
  1177. // TSS - need reverse lookup of addressee from address
  1178. int rhost_id = Address_To_Rhostid(p_address);
  1179. if (rhost_id != INVALID_RHOST_ID) {
  1180. WWASSERT(PRHost[rhost_id] != NULL);
  1181. }
  1182. if (rand() < SimulatedPacketDuplicationPerRANDMAX) {
  1183. //
  1184. // we'll send a duplicate
  1185. //
  1186. packet.Set_Num_Sends(packet.Get_Num_Sends() + 1);
  1187. }
  1188. //static int succcount = 0;
  1189. //static int failcount = 0;
  1190. for (int i = 0; i < packet.Get_Num_Sends(); i++) {
  1191. int ret_code;
  1192. if (rhost_id == INVALID_RHOST_ID) {
  1193. ret_code = Send_Wrapper(packet, p_address);
  1194. } else {
  1195. ret_code = Send_Wrapper(packet, rhost_id);
  1196. }
  1197. if (SEND_RESOURCE_FAILURE(ret_code)) {
  1198. //Handle_Send_Resource_Failure(rhost_id);
  1199. WWDEBUG_SAY(("WARNING: cConnection::Send_Packet_To_Address : SEND_RESOURCE_FAILURE\n"));
  1200. } else {
  1201. //succcount++;
  1202. TotalCompressedBytesSent += packet.Get_Compressed_Size_Bytes();
  1203. TotalUncompressedBytesSent += packet.Get_Uncompressed_Size_Bytes();
  1204. USHORT bits_sent = Calculate_Packet_Bits(packet.Get_Compressed_Size_Bytes());
  1205. if (rhost_id != INVALID_RHOST_ID) {
  1206. PRHost[rhost_id]->Get_Stats().StatSample[STAT_PktSent]++;
  1207. PRHost[rhost_id]->Get_Stats().StatSample[STAT_AppByteSent] += packet.Get_Compressed_Size_Bytes();
  1208. //PRHost[rhost_id]->Get_Stats().StatSample[STAT_HdrByteSent] += cNetUtil::Get_Header_Bytes();
  1209. PRHost[rhost_id]->Get_Stats().StatSample[STAT_BitsSent] += bits_sent;
  1210. }
  1211. }
  1212. }
  1213. }
  1214. //------------------------------------------------------------------------------------
  1215. void cConnection::Set_R_And_U_Packet_Id(cPacket & packet, int addressee, BYTE send_type)
  1216. {
  1217. WWASSERT(PRHost[addressee] != NULL);
  1218. if (send_type == PACKETTYPE_RELIABLE) {
  1219. packet.Set_Id(PRHost[addressee]->Get_Reliable_Packet_Send_Id());
  1220. PRHost[addressee]->Increment_Reliable_Packet_Send_Id();
  1221. } else {
  1222. WWASSERT(send_type == PACKETTYPE_UNRELIABLE);
  1223. packet.Set_Id(PRHost[addressee]->Get_Unreliable_Packet_Send_Id());
  1224. PRHost[addressee]->Increment_Unreliable_Packet_Send_Id();
  1225. }
  1226. }
  1227. //------------------------------------------------------------------------------------
  1228. void cConnection::R_And_U_Send(
  1229. cPacket & packet,
  1230. int addressee)
  1231. {
  1232. WWASSERT(PRHost[addressee] != NULL);
  1233. if (packet.Get_Type() == PACKETTYPE_RELIABLE) {
  1234. PRHost[addressee]->Add_Packet(packet, RELIABLE_SEND_LIST);
  1235. } else {
  1236. WWASSERT(packet.Get_Type() == PACKETTYPE_UNRELIABLE);
  1237. PRHost[addressee]->Add_Packet(packet, UNRELIABLE_SEND_LIST);
  1238. }
  1239. }
  1240. //------------------------------------------------------------------------------------
  1241. void cConnection::Send_Packet_To_Individual(cPacket & packet, int addressee, BYTE send_flags)
  1242. {
  1243. WWASSERT(InitDone);
  1244. //
  1245. // Validate inputs
  1246. //
  1247. WWASSERT(packet.Get_Compressed_Size_Bytes() > 0);
  1248. WWASSERT(addressee >= MinRHost && addressee <= MaxRHost);
  1249. WWASSERT(PRHost[addressee] != NULL);
  1250. WWASSERT(
  1251. send_flags == SEND_RELIABLE ||
  1252. send_flags == SEND_UNRELIABLE ||
  1253. send_flags == (SEND_UNRELIABLE | SEND_MULTI));
  1254. int num_sends = 1;
  1255. if (send_flags & SEND_MULTI) {
  1256. num_sends = cNetUtil::MULTI_SENDS;
  1257. }
  1258. packet.Set_Num_Sends(num_sends);
  1259. if (send_flags & SEND_RELIABLE) {
  1260. packet.Set_Type(PACKETTYPE_RELIABLE);
  1261. } else {
  1262. packet.Set_Type(PACKETTYPE_UNRELIABLE);
  1263. }
  1264. Set_R_And_U_Packet_Id(packet, addressee, packet.Get_Type());
  1265. packet.Set_Sender_Id(LocalId);
  1266. //
  1267. // Keep track of how many of each packet is sent.
  1268. //
  1269. PRHost[addressee]->Get_Stats().StatSample[STAT_MsgSent] += num_sends;
  1270. R_And_U_Send(packet, addressee);
  1271. }
  1272. /*
  1273. //------------------------------------------------------------------------------------
  1274. void cConnection::Send_Packet_To_All(cPacket & packet, BYTE send_flags)
  1275. {
  1276. WWASSERT(InitDone);
  1277. //
  1278. // Validate inputs
  1279. //
  1280. WWASSERT(packet.Get_Compressed_Size_Bytes() > 0);
  1281. WWASSERT(
  1282. send_flags == SEND_RELIABLE ||
  1283. send_flags == SEND_UNRELIABLE ||
  1284. send_flags == (SEND_UNRELIABLE | SEND_MULTI));
  1285. if (NumRHosts == 0) {
  1286. return;
  1287. }
  1288. //int num_sends = 0;
  1289. for (int rhost_id = MinRHost; rhost_id <= MaxRHost; rhost_id++) {
  1290. if (PRHost[rhost_id] != NULL) {
  1291. //if (IsServer && !PRHost[rhost_id]->Is_Ready_For_All_Data()) {
  1292. // continue;
  1293. //}
  1294. Send_Packet_To_Individual(packet, rhost_id, send_flags);
  1295. //num_sends++;
  1296. }
  1297. }
  1298. //return num_sends;
  1299. }
  1300. */
  1301. //------------------------------------------------------------------------------------
  1302. bool cConnection::Is_Established() const
  1303. {
  1304. bool is_established = true;
  1305. if (!IsServer) {
  1306. is_established = (LocalId != ID_UNKNOWN) && (PRHost[SERVER_RHOST_ID] != NULL);
  1307. }
  1308. return is_established;
  1309. }
  1310. //------------------------------------------------------------------------------------
  1311. void cConnection::Connect_Cs(cPacket & packet)
  1312. {
  1313. WWASSERT(InitDone);
  1314. WWASSERT(!IsServer);
  1315. WWASSERT(PRHost[SERVER_RHOST_ID] != NULL);
  1316. WWASSERT(LocalId == ID_UNKNOWN);
  1317. //WWDEBUG_SAY(("Connect_Cs at time %s\n", cMiscUtil::Get_Text_Time()));
  1318. int packet_id = PRHost[SERVER_RHOST_ID]->Get_Reliable_Packet_Send_Id();
  1319. PRHost[SERVER_RHOST_ID]->Increment_Reliable_Packet_Send_Id();
  1320. WWASSERT(packet_id == 0);
  1321. //WWDEBUG_SAY(("cConnection::Connect_Cs : Sending PACKETTYPE_CONNECT_CS\n"));
  1322. WWDEBUG_SAY(("CONNECT: PACKETTYPE_CONNECT_CS sent\n"));
  1323. packet.Set_Type(PACKETTYPE_CONNECT_CS);
  1324. packet.Set_Id(packet_id);
  1325. //packet.Set_Sender_Id(LocalId);//NEW
  1326. PRHost[SERVER_RHOST_ID]->Add_Packet(packet, RELIABLE_SEND_LIST);
  1327. }
  1328. //-----------------------------------------------------------------------------
  1329. void cConnection::Send_Accept_Sc(int new_rhost_id)
  1330. {
  1331. WWASSERT(new_rhost_id >= 0);
  1332. WWASSERT(InitDone);
  1333. WWASSERT(IsServer);
  1334. WWASSERT(new_rhost_id >= MinRHost && new_rhost_id <= MaxRHost);
  1335. //WWDEBUG_SAY(("cConnection::Send_Accept_Sc(%d)\n", new_rhost_id));
  1336. WWDEBUG_SAY(("CONNECT: PACKETTYPE_ACCEPT_SC (%d) sent\n", new_rhost_id));
  1337. int packet_id = PRHost[new_rhost_id]->Get_Reliable_Packet_Send_Id();
  1338. PRHost[new_rhost_id]->Increment_Reliable_Packet_Send_Id();
  1339. cPacket packet;
  1340. packet.Add(new_rhost_id);
  1341. packet.Set_Type(PACKETTYPE_ACCEPT_SC);
  1342. packet.Set_Id(packet_id);
  1343. packet.Set_Sender_Id(LocalId);
  1344. PRHost[new_rhost_id]->Add_Packet(packet, RELIABLE_SEND_LIST);
  1345. }
  1346. //-----------------------------------------------------------------------------
  1347. void cConnection::Send_Refusal_Sc(LPSOCKADDR_IN p_address, REFUSAL_CODE refusal_code)
  1348. {
  1349. WWASSERT(p_address != NULL);
  1350. //
  1351. // This is a refusal originating from the wwnet layer
  1352. //
  1353. WWDEBUG_SAY(("cConnection::Send_Refusal_Sc (%d)\n", refusal_code));
  1354. WWASSERT(InitDone);
  1355. WWASSERT(IsServer);
  1356. //
  1357. // The id is not per-client... because we don't hold per client information
  1358. // for this guy.
  1359. //
  1360. int packet_id = RefusalPacketSendId++;
  1361. cPacket packet;
  1362. packet.Add((int)refusal_code);
  1363. packet.Set_Type(PACKETTYPE_REFUSAL_SC);
  1364. packet.Set_Id(packet_id);
  1365. packet.Set_Sender_Id(LocalId);
  1366. //
  1367. // Send redundantly, because it's unreliable
  1368. //
  1369. packet.Set_Num_Sends(cNetUtil::MULTI_SENDS);
  1370. Send_Packet_To_Address(packet, p_address);
  1371. }
  1372. //-----------------------------------------------------------------------------
  1373. void cConnection::Send_Ack(LPSOCKADDR_IN p_address, int packet_id)
  1374. {
  1375. WWASSERT(p_address != NULL);
  1376. WWASSERT(InitDone);
  1377. WWASSERT(packet_id >= 0);
  1378. WWASSERT(LocalId != ID_UNKNOWN); //TSS - bug - asserted here when 50% packet loss or crc failures
  1379. //WWDEBUG_SAY(("Ack reply for packet is %d\n", packet_id));
  1380. //WWDEBUG_SAY(("Sending ack for packet %d to %s\n", packet_id, Addr_As_String(p_address)));
  1381. cPacket packet;
  1382. packet.Set_Type(PACKETTYPE_ACK);
  1383. packet.Set_Id(packet_id);
  1384. packet.Set_Sender_Id(LocalId);
  1385. //
  1386. // Acks are unreliable
  1387. //
  1388. int addressee = Address_To_Rhostid(p_address);
  1389. if (addressee != INVALID_RHOST_ID) {
  1390. WWASSERT(PRHost[addressee] != NULL);
  1391. PRHost[addressee]->Get_Stats().StatSample[STAT_AckCountSent]++;
  1392. PRHost[addressee]->Get_Stats().StatSample[STAT_UPktSent]++;
  1393. PRHost[addressee]->Get_Stats().StatSample[STAT_UByteSent] += packet.Get_Compressed_Size_Bytes();
  1394. }
  1395. //unsigned long time = TIMEGETTIME() / 1000;
  1396. //WWDEBUG_SAY(("Sending ack at %d\n", time));
  1397. Send_Packet_To_Address(packet, p_address);
  1398. }
  1399. //-----------------------------------------------------------------------------
  1400. void cConnection::Destroy_Connection(int rhost_id)
  1401. {
  1402. WWASSERT(rhost_id >= 0);
  1403. WWASSERT(InitDone);
  1404. WWASSERT(rhost_id >= MinRHost && rhost_id <= MaxRHost);
  1405. if (PRHost[rhost_id] != NULL) {
  1406. delete PRHost[rhost_id];
  1407. PRHost[rhost_id] = NULL;
  1408. NumRHosts--;
  1409. WWASSERT(NumRHosts >= 0);
  1410. }
  1411. }
  1412. //-----------------------------------------------------------------------------
  1413. void cConnection::Send_Keepalives()
  1414. {
  1415. //
  1416. /////// Keepalives are only sent when we have heard nothing from the rhost for a while.
  1417. //
  1418. WWASSERT(InitDone);
  1419. if (LocalId != ID_UNKNOWN) {
  1420. for (int rhost_id = MinRHost; rhost_id <= MaxRHost; rhost_id++) {
  1421. if (PRHost[rhost_id] != NULL && ThisFrameTimeMs -
  1422. PRHost[rhost_id]->Get_Last_Keepalive_Time_Ms() > cNetUtil::KEEPALIVE_TIMEOUT_MS) {
  1423. int service_rate = (int)(1000 *
  1424. (ServiceCount - PRHost[rhost_id]->Get_Last_Service_Count()) / (ThisFrameTimeMs -
  1425. PRHost[rhost_id]->Get_Last_Keepalive_Time_Ms()));
  1426. PRHost[rhost_id]->Set_Last_Service_Count(ServiceCount);
  1427. PRHost[rhost_id]->Set_Last_Keepalive_Time_Ms(ThisFrameTimeMs);
  1428. //WWDEBUG_SAY(("Sending keepalive to rhost %d at time %d\n", rhost_id, TIMEGETTIME()));
  1429. //
  1430. // Keepalive is a reliable message
  1431. //
  1432. int packet_id = PRHost[rhost_id]->Get_Reliable_Packet_Send_Id();
  1433. PRHost[rhost_id]->Increment_Reliable_Packet_Send_Id();
  1434. cPacket packet;
  1435. packet.Add((float) PRHost[rhost_id]->Get_Stats().Get_Pc_Packetloss_Received());
  1436. packet.Add(service_rate);
  1437. packet.Set_Type(PACKETTYPE_KEEPALIVE);
  1438. packet.Set_Id(packet_id);
  1439. packet.Set_Sender_Id(LocalId);
  1440. PRHost[rhost_id]->Add_Packet(packet, RELIABLE_SEND_LIST);
  1441. }
  1442. }
  1443. }
  1444. }
  1445. //-----------------------------------------------------------------------------
  1446. double cConnection::Get_Threshold_Priority(int rhost_id)
  1447. {
  1448. WWASSERT(rhost_id >= 0);
  1449. WWASSERT(PRHost[rhost_id] != NULL);
  1450. return PRHost[rhost_id]->Get_Threshold_Priority();
  1451. }
  1452. //-----------------------------------------------------------------------------
  1453. void cConnection::Set_Max_Acceptable_Packetloss_Pc(double max_packetloss_pc)
  1454. {
  1455. WWASSERT(max_packetloss_pc >= 0 && max_packetloss_pc <= 100);
  1456. //WWDEBUG_SAY(("cConnection::Set_Max_Acceptable_Packetloss_Pc: %5.2f\n",
  1457. // MaxAcceptablePacketlossPc));
  1458. MaxAcceptablePacketlossPc = max_packetloss_pc;
  1459. }
  1460. //-----------------------------------------------------------------------------
  1461. bool cConnection::Demultiplex_R_Or_U_Packet(cPacket * p_packet, int rhost_id)
  1462. {
  1463. WWASSERT(p_packet != NULL);
  1464. WWASSERT(rhost_id >= 0);
  1465. bool is_aborted;
  1466. WWASSERT(PRHost[rhost_id] != NULL);
  1467. if (IsServer) {
  1468. //WWPROFILE("cConnection::Server_Packet_Handler");
  1469. //Server_Packet_Handler(*p_packet, rhost_id);
  1470. WWASSERT(ServerPacketHandler != NULL);
  1471. ServerPacketHandler(*p_packet, rhost_id);
  1472. } else {
  1473. //WWPROFILE("cConnection::Client_Packet_Handler");
  1474. //Client_Packet_Handler(*p_packet);
  1475. WWASSERT(ClientPacketHandler != NULL);
  1476. ClientPacketHandler(*p_packet);
  1477. }
  1478. if (PRHost[rhost_id] == NULL) {
  1479. is_aborted = true;
  1480. } else {
  1481. //WWASSERT(p_packet->Is_Flushed());
  1482. is_aborted = false;
  1483. }
  1484. return is_aborted;
  1485. }
  1486. //-----------------------------------------------------------------------------
  1487. //
  1488. // Service_Read() should be called once per frame on both C & S
  1489. //
  1490. void cConnection::Service_Read()
  1491. {
  1492. //WWDEBUG_SAY(("cConnection::Service_Read\n"));
  1493. WWASSERT(InitDone);
  1494. CombinedStats.StatSample[STAT_ServiceCount]++;
  1495. ThisFrameTimeMs = TIMEGETTIME();
  1496. if (ExtraTimeoutTime && (ThisFrameTimeMs - ExtraTimeoutTimeStarted) > (ExtraTimeoutTime * 2)) {
  1497. ExtraTimeoutTime = 0;
  1498. ExtraTimeoutTimeStarted = 0;
  1499. }
  1500. //
  1501. // Receive as many packets as are available
  1502. //
  1503. //int start_time;
  1504. //start_time = TIMEGETTIME();
  1505. /*
  1506. if (Is_Packet_Latency_Simulation_Active()) {
  1507. Buffer_Packets();
  1508. }
  1509. */
  1510. {
  1511. WWPROFILE("Receive Packets");
  1512. while (Receive_Packet());
  1513. }
  1514. /*
  1515. int time_spent = (int) TIMEGETTIME() - start_time;
  1516. if (time_spent > cNetUtil::Get_Max_Receive_Time_Ms()) {
  1517. WWDEBUG_SAY(("*** WWNET: Too much time spent (%d ms)) receiving packets.\n",
  1518. time_spent));
  1519. }
  1520. */
  1521. if (!CanProcess) {
  1522. return;
  1523. }
  1524. int rhost_id;
  1525. //
  1526. // Process as many reliable packets as are available in sequence
  1527. //
  1528. //start_time = (int) TIMEGETTIME();
  1529. {
  1530. WWPROFILE("Process R Packets");
  1531. for (rhost_id = MinRHost; rhost_id <= MaxRHost; rhost_id++) {
  1532. if (PRHost[rhost_id] != NULL) {
  1533. PRHost[rhost_id]->Compute_List_Max(RELIABLE_RCV_LIST);
  1534. for (SLNode<cPacket> * objnode = PRHost[rhost_id]->Get_Packet_List(RELIABLE_RCV_LIST).Head();
  1535. objnode != NULL;) {
  1536. cPacket * p_packet = objnode->Data();
  1537. WWASSERT(p_packet != NULL);
  1538. objnode = objnode->Next();
  1539. int comparison = p_packet->Get_Id() - PRHost[rhost_id]->Get_Reliable_Packet_Rcv_Id();
  1540. if (comparison < 0) {
  1541. //
  1542. // Duplicate packet, discard
  1543. //
  1544. CombinedStats.StatSample[STAT_DiscardCount]++;
  1545. /*
  1546. WWDEBUG_SAY(("%s removing duplicate reliable packet (id %d)) [ReliablePacketRcvId is %d]\n",
  1547. IsServer ? "Server" : "Client",
  1548. p_packet->Get_Id(),
  1549. PRHost[rhost_id]->Get_Reliable_Packet_Rcv_Id()));
  1550. */
  1551. PRHost[rhost_id]->Get_Packet_List(RELIABLE_RCV_LIST).Remove_Head();
  1552. p_packet->Flush();
  1553. delete p_packet;
  1554. } else if (comparison == 0) {
  1555. /*
  1556. bool need_abort = false;
  1557. switch (p_packet->Get_Type()) {
  1558. case PACKETTYPE_KEEPALIVE:
  1559. case PACKETTYPE_ACCEPT_SC:
  1560. //
  1561. // Don't pass on reliable system packets... they are in
  1562. // the list solely to maintain packet sequencing.
  1563. //
  1564. p_packet->Flush();// is this necessary?
  1565. break;
  1566. case PACKETTYPE_RELIABLE:
  1567. need_abort = Demultiplex_R_Or_U_Packet(p_packet, rhost_id);
  1568. break;
  1569. default:
  1570. DIE;
  1571. }
  1572. if (need_abort) {
  1573. break;
  1574. }
  1575. */
  1576. WWASSERT(p_packet->Get_Type() >= PACKETTYPE_FIRST && p_packet->Get_Type() <= PACKETTYPE_LAST);
  1577. if (p_packet->Get_Type() == PACKETTYPE_RELIABLE) {
  1578. bool abort = Demultiplex_R_Or_U_Packet(p_packet, rhost_id);
  1579. if (abort) {
  1580. break;
  1581. }
  1582. }
  1583. //
  1584. // This may help detect if the packet got deallocated or something bad...
  1585. //
  1586. WWASSERT(p_packet->Get_Type() >= PACKETTYPE_FIRST && p_packet->Get_Type() <= PACKETTYPE_LAST);
  1587. PRHost[rhost_id]->Get_Packet_List(RELIABLE_RCV_LIST).Remove_Head();
  1588. p_packet->Flush();
  1589. delete p_packet;
  1590. PRHost[rhost_id]->Increment_Reliable_Packet_Rcv_Id();
  1591. } else {
  1592. WWASSERT(comparison > 0);
  1593. //
  1594. // We are done... we cannot process the next packet in the list yet.
  1595. //
  1596. break;
  1597. }
  1598. }
  1599. }
  1600. }
  1601. }
  1602. /*
  1603. time_spent = (int) TIMEGETTIME() - start_time;
  1604. if (time_spent > cNetUtil::Get_Max_Receive_Time_Ms()) {
  1605. WWDEBUG_SAY(("*** WWNET: Too much time (%d ms)) spent receiving reliable queued packets.\n",
  1606. time_spent));
  1607. }
  1608. */
  1609. //
  1610. // Process all unreliable packets.
  1611. //
  1612. //start_time = (int) TIMEGETTIME();
  1613. {
  1614. WWPROFILE("Process U Packets");
  1615. for (rhost_id = MinRHost; rhost_id <= MaxRHost; rhost_id++) {
  1616. if (PRHost[rhost_id] != NULL) {
  1617. PRHost[rhost_id]->Compute_List_Max(UNRELIABLE_RCV_LIST);
  1618. //broken PRHost[rhost_id]->Set_List_Packet_Size(UNRELIABLE_RCV_LIST, 0);
  1619. unsigned long list_processing_start = TIMEGETTIME();
  1620. for (SLNode<cPacket> * objnode = PRHost[rhost_id]->Get_Packet_List(UNRELIABLE_RCV_LIST).Head();
  1621. objnode != NULL; objnode = objnode->Next()) {
  1622. cPacket * p_packet = objnode->Data();
  1623. WWASSERT(p_packet != NULL);
  1624. WWASSERT(p_packet->Get_Id() >= 0);
  1625. if (p_packet->Get_Id() < PRHost[rhost_id]->Get_Unreliable_Packet_Rcv_Id()) {
  1626. //
  1627. // Duplicate packet, discard
  1628. //
  1629. CombinedStats.StatSample[STAT_DiscardCount]++;
  1630. /*
  1631. WWDEBUG_SAY(("Ignoring duplicate unreliable packet (id %d)) [UnreliablePacketRcvId is %d]\n",
  1632. p_packet->Id, PRHost[rhost_id]->UnreliablePacketRcvId));
  1633. */
  1634. } else {
  1635. //WWASSERT(p_packet->Get_Type() == (BYTE) PACKETTYPE_UNRELIABLE);
  1636. {
  1637. //WWPROFILE("Demultiplex_R_Or_U_Packet");
  1638. bool abort = Demultiplex_R_Or_U_Packet(p_packet, rhost_id);
  1639. if (abort) {
  1640. break;
  1641. }
  1642. }
  1643. PRHost[rhost_id]->Set_Unreliable_Packet_Rcv_Id(p_packet->Get_Id());
  1644. }
  1645. }
  1646. if (PRHost[rhost_id] != NULL) {
  1647. PRHost[rhost_id]->Set_List_Processing_Time(UNRELIABLE_RCV_LIST, TIMEGETTIME() - list_processing_start);
  1648. }
  1649. if (PRHost[rhost_id] != NULL) {
  1650. //
  1651. // Destroy list
  1652. //
  1653. for (SLNode<cPacket> * objnode = PRHost[rhost_id]->Get_Packet_List(UNRELIABLE_RCV_LIST).Head();
  1654. objnode != NULL; objnode = objnode->Next()) {
  1655. cPacket * p_packet = objnode->Data();
  1656. p_packet->Flush();
  1657. WWASSERT(p_packet != NULL);
  1658. delete p_packet;
  1659. }
  1660. PRHost[rhost_id]->Get_Packet_List(UNRELIABLE_RCV_LIST).Remove_All();
  1661. }
  1662. }
  1663. }
  1664. }
  1665. /*
  1666. time_spent = (int) TIMEGETTIME() - start_time;
  1667. if (time_spent > cNetUtil::Get_Max_Receive_Time_Ms()) {
  1668. WWDEBUG_SAY(("*** WWNET: Too much time (%d ms)) spent receiving unreliable queued packets.\n",
  1669. time_spent));
  1670. }
  1671. */
  1672. if (IsServer) {
  1673. //
  1674. // Notify Server of recommended evictions
  1675. //
  1676. for (rhost_id = MinRHost; rhost_id <= MaxRHost; rhost_id++) {
  1677. if (PRHost[rhost_id] != NULL && PRHost[rhost_id]->Must_Evict()) {
  1678. PRHost[rhost_id]->Set_Must_Evict(false);
  1679. //Eviction_Handler(rhost_id);
  1680. WWASSERT(EvictionHandler != NULL);
  1681. EvictionHandler(rhost_id);
  1682. }
  1683. }
  1684. }
  1685. }
  1686. //-----------------------------------------------------------------------------
  1687. void cConnection::Set_Bandwidth_Budget_Out(ULONG bw_budget)
  1688. {
  1689. //WWASSERT(bw_budget >= 0);
  1690. BandwidthBudgetOut = bw_budget;
  1691. //
  1692. // If we only have very limited bandwidth available then it's silly to have huge send buffers since that can mask
  1693. // problems with outgoing packets until it's too late to recover. ST - 10/17/2001 12:51PM
  1694. //
  1695. if (!cSinglePlayerData::Is_Single_Player()) {
  1696. if (Sock != INVALID_SOCKET) {
  1697. // make the buffers big enough for 3 seconds of data.
  1698. int new_buffer_size = (bw_budget / 8) * 3;
  1699. new_buffer_size = min(new_buffer_size, 250000);
  1700. cNetUtil::Set_Socket_Buffer_Sizes(Sock, new_buffer_size);
  1701. }
  1702. }
  1703. }
  1704. //-----------------------------------------------------------------------------
  1705. void cConnection::Clear_Resend_Counts()
  1706. {
  1707. //WWDEBUG_SAY(("cConnection::Clear_Resend_Counts()\n"));
  1708. SLNode<cPacket> * objnode;
  1709. cPacket * p_packet;
  1710. for (int rhost_id = MinRHost; rhost_id <= MaxRHost; rhost_id++) {
  1711. if (PRHost[rhost_id] != NULL) {
  1712. for (objnode = PRHost[rhost_id]->Get_Packet_List(RELIABLE_SEND_LIST).Head();
  1713. objnode != NULL; objnode = objnode->Next()) {
  1714. p_packet = objnode->Data();
  1715. WWASSERT(p_packet != NULL);
  1716. if (p_packet->Get_Resend_Count() > 0) {
  1717. p_packet->Clear_Resend_Count();
  1718. }
  1719. }
  1720. }
  1721. }
  1722. }
  1723. //-----------------------------------------------------------------------------
  1724. cRemoteHost * cConnection::Get_Remote_Host(int rhost)
  1725. {
  1726. WWASSERT(rhost >= MinRHost && rhost <= MaxRHost);
  1727. /*
  1728. if (rhost < MinRHost || rhost > MaxRHost) {
  1729. WWDEBUG_SAY((">>> %d: %d,%d IS:%d\n", rhost, MinRHost, MaxRHost,
  1730. IsServer));
  1731. DIE;
  1732. }
  1733. */
  1734. return PRHost[rhost];
  1735. }
  1736. //-----------------------------------------------------------------------------
  1737. //
  1738. // Service_Send() should be called once per frame on both C & S
  1739. //
  1740. void cConnection::Service_Send(bool is_urgent)
  1741. {
  1742. WWASSERT(InitDone);
  1743. ServiceCount++;
  1744. //
  1745. // Set TargetBps for all rhosts
  1746. //
  1747. int num_real_remote_hosts = NumRHosts;
  1748. if (IsServer && !IsDedicatedServer) {
  1749. num_real_remote_hosts--;
  1750. if (PRHost[1] != NULL) {
  1751. PRHost[1]->Set_Target_Bps(10000000);//TSS - won't this just be overwritten below???
  1752. }
  1753. }
  1754. if (num_real_remote_hosts > 0) { // necessary?
  1755. if (IsServer && BandwidthBalancer.IsEnabled) {
  1756. BandwidthBalancer.Adjust(this, IsDedicatedServer);
  1757. } else {
  1758. ULONG bps_per_rhost = (ULONG) (BandwidthBudgetOut / (float) num_real_remote_hosts);
  1759. for (int rhost_id = MinRHost; rhost_id <= MaxRHost; rhost_id++) {
  1760. if (PRHost[rhost_id] != NULL) {
  1761. //
  1762. // Do not exceed the max bps set by the client.
  1763. //
  1764. int bps = bps_per_rhost;
  1765. int max_bps = PRHost[rhost_id]->Get_Maximum_Bps();
  1766. if (max_bps != 0 && max_bps < bps) {
  1767. bps = max_bps;
  1768. }
  1769. PRHost[rhost_id]->Set_Target_Bps(bps);
  1770. //WWDEBUG_SAY(("Compressed bandwidth out to client = %d bps\n", PacketManager.Get_Compressed_Bandwidth_Out(&(PRHost[rhost_id]->Get_Address()))));
  1771. }
  1772. }
  1773. }
  1774. }
  1775. int rhost_id;
  1776. //
  1777. // Reliable sends and resends
  1778. //
  1779. bool any_bad = false;
  1780. for (rhost_id = MinRHost; rhost_id <= MaxRHost; rhost_id++) {
  1781. cRemoteHost * p_rhost = PRHost[rhost_id];
  1782. if (p_rhost != NULL) {
  1783. p_rhost->Compute_List_Max(RELIABLE_SEND_LIST);
  1784. /*
  1785. //
  1786. // Send any reliable combined-packet
  1787. //
  1788. cPacket * & p_packet_rs = p_rhost->Get_P_Comb_Rel_Packet();
  1789. if (p_packet_rs != NULL) {
  1790. Internal_Send_Packet_To_Individual(*p_packet_rs, rhost_id, PACKETTYPE_RELIABLE);
  1791. p_packet_rs->Flush();
  1792. delete p_packet_rs;
  1793. p_packet_rs = NULL;
  1794. }
  1795. */
  1796. int resent_packets = 0;
  1797. //
  1798. // Send any appropriate reliable queued packets
  1799. //
  1800. for (SLNode<cPacket> * objnode = p_rhost->Get_Packet_List(RELIABLE_SEND_LIST).Head();
  1801. objnode != NULL;) {
  1802. cPacket * p_packet = objnode->Data();
  1803. objnode = objnode->Next();
  1804. WWASSERT(p_packet != NULL);
  1805. if (p_packet->Get_Resend_Count() > 1) {
  1806. resent_packets++;
  1807. if (ThisFrameTimeMs - p_packet->Get_First_Send_Time() > 5000) {
  1808. any_bad = true;
  1809. }
  1810. }
  1811. if (Is_Time_To_Resend_Packet_To_Remote_Host(p_packet, p_rhost)) {
  1812. //
  1813. // This will hold true for new packets because Sendtime is set high negative
  1814. //
  1815. //
  1816. // Resends are reliable
  1817. //
  1818. p_rhost->Get_Stats().StatSample[STAT_RPktSent]++;
  1819. p_rhost->Get_Stats().StatSample[STAT_RByteSent] += p_packet->Get_Compressed_Size_Bytes();
  1820. //
  1821. // Send!
  1822. //
  1823. //if (p_packet->Get_Resend_Count() > 0) {
  1824. //if (p_packet->Get_Resend_Count() > 0 && p_packet->Get_Resend_Count() % 10 == 0) {
  1825. //WWDEBUG_SAY(("Resending packet %d to %s after %dms. Resent %d times\n", p_packet->Get_Id(), Addr_As_String(&(p_rhost->Get_Address())), ThisFrameTimeMs - p_packet->Get_First_Send_Time(), p_packet->Get_Resend_Count()));
  1826. //}
  1827. Send_Packet_To_Address(*p_packet, &(p_rhost->Get_Address()));
  1828. p_packet->Set_Send_Time();
  1829. /*
  1830. if (p_rhost->Is_Ready_For_All_Data()) {
  1831. p_packet->Increment_Resend_Count();
  1832. }
  1833. */
  1834. p_packet->Increment_Resend_Count();
  1835. if (p_packet->Get_Resend_Count() > 0) {
  1836. p_rhost->Get_Stats().StatSample[STAT_ResendCount]++;
  1837. p_rhost->Increment_Resends();
  1838. }
  1839. // In a LAN game, if resend time is low. Say 4 ms, and we only resend 50 times, thats 200ms total before the game
  1840. // craps out. Any kind of network or machine hiccup could cause the game to quit. This is an experimant to see if that's
  1841. // what is causing our disconnect at game start.
  1842. //
  1843. // As it happens, the main thread can get lost loading textures for several seconds at the end of a game load
  1844. // so some sort of overall timeout is neccessary.
  1845. //
  1846. // TSS 09/24/01 - new loading lags worse than 10 seconds... bumping it up
  1847. // to 20s.
  1848. //
  1849. // ST 1/24/2002 2:16PM. Can't time out players when we are loading or we get DataSafe access from the wrong
  1850. // thread.
  1851. //
  1852. if (Is_Packet_Too_Old(p_packet, p_rhost) && CanProcess) {
  1853. WWDEBUG_SAY(("*** WWNET: Connection timed out - assuming connection to rhost %d is broken.\n", rhost_id));
  1854. WWDEBUG_SAY(("*** WWNET: ThisFrameTimeMs - p_packet->Get_First_Send_Time() == %d\n", ThisFrameTimeMs - p_packet->Get_First_Send_Time()));
  1855. //
  1856. // Define the connection as broken
  1857. //
  1858. WWDEBUG_SAY(("*** Breaking connection on packet %d ... internal ping = %d/%d/%d ms, ResendTimeoutMs = %d ms\n",
  1859. p_packet->Get_Id(),
  1860. p_rhost->Get_Min_Internal_Pingtime_Ms(),
  1861. p_rhost->Get_Average_Internal_Pingtime_Ms(),
  1862. p_rhost->Get_Max_Internal_Pingtime_Ms(),
  1863. p_rhost->Get_Resend_Timeout_Ms()));
  1864. Destroy_Connection(rhost_id);
  1865. //WWDEBUG_SAY(("*** WWNET: Exceeded maximum resends (%d)) - assuming connection to rhost %d is broken.\n",
  1866. // cNetUtil::MAX_RESENDS, rhost_id));
  1867. if (IsServer) {
  1868. //Server_Broken_Connection_Handler(rhost_id); // Inform app level of this disaster
  1869. WWASSERT(ServerBrokenConnectionHandler != NULL);
  1870. ServerBrokenConnectionHandler(rhost_id);
  1871. } else {
  1872. //Client_Broken_Connection_Handler(); // Inform app level of this disaster
  1873. WWASSERT(ClientBrokenConnectionHandler != NULL);
  1874. ClientBrokenConnectionHandler();
  1875. }
  1876. break;
  1877. }
  1878. }
  1879. }
  1880. // Keep track of how many packets in the queue are waiting on late acks.
  1881. p_rhost->Set_Total_Resent_Packets_In_Queue(resent_packets);
  1882. }
  1883. }
  1884. IsBadConnection = any_bad;
  1885. //
  1886. // Unreliable sends and resends
  1887. //
  1888. for (rhost_id = MinRHost; rhost_id <= MaxRHost; rhost_id++) {
  1889. cRemoteHost * p_rhost = PRHost[rhost_id];
  1890. if (p_rhost != NULL) {
  1891. p_rhost->Compute_List_Max(UNRELIABLE_SEND_LIST);
  1892. /*
  1893. //
  1894. // Send any unreliable combined-packet
  1895. //
  1896. cPacket * & p_packet_u = p_rhost->Get_P_Comb_Unrel_Packet();
  1897. if (p_packet_u != NULL) {
  1898. Internal_Send_Packet_To_Individual(*p_packet_u, rhost_id, PACKETTYPE_UNRELIABLE);
  1899. p_packet_u->Flush();
  1900. delete p_packet_u;
  1901. p_packet_u = NULL;
  1902. }
  1903. */
  1904. //
  1905. // Send any appropriate queued packets
  1906. //
  1907. for (SLNode<cPacket> * objnode = p_rhost->Get_Packet_List(UNRELIABLE_SEND_LIST).Head();
  1908. objnode != NULL; objnode = objnode->Next()) {
  1909. cPacket * p_packet = objnode->Data();
  1910. WWASSERT(p_packet != NULL);
  1911. p_rhost->Get_Stats().StatSample[STAT_UPktSent]++;
  1912. p_rhost->Get_Stats().StatSample[STAT_UByteSent] += p_packet->Get_Compressed_Size_Bytes();
  1913. //
  1914. // Send!
  1915. //
  1916. Send_Packet_To_Address(*p_packet, &(p_rhost->Get_Address()));
  1917. }
  1918. // destroy all
  1919. for (objnode = p_rhost->Get_Packet_List(UNRELIABLE_SEND_LIST).Head();
  1920. objnode != NULL; objnode = objnode->Next()) {
  1921. cPacket * p_packet = objnode->Data();
  1922. WWASSERT(p_packet != NULL);
  1923. p_packet->Flush();
  1924. delete p_packet;
  1925. }
  1926. p_rhost->Get_Packet_List(UNRELIABLE_SEND_LIST).Remove_All();
  1927. }
  1928. }
  1929. //
  1930. // Send keepalives if necessary
  1931. //
  1932. Send_Keepalives();
  1933. //
  1934. // Monkey with the stats for a while
  1935. //
  1936. float sample_time_ms = ThisFrameTimeMs - CombinedStats.Get_Sample_Start_Time();
  1937. if (IsServer && NumRHosts > 0 &&
  1938. sample_time_ms > cNetUtil::NETSTATS_SAMPLE_TIME_MS) {
  1939. for (int statistic = 0; statistic < STAT_COUNT; statistic++) {
  1940. for (rhost_id = MinRHost; rhost_id <= MaxRHost; rhost_id++) {
  1941. if (PRHost[rhost_id] != NULL) {
  1942. CombinedStats.StatSample[statistic] += PRHost[rhost_id]->Get_Stats().StatSnapshot[statistic];
  1943. }
  1944. }
  1945. AveragedStats.StatSample[statistic] = cMathUtil::Round(
  1946. CombinedStats.StatSample[statistic] / (double) NumRHosts);
  1947. }
  1948. AveragedStats.Update_If_Sample_Done(ThisFrameTimeMs);
  1949. }
  1950. CombinedStats.Update_If_Sample_Done(ThisFrameTimeMs);
  1951. for (rhost_id = MinRHost; rhost_id <= MaxRHost; rhost_id++) {
  1952. if (PRHost[rhost_id] != NULL) {
  1953. bool is_updated = PRHost[rhost_id]->Get_Stats().Update_If_Sample_Done(
  1954. ThisFrameTimeMs, false);
  1955. if (is_updated) {
  1956. PRHost[rhost_id]->Adjust_Resend_Timeout();
  1957. PRHost[rhost_id]->Adjust_Flow_If_Necessary(sample_time_ms);
  1958. }
  1959. }
  1960. }
  1961. //
  1962. // Service the packet manager
  1963. //
  1964. PacketManager.Flush(is_urgent);
  1965. }
  1966. //-----------------------------------------------------------------------------
  1967. void cConnection::Install_Accept_Handler(Accept_Handler handler)
  1968. {
  1969. WWASSERT(handler != NULL);
  1970. AcceptHandler = handler;
  1971. }
  1972. //-----------------------------------------------------------------------------
  1973. void cConnection::Install_Refusal_Handler(Refusal_Handler handler)
  1974. {
  1975. WWASSERT(handler != NULL);
  1976. RefusalHandler = handler;
  1977. }
  1978. //-----------------------------------------------------------------------------
  1979. void cConnection::Install_Server_Broken_Connection_Handler(Server_Broken_Connection_Handler handler)
  1980. {
  1981. WWASSERT(handler != NULL);
  1982. ServerBrokenConnectionHandler = handler;
  1983. }
  1984. //-----------------------------------------------------------------------------
  1985. void cConnection::Install_Client_Broken_Connection_Handler(Client_Broken_Connection_Handler handler)
  1986. {
  1987. WWASSERT(handler != NULL);
  1988. ClientBrokenConnectionHandler = handler;
  1989. }
  1990. //-----------------------------------------------------------------------------
  1991. void cConnection::Install_Eviction_Handler(Eviction_Handler handler)
  1992. {
  1993. WWASSERT(handler != NULL);
  1994. EvictionHandler = handler;
  1995. }
  1996. //-----------------------------------------------------------------------------
  1997. void cConnection::Install_Conn_Handler(Conn_Handler handler)
  1998. {
  1999. WWASSERT(handler != NULL);
  2000. ConnHandler = handler;
  2001. }
  2002. //-----------------------------------------------------------------------------
  2003. void cConnection::Install_Application_Acceptance_Handler(Application_Acceptance_Handler handler)
  2004. {
  2005. WWASSERT(handler != NULL);
  2006. ApplicationAcceptanceHandler = handler;
  2007. }
  2008. //-----------------------------------------------------------------------------
  2009. void cConnection::Install_Server_Packet_Handler(Server_Packet_Handler handler)
  2010. {
  2011. WWASSERT(handler != NULL);
  2012. ServerPacketHandler = handler;
  2013. }
  2014. //-----------------------------------------------------------------------------
  2015. void cConnection::Install_Client_Packet_Handler(Client_Packet_Handler handler)
  2016. {
  2017. WWASSERT(handler != NULL);
  2018. ClientPacketHandler = handler;
  2019. }
  2020. //-----------------------------------------------------------------------------
  2021. void cConnection::Set_Rhost_Is_In_Game(int id, bool state)
  2022. {
  2023. if (IsServer) {
  2024. for (int i = MinRHost; i <= MaxRHost; i++) {
  2025. if (PRHost[i] && PRHost[i]->Get_Id() == id) {
  2026. PRHost[i]->Set_Is_Loading(!state);
  2027. break;
  2028. }
  2029. }
  2030. }
  2031. }
  2032. void cConnection::Set_Rhost_Expect_Packet_Flood(int id, bool state)
  2033. {
  2034. if (IsServer) {
  2035. for (int i = MinRHost; i <= MaxRHost; i++) {
  2036. if (PRHost[i] && PRHost[i]->Get_Id() == id) {
  2037. PRHost[i]->Set_Flood(state);
  2038. break;
  2039. }
  2040. }
  2041. }
  2042. }
  2043. //-----------------------------------------------------------------------------
  2044. bool cConnection::Is_Time_To_Resend_Packet_To_Remote_Host(const cPacket *packet, cRemoteHost *rhost)
  2045. {
  2046. WWASSERT(ThisFrameTimeMs >= 0);
  2047. WWASSERT(packet);
  2048. WWASSERT(rhost);
  2049. if (!packet || !rhost) {
  2050. return(false);
  2051. }
  2052. unsigned long last_send_time = packet->Get_Send_Time();
  2053. if (last_send_time == cPacket::Get_Default_Send_Time()) {
  2054. return(true);
  2055. }
  2056. //
  2057. // Basically this slows down the resend rate each time we resend
  2058. //
  2059. float resend_timeout = (float) rhost->Get_Resend_Timeout_Ms();
  2060. WWASSERT(resend_timeout != 0);
  2061. float resend_count = (float) packet->Get_Resend_Count();
  2062. float timeout_multiplier = 0.5f;
  2063. float total_timeout = resend_timeout;
  2064. if (IsServer) {
  2065. bool loading = rhost->Get_Is_Loading();
  2066. //
  2067. // Slow down resend rate if remote host is loading. He might not be able to respond anyway.
  2068. //
  2069. if (loading) {
  2070. timeout_multiplier = timeout_multiplier * 2.0f;
  2071. }
  2072. }
  2073. total_timeout = resend_timeout + (resend_timeout * resend_count * timeout_multiplier);
  2074. //
  2075. // Max resend timeout of 3 secs.
  2076. //
  2077. total_timeout = min(total_timeout, 3000.0f);
  2078. if (ThisFrameTimeMs - packet->Get_Send_Time() >= (unsigned long)total_timeout) {
  2079. //WWDEBUG_SAY(("Time to resend packet %d, age = %d, timeout = %d, resend count = %d\n", packet->Get_Id(), (int)(ThisFrameTimeMs - packet->Get_Send_Time()), (int)total_timeout, packet->Get_Resend_Count()));
  2080. return(true);
  2081. }
  2082. return(false);
  2083. }
  2084. //-----------------------------------------------------------------------------
  2085. bool cConnection::Is_Packet_Too_Old(const cPacket *packet, cRemoteHost *rhost)
  2086. {
  2087. WWASSERT(ThisFrameTimeMs >= 0);
  2088. WWASSERT(packet);
  2089. WWASSERT(rhost);
  2090. if (!packet || !rhost) {
  2091. return(false);
  2092. }
  2093. if (packet->Get_Send_Time() == cPacket::Get_Default_Send_Time()) {
  2094. return(false);
  2095. }
  2096. unsigned long timeout = 0;
  2097. if (IsServer) {
  2098. timeout = cNetUtil::SERVER_CONNECTION_LOSS_TIMEOUT;
  2099. //
  2100. // Server needs to allow more time for players entering the game.
  2101. //
  2102. if (rhost->Get_Is_Loading() || rhost->Was_Recently_Loading(ThisFrameTimeMs)) {
  2103. timeout += cNetUtil::SERVER_CONNECTION_LOSS_TIMEOUT_LOADING_ALLOWANCE;
  2104. } else {
  2105. int num_remote_hosts = Get_Num_RHosts();
  2106. if (!IsDedicatedServer) {
  2107. num_remote_hosts--;
  2108. }
  2109. if (num_remote_hosts < 1) {
  2110. timeout += cNetUtil::SERVER_CONNECTION_LOSS_TIMEOUT_LOADING_ALLOWANCE;
  2111. }
  2112. }
  2113. } else {
  2114. //
  2115. // Client just uses a constant value.
  2116. //
  2117. timeout = cNetUtil::CLIENT_CONNECTION_LOSS_TIMEOUT;
  2118. //
  2119. // Modified when server is potentially loading.
  2120. //
  2121. timeout += ExtraTimeoutTime;
  2122. }
  2123. if (ThisFrameTimeMs > packet->Get_First_Send_Time()) {
  2124. if (ThisFrameTimeMs - packet->Get_First_Send_Time() > timeout) {
  2125. return(true);
  2126. }
  2127. }
  2128. return(false);
  2129. }
  2130. //-----------------------------------------------------------------------------
  2131. void cConnection::Allow_Extra_Timeout_For_Loading(void)
  2132. {
  2133. ExtraTimeoutTime = cNetUtil::SERVER_CONNECTION_LOSS_TIMEOUT_LOADING_ALLOWANCE;
  2134. ExtraTimeoutTimeStarted = TIMEGETTIME();
  2135. }
  2136. #ifdef WWDEBUG
  2137. void cConnection::Set_Latency(int low, int high)
  2138. {
  2139. LatencyAddLow = low;
  2140. LatencyAddHigh = high;
  2141. CurrentLatencyAdd = LatencyAddLow + ((LatencyAddHigh - LatencyAddLow) / 2);
  2142. }
  2143. void cConnection::Get_Latency(int &low, int &high, int &current)
  2144. {
  2145. low = LatencyAddLow;
  2146. high = LatencyAddHigh;
  2147. current = CurrentLatencyAdd;
  2148. }
  2149. #endif //WWDEBUG
  2150. //KEEPALIVE_TIMEOUT_MS(cNetUtil::Get_Default_Keepalive_Timeout_Ms()),
  2151. //MAX_RESENDS(cNetUtil::Get_Default_Max_Resends()),
  2152. //MULTI_SENDS(cNetUtil::Get_Default_Multi_Sends()), //if (!Application_Acceptance_Handler(packet)) {