Untitled
unknown
c_cpp
a year ago
6.4 kB
7
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