Clone of Bael'Zharon's Respite @ https://github.com/boardwalk/bzr

Session.cpp 25KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882
  1. /*
  2. * Bael'Zharon's Respite
  3. * Copyright (C) 2014 Daniel Skorupski
  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 2 of the License, or
  8. * (at your option) any later version.
  9. * This program is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. * GNU General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU General Public License along
  15. * with this program; if not, write to the Free Software Foundation, Inc.,
  16. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  17. */
  18. #include "net/Session.h"
  19. #include "net/SessionManager.h"
  20. #include "net/Socket.h"
  21. #include "BinReader.h"
  22. #include "BinWriter.h"
  23. #include "Core.h"
  24. #include "Log.h"
  25. #include <algorithm>
  26. #ifndef _WIN32
  27. #include <arpa/inet.h>
  28. #endif
  29. enum OptionalHeaderFlags
  30. {
  31. kDisposable = 0x00000001, // this header may be removed from a retransmission
  32. kExclusive = 0x00000002, // a packet with this header has its own sequence number
  33. kNotConn = 0x00000004, // this header is sent before connect request/reply handshake completes
  34. kTimeSensitive = 0x00000008,
  35. kShouldPiggyBack = 0x00000010, // this header should ride along in a packet with others headers and content
  36. kHighPriority = 0x00000020,
  37. kCountsAsTouch = 0x00000040,
  38. kEncrypted = 0x20000000, // a packet with this header has its checksum encrypted
  39. kSigned = 0x40000000
  40. };
  41. enum PacketFlags
  42. {
  43. kRetransmission = 0x00000001,
  44. kEncryptedChecksum = 0x00000002,
  45. kBlobFragments = 0x00000004,
  46. kServerSwitch = 0x00000100, // CServerSwitchStruct (60, kHighPriority|kCountsAsTouch)
  47. kUnknown1 = 0x00000200, // CLogonRouteHeader (sockaddr_in) (7, kDisposable|kExclusive|kNotConn)
  48. kUnknown2 = 0x00000400, // EmptyHeader (7, kDisposable|kExclusive|kNotConn)
  49. kReferral = 0x00000800, // CReferralStruct (40000062, kExclusive|kHighPriority|kCountsAsTouch|kSigned)
  50. kRequestRetransmit = 0x00001000, // SeqIDList (33, kDisposable|kExclusive|kShouldPiggyBack|kHighPriority)
  51. kRejectRetransmit = 0x00002000, // SeqIDList (33, kDisposable|kExclusive|kShouldPiggyBack|kHighPriority)
  52. kAckSequence = 0x00004000, // CPakHeader (unsigned long) (1, kDisposable)
  53. kDisconnect = 0x00008000, // EmptyHeader (3, kDisposable|kExclusive)
  54. kLogon = 0x00010000, // CLogonHeader (?)
  55. kReferred = 0x00020000, // uint64_t (7, kDisposable|kExclusive|kNotConn)
  56. kConnectRequest = 0x00040000, // CConnectHeader (?)
  57. kConnectResponse = 0x00080000, // uint64_t (20000007, kDisposable|kExclusive|kNotConn|kEncrypted)
  58. kNetError1 = 0x00100000, // PackObjHeader<NetError> (7, kDisposable|kExclusive|kNotConn)
  59. kNetError2 = 0x00200000, // PackObjHeader<NetError> (2, kExclusive)
  60. kCICMDCommand = 0x00400000, // CICMDCommandStruct (7, kDisposable|kExclusive|kNotConn)
  61. kTimeSync = 0x01000000, // CTimeSyncHeader (?)
  62. kEchoRequest = 0x02000000, // CEchoRequestHeader (?)
  63. kEchoResponse = 0x04000000, // CEchoResponseHeader (?)
  64. kFlow = 0x08000000 // CFlowStruct (10, kShouldPiggyBack)
  65. };
  66. enum class ServerSwitchType
  67. {
  68. WorldSwitch,
  69. LogonSwitch,
  70. };
  71. static const chrono::milliseconds kLogonPacketDelay(300);
  72. static const chrono::milliseconds kReferredPacketDelay(300);
  73. static const chrono::milliseconds kConnectResponsePacketDelay(300);
  74. static const chrono::milliseconds kPingPacketDelay(2000);
  75. static const chrono::milliseconds kMissingPacketDelay(300);
  76. static const size_t kMaxPeriodicSent = 10;
  77. static ostream& operator<<(ostream& os, const PacketHeader& header)
  78. {
  79. os << "sequence=" << hexn(header.sequence)
  80. << " flags=" << hexn(header.flags)
  81. << " checksum=" << hexn(header.checksum)
  82. << " netId=" << hexn(header.netId)
  83. << " time=" << hexn(header.time)
  84. << " size=" << hexn(header.size)
  85. << " iteration=" << hexn(header.iteration);
  86. return os;
  87. }
  88. static ostream& operator<<(ostream& os, const FragmentHeader& header)
  89. {
  90. os << "id=" << hexn(header.id)
  91. << " count=" << hexn(header.count)
  92. << " size=" << hexn(header.size)
  93. << " index=" << hexn(header.index)
  94. << " queueId=" << hexn(header.queueId);
  95. return os;
  96. }
  97. static uint32_t checksum(const void* data, size_t size)
  98. {
  99. uint32_t result = static_cast<uint32_t>(size) << 16;
  100. for(size_t i = 0; i < size / 4; i++)
  101. {
  102. result += static_cast<const uint32_t*>(data)[i];
  103. }
  104. int shift = 24;
  105. for(size_t i = (size / 4) * 4; i < size; i++)
  106. {
  107. result += static_cast<const uint8_t*>(data)[i] << shift;
  108. shift -= 8;
  109. }
  110. return result;
  111. }
  112. static uint32_t checksumHeader(const PacketHeader& header)
  113. {
  114. PacketHeader& header_nc = const_cast<PacketHeader&>(header);
  115. uint32_t origChecksum = header.checksum;
  116. header_nc.checksum = 0xBADD70DD;
  117. uint32_t result = checksum(&header, sizeof(PacketHeader));
  118. header_nc.checksum = origChecksum;
  119. return result;
  120. }
  121. static uint32_t checksumContent(const PacketHeader& header, const void* data)
  122. {
  123. if(header.flags & kBlobFragments)
  124. {
  125. BinReader reader(data, header.size);
  126. if(header.flags & kServerSwitch)
  127. {
  128. reader.readRaw(8);
  129. }
  130. if(header.flags & kRequestRetransmit)
  131. {
  132. uint32_t nseq = reader.readInt();
  133. reader.readRaw(nseq * sizeof(uint32_t));
  134. }
  135. if(header.flags & kRejectRetransmit)
  136. {
  137. uint32_t nseq = reader.readInt();
  138. reader.readRaw(nseq * sizeof(uint32_t));
  139. }
  140. if(header.flags & kAckSequence)
  141. {
  142. reader.readRaw(4);
  143. }
  144. if(header.flags & kCICMDCommand)
  145. {
  146. reader.readRaw(8);
  147. }
  148. if(header.flags & kTimeSync)
  149. {
  150. reader.readRaw(8);
  151. }
  152. if(header.flags & kEchoRequest)
  153. {
  154. reader.readRaw(4);
  155. }
  156. if(header.flags & kEchoResponse)
  157. {
  158. reader.readRaw(8);
  159. }
  160. if(header.flags & kFlow)
  161. {
  162. reader.readRaw(6);
  163. }
  164. uint32_t result = checksum(data, reader.position());
  165. while(reader.remaining() != 0)
  166. {
  167. const FragmentHeader* fragment = reader.readPointer<FragmentHeader>();
  168. reader.readRaw(fragment->size - sizeof(FragmentHeader));
  169. result += checksum(fragment, fragment->size);
  170. }
  171. assert(reader.remaining() == 0);
  172. return result;
  173. }
  174. return checksum(data, header.size);
  175. }
  176. static uint32_t checksumPacket(const Packet& packet, ChecksumXorGenerator& xorGen)
  177. {
  178. uint32_t xorVal = (packet.header.flags & kEncryptedChecksum) ? xorGen.get(packet.header.sequence) : 0;
  179. return checksumHeader(packet.header) + (checksumContent(packet.header, packet.payload) ^ xorVal);
  180. }
  181. Session::Session(SessionManager& manager,
  182. Address address,
  183. string accountName,
  184. string accountKey) :
  185. manager_(manager),
  186. address_(address),
  187. state_(State::kLogon),
  188. sessionBegin_(net_clock::now()),
  189. nextPeriodic_(sessionBegin_),
  190. numPeriodicSent_(0),
  191. accountName_(move(accountName)),
  192. accountKey_(move(accountKey)),
  193. blobId_(0)
  194. {
  195. LOG(Net, Info) << address_ << " logon session created\n";
  196. }
  197. Session::Session(SessionManager& manager,
  198. Address address,
  199. uint64_t cookie) :
  200. manager_(manager),
  201. address_(address),
  202. state_(State::kReferred),
  203. sessionBegin_(net_clock::now()),
  204. nextPeriodic_(sessionBegin_),
  205. numPeriodicSent_(0),
  206. cookie_(cookie),
  207. blobId_(0)
  208. {
  209. LOG(Net, Info) << address_ << " referred session created\n";
  210. }
  211. Session::~Session()
  212. {
  213. LOG(Net, Info) << address_ << " destroyed\n";
  214. }
  215. void Session::handle(const Packet& packet)
  216. {
  217. uint32_t calcChecksum = checksumPacket(packet, serverXorGen_);
  218. if(packet.header.checksum != calcChecksum)
  219. {
  220. LOG(Net, Warn) << address_ << " dropping packet, calc checksum is " << hexn(calcChecksum) << ", packet has " << hexn(packet.header.checksum) << "\n";
  221. return;
  222. }
  223. LOG(Net, Debug) << address_ << " received packet, " << packet.header << "\n";
  224. BinReader reader(packet.payload, packet.header.size);
  225. if(state_ == State::kConnectResponse)
  226. {
  227. state_ = State::kConnected;
  228. nextPeriodic_ = net_clock::now() + kPingPacketDelay;
  229. numPeriodicSent_ = 0;
  230. LOG(Net, Info) << address_ << " transitioned to connected\n";
  231. }
  232. if(state_ == State::kLogon || state_ == State::kReferred)
  233. {
  234. // TODO Handle kNetError1 here
  235. if(packet.header.flags != kConnectRequest)
  236. {
  237. LOG(Net, Warn) << address_ << " dropping packet, flags should be " << hexn(static_cast<uint32_t>(kConnectRequest)) << ", packet has " << hexn(packet.header.flags) << "\n";
  238. return;
  239. }
  240. handleConnect(reader, packet.header);
  241. state_ = State::kConnectResponse;
  242. numPeriodicSent_ = 0;
  243. sendConnectResponse();
  244. }
  245. else if(state_ == State::kConnected)
  246. {
  247. if(packet.header.flags != kAckSequence) // AckSequence alone does not get it's own sequence
  248. {
  249. if(packet.header.sequence <= serverSequence_ || serverPackets_.find(packet.header.sequence) != serverPackets_.end())
  250. {
  251. LOG(Net, Warn) << address_ << " dropping packet, already received sequence " << packet.header.sequence << "\n";
  252. return;
  253. }
  254. }
  255. if(packet.header.netId != serverNetId_)
  256. {
  257. LOG(Net, Warn) << address_ << " dropping packet, server net id is " << serverNetId_ << ", packet has " << packet.header.netId << "\n";
  258. return;
  259. }
  260. if(packet.header.iteration != iteration_)
  261. {
  262. LOG(Net, Warn) << address_ << " dropping packet, iteration is " << iteration_ << ", packet has " << packet.header.iteration << "\n";
  263. return;
  264. }
  265. // record that we've received the packet
  266. serverPackets_.insert(packet.header.sequence);
  267. advanceServerSequence();
  268. // record that we've received some bytes
  269. lastFlowBytes_ += static_cast<uint32_t>(sizeof(PacketHeader) + packet.header.size);
  270. uint32_t flags = packet.header.flags & ~(kRetransmission | kEncryptedChecksum);
  271. if(flags == kServerSwitch)
  272. {
  273. handleServerSwitch(reader);
  274. }
  275. else if(flags == kReferral)
  276. {
  277. handleReferral(reader);
  278. }
  279. else
  280. {
  281. if(flags & kRequestRetransmit)
  282. {
  283. handleRequestRetransmit(reader);
  284. flags &= ~kRequestRetransmit;
  285. }
  286. if(flags & kRejectRetransmit)
  287. {
  288. handleRejectRetransmit(reader);
  289. flags &= ~kRejectRetransmit;
  290. }
  291. if(flags & kAckSequence)
  292. {
  293. handleAckSequence(reader);
  294. flags &= ~kAckSequence;
  295. }
  296. if(flags & kTimeSync)
  297. {
  298. handleTimeSync(reader);
  299. flags &= ~kTimeSync;
  300. }
  301. if(flags & kEchoResponse)
  302. {
  303. handleEchoResponse(reader);
  304. flags &= ~kEchoResponse;
  305. }
  306. if(flags & kFlow)
  307. {
  308. handleFlow(reader);
  309. flags &= ~kFlow;
  310. }
  311. if(flags & kBlobFragments)
  312. {
  313. handleBlobFragments(reader);
  314. flags &= ~kBlobFragments;
  315. }
  316. if(flags != 0)
  317. {
  318. LOG(Net, Error) << address_ << " unhandled flags " << hexn(flags) << " in packet\n";
  319. throw runtime_error("unhandled flags");
  320. }
  321. }
  322. }
  323. else
  324. {
  325. throw logic_error("bad state");
  326. }
  327. assert(reader.remaining() == 0);
  328. }
  329. void Session::tick(net_time_point now)
  330. {
  331. if(numPeriodicSent_ > kMaxPeriodicSent)
  332. {
  333. throw runtime_error("session timed out");
  334. }
  335. if(state_ == State::kLogon)
  336. {
  337. if(now > nextPeriodic_)
  338. {
  339. sendLogon();
  340. }
  341. }
  342. else if(state_ == State::kReferred)
  343. {
  344. if(now > nextPeriodic_)
  345. {
  346. sendReferred();
  347. }
  348. }
  349. else if(state_ == State::kConnectResponse)
  350. {
  351. if(now > nextPeriodic_)
  352. {
  353. sendConnectResponse();
  354. }
  355. }
  356. else if(state_ == State::kConnected)
  357. {
  358. Packet packet;
  359. packet.address = sendAddress();
  360. BinWriter writer(packet.payload, sizeof(packet.payload));
  361. uint16_t time = chrono::duration_cast<SessionDuration>(now - sessionBegin_).count();
  362. uint32_t flags = 0;
  363. /*
  364. if(now > nextRequestMissing_)
  365. {
  366. flags |= kRequestRetransmit;
  367. vector<uint32_t> missingPackets;
  368. uint32_t previousSequence = serverLeadingSequence_;
  369. for(uint32_t sequence : serverPackets_)
  370. {
  371. for(uint32_t missingSequence = previousSequence + 1; missingSequence < sequence; missingSequence++)
  372. {
  373. missingPackets.push_back(missingSequence);
  374. }
  375. previousSequence = sequence;
  376. }
  377. writer.writeInt(static_cast<uint32_t>(missingPackets.size()));
  378. for(uint32_t sequence : missingPackets)
  379. {
  380. writer.writeInt(sequence);
  381. }
  382. nextRequestMissing_ = now + kMissingPacketDelay;
  383. }
  384. */
  385. /*
  386. if(serverLeadingSequence_ > serverSequence_)
  387. {
  388. flags |= kAckSequence;
  389. writer.writeInt(serverLeadingSequence_);
  390. serverSequence_ = serverLeadingSequence_;
  391. LOG(Net, Debug) << address_ << " sending ack sequence " << serverLeadingSequence_ << "\n";
  392. }
  393. */
  394. if(now > nextPeriodic_)
  395. {
  396. flags |= kTimeSync;
  397. writer.writeDouble(beginTime_ + chrono::duration<double>(now - beginLocalTime_).count());
  398. flags |= kEchoRequest;
  399. writer.writeFloat(chrono::duration<float>(now - manager_.getClientBegin()).count());
  400. if(lastFlowBytes_ != 0)
  401. {
  402. flags |= kFlow;
  403. writer.writeInt(lastFlowBytes_);
  404. writer.writeShort(lastFlowTime_);
  405. lastFlowBytes_ = 0;
  406. lastFlowTime_ = time;
  407. }
  408. nextPeriodic_ = now + kPingPacketDelay;
  409. LOG(Net, Debug) << address_ << " sending time sync, echo request, flow\n";
  410. }
  411. if(flags != 0)
  412. {
  413. packet.header.sequence = clientLeadingSequence_ + 1;
  414. packet.header.flags = flags | kEncryptedChecksum;
  415. packet.header.netId = clientNetId_;
  416. packet.header.time = time;
  417. packet.header.size = static_cast<uint16_t>(writer.position());
  418. packet.header.iteration = iteration_;
  419. packet.header.checksum = checksumPacket(packet, clientXorGen_); // must be done last
  420. LOG(Net, Debug) << address_ << " sending packet " << packet.header << "\n";
  421. manager_.send(packet);
  422. packet.header.flags |= kRetransmission;
  423. packet.header.checksum = checksumPacket(packet, clientXorGen_); // must be done last
  424. clientPackets_[packet.header.sequence].reset(new Packet(packet));
  425. clientLeadingSequence_++;
  426. // since we already generated the retransmission checksum, we can purge right away
  427. clientXorGen_.purge(clientLeadingSequence_);
  428. }
  429. }
  430. else
  431. {
  432. throw logic_error("bad state");
  433. }
  434. }
  435. void Session::sendBlob(BlobPtr blob)
  436. {
  437. Packet packet;
  438. packet.address = sendAddress();
  439. packet.header.sequence = clientLeadingSequence_ + 1;
  440. packet.header.flags = kEncryptedChecksum | kBlobFragments;
  441. packet.header.netId = clientNetId_;
  442. packet.header.time = chrono::duration_cast<SessionDuration>(net_clock::now() - sessionBegin_).count();
  443. packet.header.iteration = iteration_;
  444. BinWriter writer(packet.payload, sizeof(packet.payload));
  445. // HACK
  446. //packet.header.flags |= kAckSequence;
  447. //writer.writeInt(2);
  448. FragmentHeader fragment;
  449. fragment.id = blobId_++;
  450. fragment.count = 1;
  451. fragment.size = static_cast<uint16_t>(sizeof(FragmentHeader) + blob->size);
  452. fragment.index = 0;
  453. fragment.queueId = blob->queueId;
  454. writer.writeRaw(&fragment, sizeof(fragment));
  455. writer.writeRaw(blob.get() + 1, blob->size);
  456. packet.header.size = static_cast<uint16_t>(writer.position());
  457. packet.header.checksum = checksumPacket(packet, clientXorGen_);
  458. manager_.send(packet);
  459. LOG(Net, Debug) << address_ << " sending " << packet.header << "\n";
  460. LOG(Net, Debug) << " fragment " << fragment << "\n";
  461. packet.header.flags |= kRetransmission;
  462. packet.header.checksum = checksumPacket(packet, clientXorGen_);
  463. clientPackets_[packet.header.sequence].reset(new Packet(packet));
  464. clientLeadingSequence_++;
  465. clientXorGen_.purge(clientLeadingSequence_);
  466. }
  467. Address Session::baseAddress() const
  468. {
  469. return address_;
  470. }
  471. Address Session::sendAddress() const
  472. {
  473. if(state_ == State::kConnectResponse)
  474. {
  475. return Address(address_.ip(), address_.port() + 1);
  476. }
  477. else
  478. {
  479. return address_;
  480. }
  481. }
  482. Address Session::recvAddress() const
  483. {
  484. if(state_ == State::kLogon || state_ == State::kReferred)
  485. {
  486. return address_;
  487. }
  488. else
  489. {
  490. return Address(address_.ip(), address_.port() + 1);
  491. }
  492. }
  493. net_time_point Session::nextTick() const
  494. {
  495. return min(nextPeriodic_, nextRequestMissing_);
  496. }
  497. BlobAssembler& Session::blobAssembler()
  498. {
  499. return blobAssembler_;
  500. }
  501. void Session::sendLogon()
  502. {
  503. Packet packet;
  504. packet.address = sendAddress();
  505. memset(&packet.header, 0, sizeof(packet.header));
  506. packet.header.flags = kLogon;
  507. BinWriter writer(packet.payload, sizeof(packet.payload));
  508. writer.writeString("1802"); // NetVersion
  509. size_t authDataLenOff = writer.position();
  510. writer.skip(sizeof(uint32_t));
  511. writer.writeInt(0x40000002); // GLSUserNameTicket_NetAuthType
  512. writer.writeInt(0);
  513. writer.writeInt(static_cast<uint32_t>(time(NULL)));
  514. writer.writeString(accountName_);
  515. writer.writeInt(0);
  516. writer.writeInt(static_cast<uint32_t>(sizeof(uint16_t) + accountKey_.size()));
  517. writer.writeShort(0xF480);
  518. writer.writeRaw(accountKey_.data(), accountKey_.size());
  519. packet.header.size = static_cast<uint16_t>(writer.position());
  520. writer.seek(authDataLenOff);
  521. writer.writeInt(static_cast<uint32_t>(packet.header.size - (authDataLenOff + sizeof(uint32_t))));
  522. packet.header.checksum = checksumPacket(packet, clientXorGen_); // must be done last
  523. manager_.send(packet);
  524. nextPeriodic_ = net_clock::now() + kLogonPacketDelay;
  525. numPeriodicSent_++;
  526. LOG(Net, Info) << address_ << " sent logon\n";
  527. }
  528. void Session::sendReferred()
  529. {
  530. Packet packet;
  531. packet.address = sendAddress();
  532. memset(&packet.header, 0, sizeof(packet.header));
  533. packet.header.flags = kReferred;
  534. packet.header.size = sizeof(uint64_t);
  535. BinWriter writer(packet.payload, sizeof(packet.payload));
  536. writer.writeLong(cookie_);
  537. packet.header.checksum = checksumPacket(packet, clientXorGen_); // must be done last
  538. manager_.send(packet);
  539. nextPeriodic_ = net_clock::now() + kReferredPacketDelay;
  540. numPeriodicSent_++;
  541. LOG(Net, Info) << address_ << " sent referred\n";
  542. }
  543. void Session::sendConnectResponse()
  544. {
  545. Packet packet;
  546. packet.address = sendAddress();
  547. memset(&packet.header, 0, sizeof(packet.header));
  548. packet.header.flags = kConnectResponse;
  549. packet.header.netId = clientNetId_;
  550. packet.header.size = sizeof(uint64_t);
  551. packet.header.iteration = iteration_;
  552. BinWriter writer(packet.payload, sizeof(packet.payload));
  553. writer.writeLong(cookie_);
  554. packet.header.checksum = checksumPacket(packet, clientXorGen_); // must be done last
  555. manager_.send(packet);
  556. nextPeriodic_ = net_clock::now() + kConnectResponsePacketDelay;
  557. numPeriodicSent_++;
  558. LOG(Net, Info) << address_ << " sent connect response\n";
  559. }
  560. void Session::handleBlobFragments(BinReader& reader)
  561. {
  562. while(reader.remaining() != 0)
  563. {
  564. const FragmentHeader* fragment = reader.readPointer<FragmentHeader>();
  565. reader.readRaw(fragment->size - sizeof(FragmentHeader));
  566. blobAssembler_.addFragment(fragment);
  567. }
  568. LOG(Net, Info) << address_ << " received blob fragments\n";
  569. }
  570. void Session::handleServerSwitch(BinReader& reader)
  571. {
  572. /*sequence*/ reader.readInt();
  573. /*type*/ reader.readInt();
  574. manager_.setPrimary(this);
  575. LOG(Net, Info) << address_ << " received server switch\n";
  576. }
  577. void Session::handleRequestRetransmit(BinReader& reader)
  578. {
  579. uint32_t numSequence = reader.readInt();
  580. for(uint32_t i = 0; i < numSequence; i++)
  581. {
  582. uint32_t sequence = reader.readInt();
  583. auto it = clientPackets_.find(sequence);
  584. if(it == clientPackets_.end())
  585. {
  586. LOG(Net, Warn) << address_ << " ignoring retransmit request of " << sequence << "\n";
  587. continue;
  588. }
  589. manager_.send(*it->second);
  590. }
  591. LOG(Net, Debug) << address_ << " received request retransmit for " << numSequence << " packets\n";
  592. }
  593. void Session::handleRejectRetransmit(BinReader& reader)
  594. {
  595. uint32_t numSequence = reader.readInt();
  596. for(uint32_t i = 0; i < numSequence; i++)
  597. {
  598. uint32_t sequence = reader.readInt();
  599. if(sequence > serverSequence_)
  600. {
  601. serverPackets_.insert(sequence);
  602. }
  603. }
  604. advanceServerSequence();
  605. LOG(Net, Debug) << address_ << " received reject retransmit for " << numSequence << " packets\n";
  606. }
  607. void Session::handleAckSequence(BinReader& reader)
  608. {
  609. clientSequence_ = max(clientSequence_, reader.readInt());
  610. for(auto it = clientPackets_.begin(); it != clientPackets_.end(); /**/)
  611. {
  612. if(it->first > clientSequence_)
  613. {
  614. break;
  615. }
  616. it = clientPackets_.erase(it);
  617. }
  618. LOG(Net, Debug) << address_ << " received ack sequence " << clientSequence_ << "\n";
  619. }
  620. void Session::handleReferral(BinReader& reader)
  621. {
  622. uint64_t cookie = reader.readLong();
  623. /*family*/ reader.readShort();
  624. uint16_t port = htons(reader.readShort());
  625. uint32_t ip = htonl(reader.readInt());
  626. /*zero*/ reader.readRaw(8);
  627. /*serverId*/ reader.readShort();
  628. /*padding*/ reader.readRaw(6);
  629. Address referral(ip, port);
  630. if(manager_.exists(referral))
  631. {
  632. LOG(Net, Warn) << address_ << " received referral for existing session " << referral << "\n";
  633. return;
  634. }
  635. unique_ptr<Session> session(new Session(manager_, referral, cookie));
  636. manager_.add(move(session));
  637. LOG(Net, Info) << address_ << " received referral to " << referral << "\n";
  638. }
  639. void Session::handleConnect(BinReader& reader, const PacketHeader& header)
  640. {
  641. double beginTime = reader.readDouble();
  642. uint64_t cookie = reader.readLong();
  643. uint16_t clientNetId = static_cast<uint16_t>(reader.readInt());
  644. uint32_t serverSeed = reader.readInt();
  645. uint32_t clientSeed = reader.readInt();
  646. reader.readInt(); // padding
  647. cookie_ = cookie;
  648. serverSequence_ = 1;
  649. serverLeadingSequence_ = 1;
  650. clientSequence_ = 1;
  651. clientLeadingSequence_ = 1;
  652. serverNetId_ = header.netId;
  653. clientNetId_ = clientNetId;
  654. iteration_ = header.iteration;
  655. serverXorGen_.init(serverSeed);
  656. clientXorGen_.init(clientSeed);
  657. beginTime_ = beginTime;
  658. beginLocalTime_ = net_clock::now();
  659. serverPackets_.clear();
  660. clientPackets_.clear();
  661. nextRequestMissing_ = net_time_point::max();
  662. lastFlowTime_ = 0;
  663. lastFlowBytes_ = 0;
  664. LOG(Net, Info) << address_ << " received connect\n";
  665. }
  666. void Session::handleTimeSync(BinReader& reader)
  667. {
  668. beginTime_ = reader.readDouble();
  669. beginLocalTime_ = net_clock::now();
  670. LOG(Net, Debug) << address_ << " received time sync " << beginTime_ << "\n";
  671. }
  672. void Session::handleEchoResponse(BinReader& reader)
  673. {
  674. numPeriodicSent_ = 0;
  675. // Ignored for now
  676. /*pingTime*/ reader.readFloat();
  677. /*pingResult*/ reader.readFloat();
  678. LOG(Net, Debug) << address_ << " received echo response\n";
  679. }
  680. void Session::handleFlow(BinReader& reader)
  681. {
  682. // Ignored for now
  683. /*numBytes*/ reader.readInt();
  684. /*time*/ reader.readShort();
  685. LOG(Net, Debug) << address_ << " received flow\n";
  686. }
  687. void Session::advanceServerSequence()
  688. {
  689. auto it = serverPackets_.begin();
  690. while(it != serverPackets_.end())
  691. {
  692. if(*it != serverLeadingSequence_ + 1)
  693. {
  694. break;
  695. }
  696. it = serverPackets_.erase(it);
  697. serverLeadingSequence_++;
  698. }
  699. serverXorGen_.purge(serverLeadingSequence_);
  700. if(!serverPackets_.empty())
  701. {
  702. if(nextRequestMissing_ == net_time_point::max())
  703. {
  704. nextRequestMissing_ = net_clock::now() + kMissingPacketDelay;
  705. }
  706. }
  707. else
  708. {
  709. if(nextRequestMissing_ != net_time_point::max())
  710. {
  711. nextRequestMissing_ = net_time_point::max();
  712. }
  713. }
  714. }