mtproto_tcp_socket.cpp 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. /*
  2. This file is part of Telegram Desktop,
  3. the official desktop application for the Telegram messaging service.
  4. For license and copyright information please follow this link:
  5. https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
  6. */
  7. #include "mtproto/details/mtproto_tcp_socket.h"
  8. #include "base/invoke_queued.h"
  9. namespace MTP::details {
  10. TcpSocket::TcpSocket(
  11. not_null<QThread*> thread,
  12. const QNetworkProxy &proxy,
  13. bool protocolForFiles)
  14. : AbstractSocket(thread) {
  15. _socket.moveToThread(thread);
  16. _socket.setProxy(proxy);
  17. if (protocolForFiles) {
  18. _socket.setSocketOption(
  19. QAbstractSocket::SendBufferSizeSocketOption,
  20. kFilesSendBufferSize);
  21. _socket.setSocketOption(
  22. QAbstractSocket::ReceiveBufferSizeSocketOption,
  23. kFilesReceiveBufferSize);
  24. }
  25. const auto wrap = [&](auto handler) {
  26. return [=](auto &&...args) {
  27. InvokeQueued(this, [=] { handler(args...); });
  28. };
  29. };
  30. using Error = QAbstractSocket::SocketError;
  31. connect(
  32. &_socket,
  33. &QTcpSocket::connected,
  34. wrap([=] { _connected.fire({}); }));
  35. connect(
  36. &_socket,
  37. &QTcpSocket::disconnected,
  38. wrap([=] { _disconnected.fire({}); }));
  39. connect(
  40. &_socket,
  41. &QTcpSocket::readyRead,
  42. wrap([=] { _readyRead.fire({}); }));
  43. connect(
  44. &_socket,
  45. &QAbstractSocket::errorOccurred,
  46. wrap([=](Error e) { handleError(e); }));
  47. }
  48. void TcpSocket::connectToHost(const QString &address, int port) {
  49. _socket.connectToHost(address, port);
  50. }
  51. bool TcpSocket::isGoodStartNonce(bytes::const_span nonce) {
  52. Expects(nonce.size() >= 2 * sizeof(uint32));
  53. const auto bytes = nonce.data();
  54. const auto zero = *reinterpret_cast<const uchar*>(bytes);
  55. const auto first = *reinterpret_cast<const uint32*>(bytes);
  56. const auto second = *(reinterpret_cast<const uint32*>(bytes) + 1);
  57. const auto reserved01 = 0x000000EFU;
  58. const auto reserved11 = 0x44414548U;
  59. const auto reserved12 = 0x54534F50U;
  60. const auto reserved13 = 0x20544547U;
  61. const auto reserved14 = 0xEEEEEEEEU;
  62. const auto reserved15 = 0xDDDDDDDDU;
  63. const auto reserved16 = 0x02010316U;
  64. const auto reserved21 = 0x00000000U;
  65. return (zero != reserved01)
  66. && (first != reserved11)
  67. && (first != reserved12)
  68. && (first != reserved13)
  69. && (first != reserved14)
  70. && (first != reserved15)
  71. && (first != reserved16)
  72. && (second != reserved21);
  73. }
  74. void TcpSocket::timedOut() {
  75. }
  76. bool TcpSocket::isConnected() {
  77. return (_socket.state() == QAbstractSocket::ConnectedState);
  78. }
  79. bool TcpSocket::hasBytesAvailable() {
  80. return _socket.bytesAvailable() > 0;
  81. }
  82. int64 TcpSocket::read(bytes::span buffer) {
  83. return _socket.read(
  84. reinterpret_cast<char*>(buffer.data()),
  85. buffer.size());
  86. }
  87. void TcpSocket::write(bytes::const_span prefix, bytes::const_span buffer) {
  88. Expects(!buffer.empty());
  89. if (!prefix.empty()) {
  90. _socket.write(
  91. reinterpret_cast<const char*>(prefix.data()),
  92. prefix.size());
  93. }
  94. _socket.write(
  95. reinterpret_cast<const char*>(buffer.data()),
  96. buffer.size());
  97. }
  98. int32 TcpSocket::debugState() {
  99. return _socket.state();
  100. }
  101. QString TcpSocket::debugPostfix() const {
  102. return QString();
  103. }
  104. void TcpSocket::handleError(int errorCode) {
  105. logError(errorCode, _socket.errorString());
  106. _error.fire({});
  107. }
  108. } // namespace MTP::details