Untitled
unknown
c_cpp
6 months ago
6.4 kB
3
Indexable
NativeByteBuffer *Datacenter::createRequestsData(std::vector<std::unique_ptr<NetworkMessage>> &requests, int32_t *quickAckId, Connection *connection, bool pfsInit) { int64_t authKeyId; ByteArray *authKey = getAuthKey(connection->getConnectionType(), pfsInit, &authKeyId, 1); if (authKey == nullptr) { return nullptr; } int64_t messageId; TLObject *messageBody; bool freeMessageBody = false; int32_t messageSeqNo; if (requests.size() == 1) { NetworkMessage *networkMessage = requests[0].get(); if (networkMessage->message->outgoingBody != nullptr) { messageBody = networkMessage->message->outgoingBody; } else { messageBody = networkMessage->message->body.get(); } if (LOGS_ENABLED) DEBUG_D("connection(%p, account%u, dc%u, type %d) send message (session: 0x%" PRIx64 ", seqno: %d, messageid: 0x%" PRIx64 "): %s(%p)", connection, instanceNum, datacenterId, connection->getConnectionType(), (uint64_t) connection->getSessionId(), networkMessage->message->seqno, (uint64_t) networkMessage->message->msg_id, typeid(*messageBody).name(), messageBody); auto messageTime = (int64_t) (networkMessage->message->msg_id / 4294967296.0 * 1000); int64_t currentTime = ConnectionsManager::getInstance(instanceNum).getCurrentTimeMillis() + (int64_t) ConnectionsManager::getInstance(instanceNum).getTimeDifference() * 1000; if (!pfsInit && (networkMessage->forceContainer || messageTime < currentTime - 30000 || messageTime > currentTime + 25000)) { if (LOGS_ENABLED) DEBUG_D("wrap message in container"); auto messageContainer = new TL_msg_container(); messageContainer->messages.push_back(std::move(networkMessage->message)); messageId = ConnectionsManager::getInstance(instanceNum).generateMessageId(); messageBody = messageContainer; messageSeqNo = connection->generateMessageSeqNo(false); freeMessageBody = true; } else { messageId = networkMessage->message->msg_id; messageSeqNo = networkMessage->message->seqno; } } else { if (LOGS_ENABLED) DEBUG_D("start write messages to container"); auto messageContainer = new TL_msg_container(); size_t count = requests.size(); for (uint32_t a = 0; a < count; a++) { NetworkMessage *networkMessage = requests[a].get(); if (networkMessage->message->outgoingBody != nullptr) { messageBody = networkMessage->message->outgoingBody; } else { messageBody = networkMessage->message->body.get(); } if (LOGS_ENABLED) DEBUG_D("connection(%p, account%u, dc%u, type %d) send message (session: 0x%" PRIx64 ", seqno: %d, messageid: 0x%" PRIx64 "): %s(%p)", connection, instanceNum, datacenterId, connection->getConnectionType(), (uint64_t) connection->getSessionId(), networkMessage->message->seqno, (uint64_t) networkMessage->message->msg_id, typeid(*messageBody).name(), messageBody); messageContainer->messages.push_back(std::unique_ptr<TL_message>(std::move(networkMessage->message))); } messageId = ConnectionsManager::getInstance(instanceNum).generateMessageId(); messageBody = messageContainer; freeMessageBody = true; messageSeqNo = connection->generateMessageSeqNo(false); } int32_t mtProtoVersion; if (pfsInit) { mtProtoVersion = 1; } else { mtProtoVersion = 2; } uint32_t messageSize = messageBody->getObjectSize(); uint32_t additionalSize = (32 + messageSize) % 16; if (additionalSize != 0) { additionalSize = 16 - additionalSize; } if (mtProtoVersion == 2) { uint8_t index; RAND_bytes(&index, 1); additionalSize += (2 + (index % 14)) * 16; } NativeByteBuffer *buffer = BuffersStorage::getInstance().getFreeBuffer(24 + 32 + messageSize + additionalSize); buffer->writeInt64(authKeyId); buffer->position(24); if (pfsInit) { int64_t value; RAND_bytes((uint8_t *) &value, 8); buffer->writeInt64(value); RAND_bytes((uint8_t *) &value, 8); buffer->writeInt64(value); } else { buffer->writeInt64(getServerSalt(Connection::isMediaConnectionType(connection->getConnectionType()))); buffer->writeInt64(connection->getSessionId()); } buffer->writeInt64(messageId); buffer->writeInt32(messageSeqNo); buffer->writeInt32(messageSize); messageBody->serializeToStream(buffer); if (freeMessageBody) { delete messageBody; } if (additionalSize != 0) { RAND_bytes(buffer->bytes() + 24 + 32 + messageSize, additionalSize); } thread_local static uint8_t messageKey[96]; switch (mtProtoVersion) { case 2: { SHA256_Init(&sha256Ctx); SHA256_Update(&sha256Ctx, authKey->bytes + 88, 32); SHA256_Update(&sha256Ctx, buffer->bytes() + 24, 32 + messageSize + additionalSize); SHA256_Final(messageKey, &sha256Ctx); if (quickAckId != nullptr) { *quickAckId = (((messageKey[0] & 0xff)) | ((messageKey[1] & 0xff) << 8) | ((messageKey[2] & 0xff) << 16) | ((messageKey[3] & 0xff) << 24)) & 0x7fffffff; } break; } default: { SHA1(buffer->bytes() + 24, 32 + messageSize, messageKey + 4); if (quickAckId != nullptr) { *quickAckId = (((messageKey[4] & 0xff)) | ((messageKey[5] & 0xff) << 8) | ((messageKey[6] & 0xff) << 16) | ((messageKey[7] & 0xff) << 24)) & 0x7fffffff; } break; } } memcpy(buffer->bytes() + 8, messageKey + 8, 16); generateMessageKey(instanceNum, authKey->bytes, messageKey + 8, messageKey + 32, false, mtProtoVersion); aesIgeEncryption(buffer->bytes() + 24, messageKey + 32, messageKey + 64, true, false, buffer->limit() - 24); return buffer; }
Editor is loading...
Leave a Comment