Connection.cpp 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764
  1. /*
  2. * This is the source code of tgnet library v. 1.1
  3. * It is licensed under GNU GPL v. 2 or later.
  4. * You should have received a copy of the license in this archive (see LICENSE).
  5. *
  6. * Copyright Nikolai Kudashov, 2015-2018.
  7. */
  8. #include <openssl/rand.h>
  9. #include <stdlib.h>
  10. #include <cstring>
  11. #include <openssl/sha.h>
  12. #include <algorithm>
  13. #include "Connection.h"
  14. #include "ConnectionsManager.h"
  15. #include "BuffersStorage.h"
  16. #include "FileLog.h"
  17. #include "Timer.h"
  18. #include "Datacenter.h"
  19. #include "NativeByteBuffer.h"
  20. #include "ByteArray.h"
  21. thread_local static uint32_t lastConnectionToken = 1;
  22. Connection::Connection(Datacenter *datacenter, ConnectionType type, int8_t num) : ConnectionSession(datacenter->instanceNum), ConnectionSocket(datacenter->instanceNum) {
  23. currentDatacenter = datacenter;
  24. connectionNum = num;
  25. connectionType = type;
  26. genereateNewSessionId();
  27. connectionState = TcpConnectionStageIdle;
  28. reconnectTimer = new Timer(datacenter->instanceNum, [&] {
  29. reconnectTimer->stop();
  30. waitForReconnectTimer = false;
  31. connect();
  32. });
  33. }
  34. Connection::~Connection() {
  35. if (reconnectTimer != nullptr) {
  36. reconnectTimer->stop();
  37. delete reconnectTimer;
  38. reconnectTimer = nullptr;
  39. }
  40. }
  41. void Connection::suspendConnection() {
  42. suspendConnection(false);
  43. }
  44. void Connection::suspendConnection(bool idle) {
  45. reconnectTimer->stop();
  46. waitForReconnectTimer = false;
  47. if (connectionState == TcpConnectionStageIdle || connectionState == TcpConnectionStageSuspended) {
  48. return;
  49. }
  50. if (LOGS_ENABLED) DEBUG_D("connection(%p, account%u, dc%u, type %d) suspend", this, currentDatacenter->instanceNum, currentDatacenter->getDatacenterId(), connectionType);
  51. connectionState = idle ? TcpConnectionStageIdle : TcpConnectionStageSuspended;
  52. dropConnection();
  53. ConnectionsManager::getInstance(currentDatacenter->instanceNum).onConnectionClosed(this, 0);
  54. firstPacketSent = false;
  55. if (restOfTheData != nullptr) {
  56. restOfTheData->reuse();
  57. restOfTheData = nullptr;
  58. }
  59. lastPacketLength = 0;
  60. connectionToken = 0;
  61. wasConnected = false;
  62. }
  63. void Connection::onReceivedData(NativeByteBuffer *buffer) {
  64. AES_ctr128_encrypt(buffer->bytes(), buffer->bytes(), buffer->limit(), &decryptKey, decryptIv, decryptCount, &decryptNum);
  65. failedConnectionCount = 0;
  66. if (connectionType == ConnectionTypeGeneric || connectionType == ConnectionTypeTemp || connectionType == ConnectionTypeGenericMedia) {
  67. receivedDataAmount += buffer->limit();
  68. if (receivedDataAmount >= 512 * 1024) {
  69. if (currentTimeout > 4) {
  70. currentTimeout -= 2;
  71. setTimeout(currentTimeout);
  72. }
  73. receivedDataAmount = 0;
  74. }
  75. }
  76. NativeByteBuffer *parseLaterBuffer = nullptr;
  77. if (restOfTheData != nullptr) {
  78. if (lastPacketLength == 0) {
  79. if (restOfTheData->capacity() - restOfTheData->position() >= buffer->limit()) {
  80. restOfTheData->limit(restOfTheData->position() + buffer->limit());
  81. restOfTheData->writeBytes(buffer);
  82. buffer = restOfTheData;
  83. } else {
  84. NativeByteBuffer *newBuffer = BuffersStorage::getInstance().getFreeBuffer(restOfTheData->limit() + buffer->limit());
  85. restOfTheData->rewind();
  86. newBuffer->writeBytes(restOfTheData);
  87. newBuffer->writeBytes(buffer);
  88. buffer = newBuffer;
  89. restOfTheData->reuse();
  90. restOfTheData = newBuffer;
  91. }
  92. } else {
  93. uint32_t len;
  94. if (lastPacketLength - restOfTheData->position() <= buffer->limit()) {
  95. len = lastPacketLength - restOfTheData->position();
  96. } else {
  97. len = buffer->limit();
  98. }
  99. uint32_t oldLimit = buffer->limit();
  100. buffer->limit(len);
  101. restOfTheData->writeBytes(buffer);
  102. buffer->limit(oldLimit);
  103. if (restOfTheData->position() == lastPacketLength) {
  104. parseLaterBuffer = buffer->hasRemaining() ? buffer : nullptr;
  105. buffer = restOfTheData;
  106. } else {
  107. if (LOGS_ENABLED) DEBUG_D("connection(%p, account%u, dc%u, type %d) received packet size less(%u) then message size(%u)", this, currentDatacenter->instanceNum, currentDatacenter->getDatacenterId(), connectionType, restOfTheData->position(), lastPacketLength);
  108. return;
  109. }
  110. }
  111. }
  112. buffer->rewind();
  113. while (buffer->hasRemaining()) {
  114. if (!hasSomeDataSinceLastConnect) {
  115. currentDatacenter->storeCurrentAddressAndPortNum();
  116. isTryingNextPort = false;
  117. if (connectionType == ConnectionTypeProxy) {
  118. setTimeout(5);
  119. } else if (connectionType == ConnectionTypePush) {
  120. setTimeout(60 * 15);
  121. } else if (connectionType == ConnectionTypeUpload) {
  122. if (ConnectionsManager::getInstance(currentDatacenter->instanceNum).networkSlow) {
  123. setTimeout(40);
  124. } else {
  125. setTimeout(25);
  126. }
  127. } else if (connectionType == ConnectionTypeDownload) {
  128. setTimeout(25);
  129. } else {
  130. setTimeout(currentTimeout);
  131. }
  132. }
  133. hasSomeDataSinceLastConnect = true;
  134. uint32_t currentPacketLength = 0;
  135. uint32_t mark = buffer->position();
  136. uint32_t len;
  137. if (currentProtocolType == ProtocolTypeEF) {
  138. uint8_t fByte = buffer->readByte(nullptr);
  139. if ((fByte & (1 << 7)) != 0) {
  140. buffer->position(mark);
  141. if (buffer->remaining() < 4) {
  142. NativeByteBuffer *reuseLater = restOfTheData;
  143. restOfTheData = BuffersStorage::getInstance().getFreeBuffer(16384);
  144. restOfTheData->writeBytes(buffer);
  145. restOfTheData->limit(restOfTheData->position());
  146. lastPacketLength = 0;
  147. if (reuseLater != nullptr) {
  148. reuseLater->reuse();
  149. }
  150. break;
  151. }
  152. int32_t ackId = buffer->readBigInt32(nullptr) & (~(1 << 31));
  153. ConnectionsManager::getInstance(currentDatacenter->instanceNum).onConnectionQuickAckReceived(this, ackId);
  154. continue;
  155. }
  156. if (fByte != 0x7f) {
  157. currentPacketLength = ((uint32_t) fByte) * 4;
  158. } else {
  159. buffer->position(mark);
  160. if (buffer->remaining() < 4) {
  161. if (restOfTheData == nullptr || (restOfTheData != nullptr && restOfTheData->position() != 0)) {
  162. NativeByteBuffer *reuseLater = restOfTheData;
  163. restOfTheData = BuffersStorage::getInstance().getFreeBuffer(16384);
  164. restOfTheData->writeBytes(buffer);
  165. restOfTheData->limit(restOfTheData->position());
  166. lastPacketLength = 0;
  167. if (reuseLater != nullptr) {
  168. reuseLater->reuse();
  169. }
  170. } else {
  171. restOfTheData->position(restOfTheData->limit());
  172. }
  173. break;
  174. }
  175. currentPacketLength = ((uint32_t) buffer->readInt32(nullptr) >> 8) * 4;
  176. }
  177. len = currentPacketLength + (fByte != 0x7f ? 1 : 4);
  178. } else {
  179. if (buffer->remaining() < 4) {
  180. if (restOfTheData == nullptr || (restOfTheData != nullptr && restOfTheData->position() != 0)) {
  181. NativeByteBuffer *reuseLater = restOfTheData;
  182. restOfTheData = BuffersStorage::getInstance().getFreeBuffer(16384);
  183. restOfTheData->writeBytes(buffer);
  184. restOfTheData->limit(restOfTheData->position());
  185. lastPacketLength = 0;
  186. if (reuseLater != nullptr) {
  187. reuseLater->reuse();
  188. }
  189. } else {
  190. restOfTheData->position(restOfTheData->limit());
  191. }
  192. break;
  193. }
  194. uint32_t fInt = buffer->readUint32(nullptr);
  195. if ((fInt & (0x80000000)) != 0) {
  196. ConnectionsManager::getInstance(currentDatacenter->instanceNum).onConnectionQuickAckReceived(this, fInt & (~(1 << 31)));
  197. continue;
  198. }
  199. currentPacketLength = fInt;
  200. len = currentPacketLength + 4;
  201. }
  202. if (currentProtocolType != ProtocolTypeDD && currentProtocolType != ProtocolTypeTLS && currentPacketLength % 4 != 0 || currentPacketLength > 2 * 1024 * 1024) {
  203. if (LOGS_ENABLED) DEBUG_D("connection(%p, account%u, dc%u, type %d) received invalid packet length", this, currentDatacenter->instanceNum, currentDatacenter->getDatacenterId(), connectionType);
  204. reconnect();
  205. return;
  206. }
  207. if (currentPacketLength < buffer->remaining()) {
  208. if (LOGS_ENABLED) DEBUG_D("connection(%p, account%u, dc%u, type %d) received message len %u but packet larger %u", this, currentDatacenter->instanceNum, currentDatacenter->getDatacenterId(), connectionType, currentPacketLength, buffer->remaining());
  209. } else if (currentPacketLength == buffer->remaining()) {
  210. if (LOGS_ENABLED) DEBUG_D("connection(%p, account%u, dc%u, type %d) received message len %u equal to packet size", this, currentDatacenter->instanceNum, currentDatacenter->getDatacenterId(), connectionType, currentPacketLength);
  211. } else {
  212. if (LOGS_ENABLED) DEBUG_D("connection(%p, account%u, dc%u, type %d) received packet size less(%u) then message size(%u)", this, currentDatacenter->instanceNum, currentDatacenter->getDatacenterId(), connectionType, buffer->remaining(), currentPacketLength);
  213. NativeByteBuffer *reuseLater = nullptr;
  214. if (restOfTheData != nullptr && restOfTheData->capacity() < len) {
  215. reuseLater = restOfTheData;
  216. restOfTheData = nullptr;
  217. }
  218. if (restOfTheData == nullptr) {
  219. buffer->position(mark);
  220. restOfTheData = BuffersStorage::getInstance().getFreeBuffer(len);
  221. restOfTheData->writeBytes(buffer);
  222. } else {
  223. restOfTheData->position(restOfTheData->limit());
  224. restOfTheData->limit(len);
  225. }
  226. lastPacketLength = len;
  227. if (reuseLater != nullptr) {
  228. reuseLater->reuse();
  229. }
  230. return;
  231. }
  232. uint32_t old = buffer->limit();
  233. buffer->limit(buffer->position() + currentPacketLength);
  234. ConnectionsManager::getInstance(currentDatacenter->instanceNum).onConnectionDataReceived(this, buffer, currentPacketLength);
  235. buffer->position(buffer->limit());
  236. buffer->limit(old);
  237. if (restOfTheData != nullptr) {
  238. if ((lastPacketLength != 0 && restOfTheData->position() == lastPacketLength) || (lastPacketLength == 0 && !restOfTheData->hasRemaining())) {
  239. restOfTheData->reuse();
  240. restOfTheData = nullptr;
  241. } else {
  242. restOfTheData->compact();
  243. restOfTheData->limit(restOfTheData->position());
  244. restOfTheData->position(0);
  245. }
  246. }
  247. if (parseLaterBuffer != nullptr) {
  248. buffer = parseLaterBuffer;
  249. parseLaterBuffer = nullptr;
  250. }
  251. }
  252. }
  253. void Connection::connect() {
  254. if (waitForReconnectTimer) {
  255. return;
  256. }
  257. if (!ConnectionsManager::getInstance(currentDatacenter->instanceNum).isNetworkAvailable()) {
  258. ConnectionsManager::getInstance(currentDatacenter->instanceNum).onConnectionClosed(this, 0);
  259. return;
  260. }
  261. if (connectionState == TcpConnectionStageConnected || connectionState == TcpConnectionStageConnecting) {
  262. return;
  263. }
  264. connectionInProcess = true;
  265. connectionState = TcpConnectionStageConnecting;
  266. isMediaConnection = false;
  267. uint8_t strategy = ConnectionsManager::getInstance(currentDatacenter->instanceNum).getIpStratagy();
  268. uint32_t ipv6;
  269. if (strategy == USE_IPV6_ONLY) {
  270. ipv6 = TcpAddressFlagIpv6;
  271. } else if (strategy == USE_IPV4_IPV6_RANDOM) {
  272. if (ConnectionsManager::getInstance(currentDatacenter->instanceNum).lastProtocolUsefullData) {
  273. ipv6 = ConnectionsManager::getInstance(currentDatacenter->instanceNum).lastProtocolIsIpv6 ? TcpAddressFlagIpv6 : 0;
  274. } else {
  275. uint8_t value;
  276. RAND_bytes(&value, 1);
  277. ipv6 = value % 3 == 0 ? TcpAddressFlagIpv6 : 0;
  278. ConnectionsManager::getInstance(currentDatacenter->instanceNum).lastProtocolIsIpv6 = ipv6 != 0;
  279. }
  280. if (connectionType == ConnectionTypeGeneric) {
  281. ConnectionsManager::getInstance(currentDatacenter->instanceNum).lastProtocolUsefullData = false;
  282. }
  283. } else {
  284. ipv6 = 0;
  285. }
  286. uint32_t isStatic = connectionType == ConnectionTypeProxy || !ConnectionsManager::getInstance(currentDatacenter->instanceNum).proxyAddress.empty() ? TcpAddressFlagStatic : 0;
  287. TcpAddress *tcpAddress = nullptr;
  288. if (isMediaConnectionType(connectionType)) {
  289. currentAddressFlags = TcpAddressFlagDownload | isStatic;
  290. tcpAddress = currentDatacenter->getCurrentAddress(currentAddressFlags | ipv6);
  291. if (tcpAddress == nullptr) {
  292. currentAddressFlags = isStatic;
  293. tcpAddress = currentDatacenter->getCurrentAddress(currentAddressFlags | ipv6);
  294. } else {
  295. isMediaConnection = true;
  296. }
  297. if (tcpAddress == nullptr && ipv6) {
  298. ipv6 = 0;
  299. currentAddressFlags = TcpAddressFlagDownload | isStatic;
  300. tcpAddress = currentDatacenter->getCurrentAddress(currentAddressFlags);
  301. if (tcpAddress == nullptr) {
  302. currentAddressFlags = isStatic;
  303. tcpAddress = currentDatacenter->getCurrentAddress(currentAddressFlags);
  304. } else {
  305. isMediaConnection = true;
  306. }
  307. }
  308. } else if (connectionType == ConnectionTypeTemp) {
  309. currentAddressFlags = TcpAddressFlagTemp;
  310. tcpAddress = currentDatacenter->getCurrentAddress(currentAddressFlags);
  311. ipv6 = 0;
  312. } else {
  313. currentAddressFlags = isStatic;
  314. tcpAddress = currentDatacenter->getCurrentAddress(currentAddressFlags | ipv6);
  315. if (tcpAddress == nullptr && ipv6) {
  316. ipv6 = 0;
  317. tcpAddress = currentDatacenter->getCurrentAddress(currentAddressFlags);
  318. }
  319. }
  320. if (tcpAddress == nullptr) {
  321. hostAddress = "";
  322. } else {
  323. hostAddress = tcpAddress->address;
  324. secret = tcpAddress->secret;
  325. }
  326. if (tcpAddress != nullptr && isStatic) {
  327. hostPort = (uint16_t) tcpAddress->port;
  328. } else {
  329. hostPort = (uint16_t) currentDatacenter->getCurrentPort(currentAddressFlags);
  330. }
  331. reconnectTimer->stop();
  332. if (LOGS_ENABLED) DEBUG_D("connection(%p, account%u, dc%u, type %d) connecting (%s:%hu)", this, currentDatacenter->instanceNum, currentDatacenter->getDatacenterId(), connectionType, hostAddress.c_str(), hostPort);
  333. firstPacketSent = false;
  334. if (restOfTheData != nullptr) {
  335. restOfTheData->reuse();
  336. restOfTheData = nullptr;
  337. }
  338. lastPacketLength = 0;
  339. wasConnected = false;
  340. hasSomeDataSinceLastConnect = false;
  341. openConnection(hostAddress, hostPort, secret, ipv6 != 0, ConnectionsManager::getInstance(currentDatacenter->instanceNum).currentNetworkType);
  342. if (connectionType == ConnectionTypeProxy) {
  343. setTimeout(5);
  344. } else if (connectionType == ConnectionTypePush) {
  345. if (isTryingNextPort) {
  346. setTimeout(20);
  347. } else {
  348. setTimeout(30);
  349. }
  350. } else if (connectionType == ConnectionTypeUpload) {
  351. if (ConnectionsManager::getInstance(currentDatacenter->instanceNum).networkSlow) {
  352. setTimeout(40);
  353. } else {
  354. setTimeout(25);
  355. }
  356. } else {
  357. if (isTryingNextPort) {
  358. setTimeout(8);
  359. } else {
  360. setTimeout(12);
  361. }
  362. }
  363. connectionInProcess = false;
  364. }
  365. void Connection::reconnect() {
  366. if (connectionType == ConnectionTypeProxy) {
  367. suspendConnection(false);
  368. } else {
  369. forceNextPort = true;
  370. suspendConnection(true);
  371. connect();
  372. }
  373. }
  374. bool Connection::hasUsefullData() {
  375. int64_t time = ConnectionsManager::getInstance(currentDatacenter->instanceNum).getCurrentTimeMonotonicMillis();
  376. if (usefullData && llabs(time - usefullDataReceiveTime) < 4 * 1000L) {
  377. return false;
  378. }
  379. return usefullData;
  380. }
  381. bool Connection::isSuspended() {
  382. return connectionState == TcpConnectionStageSuspended;
  383. }
  384. bool Connection::isMediaConnectionType(ConnectionType type) {
  385. return (type & ConnectionTypeGenericMedia) != 0 || (type & ConnectionTypeDownload) != 0;
  386. }
  387. void Connection::setHasUsefullData() {
  388. if (!usefullData) {
  389. usefullDataReceiveTime = ConnectionsManager::getInstance(currentDatacenter->instanceNum).getCurrentTimeMonotonicMillis();
  390. usefullData = true;
  391. lastReconnectTimeout = 50;
  392. }
  393. }
  394. bool Connection::allowsCustomPadding() {
  395. return currentProtocolType == ProtocolTypeTLS || currentProtocolType == ProtocolTypeDD || currentProtocolType == ProtocolTypeEF;
  396. }
  397. void Connection::sendData(NativeByteBuffer *buff, bool reportAck, bool encrypted) {
  398. if (buff == nullptr) {
  399. return;
  400. }
  401. buff->rewind();
  402. if (connectionState == TcpConnectionStageIdle || connectionState == TcpConnectionStageReconnecting || connectionState == TcpConnectionStageSuspended) {
  403. connect();
  404. }
  405. if (isDisconnected()) {
  406. buff->reuse();
  407. if (LOGS_ENABLED) DEBUG_D("connection(%p, account%u, dc%u, type %d) disconnected, don't send data", this, currentDatacenter->instanceNum, currentDatacenter->getDatacenterId(), connectionType);
  408. return;
  409. }
  410. uint32_t bufferLen = 0;
  411. uint32_t packetLength;
  412. uint8_t useSecret = 0;
  413. if (!firstPacketSent) {
  414. if (!overrideProxyAddress.empty()) {
  415. if (!overrideProxySecret.empty()) {
  416. useSecret = 1;
  417. } else if (!secret.empty()) {
  418. useSecret = 2;
  419. }
  420. } else if (!ConnectionsManager::getInstance(currentDatacenter->instanceNum).proxyAddress.empty() && !ConnectionsManager::getInstance(currentDatacenter->instanceNum).proxySecret.empty()) {
  421. useSecret = 1;
  422. } else if (!secret.empty()) {
  423. useSecret = 2;
  424. }
  425. if (useSecret != 0) {
  426. std::string *currentSecret = getCurrentSecret(useSecret);
  427. if (currentSecret->length() >= 17 && (*currentSecret)[0] == '\xdd') {
  428. currentProtocolType = ProtocolTypeDD;
  429. } else if (currentSecret->length() > 17 && (*currentSecret)[0] == '\xee') {
  430. currentProtocolType = ProtocolTypeTLS;
  431. } else {
  432. currentProtocolType = ProtocolTypeEF;
  433. }
  434. } else {
  435. currentProtocolType = ProtocolTypeEF;
  436. }
  437. }
  438. uint32_t additinalPacketSize = 0;
  439. if (currentProtocolType == ProtocolTypeEF) {
  440. packetLength = buff->limit() / 4;
  441. if (packetLength < 0x7f) {
  442. bufferLen++;
  443. } else {
  444. bufferLen += 4;
  445. }
  446. } else {
  447. packetLength = buff->limit();
  448. if (currentProtocolType == ProtocolTypeDD || currentProtocolType == ProtocolTypeTLS) {
  449. RAND_bytes((uint8_t *) &additinalPacketSize, 4);
  450. if (!encrypted) {
  451. additinalPacketSize = additinalPacketSize % 257;
  452. } else {
  453. additinalPacketSize = additinalPacketSize % 16;
  454. }
  455. packetLength += additinalPacketSize;
  456. } else {
  457. RAND_bytes((uint8_t *) &additinalPacketSize, 4);
  458. if (!encrypted) {
  459. additinalPacketSize = additinalPacketSize % 257;
  460. uint32_t additionalSize = additinalPacketSize % 4;
  461. if (additionalSize != 0) {
  462. additinalPacketSize += (4 - additionalSize);
  463. }
  464. }
  465. packetLength += additinalPacketSize;
  466. }
  467. bufferLen += 4;
  468. }
  469. if (!firstPacketSent) {
  470. bufferLen += 64;
  471. }
  472. NativeByteBuffer *buffer = BuffersStorage::getInstance().getFreeBuffer(bufferLen);
  473. NativeByteBuffer *buffer2;
  474. if (additinalPacketSize > 0) {
  475. buffer2 = BuffersStorage::getInstance().getFreeBuffer(additinalPacketSize);
  476. RAND_bytes(buffer2->bytes(), additinalPacketSize);
  477. } else {
  478. buffer2 = nullptr;
  479. }
  480. uint8_t *bytes = buffer->bytes();
  481. if (!firstPacketSent) {
  482. buffer->position(64);
  483. while (true) {
  484. RAND_bytes(bytes, 64);
  485. uint32_t val = (bytes[3] << 24) | (bytes[2] << 16) | (bytes[1] << 8) | (bytes[0]);
  486. uint32_t val2 = (bytes[7] << 24) | (bytes[6] << 16) | (bytes[5] << 8) | (bytes[4]);
  487. if (currentProtocolType == ProtocolTypeTLS || bytes[0] != 0xef && val != 0x44414548 && val != 0x54534f50 && val != 0x20544547 && val != 0x4954504f && val != 0xeeeeeeee && val != 0xdddddddd && val != 0x02010316 && val2 != 0x00000000) {
  488. if (currentProtocolType == ProtocolTypeEF) {
  489. bytes[56] = bytes[57] = bytes[58] = bytes[59] = 0xef;
  490. } else if (currentProtocolType == ProtocolTypeDD || currentProtocolType == ProtocolTypeTLS) {
  491. bytes[56] = bytes[57] = bytes[58] = bytes[59] = 0xdd;
  492. } else if (currentProtocolType == ProtocolTypeEE) {
  493. bytes[56] = bytes[57] = bytes[58] = bytes[59] = 0xee;
  494. }
  495. if (useSecret != 0) {
  496. int16_t datacenterId;
  497. if (isMediaConnection) {
  498. if (ConnectionsManager::getInstance(currentDatacenter->instanceNum).testBackend) {
  499. datacenterId = -(int16_t) (10000 + currentDatacenter->getDatacenterId());
  500. } else {
  501. datacenterId = -(int16_t) currentDatacenter->getDatacenterId();
  502. }
  503. } else {
  504. if (ConnectionsManager::getInstance(currentDatacenter->instanceNum).testBackend) {
  505. datacenterId = (int16_t) (10000 + currentDatacenter->getDatacenterId());
  506. } else {
  507. datacenterId = (int16_t) currentDatacenter->getDatacenterId();
  508. }
  509. }
  510. bytes[60] = (uint8_t) (datacenterId & 0xff);
  511. bytes[61] = (uint8_t) ((datacenterId >> 8) & 0xff);
  512. }
  513. break;
  514. }
  515. }
  516. encryptNum = decryptNum = 0;
  517. memset(encryptCount, 0, 16);
  518. memset(decryptCount, 0, 16);
  519. for (int32_t a = 0; a < 48; a++) {
  520. temp[a] = bytes[a + 8];
  521. }
  522. encryptKeyWithSecret(temp, useSecret);
  523. if (AES_set_encrypt_key(temp, 256, &encryptKey) < 0) {
  524. if (LOGS_ENABLED) DEBUG_E("unable to set encryptKey");
  525. exit(1);
  526. }
  527. memcpy(encryptIv, temp + 32, 16);
  528. for (int32_t a = 0; a < 48; a++) {
  529. temp[a] = bytes[55 - a];
  530. }
  531. encryptKeyWithSecret(temp, useSecret);
  532. if (AES_set_encrypt_key(temp, 256, &decryptKey) < 0) {
  533. if (LOGS_ENABLED) DEBUG_E("unable to set decryptKey");
  534. exit(1);
  535. }
  536. memcpy(decryptIv, temp + 32, 16);
  537. AES_ctr128_encrypt(bytes, temp, 64, &encryptKey, encryptIv, encryptCount, &encryptNum);
  538. memcpy(bytes + 56, temp + 56, 8);
  539. firstPacketSent = true;
  540. }
  541. if (currentProtocolType == ProtocolTypeEF) {
  542. if (packetLength < 0x7f) {
  543. if (reportAck) {
  544. packetLength |= (1 << 7);
  545. }
  546. buffer->writeByte((uint8_t) packetLength);
  547. bytes += (buffer->limit() - 1);
  548. AES_ctr128_encrypt(bytes, bytes, 1, &encryptKey, encryptIv, encryptCount, &encryptNum);
  549. } else {
  550. packetLength = (packetLength << 8) + 0x7f;
  551. if (reportAck) {
  552. packetLength |= (1 << 7);
  553. }
  554. buffer->writeInt32(packetLength);
  555. bytes += (buffer->limit() - 4);
  556. AES_ctr128_encrypt(bytes, bytes, 4, &encryptKey, encryptIv, encryptCount, &encryptNum);
  557. }
  558. } else {
  559. if (reportAck) {
  560. packetLength |= 0x80000000;
  561. }
  562. buffer->writeInt32(packetLength);
  563. bytes += (buffer->limit() - 4);
  564. AES_ctr128_encrypt(bytes, bytes, 4, &encryptKey, encryptIv, encryptCount, &encryptNum);
  565. }
  566. buffer->rewind();
  567. writeBuffer(buffer);
  568. buff->rewind();
  569. AES_ctr128_encrypt(buff->bytes(), buff->bytes(), buff->limit(), &encryptKey, encryptIv, encryptCount, &encryptNum);
  570. writeBuffer(buff);
  571. if (buffer2 != nullptr) {
  572. AES_ctr128_encrypt(buffer2->bytes(), buffer2->bytes(), buffer2->limit(), &encryptKey, encryptIv, encryptCount, &encryptNum);
  573. writeBuffer(buffer2);
  574. }
  575. }
  576. inline std::string *Connection::getCurrentSecret(uint8_t secretType) {
  577. if (secretType == 2) {
  578. return &secret;
  579. } else if (!overrideProxySecret.empty()) {
  580. return &overrideProxySecret;
  581. } else {
  582. return &ConnectionsManager::getInstance(currentDatacenter->instanceNum).proxySecret;
  583. }
  584. }
  585. inline void Connection::encryptKeyWithSecret(uint8_t *bytes, uint8_t secretType) {
  586. if (secretType == 0) {
  587. return;
  588. }
  589. std::string *currentSecret = getCurrentSecret(secretType);
  590. size_t a = 0;
  591. size_t size = std::min((size_t) 16, currentSecret->length());
  592. if (currentSecret->length() >= 17 && ((*currentSecret)[0] == '\xdd' || (*currentSecret)[0] == '\xee')) {
  593. a = 1;
  594. size = 17;
  595. }
  596. SHA256_CTX sha256Ctx;
  597. SHA256_Init(&sha256Ctx);
  598. SHA256_Update(&sha256Ctx, bytes, 32);
  599. char b[1];
  600. for (; a < size; a++) {
  601. b[0] = (char) (*currentSecret)[a];
  602. SHA256_Update(&sha256Ctx, b, 1);
  603. }
  604. SHA256_Final(bytes, &sha256Ctx);
  605. }
  606. void Connection::onDisconnectedInternal(int32_t reason, int32_t error) {
  607. reconnectTimer->stop();
  608. if (LOGS_ENABLED) DEBUG_D("connection(%p, account%u, dc%u, type %d) disconnected with reason %d", this, currentDatacenter->instanceNum, currentDatacenter->getDatacenterId(), connectionType, reason);
  609. bool switchToNextPort = reason == 2 && wasConnected && (!hasSomeDataSinceLastConnect || currentDatacenter->isCustomPort(currentAddressFlags)) || forceNextPort;
  610. if (connectionType == ConnectionTypeGeneric || connectionType == ConnectionTypeTemp || connectionType == ConnectionTypeGenericMedia) {
  611. if (wasConnected && reason == 2 && currentTimeout < 16) {
  612. currentTimeout += 2;
  613. }
  614. }
  615. firstPacketSent = false;
  616. if (restOfTheData != nullptr) {
  617. restOfTheData->reuse();
  618. restOfTheData = nullptr;
  619. }
  620. lastPacketLength = 0;
  621. receivedDataAmount = 0;
  622. wasConnected = false;
  623. if (connectionState != TcpConnectionStageSuspended && connectionState != TcpConnectionStageIdle) {
  624. connectionState = TcpConnectionStageIdle;
  625. }
  626. ConnectionsManager::getInstance(currentDatacenter->instanceNum).onConnectionClosed(this, reason);
  627. connectionToken = 0;
  628. uint32_t datacenterId = currentDatacenter->getDatacenterId();
  629. if (connectionState == TcpConnectionStageIdle) {
  630. connectionState = TcpConnectionStageReconnecting;
  631. failedConnectionCount++;
  632. if (failedConnectionCount == 1) {
  633. if (hasUsefullData()) {
  634. willRetryConnectCount = 3;
  635. } else {
  636. willRetryConnectCount = 1;
  637. }
  638. }
  639. if (ConnectionsManager::getInstance(currentDatacenter->instanceNum).isNetworkAvailable() && connectionType != ConnectionTypeProxy) {
  640. isTryingNextPort = true;
  641. if (failedConnectionCount > willRetryConnectCount || switchToNextPort) {
  642. currentDatacenter->nextAddressOrPort(currentAddressFlags);
  643. if (currentDatacenter->isRepeatCheckingAddresses() && (ConnectionsManager::getInstance(currentDatacenter->instanceNum).getIpStratagy() == USE_IPV4_ONLY || ConnectionsManager::getInstance(currentDatacenter->instanceNum).getIpStratagy() == USE_IPV6_ONLY)) {
  644. if (LOGS_ENABLED) DEBUG_D("started retrying connection, set ipv4 ipv6 random strategy");
  645. ConnectionsManager::getInstance(currentDatacenter->instanceNum).setIpStrategy(USE_IPV4_IPV6_RANDOM);
  646. }
  647. failedConnectionCount = 0;
  648. }
  649. }
  650. if (error == 0x68 || error == 0x71) {
  651. if (connectionType != ConnectionTypeProxy) {
  652. waitForReconnectTimer = true;
  653. reconnectTimer->setTimeout(lastReconnectTimeout, false);
  654. lastReconnectTimeout *= 2;
  655. if (lastReconnectTimeout > 400) {
  656. lastReconnectTimeout = 400;
  657. }
  658. reconnectTimer->start();
  659. }
  660. } else {
  661. waitForReconnectTimer = false;
  662. if (connectionType == ConnectionTypeGenericMedia && currentDatacenter->isHandshaking(true) || connectionType == ConnectionTypeGeneric && (currentDatacenter->isHandshaking(false) || datacenterId == ConnectionsManager::getInstance(currentDatacenter->instanceNum).currentDatacenterId || datacenterId == ConnectionsManager::getInstance(currentDatacenter->instanceNum).movingToDatacenterId)) {
  663. if (LOGS_ENABLED) DEBUG_D("connection(%p, account%u, dc%u, type %d) reconnect %s:%hu", this, currentDatacenter->instanceNum, currentDatacenter->getDatacenterId(), connectionType, hostAddress.c_str(), hostPort);
  664. reconnectTimer->setTimeout(1000, false);
  665. reconnectTimer->start();
  666. }
  667. }
  668. }
  669. usefullData = false;
  670. }
  671. void Connection::onDisconnected(int32_t reason, int32_t error) {
  672. if (connectionInProcess) {
  673. ConnectionsManager::getInstance(currentDatacenter->instanceNum).scheduleTask([&, reason, error] {
  674. onDisconnectedInternal(reason, error);
  675. });
  676. } else {
  677. onDisconnectedInternal(reason, error);
  678. }
  679. }
  680. void Connection::onConnected() {
  681. connectionState = TcpConnectionStageConnected;
  682. connectionToken = lastConnectionToken++;
  683. wasConnected = true;
  684. if (LOGS_ENABLED) DEBUG_D("connection(%p, account%u, dc%u, type %d) connected to %s:%hu", this, currentDatacenter->instanceNum, currentDatacenter->getDatacenterId(), connectionType, hostAddress.c_str(), hostPort);
  685. ConnectionsManager::getInstance(currentDatacenter->instanceNum).onConnectionConnected(this);
  686. }
  687. bool Connection::hasPendingRequests() {
  688. return ConnectionsManager::getInstance(currentDatacenter->instanceNum).hasPendingRequestsForConnection(this);
  689. }
  690. Datacenter *Connection::getDatacenter() {
  691. return currentDatacenter;
  692. }
  693. ConnectionType Connection::getConnectionType() {
  694. return connectionType;
  695. }
  696. int8_t Connection::getConnectionNum() {
  697. return connectionNum;
  698. }
  699. uint32_t Connection::getConnectionToken() {
  700. return connectionToken;
  701. }