1
0
mirror of https://github.com/danog/libtgvoip.git synced 2024-11-30 04:39:03 +01:00

Fix legaacy support

This commit is contained in:
Daniil Gentili 2020-03-28 17:05:24 +01:00
parent bb62971f5f
commit 0dc1e6c96d
Signed by: danog
GPG Key ID: 8C1BE3B34B230CA7
11 changed files with 57 additions and 32 deletions

View File

@ -187,7 +187,7 @@ public:
setNetworkType(initialNetworkType); setNetworkType(initialNetworkType);
controller_->SetEncryptionKey(encryptionKey.value, encryptionKey.isOutgoing); controller_->SetEncryptionKey(encryptionKey.value, encryptionKey.isOutgoing);
controller_->SetRemoteEndpoints(mappedEndpoints, config.enableP2P, 110); controller_->SetRemoteEndpoints(mappedEndpoints, config.enableP2P, config.maxApiLayer);
controller_->Start(); controller_->Start();

View File

@ -5,6 +5,7 @@
// //
#pragma once #pragma once
//#define LOG_PACKETS 1
#include <array> #include <array>

View File

@ -43,7 +43,6 @@ int64_t VoIPController::GetPreferredRelayID()
void VoIPController::SetRemoteEndpoints(vector<Endpoint> endpoints, bool allowP2p, int32_t connectionMaxLayer) void VoIPController::SetRemoteEndpoints(vector<Endpoint> endpoints, bool allowP2p, int32_t connectionMaxLayer)
{ {
connectionMaxLayer = 110;
LOGW("Set remote endpoints, allowP2P=%d, connectionMaxLayer=%u", allowP2p ? 1 : 0, connectionMaxLayer); LOGW("Set remote endpoints, allowP2P=%d, connectionMaxLayer=%u", allowP2p ? 1 : 0, connectionMaxLayer);
assert(!runReceiver); assert(!runReceiver);
preferredRelay = 0; preferredRelay = 0;

View File

@ -38,7 +38,9 @@ void VoIPController::SendPacket(OutgoingPacket &&pkt, double retryInterval, doub
if (ver.isNew()) if (ver.isNew())
{ {
packet.prepare(pm, currentExtras, endpoint.id); packet.prepare(pm, currentExtras, endpoint.id);
//LOGW("Sending outgoing packet: %s", packet.print().c_str()); #ifdef LOG_PACKETS
LOGW("Sending outgoing packet: %s", packet.print().c_str());
#endif
//BufferOutputStream out(packet.getSize()); // Can precalc, should check if it's worth it //BufferOutputStream out(packet.getSize()); // Can precalc, should check if it's worth it
BufferOutputStream out(1500); BufferOutputStream out(1500);
@ -60,7 +62,9 @@ void VoIPController::SendPacket(OutgoingPacket &&pkt, double retryInterval, doub
packet.prepare(pm, currentExtras, endpoint.id, legacyPm, ver.peerVersion); packet.prepare(pm, currentExtras, endpoint.id, legacyPm, ver.peerVersion);
uint32_t seq = packet.legacySeq; uint32_t seq = packet.legacySeq;
LOGW("Sending (legacy) outgoing packet: %s", packet.print().c_str()); #ifdef LOG_PACKETS
LOGW("Sending legacy outgoing packet: %s", packet.print().c_str());
#endif
std::vector<std::pair<Buffer, bool>> out; std::vector<std::pair<Buffer, bool>> out;
packet.serializeLegacy(out, ver, state, callID); packet.serializeLegacy(out, ver, state, callID);

View File

@ -99,9 +99,6 @@ void VoIPController::ProcessIncomingPacket(NetworkPacket &npacket, Endpoint &src
} }
} }
} }
#ifdef LOG_PACKETS
LOGW("Got%s incoming packet: %s", packet.legacy ? " legacy" : "", packet.print().c_str());
#endif
packetsReceived++; packetsReceived++;
ProcessIncomingPacket(packet, srcEndpoint); ProcessIncomingPacket(packet, srcEndpoint);
@ -117,6 +114,10 @@ void VoIPController::ProcessIncomingPacket(NetworkPacket &npacket, Endpoint &src
void VoIPController::ProcessIncomingPacket(Packet &packet, Endpoint &srcEndpoint) void VoIPController::ProcessIncomingPacket(Packet &packet, Endpoint &srcEndpoint)
{ {
#ifdef LOG_PACKETS
LOGW("Got%s incoming packet: %s", packet.legacy ? " legacy" : "", packet.print().c_str());
#endif
// Use packet manager of outgoing stream // Use packet manager of outgoing stream
PacketManager &manager = outgoingStreams[packet.legacy ? StreamId::Signaling : packet.streamId]->packetManager; PacketManager &manager = outgoingStreams[packet.legacy ? StreamId::Signaling : packet.streamId]->packetManager;
@ -407,14 +408,13 @@ void VoIPController::ProcessExtraData(const Wrapped<Extra> &_data, Endpoint &src
{ {
receivedInitAck = true; receivedInitAck = true;
LOGE("Canceling init timeout");
messageThread.Cancel(initTimeoutID); messageThread.Cancel(initTimeoutID);
initTimeoutID = MessageThread::INVALID_ID; initTimeoutID = MessageThread::INVALID_ID;
LOGE("Canceled init timeout");
ver.peerVersion = data.peerVersion; ver.peerVersion = data.peerVersion;
if (data.minVersion > PROTOCOL_VERSION || data.peerVersion < MIN_PROTOCOL_VERSION) if (data.minVersion > PROTOCOL_VERSION || data.peerVersion < MIN_PROTOCOL_VERSION)
{ {
LOGE("Got incompatible protocol in initAck (minVersion %u, peerVersion %u)", data.minVersion, data.peerVersion);
lastError = ERROR_INCOMPATIBLE; lastError = ERROR_INCOMPATIBLE;
SetState(STATE_FAILED); SetState(STATE_FAILED);

View File

@ -6,7 +6,7 @@ void VoIPController::SendPacketReliably(PendingOutgoingPacket &pkt, double retry
{ {
ENFORCE_MSG_THREAD; ENFORCE_MSG_THREAD;
#ifdef LOG_PACKETS #ifdef LOG_PACKETS
LOGV("Send reliably, type=%u, len=%u, retry=%.3f, timeout=%.3f, tries=%hhu", type, unsigned(len), retryInterval, timeout, tries); LOGV("Send reliably, seqNo=%hhu, streamId=%u, len=%u, retry=%.3f, timeout=%.3f, tries=%hhu", pkt.pktInfo.seq, pkt.pktInfo.streamId, unsigned(pkt.packet->Length()), retryInterval, timeout, tries);
#endif #endif
reliablePackets.push_back(ReliableOutgoingPacket{std::move(pkt), reliablePackets.push_back(ReliableOutgoingPacket{std::move(pkt),
retryInterval, retryInterval,

View File

@ -82,7 +82,7 @@ bool Packet::parseLegacy(const BufferInputStream &in, const VersionInfo &ver)
} }
else if (type == PKT_STREAM_DATA || type == PKT_STREAM_DATA_X2 || type == PKT_STREAM_DATA_X3) else if (type == PKT_STREAM_DATA || type == PKT_STREAM_DATA_X2 || type == PKT_STREAM_DATA_X3)
{ {
for (uint8_t count = PKT_STREAM_DATA ? 1 : PKT_STREAM_DATA_X2 ? 2 : 3; count > 0; --count) for (uint8_t count = type == PKT_STREAM_DATA ? 1 : type == PKT_STREAM_DATA_X2 ? 2 : 3; count > 0; --count)
{ {
Packet *packet = this; Packet *packet = this;
if (count > 1) if (count > 1)
@ -94,15 +94,16 @@ bool Packet::parseLegacy(const BufferInputStream &in, const VersionInfo &ver)
uint8_t flags; uint8_t flags;
uint16_t len; uint16_t len;
if (!(in.TryRead(packet->streamId) && if (!(in.TryRead(flags) &&
in.TryRead(flags) && (flags & STREAM_DATA_FLAG_LEN16
flags & STREAM_DATA_FLAG_LEN16 ? in.TryRead(len)
? in.TryRead(len) : in.TryReadCompat<uint8_t>(len)) &&
: in.TryReadCompat<uint8_t>(len) && in.TryRead(packet->seq)))
in.TryRead(packet->seq))) // damn you autoindentation
return false; return false;
packet->streamId = flags & 0x3F;
packet->seq /= 60; // Constant frame duration packet->seq /= 60; // Constant frame duration
packet->seq += 1; // Account for seqs starting at 1
bool fragmented = static_cast<bool>(len & STREAM_DATA_XFLAG_FRAGMENTED); bool fragmented = static_cast<bool>(len & STREAM_DATA_XFLAG_FRAGMENTED);
bool extraFEC = static_cast<bool>(len & STREAM_DATA_XFLAG_EXTRA_FEC); bool extraFEC = static_cast<bool>(len & STREAM_DATA_XFLAG_EXTRA_FEC);
@ -142,7 +143,9 @@ bool Packet::parseLegacy(const BufferInputStream &in, const VersionInfo &ver)
} }
} }
} }
} else { }
else
{
LOGW("Got unknown legacy packet type %hhu (probably new packet)", type); LOGW("Got unknown legacy packet type %hhu (probably new packet)", type);
return false; return false;
} }
@ -170,7 +173,9 @@ void Packet::serializeLegacy(std::vector<std::pair<Buffer, bool>> &outArray, con
uint8_t type = extra.d->chooseType(ver.peerVersion); uint8_t type = extra.d->chooseType(ver.peerVersion);
#ifdef LOG_PACKETS
LOGW("Serializing separate legacy packet of type %s", VoIPController::GetPacketTypeString(type).c_str()); LOGW("Serializing separate legacy packet of type %s", VoIPController::GetPacketTypeString(type).c_str());
#endif
if (ver.peerVersion >= 8 || (!ver.peerVersion && ver.connectionMaxLayer >= 92)) if (ver.peerVersion >= 8 || (!ver.peerVersion && ver.connectionMaxLayer >= 92))
{ {
@ -228,7 +233,7 @@ void Packet::serializeLegacy(std::vector<std::pair<Buffer, bool>> &outArray, con
} }
if (data) if (data)
{ {
LOGW("Serializing legacy data len %u", (unsigned int)data->Length()); //LOGW("Serializing legacy data len %u", (unsigned int)data->Length());
BufferOutputStream out(1500); BufferOutputStream out(1500);
@ -253,11 +258,9 @@ void Packet::serializeLegacy(std::vector<std::pair<Buffer, bool>> &outArray, con
out.WriteByte(static_cast<uint8_t>(data->Length())); out.WriteByte(static_cast<uint8_t>(data->Length()));
} }
out.WriteInt32(seq * 60); out.WriteInt32((seq - 1) * 60); // Account for seq starting at 1
out.WriteBytes(*data); out.WriteBytes(*data);
//LOGE("SEND: For pts %u = seq %u, using seq %u", audioTimestampOut, audioTimestampOut/60 + 1, packetManager.getLocalSeq());
if (hasExtraFEC) if (hasExtraFEC)
{ {
out.Write(extraECArray, ver); out.Write(extraECArray, ver);

View File

@ -6,6 +6,7 @@
namespace tgvoip namespace tgvoip
{ {
#define PRINT_MASK(mask) (std::bitset<sizeof(mask) * 8>{mask}).to_string('-', '*').c_str()
#define SEQ_MAX 0xFFFFFFFF #define SEQ_MAX 0xFFFFFFFF
inline bool seqgt(uint32_t s1, uint32_t s2) inline bool seqgt(uint32_t s1, uint32_t s2)
@ -90,6 +91,12 @@ public:
// Check if local seq was acked // Check if local seq was acked
bool wasLocalAcked(uint32_t seq) const; bool wasLocalAcked(uint32_t seq) const;
// Get last mask returned from remote
inline uint32_t getLocalAckMask() const
{
return lastAckedSeqsMask;
}
private: private:
// Seqno of last acked packet // Seqno of last acked packet
uint32_t lastAckedSeq = 0; uint32_t lastAckedSeq = 0;

View File

@ -13,10 +13,10 @@ bool Packet::parse(const BufferInputStream &in, const VersionInfo &ver)
uint16_t length = 0; uint16_t length = 0;
uint8_t flags; uint8_t flags;
bool res = in.TryRead(seq) && bool res = in.TryRead(flags) &&
in.TryRead(seq) &&
in.TryRead(ackSeq) && in.TryRead(ackSeq) &&
in.TryRead(ackMask) && in.TryRead(ackMask);
in.TryRead(flags);
if (!res) if (!res)
return false; return false;
@ -76,10 +76,10 @@ void Packet::serialize(BufferOutputStream &out, const VersionInfo &ver) const
if (extraSignaling) if (extraSignaling)
flags |= Flags::ExtraSignaling; flags |= Flags::ExtraSignaling;
out.WriteByte(shortStreamId | (flags << 2));
out.WriteUInt32(seq); out.WriteUInt32(seq);
out.WriteUInt32(ackSeq); out.WriteUInt32(ackSeq);
out.WriteUInt32(ackMask); out.WriteUInt32(ackMask);
out.WriteByte(shortStreamId | (flags << 2));
if (shortStreamId == StreamId::Extended) if (shortStreamId == StreamId::Extended)
out.WriteByte(streamId); out.WriteByte(streamId);
@ -131,8 +131,8 @@ void Packet::prepare(PacketManager &pm, std::vector<UnacknowledgedExtraData> &cu
if (pm != legacyPm) if (pm != legacyPm)
{ {
legacySeq = legacyPm.nextLocalSeq(); legacySeq = legacyPm.nextLocalSeq();
ackSeq = pm.getLastRemoteSeq(); ackSeq = legacyPm.getLastRemoteSeq();
ackMask = pm.getRemoteAckMask(); ackMask = legacyPm.getRemoteAckMask();
} }
else else
{ {
@ -150,10 +150,16 @@ void Packet::prepare(PacketManager &pm, std::vector<UnacknowledgedExtraData> &cu
extraSignaling.v.push_back(extra.data); extraSignaling.v.push_back(extra.data);
if (extra.data.d->chooseType(peerVersion) == PKT_NOP) if (extra.data.d->chooseType(peerVersion) == PKT_NOP)
{ {
#ifdef LOG_PACKETS
LOGW("Adding legacy seq %u to extra %s", seq, extra.data.print().c_str());
#endif
extra.seqs.Add(seq); extra.seqs.Add(seq);
} }
else else
{ {
#ifdef LOG_PACKETS
LOGW("Adding legacy seq %u to extra %s", tmpLegacySeq, extra.data.print().c_str());
#endif
extra.seqs.Add(tmpLegacySeq++); extra.seqs.Add(tmpLegacySeq++);
} }
} }

View File

@ -3,6 +3,7 @@
#include "../../net/CongestionControl.h" #include "../../net/CongestionControl.h"
#include "../protocol/Extra.h" #include "../protocol/Extra.h"
#include "../protocol/Interface.h" #include "../protocol/Interface.h"
#include "PacketManager.h"
#include <memory> #include <memory>
#include <vector> #include <vector>
//#include "../net/PacketSender.h" //#include "../net/PacketSender.h"
@ -10,7 +11,6 @@
namespace tgvoip namespace tgvoip
{ {
class PacketSender; class PacketSender;
class PacketManager;
struct PendingOutgoingPacket struct PendingOutgoingPacket
{ {
PendingOutgoingPacket(std::shared_ptr<Buffer> &&_packet, CongestionControlPacket &&_pktInfo, int64_t _endpoint) : packet(std::move(_packet)), PendingOutgoingPacket(std::shared_ptr<Buffer> &&_packet, CongestionControlPacket &&_pktInfo, int64_t _endpoint) : packet(std::move(_packet)),
@ -142,7 +142,11 @@ public:
{ {
std::stringstream res; std::stringstream res;
res << ((data && data->Length()) ? "Data packet" : extraEC ? "EC packet" : extraSignaling ? "Signaling packet" : nopPacket ? "NOP packet" : "Empty packet"); res << ((data && data->Length()) ? "Data packet" : extraEC ? "EC packet" : extraSignaling ? "Signaling packet" : nopPacket ? "NOP packet" : "Empty packet");
res << " (seq=" << seq << ", legacySeq=" << legacySeq << ", streamId=" << int(streamId) << ")"; res << " (seq=" << seq << ", legacySeq=" << legacySeq;
#ifdef LOG_PACKETS
res << ", ackSeq=" << ackSeq << ", ackMask=" << PRINT_MASK(ackMask);
#endif
res << ", streamId=" << int(streamId) << ")";
if (extraEC) if (extraEC)
res << "; extraEC"; res << "; extraEC";
if (extraSignaling) if (extraSignaling)
@ -172,6 +176,7 @@ public:
streamId = 0; streamId = 0;
data = nullptr; data = nullptr;
recvTS = 0; recvTS = 0;
legacy = false;
for (auto &v : extraEC) { for (auto &v : extraEC) {
v.d = nullptr; v.d = nullptr;
} }

View File

@ -2,8 +2,6 @@
// Try unifying all flags, lengths and so on // Try unifying all flags, lengths and so on
packet$_ packet$_
seq:# ackSeq:# ackMask:# // Different sequence for each streamId
streamId:(## 2) // Max 2 streams, we don't need much anyway (0 and 3 are reserved values) streamId:(## 2) // Max 2 streams, we don't need much anyway (0 and 3 are reserved values)
// If 0, is a pure-service message // If 0, is a pure-service message
// If 1, is an audio packet // If 1, is an audio packet
@ -11,6 +9,8 @@ packet$_
// If 3, is packet from one of the group call streams // If 3, is packet from one of the group call streams
flags:(## 6) flags:(## 6)
seq:# ackSeq:# ackMask:# // Different sequence for each streamId
streamIdExtended:(streamId == 3 ? (## 8) : false) // Extended stream ID for group calls streamIdExtended:(streamId == 3 ? (## 8) : false) // Extended stream ID for group calls
length:(## flags.0 ? 11 : (streamId > 0 ? 8 : 0)) length:(## flags.0 ? 11 : (streamId > 0 ? 8 : 0))