1
0
mirror of https://github.com/danog/libtgvoip.git synced 2024-11-29 20:29:01 +01:00

Begin refactoring protocol structures

This commit is contained in:
Daniil Gentili 2020-03-17 20:11:27 +01:00
parent bbe8734bba
commit 16ff209ff7
Signed by: danog
GPG Key ID: 8C1BE3B34B230CA7
16 changed files with 513 additions and 199 deletions

View File

@ -20,6 +20,7 @@ controller/audio/OpusEncoder.cpp \
controller/audio/AudioPacketSender.cpp \
controller/net/PacketReassembler.cpp \
controller/protocol/PacketManager.cpp \
controller/protocol/PacketStructs.cpp \
VoIPGroupController.cpp \
VoIPServerConfig.cpp \
audio/AudioIO.cpp \

View File

@ -818,7 +818,8 @@ am__libtgvoip_la_SOURCES_DIST = TgVoip.cpp VoIPController.cpp \
controller/audio/OpusEncoder.cpp \
controller/audio/AudioPacketSender.cpp \
controller/net/PacketReassembler.cpp \
controller/protocol/PacketManager.cpp VoIPGroupController.cpp \
controller/protocol/PacketManager.cpp \
controller/protocol/PacketStructs.cpp VoIPGroupController.cpp \
VoIPServerConfig.cpp audio/AudioIO.cpp audio/AudioInput.cpp \
audio/AudioOutput.cpp audio/Resampler.cpp \
audio/AudioInputTester.cpp os/posix/NetworkSocketPosix.cpp \
@ -1759,7 +1760,8 @@ am__objects_12 = TgVoip.lo VoIPController.lo tools/Buffers.lo \
controller/audio/OpusEncoder.lo \
controller/audio/AudioPacketSender.lo \
controller/net/PacketReassembler.lo \
controller/protocol/PacketManager.lo VoIPGroupController.lo \
controller/protocol/PacketManager.lo \
controller/protocol/PacketStructs.lo VoIPGroupController.lo \
VoIPServerConfig.lo audio/AudioIO.lo audio/AudioInput.lo \
audio/AudioOutput.lo audio/Resampler.lo \
audio/AudioInputTester.lo os/posix/NetworkSocketPosix.lo \
@ -2076,6 +2078,7 @@ am__depfiles_remade = ./$(DEPDIR)/TgVoip.Plo \
controller/net/$(DEPDIR)/NetworkSocket.Plo \
controller/net/$(DEPDIR)/PacketReassembler.Plo \
controller/protocol/$(DEPDIR)/PacketManager.Plo \
controller/protocol/$(DEPDIR)/PacketStructs.Plo \
os/darwin/$(DEPDIR)/AudioInputAudioUnit.Plo \
os/darwin/$(DEPDIR)/AudioInputAudioUnitOSX.Plo \
os/darwin/$(DEPDIR)/AudioOutputAudioUnit.Plo \
@ -2393,7 +2396,8 @@ SRC = TgVoip.cpp VoIPController.cpp tools/Buffers.cpp \
controller/audio/OpusEncoder.cpp \
controller/audio/AudioPacketSender.cpp \
controller/net/PacketReassembler.cpp \
controller/protocol/PacketManager.cpp VoIPGroupController.cpp \
controller/protocol/PacketManager.cpp \
controller/protocol/PacketStructs.cpp VoIPGroupController.cpp \
VoIPServerConfig.cpp audio/AudioIO.cpp audio/AudioInput.cpp \
audio/AudioOutput.cpp audio/Resampler.cpp \
audio/AudioInputTester.cpp os/posix/NetworkSocketPosix.cpp \
@ -2571,6 +2575,9 @@ controller/protocol/$(DEPDIR)/$(am__dirstamp):
controller/protocol/PacketManager.lo: \
controller/protocol/$(am__dirstamp) \
controller/protocol/$(DEPDIR)/$(am__dirstamp)
controller/protocol/PacketStructs.lo: \
controller/protocol/$(am__dirstamp) \
controller/protocol/$(DEPDIR)/$(am__dirstamp)
audio/$(am__dirstamp):
@$(MKDIR_P) audio
@: > audio/$(am__dirstamp)
@ -4039,6 +4046,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@controller/net/$(DEPDIR)/NetworkSocket.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@controller/net/$(DEPDIR)/PacketReassembler.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@controller/protocol/$(DEPDIR)/PacketManager.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@controller/protocol/$(DEPDIR)/PacketStructs.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@os/darwin/$(DEPDIR)/AudioInputAudioUnit.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@os/darwin/$(DEPDIR)/AudioInputAudioUnitOSX.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@os/darwin/$(DEPDIR)/AudioOutputAudioUnit.Plo@am__quote@ # am--include-marker
@ -4929,6 +4937,7 @@ distclean: distclean-am
-rm -f controller/net/$(DEPDIR)/NetworkSocket.Plo
-rm -f controller/net/$(DEPDIR)/PacketReassembler.Plo
-rm -f controller/protocol/$(DEPDIR)/PacketManager.Plo
-rm -f controller/protocol/$(DEPDIR)/PacketStructs.Plo
-rm -f os/darwin/$(DEPDIR)/AudioInputAudioUnit.Plo
-rm -f os/darwin/$(DEPDIR)/AudioInputAudioUnitOSX.Plo
-rm -f os/darwin/$(DEPDIR)/AudioOutputAudioUnit.Plo
@ -5299,6 +5308,7 @@ maintainer-clean: maintainer-clean-am
-rm -f controller/net/$(DEPDIR)/NetworkSocket.Plo
-rm -f controller/net/$(DEPDIR)/PacketReassembler.Plo
-rm -f controller/protocol/$(DEPDIR)/PacketManager.Plo
-rm -f controller/protocol/$(DEPDIR)/PacketStructs.Plo
-rm -f os/darwin/$(DEPDIR)/AudioInputAudioUnit.Plo
-rm -f os/darwin/$(DEPDIR)/AudioInputAudioUnitOSX.Plo
-rm -f os/darwin/$(DEPDIR)/AudioOutputAudioUnit.Plo

