mirror of https://github.com/procxx/kepka.git
fixed webpage preview layout, switched to abridged version of the tcp protocol
This commit is contained in:
parent
759e062bcc
commit
f5dd8f8112
Telegram/SourceFiles
|
@ -455,6 +455,25 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
bool readSkipBlockCommand() {
|
||||
const QChar *afterCmd = textSkipCommand(ptr, end, links.size() < 0x7FFF);
|
||||
if (afterCmd == ptr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
ushort cmd = (++ptr)->unicode();
|
||||
++ptr;
|
||||
|
||||
switch (cmd) {
|
||||
case TextCommandSkipBlock:
|
||||
createSkipBlock(ptr->unicode(), (ptr + 1)->unicode());
|
||||
break;
|
||||
}
|
||||
|
||||
ptr = afterCmd;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool readCommand() {
|
||||
const QChar *afterCmd = textSkipCommand(ptr, end, links.size() < 0x7FFF);
|
||||
if (afterCmd == ptr) {
|
||||
|
@ -530,7 +549,6 @@ public:
|
|||
} break;
|
||||
|
||||
case TextCommandSkipBlock:
|
||||
createBlock();
|
||||
createSkipBlock(ptr->unicode(), (ptr + 1)->unicode());
|
||||
break;
|
||||
|
||||
|
@ -703,6 +721,13 @@ public:
|
|||
if (sumFinished || _t->_text.size() >= 0x8000) break; // 32k max
|
||||
}
|
||||
createBlock();
|
||||
if (sumFinished && rich) { // we could've skipped the final skip block command
|
||||
for (; ptr < end; ++ptr) {
|
||||
if (*ptr == TextCommand && readSkipBlockCommand()) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
removeFlags.clear();
|
||||
|
||||
_t->_links.resize(maxLnkIndex);
|
||||
|
|
|
@ -405,33 +405,44 @@ namespace {
|
|||
return mayBeBadKey;
|
||||
}
|
||||
|
||||
mtpBuffer _handleTcpResponse(mtpPrime *packet, uint32 size) {
|
||||
if (size < 4 || size * sizeof(mtpPrime) > MTPPacketSizeMax) {
|
||||
LOG(("TCP Error: bad packet size %1").arg(size * sizeof(mtpPrime)));
|
||||
uint32 _tcpPacketSize(const char *packet) { // must have at least 4 bytes readable
|
||||
uint32 result = (packet[0] > 0) ? packet[0] : 0;
|
||||
if (result == 0x7f) {
|
||||
const uchar *bytes = reinterpret_cast<const uchar*>(packet);
|
||||
result = (((uint32(bytes[3]) << 8) | uint32(bytes[2])) << 8) | uint32(bytes[1]);
|
||||
return (result << 2) + 4;
|
||||
}
|
||||
return (result << 2) + 1;
|
||||
}
|
||||
|
||||
mtpBuffer _handleTcpResponse(const char *packet, uint32 length) {
|
||||
if (length < 5 || length > MTPPacketSizeMax) {
|
||||
LOG(("TCP Error: bad packet size %1").arg(length));
|
||||
return mtpBuffer(1, -500);
|
||||
}
|
||||
if (packet[0] != int32(size * sizeof(mtpPrime))) {
|
||||
int32 size = packet[0], len = length - 1;
|
||||
if (size == 0x7f) {
|
||||
const uchar *bytes = reinterpret_cast<const uchar*>(packet);
|
||||
size = (((uint32(bytes[3]) << 8) | uint32(bytes[2])) << 8) | uint32(bytes[1]);
|
||||
len -= 3;
|
||||
}
|
||||
if (size * sizeof(mtpPrime) != len) {
|
||||
LOG(("TCP Error: bad packet header"));
|
||||
TCP_LOG(("TCP Error: bad packet header, packet: %1").arg(Logs::mb(packet, size * sizeof(mtpPrime)).str()));
|
||||
TCP_LOG(("TCP Error: bad packet header, packet: %1").arg(Logs::mb(packet, length).str()));
|
||||
return mtpBuffer(1, -500);
|
||||
}
|
||||
if (packet[size - 1] != hashCrc32(packet, (size - 1) * sizeof(mtpPrime))) {
|
||||
LOG(("TCP Error: bad packet checksum"));
|
||||
TCP_LOG(("TCP Error: bad packet checksum, packet: %1").arg(Logs::mb(packet, size * sizeof(mtpPrime)).str()));
|
||||
return mtpBuffer(1, -500);
|
||||
}
|
||||
TCP_LOG(("TCP Info: packet received, num = %1, size = %2").arg(packet[1]).arg(size * sizeof(mtpPrime)));
|
||||
if (size == 4) {
|
||||
if (packet[2] == -429) {
|
||||
TCP_LOG(("TCP Info: packet received, size = %1").arg(size * sizeof(mtpPrime)));
|
||||
if (size == 1) {
|
||||
if (packet[0] == -429) {
|
||||
LOG(("Protocol Error: -429 flood code returned!"));
|
||||
} else {
|
||||
LOG(("TCP Error: error packet received, code = %1").arg(packet[2]));
|
||||
LOG(("TCP Error: error packet received, code = %1").arg(packet[0]));
|
||||
}
|
||||
return mtpBuffer(1, packet[2]);
|
||||
return mtpBuffer(1, packet[0]);
|
||||
}
|
||||
|
||||
mtpBuffer data(size - 3);
|
||||
memcpy(data.data(), packet + 2, (size - 3) * sizeof(mtpPrime));
|
||||
mtpBuffer data(size);
|
||||
memcpy(data.data(), packet + (length - len), size * sizeof(mtpPrime));
|
||||
|
||||
return data;
|
||||
}
|
||||
|
@ -557,7 +568,7 @@ void MTPabstractTcpConnection::socketRead() {
|
|||
if (packetLeft) {
|
||||
packetLeft -= bytes;
|
||||
if (!packetLeft) {
|
||||
socketPacket((mtpPrime*)(currentPos - packetRead), packetRead >> 2);
|
||||
socketPacket(currentPos - packetRead, packetRead);
|
||||
currentPos = (char*)shortBuffer;
|
||||
packetRead = packetLeft = 0;
|
||||
readingToShort = true;
|
||||
|
@ -568,14 +579,14 @@ void MTPabstractTcpConnection::socketRead() {
|
|||
} else {
|
||||
bool move = false;
|
||||
while (packetRead >= 4) {
|
||||
uint32 packetSize = *(uint32*)(currentPos - packetRead);
|
||||
if (packetSize < 16 || packetSize > MTPPacketSizeMax || (packetSize & 0x03)) {
|
||||
uint32 packetSize = _tcpPacketSize(currentPos - packetRead);
|
||||
if (packetSize < 5 || packetSize > MTPPacketSizeMax) {
|
||||
LOG(("TCP Error: packet size = %1").arg(packetSize));
|
||||
emit error();
|
||||
return;
|
||||
}
|
||||
if (packetRead >= packetSize) {
|
||||
socketPacket((mtpPrime*)(currentPos - packetRead), packetSize >> 2);
|
||||
socketPacket(currentPos - packetRead, packetSize);
|
||||
packetRead -= packetSize;
|
||||
packetLeft = 0;
|
||||
move = true;
|
||||
|
@ -704,15 +715,41 @@ void MTPautoConnection::sendData(mtpBuffer &buffer) {
|
|||
}
|
||||
}
|
||||
|
||||
uint32 FourCharsToUInt(char ch1, char ch2, char ch3, char ch4) {
|
||||
char ch[4] = { ch1, ch2, ch3, ch4 };
|
||||
return *reinterpret_cast<uint32*>(ch);
|
||||
}
|
||||
|
||||
void MTPautoConnection::tcpSend(mtpBuffer &buffer) {
|
||||
uint32 size = buffer.size(), len = size * 4;
|
||||
if (!packetNum) {
|
||||
char nonce[64];
|
||||
uint32 *first = reinterpret_cast<uint32*>(nonce), *second = first + 1;
|
||||
uint32 g1 = FourCharsToUInt('P', 'O', 'S', 'T'), g2 = FourCharsToUInt('G', 'E', 'T', ' '), g3 = FourCharsToUInt('H', 'E', 'A', 'D');
|
||||
uint32 first1 = 0x44414548U, first2 = 0x54534f50U, first3 = 0x20544547U, first4 = 0x20544547U, first5 = 0xeeeeeeeeU;
|
||||
uint32 second1 = 0;
|
||||
do {
|
||||
memset_rand(nonce, sizeof(nonce));
|
||||
} while (*first == first1 || *first == first2 || *first == first3 || *first == first4 || *first == first5 || *second == second1 || nonce[0] == 0xef);
|
||||
sock.write(nonce, sizeof(nonce));
|
||||
}
|
||||
++packetNum;
|
||||
|
||||
buffer[0] = len;
|
||||
buffer[1] = packetNum++;
|
||||
buffer[size - 1] = hashCrc32(&buffer[0], len - 4);
|
||||
TCP_LOG(("TCP Info: write %1 packet %2 bytes").arg(packetNum).arg(len));
|
||||
uint32 size = buffer.size() - 3, len = size * 4;
|
||||
char *data = reinterpret_cast<char*>(&buffer[0]);
|
||||
if (size < 0x7f) {
|
||||
data[7] = char(size);
|
||||
TCP_LOG(("TCP Info: write %1 packet %2").arg(packetNum).arg(len + 1));
|
||||
|
||||
sock.write((const char*)&buffer[0], len);
|
||||
sock.write(data + 7, len + 1);
|
||||
} else {
|
||||
data[4] = 0x7f;
|
||||
reinterpret_cast<uchar*>(data)[5] = uchar(size & 0xFF);
|
||||
reinterpret_cast<uchar*>(data)[6] = uchar((size >> 8) & 0xFF);
|
||||
reinterpret_cast<uchar*>(data)[7] = uchar((size >> 16) & 0xFF);
|
||||
TCP_LOG(("TCP Info: write %1 packet %2").arg(packetNum).arg(len + 4));
|
||||
|
||||
sock.write(data + 4, len + 4);
|
||||
}
|
||||
}
|
||||
|
||||
void MTPautoConnection::httpSend(mtpBuffer &buffer) {
|
||||
|
@ -831,10 +868,10 @@ void MTPautoConnection::requestFinished(QNetworkReply *reply) {
|
|||
}
|
||||
}
|
||||
|
||||
void MTPautoConnection::socketPacket(mtpPrime *packet, uint32 size) {
|
||||
void MTPautoConnection::socketPacket(const char *packet, uint32 length) {
|
||||
if (status == FinishedWork) return;
|
||||
|
||||
mtpBuffer data = _handleTcpResponse(packet, size);
|
||||
mtpBuffer data = _handleTcpResponse(packet, length);
|
||||
if (data.size() == 1) {
|
||||
if (status == WaitingBoth) {
|
||||
status = WaitingHttp;
|
||||
|
@ -984,14 +1021,35 @@ void MTPtcpConnection::sendData(mtpBuffer &buffer) {
|
|||
return;
|
||||
}
|
||||
|
||||
uint32 size = buffer.size(), len = size * 4;
|
||||
if (!packetNum) {
|
||||
char nonce[64];
|
||||
uint32 *first = reinterpret_cast<uint32*>(nonce), *second = first + 1;
|
||||
uint32 g1 = FourCharsToUInt('P', 'O', 'S', 'T'), g2 = FourCharsToUInt('G', 'E', 'T', ' '), g3 = FourCharsToUInt('H', 'E', 'A', 'D');
|
||||
uint32 first1 = 0x44414548U, first2 = 0x54534f50U, first3 = 0x20544547U, first4 = 0x20544547U, first5 = 0xeeeeeeeeU;
|
||||
uint32 second1 = 0;
|
||||
do {
|
||||
memset_rand(nonce, sizeof(nonce));
|
||||
} while (*first == first1 || *first == first2 || *first == first3 || *first == first4 || *first == first5 || *second == second1 || nonce[0] == 0xef);
|
||||
sock.write(nonce, sizeof(nonce));
|
||||
}
|
||||
++packetNum;
|
||||
|
||||
buffer[0] = len;
|
||||
buffer[1] = packetNum++;
|
||||
buffer[size - 1] = hashCrc32(&buffer[0], len - 4);
|
||||
TCP_LOG(("TCP Info: write %1 packet %2 bytes %3").arg(packetNum).arg(len).arg(Logs::mb(&buffer[0], len).str()));
|
||||
uint32 size = buffer.size() - 3, len = size * 4;
|
||||
char *data = reinterpret_cast<char*>(&buffer[0]);
|
||||
if (size < 0x7f) {
|
||||
data[7] = char(size);
|
||||
TCP_LOG(("TCP Info: write %1 packet %2").arg(packetNum).arg(len + 1));
|
||||
|
||||
sock.write((const char*)&buffer[0], len);
|
||||
sock.write(data + 7, len + 1);
|
||||
} else {
|
||||
data[4] = 0x7f;
|
||||
reinterpret_cast<uchar*>(data)[5] = uchar(size & 0xFF);
|
||||
reinterpret_cast<uchar*>(data)[6] = uchar((size >> 8) & 0xFF);
|
||||
reinterpret_cast<uchar*>(data)[7] = uchar((size >> 16) & 0xFF);
|
||||
TCP_LOG(("TCP Info: write %1 packet %2").arg(packetNum).arg(len + 4));
|
||||
|
||||
sock.write(data + 4, len + 4);
|
||||
}
|
||||
}
|
||||
|
||||
void MTPtcpConnection::disconnectFromServer() {
|
||||
|
@ -1011,10 +1069,10 @@ void MTPtcpConnection::connectToServer(const QString &addr, int32 port, int32 fl
|
|||
sock.connectToHost(QHostAddress(_addr), _port);
|
||||
}
|
||||
|
||||
void MTPtcpConnection::socketPacket(mtpPrime *packet, uint32 size) {
|
||||
void MTPtcpConnection::socketPacket(const char *packet, uint32 length) {
|
||||
if (status == FinishedWork) return;
|
||||
|
||||
mtpBuffer data = _handleTcpResponse(packet, size);
|
||||
mtpBuffer data = _handleTcpResponse(packet, length);
|
||||
if (data.size() == 1) {
|
||||
bool mayBeBadKey = (data[0] == -410) && _sentEncrypted;
|
||||
emit error(mayBeBadKey);
|
||||
|
|
|
@ -168,7 +168,7 @@ protected:
|
|||
char *currentPos;
|
||||
mtpBuffer longBuffer;
|
||||
mtpPrime shortBuffer[MTPShortBufferSize];
|
||||
virtual void socketPacket(mtpPrime *packet, uint32 packetSize) = 0;
|
||||
virtual void socketPacket(const char *packet, uint32 length) = 0;
|
||||
|
||||
};
|
||||
|
||||
|
@ -203,7 +203,7 @@ public slots:
|
|||
|
||||
protected:
|
||||
|
||||
void socketPacket(mtpPrime *packet, uint32 packetSize);
|
||||
void socketPacket(const char *packet, uint32 length);
|
||||
|
||||
private:
|
||||
|
||||
|
@ -261,7 +261,7 @@ public slots:
|
|||
|
||||
protected:
|
||||
|
||||
void socketPacket(mtpPrime *packet, uint32 packetSize);
|
||||
void socketPacket(const char *packet, uint32 length);
|
||||
|
||||
private:
|
||||
|
||||
|
@ -285,7 +285,7 @@ class MTPhttpConnection : public MTPabstractConnection {
|
|||
public:
|
||||
|
||||
MTPhttpConnection(QThread *thread);
|
||||
|
||||
|
||||
void sendData(mtpBuffer &buffer);
|
||||
void disconnectFromServer();
|
||||
void connectToServer(const QString &addr, int32 port, int32 flags);
|
||||
|
@ -441,7 +441,7 @@ private:
|
|||
|
||||
// if badTime received - search for ids in sessionData->haveSent and sessionData->wereAcked and sync time/salt, return true if found
|
||||
bool requestsFixTimeSalt(const QVector<MTPlong> &ids, int32 serverTime, uint64 serverSalt);
|
||||
|
||||
|
||||
// remove msgs with such ids from sessionData->haveSent, add to sessionData->wereAcked
|
||||
void requestsAcked(const QVector<MTPlong> &ids, bool byResponse = false);
|
||||
|
||||
|
@ -491,7 +491,7 @@ private:
|
|||
MTPlong retry_id;
|
||||
|
||||
int32 g;
|
||||
|
||||
|
||||
uchar aesKey[32], aesIV[32];
|
||||
uint32 auth_key[64];
|
||||
MTPlong auth_key_hash;
|
||||
|
|
Loading…
Reference in New Issue