View File

@ -62,7 +62,6 @@ enum ProtocolVersions
// Extra packet flags
#define XPFLAG_HAS_EXTRA 1 // Signaling
#define XPFLAG_HAS_RECV_TS 2 // Video calls
#define XPFLAG_HAS_TRANSPORT_ID 4 // TODO: remove, not used
// Extra signaling packet types
@ -74,6 +73,9 @@ enum ProtocolVersions
#define EXTRA_TYPE_REQUEST_GROUP 6
#define EXTRA_TYPE_IPV6_ENDPOINT 7
#define EXTRA_TYPE_INIT 8
#define EXTRA_TYPE_INIT_ACK 9
// Stream signaling flags
#define STREAM_FLAG_ENABLED 1
#define STREAM_FLAG_DTX 2

View File

@ -38,7 +38,7 @@ size_t VoIPController::decryptPacket(unsigned char *buffer, BufferInputStream &i
else
{
memcpy(buffer + in.GetOffset(), aesOut, in.Remaining());
in.ReadInt32();
return in.ReadInt32();
}
}

View File

@ -196,7 +196,7 @@ void JitterBuffer::PutInternal(const jitter_packet_t &pkt, bool overwriteExistin
slot->buffer = bufferPool.Get();
slot->recvTimeDiff = time - prevRecvTime;
slot->isEC = pkt.isEC;
slot->buffer.CopyFromOtherBuffer(pkt.buffer, pkt.size);
slot->buffer.CopyFromOtherBuffer(pkt.buffer, pkt.size); // This prevents undefined behaviour
#ifdef TGVOIP_DUMP_JITTER_STATS
fprintf(dump, "%u\t%.03f\t%d\t%.03f\t%.03f\t%.03f\n", pkt.timestamp, time, GetCurrentDelay(), lastMeasuredJitter, lastMeasuredDelay, minDelay);
#endif

View File

@ -204,6 +204,13 @@ NetworkAddress NetworkAddress::IPv4(uint32_t addr)
a.addr.ipv4 = addr;
return a;
}
NetworkAddress NetworkAddress::IPv4(const BufferInputStream &in)
{
NetworkAddress a;
a.isIPv6 = false;
a.addr.ipv4 = in.ReadUInt32();
return a;
}
NetworkAddress NetworkAddress::IPv6(std::string str)
{
@ -224,6 +231,13 @@ NetworkAddress NetworkAddress::IPv6(const uint8_t addr[16])
memcpy(a.addr.ipv6, addr, 16);
return a;
}
NetworkAddress NetworkAddress::IPv6(const BufferInputStream &in)
{
NetworkAddress a;
a.isIPv6 = true;
in.ReadBytes(a.addr.ipv6, 16);
return a;
}
bool NetworkSocket::Select(std::vector<std::shared_ptr<NetworkSocket>> &readFds, std::vector<std::shared_ptr<NetworkSocket>> &writeFds, std::vector<std::shared_ptr<NetworkSocket>> &errorFds, const std::unique_ptr<SocketSelectCanceller> &canceller)
{

View File

@ -57,8 +57,10 @@ public:
static NetworkAddress Empty();
static NetworkAddress IPv4(std::string str);
static NetworkAddress IPv4(uint32_t addr);
static NetworkAddress IPv4(const BufferInputStream &in);
static NetworkAddress IPv6(std::string str);
static NetworkAddress IPv6(const uint8_t addr[16]);
static NetworkAddress IPv6(const BufferInputStream &in);
bool isIPv6 = false;
union {

View File

@ -3,84 +3,6 @@
using namespace tgvoip;
using namespace std;
bool VoIPController::legacyParsePacket(const BufferInputStream &in, unsigned char &type, uint32_t &ackId, uint32_t &pseq, uint32_t &acks, unsigned char &pflags, size_t &packetInnerLen)
{
uint32_t tlid = in.ReadUInt32();
if (tlid == TLID_DECRYPTED_AUDIO_BLOCK)
{
in.ReadInt64(); // random id
uint32_t randLen = in.ReadTlLength();
in.Seek(in.GetOffset() + randLen + pad4(randLen));
uint32_t flags = in.ReadUInt32();
type = (unsigned char)((flags >> 24) & 0xFF);
if (!(flags & LEGACY_PFLAG_HAS_SEQ && flags & LEGACY_PFLAG_HAS_RECENT_RECV))
{
LOGW("Received packet doesn't have LEGACY_PFLAG_HAS_SEQ, LEGACY_PFLAG_HAS_RECENT_RECV, or both");
return false;
}
if (flags & LEGACY_PFLAG_HAS_CALL_ID)
{
unsigned char pktCallID[16];
in.ReadBytes(pktCallID, 16);
if (memcmp(pktCallID, callID, 16) != 0)
{
LOGW("Received packet has wrong call id");
lastError = ERROR_UNKNOWN;
SetState(STATE_FAILED);
return false;
}
}
ackId = in.ReadUInt32();
pseq = in.ReadUInt32();
acks = in.ReadUInt32();
if (flags & LEGACY_PFLAG_HAS_PROTO)
{
uint32_t proto = in.ReadUInt32();
if (proto != PROTOCOL_NAME)
{
LOGW("Received packet uses wrong protocol");
lastError = ERROR_INCOMPATIBLE;
SetState(STATE_FAILED);
return false;
}
}
if (flags & LEGACY_PFLAG_HAS_EXTRA)
{
uint32_t extraLen = in.ReadTlLength();
in.Seek(in.GetOffset() + extraLen + pad4(extraLen));
}
if (flags & LEGACY_PFLAG_HAS_DATA)
{
packetInnerLen = in.ReadTlLength();
}
pflags = 0;
}
else if (tlid == TLID_SIMPLE_AUDIO_BLOCK)
{
in.ReadInt64(); // random id
uint32_t randLen = in.ReadTlLength();
in.Seek(in.GetOffset() + randLen + pad4(randLen));
packetInnerLen = in.ReadTlLength();
type = in.ReadByte();
ackId = in.ReadUInt32();
pseq = in.ReadUInt32();
acks = in.ReadUInt32();
if (peerVersion >= 6)
pflags = in.ReadByte();
else
pflags = 0;
}
else
{
LOGW("Received a packet of unknown type %08X", tlid);
return false;
}
return true;
}
void VoIPController::legacyWritePacketHeader(uint32_t pseq, uint32_t acks, BufferOutputStream *s, unsigned char type, uint32_t length)
{

View File

@ -438,17 +438,16 @@ void VoIPController::SendExtra(Buffer &data, unsigned char type)
ENFORCE_MSG_THREAD;
LOGV("Sending extra type %u length %u", type, (unsigned int)data.Length());
for (vector<UnacknowledgedExtraData>::iterator x = currentExtras.begin(); x != currentExtras.end(); ++x)
for (auto &extra : currentExtras)
{
if (x->type == type)
if (extra.type == type)
{
x->firstContainingSeq = 0;
x->data = move(data);
extra.firstContainingSeq = 0;
extra.data = move(data);
return;
}
}
UnacknowledgedExtraData xd = {type, move(data), 0};
currentExtras.push_back(move(xd));
currentExtras.push_back(UnacknowledgedExtraData{type, move(data), 0});
}
void VoIPController::SendUdpPing(Endpoint &endpoint)

View File

@ -0,0 +1,183 @@
#include "PacketStructs.h"
#include "../PrivateDefines.cpp"
using namespace tgvoip;
std::shared_ptr<Extra> choose(const BufferInputStream &in, int peerVersion)
{
switch (in.ReadByte())
{
case ExtraStreamFlags::ID:
return std::make_shared<ExtraStreamFlags>();
case ExtraStreamCsd::ID:
return std::make_shared<ExtraStreamCsd>();
case ExtraLanEndpoint::ID:
return std::make_shared<ExtraLanEndpoint>();
case ExtraIpv6Endpoint::ID:
return std::make_shared<ExtraIpv6Endpoint>();
case ExtraNetworkChanged::ID:
return std::make_shared<ExtraNetworkChanged>();
case ExtraGroupCallKey::ID:
return std::make_shared<ExtraGroupCallKey>();
case ExtraGroupCallUpgrade::ID:
return std::make_shared<ExtraGroupCallUpgrade>();
}
}
bool Packet::parse(const BufferInputStream &in, int peerVersion)
{
if (peerVersion < PROTOCOL_RELIABLE)
{
return parseLegacyPacket(in, peerVersion);
}
}
bool Packet::parseLegacyPacket(const BufferInputStream &in, int peerVersion)
{
// Version-specific extraction of legacy packet fields ackId (last received packet seq on remote), (incoming packet seq) pseq, (ack mask) acks, (packet type) type, (flags) pflags, packet length
uint32_t ackId; // Last received packet seqno on remote
uint32_t pseq; // Incoming packet seqno
uint32_t acks; // Ack mask
unsigned char type, pflags; // Packet type, flags
size_t packetInnerLen = 0;
if (peerVersion >= 8)
{
type = in.ReadByte();
ackId = in.ReadUInt32();
pseq = in.ReadUInt32();
acks = in.ReadUInt32();
pflags = in.ReadByte();
packetInnerLen = in.Remaining();
}
else if (!legacyParsePacket(in, type, ackId, pseq, acks, pflags, packetInnerLen, peerVersion))
{
return false;
}
this->seq = pseq;
this->ackSeq = ackId;
this->ackMask = acks;
// Extra data
if (pflags & XPFLAG_HAS_EXTRA)
{
uint8_t extraCount = in.ReadByte();
extras.reserve(extraCount);
for (auto i = 0; i < extraCount; i++)
{
BufferInputStream inExtra = in.GetPartBuffer(in.ReadByte());
auto ptr = Extra::choose(inExtra, peerVersion);
if (ptr->parse(inExtra, peerVersion))
{
extras.push_back(std::move(ptr));
}
}
}
if (pflags & XPFLAG_HAS_RECV_TS)
{
recvTS = in.ReadUInt32();
}
if (type == PKT_INIT)
{
Buffer
}
else if (type == PKT_INIT_ACK)
{
}
else if (type == PKT_PING)
{
}
else if (type == PKT_PONG)
{
}
else if (type == PKT_NOP)
{
}
}
bool legacyParsePacket(const BufferInputStream &in, unsigned char &type, uint32_t &ackId, uint32_t &pseq, uint32_t &acks, unsigned char &pflags, size_t &packetInnerLen, int peerVersion)
{
size_t packetInnerLen = 0;
uint32_t tlid = in.ReadUInt32();
if (tlid == TLID_DECRYPTED_AUDIO_BLOCK)
{
in.ReadInt64(); // random id
uint32_t randLen = in.ReadTlLength();
in.Seek(in.GetOffset() + randLen + pad4(randLen));
uint32_t flags = in.ReadUInt32();
type = (unsigned char)((flags >> 24) & 0xFF);
if (!(flags & LEGACY_PFLAG_HAS_SEQ && flags & LEGACY_PFLAG_HAS_RECENT_RECV))
{
LOGW("Received packet doesn't have LEGACY_PFLAG_HAS_SEQ, LEGACY_PFLAG_HAS_RECENT_RECV, or both");
return false;
}
// These are all errors that weren't even used in the first place in newer protocols.
// Also, a call cannot possibly have a wrong call ID and correct encryption key (unless there's some shady legacy stuff that's going on, but for now I won't even consider it).
/*
if (flags & LEGACY_PFLAG_HAS_CALL_ID)
{
unsigned char pktCallID[16];
in.ReadBytes(pktCallID, 16);
if (memcmp(pktCallID, callID, 16) != 0)
{
LOGW("Received packet has wrong call id");
// These are all errors that weren't even used in the first place in newer protocols
//lastError = ERROR_UNKNOWN;
//SetState(STATE_FAILED);
return false;
}
}*/
ackId = in.ReadUInt32();
pseq = in.ReadUInt32();
acks = in.ReadUInt32();
if (flags & LEGACY_PFLAG_HAS_PROTO)
{
uint32_t proto = in.ReadUInt32();
if (proto != PROTOCOL_NAME)
{
LOGW("Received packet uses wrong protocol");
// These are all errors that weren't even used in the first place in newer protocols
//lastError = ERROR_INCOMPATIBLE;
//SetState(STATE_FAILED);
return false;
}
}
if (flags & LEGACY_PFLAG_HAS_EXTRA)
{
uint32_t extraLen = in.ReadTlLength();
in.Seek(in.GetOffset() + extraLen + pad4(extraLen));
}
if (flags & LEGACY_PFLAG_HAS_DATA)
{
packetInnerLen = in.ReadTlLength();
}
pflags = 0;
}
else if (tlid == TLID_SIMPLE_AUDIO_BLOCK)
{
in.ReadInt64(); // random id
uint32_t randLen = in.ReadTlLength();
in.Seek(in.GetOffset() + randLen + pad4(randLen));
packetInnerLen = in.ReadTlLength();
type = in.ReadByte();
ackId = in.ReadUInt32();
pseq = in.ReadUInt32();
acks = in.ReadUInt32();
if (peerVersion >= 6)
pflags = in.ReadByte();
else
pflags = 0;
}
else
{
LOGW("Received a packet of unknown type %08X", tlid);
return false;
}
return true;
}

View File

@ -6,18 +6,207 @@
namespace tgvoip
{
class PacketSender;
struct Packet
struct Serializable
{
virtual bool parse(const BufferInputStream &in, int peerVersion) = 0;
virtual bool serialize(BufferOutputStream &out, int peerVersion) = 0;
};
template <typename T>
struct Array
{
public:
bool parse(const BufferInputStream &in, int peerVersion) override;
bool serialize(BufferOutputStream &out, int peerVersion) override;
std::vector<std::shared_ptr<T>> contents;
};
struct Extra : public Serializable
{
static std::shared_ptr<Extra> choose(const BufferInputStream &in, int peerVersion);
};
struct Packet : public Serializable
{
public:
bool parse(const BufferInputStream &in, int peerVersion) override;
bool serialize(BufferOutputStream &out, int peerVersion) override;
private:
bool parseLegacyPacket(const BufferInputStream &in, int peerVersion);
bool parseLegacyLegacyPacket(const BufferInputStream &in, unsigned char &type, uint32_t &ackId, uint32_t &pseq, uint32_t &acks, unsigned char &pflags, size_t &packetInnerLen, int peerVersion);
public:
enum Flags : uint8_t
{
Len16 = 1,
ExtraFEC = 2,
ExtraSignaling = 4,
RecvTS = 8
};
enum EFlags : uint8_t
{
Fragmented = 1,
Keyframe = 2
};
uint32_t seq;
uint32_t ackSeq;
uint32_t ackMask;
uint8_t streamId;
uint8_t flags;
uint8_t flags = 0;
uint8_t eFlags = 0;
uint32_t recvTS = 0;
Buffer data;
uint8_t eFlags = 0;
std::vector<std::shared_ptr<Extra>> extras;
};
struct StreamInfo : public Serializable
{
public:
static std::shared_ptr<StreamInfo> choose(const BufferInputStream &in, int peerVersion)
{
return std::make_shared<StreamInfo>();
};
bool parse(const BufferInputStream &in, int peerVersion) override;
bool serialize(BufferOutputStream &out, int peerVersion) override;
uint8_t streamId = 0;
uint8_t type = 0;
uint32_t codec = 0;
uint16_t frameDuration = 0;
uint8_t enabled = 0;
};
struct ExtraStreamFlags : public Extra
{
public:
bool parse(const BufferInputStream &in, int peerVersion) override;
bool serialize(BufferOutputStream &out, int peerVersion) override;
enum Flags : uint8_t
{
Enabled = 1,
Dtx = 2,
ExtraEC = 3,
Paused = 4
};
uint8_t flags = 0;
static const uint8_t ID = 1;
};
struct ExtraStreamCsd : public Extra
{
public:
bool parse(const BufferInputStream &in, int peerVersion) override;
bool serialize(BufferOutputStream &out, int peerVersion) override;
uint16_t width = 0;
uint16_t height = 0;
std::vector<BufferInputStream> data;
static const uint8_t ID = 2;
};
struct ExtraLanEndpoint : public Extra
{
public:
virtual bool parse(const BufferInputStream &in, int peerVersion);
virtual bool serialize(BufferOutputStream &out, int peerVersion);
NetworkAddress address;
uint16_t port = 0;
static const uint8_t ID = 3;
};
struct ExtraIpv6Endpoint : public Extra
{
bool parse(const BufferInputStream &in, int peerVersion) override;
bool serialize(BufferOutputStream &out, int peerVersion) override;
NetworkAddress address;
uint16_t port = 0;
static const uint8_t ID = 7;
};
struct ExtraNetworkChanged : public Extra
{
bool parse(const BufferInputStream &in, int peerVersion) override;
bool serialize(BufferOutputStream &out, int peerVersion) override;
enum Flags : uint8_t
{
DataSavingEnabled = 1
};
uint8_t flags = 0;
static const uint8_t ID = 4;
};
struct ExtraGroupCallKey : public Extra
{
bool parse(const BufferInputStream &in, int peerVersion) override;
bool serialize(BufferOutputStream &out, int peerVersion) override;
std::array<uint8_t, 256> key;
static const uint8_t ID = 5;
};
struct ExtraGroupCallUpgrade : public Extra
{
bool parse(const BufferInputStream &in, int peerVersion) override{};
bool serialize(BufferOutputStream &out, int peerVersion) override{};
static const uint8_t ID = 6;
};
struct ExtraInit : public Extra
{
bool parse(const BufferInputStream &in, int peerVersion) override;
bool serialize(BufferOutputStream &out, int peerVersion) override;
enum Flags : uint8_t
{
DataSavingEnabled = 1,
GroupCallSupported = 2,
VideoSendSupported = 4,
VideoRecvSupported = 8
};
uint32_t peerVersion = 0;
uint32_t minVersion = 0;
uint8_t flags = 0;
std::vector<std::shared_ptr<StreamInfo>> streams;
static const uint8_t ID = 8;
};
struct ExtraInitAck : public Extra
{
bool parse(const BufferInputStream &in, int peerVersion) override;
bool serialize(BufferOutputStream &out, int peerVersion) override;
uint32_t peerVersion = 0;
uint32_t minVersion = 0;
std::vector<std::shared_ptr<StreamInfo>> streams;
static const uint8_t ID = 8;
};
// Legacy stuff
struct RecentOutgoingPacket
{
// For simple NACK reliable resending

View File

@ -906,10 +906,8 @@ void VoIPController::ProcessExtraData(Buffer &data)
{
if (!allowP2p)
return;
unsigned char _addr[16];
in.ReadBytes(_addr, 16);
NetworkAddress addr = NetworkAddress::IPv6(_addr);
uint16_t port = static_cast<uint16_t>(in.ReadInt16());
NetworkAddress addr = NetworkAddress::IPv6(in);
uint16_t port = in.ReadUInt16();
peerIPv6Available = true;
LOGV("Received peer IPv6 endpoint [%s]:%u", addr.ToString().c_str(), port);
@ -964,11 +962,6 @@ uint8_t VoIPController::WritePacketHeader(PendingOutgoingPacket &pkt, BufferOutp
s.WriteByte(flags);
if (flags & XPFLAG_HAS_TRANSPORT_ID)
{
s.WriteByte(manager.getTransportId());
}
if (!currentExtras.empty())
{
s.WriteByte(static_cast<unsigned char>(currentExtras.size()));

View File

@ -17,7 +17,7 @@ extraGroupCallUpgrade#06 = ExtraSignaling;
streamInfo$_ streamId:(## 8) type:(## 8) codec:# frameDurationIgnored:(## 16) enabled:(## 8)= StreamInfo;
// Packet
packet$_ type:(## 8) ackSeq:# seq:# ackMask:# flags:(## 8) extras:flags.0?Extras<ExtraSignaling> data:payload = Packet;
packet$_ type:(## 8) ackSeq:# seq:# ackMask:# flags:(## 8) extras:flags.0?Extras<ExtraSignaling> recvTS:flags.1?int data:payload = Packet;
payloadInit#0 peerVersion:# minVersion:# flags:# streams:Extras<StreamInfo> dataSavingEnabled:flags.0?true groupCallSupported:flags.1?true videoSendSupported:flags.2?true videoRecvSupported:flags.3?true = Payload;
payloadInitAck#1 peerVersion:# minVersion:# streams:Extras<StreamInfo> = Payload;

View File

@ -23,6 +23,7 @@ packet$_
extraFEC:flags.1?ExtraFEC
extraSignaling:flags.2?Extras<ExtraSignaling>
recvTS:flags.3?int
= Packet;
@ -32,13 +33,13 @@ extraFEC$_ mask:(## 8) [ length:(## 8) _:bytes ] = ExtraFEC;
// Extras
extras$_ {t:Type} (## 8) [ length:(## 8) extra:t ] = Extras t;
extraStreamFlags#01 streamId:(## 8) flags:# enabled:flags.0?true dtx:flags.1?true extraEC:flags.2?true paused:flags.3?true = ExtraSignaling;
extraStreamCsd#02 streamId:(## 8) width:(## 16) height:(## 16) count:(## 8) [ length:(## 8) codecSpecificData:bytes ]= ExtraSignaling;
extraStreamFlags#01 flags:(## 8) enabled:flags.0?true dtx:flags.1?true extraEC:flags.2?true paused:flags.3?true = ExtraSignaling;
extraStreamCsd#02 width:(## 16) height:(## 16) count:(## 8) [ length:(## 8) codecSpecificData:bytes ] = ExtraSignaling;
extraLanEndpoint#03 address:# port:(## 16) = ExtraSignaling;
extraIpv6Endpoint#07 address:(## 128) port:(## 16) = ExtraSignaling;
extraNetworkChanged#04 flags:# dataSavingEnabled:flags.0?true = ExtraSignaling;
extraNetworkChanged#04 flags:(## 8) dataSavingEnabled:flags.0?true = ExtraSignaling;
extraGroupCallKey#05 key:(## 256) = ExtraSignaling;
extraGroupCallUpgrade#06 = ExtraSignaling;

View File

@ -44,7 +44,7 @@ public:
uint32_t ReadTlLength() const;
void ReadBytes(unsigned char *to, size_t count) const;
void ReadBytes(Buffer &to) const;
BufferInputStream GetPartBuffer(size_t length, bool advance) const;
BufferInputStream GetPartBuffer(size_t length, bool advance = true) const;
const unsigned char *GetRawBuffer() const;
inline uint64_t ReadUInt64() const
@ -278,98 +278,6 @@ private:
std::function<void *(void *, size_t)> reallocFn;
};
template <typename T, size_t size, typename AVG_T = T>
class HistoricBuffer
{
public:
HistoricBuffer()
{
}
AVG_T Average() const
{
return std::accumulate(data.begin(), data.end(), static_cast<AVG_T>(0)) / static_cast<AVG_T>(size);
}
AVG_T Average(size_t firstN) const
{
AVG_T avg = static_cast<AVG_T>(0);
for (size_t i = 0; i < firstN; i++) // Manual iteration required to wrap around array with specific offset
{
avg += (*this)[i];
}
return avg / static_cast<AVG_T>(firstN);
}
AVG_T NonZeroAverage() const
{
AVG_T avg = static_cast<AVG_T>(0);
int nonZeroCount = 0;
for (T i : data)
{
if (i != 0)
{
nonZeroCount++;
avg += i;
}
}
if (nonZeroCount == 0)
return static_cast<AVG_T>(0);
return avg / static_cast<AVG_T>(nonZeroCount);
}
void Add(T el)
{
data[offset] = el;
offset = (offset + 1) % size;
}
T Min() const
{
return *std::min_element(data.begin(), data.end());
}
T Max() const
{
return *std::max_element(data.begin(), data.end());
}
void Reset()
{
std::fill(data.begin(), data.end(), static_cast<T>(0));
offset = 0;
}
T operator[](size_t i) const
{
assert(i < size);
// [0] should return the most recent entry, [1] the one before it, and so on
ptrdiff_t _i = offset - i - 1;
if (_i < 0) // Wrap around offset a-la posmod
_i = size + _i;
return data[_i];
}
T &operator[](size_t i)
{
assert(i < size);
// [0] should return the most recent entry, [1] the one before it, and so on
ptrdiff_t _i = offset - i - 1;
if (_i < 0) // Wrap around offset a-la posmod
_i = size + _i;
return data[_i];
}
constexpr size_t Size() const
{
return size;
}
private:
std::array<T, size> data{};
ptrdiff_t offset = 0;
};
template <size_t bufSize, size_t bufCount>
class BufferPool
{

View File

@ -15,4 +15,94 @@ TGVOIP_DISALLOW_COPY_AND_ASSIGN(TypeName); \
TypeName(TypeName&&) = default; \
TypeName& operator=(TypeName&&) = default
template <typename T, size_t size, typename AVG_T = T>
class HistoricBuffer
{
public:
HistoricBuffer()
{
}
AVG_T Average() const
{
return std::accumulate(data.begin(), data.end(), static_cast<AVG_T>(0)) / static_cast<AVG_T>(size);
}
AVG_T Average(size_t firstN) const
{
AVG_T avg = static_cast<AVG_T>(0);
for (size_t i = 0; i < firstN; i++) // Manual iteration required to wrap around array with specific offset
{
avg += (*this)[i];
}
return avg / static_cast<AVG_T>(firstN);
}
AVG_T NonZeroAverage() const
{
AVG_T avg = static_cast<AVG_T>(0);
int nonZeroCount = 0;
for (T &i : data)
{
if (i != 0)
{
nonZeroCount++;
avg += i;
}
}
if (nonZeroCount == 0)
return static_cast<AVG_T>(0);
return avg / static_cast<AVG_T>(nonZeroCount);
}
void Add(T el)
{
data[offset] = el;
offset = (offset + 1) % size;
}
T Min() const
{
return *std::min_element(data.begin(), data.end());
}
T Max() const
{
return *std::max_element(data.begin(), data.end());
}
void Reset()
{
std::fill(data.begin(), data.end(), static_cast<T>(0));
offset = 0;
}
T operator[](size_t i) const
{
assert(i < size);
// [0] should return the most recent entry, [1] the one before it, and so on
ptrdiff_t _i = offset - i - 1;
if (_i < 0) // Wrap around offset a-la posmod
_i = size + _i;
return data[_i];
}
T &operator[](size_t i)
{
assert(i < size);
// [0] should return the most recent entry, [1] the one before it, and so on
ptrdiff_t _i = offset - i - 1;
if (_i < 0) // Wrap around offset a-la posmod
_i = size + _i;
return data[_i];
}
constexpr size_t Size() const
{
return size;
}
private:
std::array<T, size> data{};
ptrdiff_t offset = 0;
};