1
0
mirror of https://github.com/danog/libtgvoip.git synced 2024-11-26 12:14:39 +01:00

Cleanup classes a bit, preparing for my strategy

This commit is contained in:
Daniil Gentili 2020-01-23 16:45:53 +01:00
parent 8bfbecb8f5
commit d2979cb7bb
Signed by: danog
GPG Key ID: 8C1BE3B34B230CA7
18 changed files with 468 additions and 414 deletions

1
.gitignore vendored
View File

@ -27,3 +27,4 @@ autom4te.cache/
*.o
*.Plo
*.lo
.vscode

View File

@ -14,6 +14,7 @@ tools/logging.cpp \
controller/MediaStreamItf.cpp \
tools/MessageThread.cpp \
controller/net/NetworkSocket.cpp \
controller/net/Endpoint.cpp \
controller/audio/OpusDecoder.cpp \
controller/audio/OpusEncoder.cpp \
controller/PacketReassembler.cpp \
@ -23,6 +24,7 @@ audio/AudioIO.cpp \
audio/AudioInput.cpp \
audio/AudioOutput.cpp \
audio/Resampler.cpp \
audio/AudioInputTester.cpp \
os/posix/NetworkSocketPosix.cpp \
video/VideoSource.cpp \
video/VideoRenderer.cpp \
@ -763,4 +765,4 @@ CXXFLAGS += -std=gnu++0x $(CFLAGS)
if TARGET_OS_OSX
OBJCFLAGS = $(CFLAGS)
OBJCXXFLAGS += -std=gnu++0x $(CFLAGS)
endif
endif

View File

@ -813,16 +813,17 @@ am__libtgvoip_la_SOURCES_DIST = TgVoip.cpp VoIPController.cpp \
controller/audio/EchoCanceller.cpp \
controller/net/JitterBuffer.cpp tools/logging.cpp \
controller/MediaStreamItf.cpp tools/MessageThread.cpp \
controller/net/NetworkSocket.cpp \
controller/net/NetworkSocket.cpp controller/net/Endpoint.cpp \
controller/audio/OpusDecoder.cpp \
controller/audio/OpusEncoder.cpp \
controller/PacketReassembler.cpp VoIPGroupController.cpp \
VoIPServerConfig.cpp audio/AudioIO.cpp audio/AudioInput.cpp \
audio/AudioOutput.cpp audio/Resampler.cpp \
os/posix/NetworkSocketPosix.cpp video/VideoSource.cpp \
video/VideoRenderer.cpp video/VideoPacketSender.cpp \
video/VideoFEC.cpp video/ScreamCongestionController.cpp \
tools/json11.cpp os/darwin/AudioInputAudioUnit.cpp \
audio/AudioInputTester.cpp os/posix/NetworkSocketPosix.cpp \
video/VideoSource.cpp video/VideoRenderer.cpp \
video/VideoPacketSender.cpp video/VideoFEC.cpp \
video/ScreamCongestionController.cpp tools/json11.cpp \
os/darwin/AudioInputAudioUnit.cpp \
os/darwin/AudioOutputAudioUnit.cpp os/darwin/AudioUnitIO.cpp \
os/darwin/AudioInputAudioUnitOSX.cpp \
os/darwin/AudioOutputAudioUnitOSX.cpp \
@ -1750,19 +1751,20 @@ am__objects_12 = TgVoip.lo VoIPController.lo tools/Buffers.lo \
controller/audio/EchoCanceller.lo \
controller/net/JitterBuffer.lo tools/logging.lo \
controller/MediaStreamItf.lo tools/MessageThread.lo \
controller/net/NetworkSocket.lo \
controller/net/NetworkSocket.lo controller/net/Endpoint.lo \
controller/audio/OpusDecoder.lo \
controller/audio/OpusEncoder.lo \
controller/PacketReassembler.lo VoIPGroupController.lo \
VoIPServerConfig.lo audio/AudioIO.lo audio/AudioInput.lo \
audio/AudioOutput.lo audio/Resampler.lo \
os/posix/NetworkSocketPosix.lo video/VideoSource.lo \
video/VideoRenderer.lo video/VideoPacketSender.lo \
video/VideoFEC.lo video/ScreamCongestionController.lo \
tools/json11.lo $(am__objects_1) $(am__objects_2) \
$(am__objects_3) $(am__objects_4) $(am__objects_5) \
$(am__objects_6) $(am__objects_7) $(am__objects_8) \
$(am__objects_9) $(am__objects_10) $(am__objects_11)
audio/AudioInputTester.lo os/posix/NetworkSocketPosix.lo \
video/VideoSource.lo video/VideoRenderer.lo \
video/VideoPacketSender.lo video/VideoFEC.lo \
video/ScreamCongestionController.lo tools/json11.lo \
$(am__objects_1) $(am__objects_2) $(am__objects_3) \
$(am__objects_4) $(am__objects_5) $(am__objects_6) \
$(am__objects_7) $(am__objects_8) $(am__objects_9) \
$(am__objects_10) $(am__objects_11)
am__objects_13 = $(am__objects_11) $(am__objects_11) $(am__objects_11) \
$(am__objects_11)
am_libtgvoip_la_OBJECTS = $(am__objects_12) $(am__objects_13)
@ -2055,14 +2057,16 @@ am__depfiles_remade = ./$(DEPDIR)/TgVoip.Plo \
./webrtc_dsp/third_party/rnnoise/src/$(DEPDIR)/rnn_vad_weights.Plo \
audio/$(DEPDIR)/AudioIO.Plo \
audio/$(DEPDIR)/AudioIOCallback.Plo \
audio/$(DEPDIR)/AudioInput.Plo audio/$(DEPDIR)/AudioOutput.Plo \
audio/$(DEPDIR)/Resampler.Plo \
audio/$(DEPDIR)/AudioInput.Plo \
audio/$(DEPDIR)/AudioInputTester.Plo \
audio/$(DEPDIR)/AudioOutput.Plo audio/$(DEPDIR)/Resampler.Plo \
controller/$(DEPDIR)/MediaStreamItf.Plo \
controller/$(DEPDIR)/PacketReassembler.Plo \
controller/audio/$(DEPDIR)/EchoCanceller.Plo \
controller/audio/$(DEPDIR)/OpusDecoder.Plo \
controller/audio/$(DEPDIR)/OpusEncoder.Plo \
controller/net/$(DEPDIR)/CongestionControl.Plo \
controller/net/$(DEPDIR)/Endpoint.Plo \
controller/net/$(DEPDIR)/JitterBuffer.Plo \
controller/net/$(DEPDIR)/NetworkSocket.Plo \
os/darwin/$(DEPDIR)/AudioInputAudioUnit.Plo \
@ -2376,19 +2380,20 @@ SRC = TgVoip.cpp VoIPController.cpp tools/Buffers.cpp \
controller/audio/EchoCanceller.cpp \
controller/net/JitterBuffer.cpp tools/logging.cpp \
controller/MediaStreamItf.cpp tools/MessageThread.cpp \
controller/net/NetworkSocket.cpp \
controller/net/NetworkSocket.cpp controller/net/Endpoint.cpp \
controller/audio/OpusDecoder.cpp \
controller/audio/OpusEncoder.cpp \
controller/PacketReassembler.cpp VoIPGroupController.cpp \
VoIPServerConfig.cpp audio/AudioIO.cpp audio/AudioInput.cpp \
audio/AudioOutput.cpp audio/Resampler.cpp \
os/posix/NetworkSocketPosix.cpp video/VideoSource.cpp \
video/VideoRenderer.cpp video/VideoPacketSender.cpp \
video/VideoFEC.cpp video/ScreamCongestionController.cpp \
tools/json11.cpp $(am__append_1) $(am__append_4) \
$(am__append_6) $(am__append_10) $(am__append_12) \
$(am__append_14) $(am__append_16) $(am__append_18) \
$(am__append_21) $(am__append_22) $(am__append_23)
audio/AudioInputTester.cpp os/posix/NetworkSocketPosix.cpp \
video/VideoSource.cpp video/VideoRenderer.cpp \
video/VideoPacketSender.cpp video/VideoFEC.cpp \
video/ScreamCongestionController.cpp tools/json11.cpp \
$(am__append_1) $(am__append_4) $(am__append_6) \
$(am__append_10) $(am__append_12) $(am__append_14) \
$(am__append_16) $(am__append_18) $(am__append_21) \
$(am__append_22) $(am__append_23)
TGVOIP_HDRS = TgVoip.h VoIPController.h tools/Buffers.h \
tools/BlockingQueue.h controller/PrivateDefines.h \
controller/net/CongestionControl.h \
@ -2535,6 +2540,8 @@ tools/MessageThread.lo: tools/$(am__dirstamp) \
tools/$(DEPDIR)/$(am__dirstamp)
controller/net/NetworkSocket.lo: controller/net/$(am__dirstamp) \
controller/net/$(DEPDIR)/$(am__dirstamp)
controller/net/Endpoint.lo: controller/net/$(am__dirstamp) \
controller/net/$(DEPDIR)/$(am__dirstamp)
controller/audio/OpusDecoder.lo: controller/audio/$(am__dirstamp) \
controller/audio/$(DEPDIR)/$(am__dirstamp)
controller/audio/OpusEncoder.lo: controller/audio/$(am__dirstamp) \
@ -2555,6 +2562,8 @@ audio/AudioOutput.lo: audio/$(am__dirstamp) \
audio/$(DEPDIR)/$(am__dirstamp)
audio/Resampler.lo: audio/$(am__dirstamp) \
audio/$(DEPDIR)/$(am__dirstamp)
audio/AudioInputTester.lo: audio/$(am__dirstamp) \
audio/$(DEPDIR)/$(am__dirstamp)
os/posix/$(am__dirstamp):
@$(MKDIR_P) os/posix
@: > os/posix/$(am__dirstamp)
@ -3991,6 +4000,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@audio/$(DEPDIR)/AudioIO.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@audio/$(DEPDIR)/AudioIOCallback.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@audio/$(DEPDIR)/AudioInput.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@audio/$(DEPDIR)/AudioInputTester.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@audio/$(DEPDIR)/AudioOutput.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@audio/$(DEPDIR)/Resampler.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@controller/$(DEPDIR)/MediaStreamItf.Plo@am__quote@ # am--include-marker
@ -3999,6 +4009,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@controller/audio/$(DEPDIR)/OpusDecoder.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@controller/audio/$(DEPDIR)/OpusEncoder.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@controller/net/$(DEPDIR)/CongestionControl.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@controller/net/$(DEPDIR)/Endpoint.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@controller/net/$(DEPDIR)/JitterBuffer.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@controller/net/$(DEPDIR)/NetworkSocket.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@os/darwin/$(DEPDIR)/AudioInputAudioUnit.Plo@am__quote@ # am--include-marker
@ -4874,6 +4885,7 @@ distclean: distclean-am
-rm -f audio/$(DEPDIR)/AudioIO.Plo
-rm -f audio/$(DEPDIR)/AudioIOCallback.Plo
-rm -f audio/$(DEPDIR)/AudioInput.Plo
-rm -f audio/$(DEPDIR)/AudioInputTester.Plo
-rm -f audio/$(DEPDIR)/AudioOutput.Plo
-rm -f audio/$(DEPDIR)/Resampler.Plo
-rm -f controller/$(DEPDIR)/MediaStreamItf.Plo
@ -4882,6 +4894,7 @@ distclean: distclean-am
-rm -f controller/audio/$(DEPDIR)/OpusDecoder.Plo
-rm -f controller/audio/$(DEPDIR)/OpusEncoder.Plo
-rm -f controller/net/$(DEPDIR)/CongestionControl.Plo
-rm -f controller/net/$(DEPDIR)/Endpoint.Plo
-rm -f controller/net/$(DEPDIR)/JitterBuffer.Plo
-rm -f controller/net/$(DEPDIR)/NetworkSocket.Plo
-rm -f os/darwin/$(DEPDIR)/AudioInputAudioUnit.Plo
@ -5240,6 +5253,7 @@ maintainer-clean: maintainer-clean-am
-rm -f audio/$(DEPDIR)/AudioIO.Plo
-rm -f audio/$(DEPDIR)/AudioIOCallback.Plo
-rm -f audio/$(DEPDIR)/AudioInput.Plo
-rm -f audio/$(DEPDIR)/AudioInputTester.Plo
-rm -f audio/$(DEPDIR)/AudioOutput.Plo
-rm -f audio/$(DEPDIR)/Resampler.Plo
-rm -f controller/$(DEPDIR)/MediaStreamItf.Plo
@ -5248,6 +5262,7 @@ maintainer-clean: maintainer-clean-am
-rm -f controller/audio/$(DEPDIR)/OpusDecoder.Plo
-rm -f controller/audio/$(DEPDIR)/OpusEncoder.Plo
-rm -f controller/net/$(DEPDIR)/CongestionControl.Plo
-rm -f controller/net/$(DEPDIR)/Endpoint.Plo
-rm -f controller/net/$(DEPDIR)/JitterBuffer.Plo
-rm -f controller/net/$(DEPDIR)/NetworkSocket.Plo
-rm -f os/darwin/$(DEPDIR)/AudioInputAudioUnit.Plo

View File

@ -19,6 +19,7 @@
#include "controller/audio/OpusDecoder.h"
#include "VoIPServerConfig.h"
#include "controller/PrivateDefines.h"
#include "controller/net/Endpoint.h"
#include "tools/json11.hpp"
#include "controller/PacketSender.h"
#include "video/VideoPacketSender.h"
@ -425,7 +426,7 @@ void VoIPController::SetNetworkType(int type)
if (_preferredRelay.type == Endpoint::Type::UDP_RELAY)
currentEndpoint = preferredRelay;
MutexGuard m(endpointsMutex);
constexpr int64_t lanID = (int64_t)(FOURCC('L', 'A', 'N', '4')) << 32;
constexpr int64_t lanID = static_cast<int64_t>(FOURCC('L', 'A', 'N', '4')) << 32;
endpoints.erase(lanID);
for (pair<const int64_t, Endpoint> &e : endpoints)
{
@ -2095,9 +2096,9 @@ void VoIPController::ProcessIncomingPacket(NetworkPacket &packet, Endpoint &srcE
size_t len = packet.data.Length();
BufferInputStream in(packet.data);
bool hasPeerTag = false;
if (peerVersion < 9 || srcEndpoint.type == Endpoint::Type::UDP_RELAY || srcEndpoint.type == Endpoint::Type::TCP_RELAY)
if (peerVersion < 9 || srcEndpoint.IsReflector())
{
if (memcmp(buffer, srcEndpoint.type == Endpoint::Type::UDP_RELAY || srcEndpoint.type == Endpoint::Type::TCP_RELAY ? (void *)srcEndpoint.peerTag : (void *)callID, 16) != 0)
if (memcmp(buffer, srcEndpoint.IsReflector() ? (void *)srcEndpoint.peerTag : (void *)callID, 16) != 0)
{
LOGW("Received packet has wrong peerTag");
return;
@ -2105,7 +2106,7 @@ void VoIPController::ProcessIncomingPacket(NetworkPacket &packet, Endpoint &srcE
in.Seek(16);
hasPeerTag = true;
}
if (in.Remaining() >= 16 && (srcEndpoint.type == Endpoint::Type::UDP_RELAY || srcEndpoint.type == Endpoint::Type::TCP_RELAY) && *reinterpret_cast<uint64_t *>(buffer + 16) == 0xFFFFFFFFFFFFFFFFLL && *reinterpret_cast<uint32_t *>(buffer + 24) == 0xFFFFFFFF)
if (in.Remaining() >= 16 && srcEndpoint.IsReflector() && *reinterpret_cast<uint64_t *>(buffer + 16) == 0xFFFFFFFFFFFFFFFFLL && *reinterpret_cast<uint32_t *>(buffer + 24) == 0xFFFFFFFF)
{
// relay special request response
in.Seek(16 + 12);
@ -2160,8 +2161,8 @@ void VoIPController::ProcessIncomingPacket(NetworkPacket &packet, Endpoint &srcE
uint32_t peerAddr = (uint32_t)in.ReadInt32();
uint32_t peerPort = (uint32_t)in.ReadInt32();
constexpr int64_t p2pID = (int64_t)(FOURCC('P', '2', 'P', '4')) << 32;
constexpr int64_t lanID = (int64_t)(FOURCC('L', 'A', 'N', '4')) << 32;
constexpr int64_t p2pID = static_cast<int64_t>(FOURCC('P', '2', 'P', '4')) << 32;
constexpr int64_t lanID = static_cast<int64_t>(FOURCC('L', 'A', 'N', '4')) << 32;
if (currentEndpoint == p2pID || currentEndpoint == lanID)
currentEndpoint = preferredRelay;
@ -2583,7 +2584,7 @@ void VoIPController::ProcessIncomingPacket(NetworkPacket &packet, Endpoint &srcE
}
Endpoint *_currentEndpoint = &endpoints.at(currentEndpoint);
if (srcEndpoint.id != currentEndpoint && (srcEndpoint.type == Endpoint::Type::UDP_RELAY || srcEndpoint.type == Endpoint::Type::TCP_RELAY) && ((_currentEndpoint->type != Endpoint::Type::UDP_RELAY && _currentEndpoint->type != Endpoint::Type::TCP_RELAY) || _currentEndpoint->averageRTT == 0))
if (srcEndpoint.id != currentEndpoint && srcEndpoint.IsReflector() && ((_currentEndpoint->type != Endpoint::Type::UDP_RELAY && _currentEndpoint->type != Endpoint::Type::TCP_RELAY) || _currentEndpoint->averageRTT == 0))
{
if (seqgt(lastSentSeq - 32, lastRemoteAckSeq))
{
@ -3034,7 +3035,7 @@ void VoIPController::ProcessIncomingPacket(NetworkPacket &packet, Endpoint &srcE
LOGV("received lan endpoint");
uint32_t peerAddr = (uint32_t)in.ReadInt32();
uint16_t peerPort = (uint16_t)in.ReadInt32();
constexpr int64_t lanID = (int64_t)(FOURCC('L', 'A', 'N', '4')) << 32;
constexpr int64_t lanID = static_cast<int64_t>(FOURCC('L', 'A', 'N', '4')) << 32;
unsigned char peerTag[16];
Endpoint lan(lanID, peerPort, NetworkAddress::IPv4(peerAddr), NetworkAddress::Empty(), Endpoint::Type::UDP_P2P_LAN, peerTag);
@ -3209,7 +3210,7 @@ void VoIPController::ProcessExtraData(Buffer &data)
LOGV("received lan endpoint (extra)");
uint32_t peerAddr = (uint32_t)in.ReadInt32();
uint16_t peerPort = (uint16_t)in.ReadInt32();
constexpr int64_t lanID = (int64_t)(FOURCC('L', 'A', 'N', '4')) << 32;
constexpr int64_t lanID = static_cast<int64_t>(FOURCC('L', 'A', 'N', '4')) << 32;
if (currentEndpoint == lanID)
currentEndpoint = preferredRelay;
@ -3268,7 +3269,7 @@ void VoIPController::ProcessExtraData(Buffer &data)
peerIPv6Available = true;
LOGV("Received peer IPv6 endpoint [%s]:%u", addr.ToString().c_str(), port);
constexpr int64_t p2pID = (int64_t)(FOURCC('P', '2', 'P', '6')) << 32;
constexpr int64_t p2pID = static_cast<int64_t>(FOURCC('P', '2', 'P', '6')) << 32;
Endpoint ep;
ep.type = Endpoint::Type::UDP_P2P_INET;
@ -3390,7 +3391,7 @@ void VoIPController::SendPacket(unsigned char *data, size_t len, Endpoint &ep, P
if (ep.type == Endpoint::Type::TCP_RELAY && !useTCP)
return;
BufferOutputStream out(len + 128);
if (ep.type == Endpoint::Type::UDP_RELAY || ep.type == Endpoint::Type::TCP_RELAY)
if (ep.IsReflector())
out.WriteBytes((unsigned char *)ep.peerTag, 16);
else if (peerVersion < 9)
out.WriteBytes(callID, 16);
@ -3465,19 +3466,14 @@ void VoIPController::SendPacket(unsigned char *data, size_t len, Endpoint &ep, P
LOGV("Sending: to=%s:%u, seq=%u, length=%u, type=%s", ep.GetAddress().ToString().c_str(), ep.port, srcPacket.seq, (unsigned int)out.GetLength(), GetPacketTypeString(srcPacket.type).c_str());
#endif
/*ActuallySendPacket(NetworkPacket{
Buffer(std::move(out)),
ep.GetAddress(),
ep.port,
ep.type==Endpoint::Type::TCP_RELAY ? NetworkProtocol::TCP : NetworkProtocol::UDP
}, ep);*/
rawSendQueue.Put(RawPendingOutgoingPacket{
NetworkPacket{
Buffer(std::move(out)),
ep.GetAddress(),
ep.port,
ep.type == Endpoint::Type::TCP_RELAY ? NetworkProtocol::TCP : NetworkProtocol::UDP},
ep.type == Endpoint::Type::TCP_RELAY ? ep.socket : nullptr});
rawSendQueue.Put(
RawPendingOutgoingPacket{
NetworkPacket{
Buffer(std::move(out)),
ep.GetAddress(),
ep.port,
ep.type == Endpoint::Type::TCP_RELAY ? NetworkProtocol::TCP : NetworkProtocol::UDP},
ep.type == Endpoint::Type::TCP_RELAY ? ep.socket : nullptr});
}
void VoIPController::ActuallySendPacket(NetworkPacket pkt, Endpoint &ep)
@ -3556,21 +3552,18 @@ std::string VoIPController::GetPacketTypeString(unsigned char type)
case PKT_STREAM_EC:
return "stream_ec";
}
char buf[255];
snprintf(buf, sizeof(buf), "unknown(%u)", type);
return string(buf);
return string("unknown(") + std::to_string(type) + ')';
}
void VoIPController::AddIPv6Relays()
{
if (!myIPv6.IsEmpty() && !didAddIPv6Relays)
{
unordered_map<string, vector<Endpoint>> endpointsByAddress;
for (pair<const int64_t, Endpoint> &_e : endpoints)
{
Endpoint &e = _e.second;
if ((e.type == Endpoint::Type::UDP_RELAY || e.type == Endpoint::Type::TCP_RELAY) && !e.v6address.IsEmpty() && !e.address.IsEmpty())
if ((e.IsReflector()) && !e.v6address.IsEmpty() && !e.address.IsEmpty())
{
endpointsByAddress[e.v6address.ToString()].push_back(e);
}
@ -3582,7 +3575,7 @@ void VoIPController::AddIPv6Relays()
{
didAddIPv6Relays = true;
e.address = NetworkAddress::Empty();
e.id = e.id ^ ((int64_t)(FOURCC('I', 'P', 'v', '6')) << 32);
e.id = e.id ^ (static_cast<int64_t>(FOURCC('I', 'P', 'v', '6')) << 32);
e.averageRTT = 0;
e.lastPingSeq = 0;
e.lastPingTime = 0;
@ -3621,7 +3614,7 @@ void VoIPController::AddTCPRelays()
tcpRelay.lastPingTime = 0;
tcpRelay.rtts.Reset();
tcpRelay.udpPongCount = 0;
tcpRelay.id = tcpRelay.id ^ ((int64_t)(FOURCC('T', 'C', 'P', 0)) << 32);
tcpRelay.id = tcpRelay.id ^ (static_cast<int64_t>(FOURCC('T', 'C', 'P', 0)) << 32);
if (setCurrentEndpointToTCP && endpoints.at(currentEndpoint).type != Endpoint::Type::TCP_RELAY)
{
LOGV("Setting current endpoint to TCP");
@ -3750,7 +3743,7 @@ void VoIPController::SendPublicEndpointsRequest(const Endpoint &relay)
NetworkProtocol::UDP});
}
Endpoint &VoIPController::GetEndpointByType(int type)
Endpoint &VoIPController::GetEndpointByType(const Endpoint::Type type)
{
if (type == Endpoint::Type::UDP_RELAY && preferredRelay)
return endpoints.at(preferredRelay);
@ -4168,7 +4161,7 @@ void VoIPController::SendRelayPings()
preferredRelay = minPingRelay->id;
_preferredRelay = minPingRelay;
LOGV("set preferred relay to %s", _preferredRelay->address.ToString().c_str());
if (_currentEndpoint->type == Endpoint::Type::UDP_RELAY || _currentEndpoint->type == Endpoint::Type::TCP_RELAY)
if (_currentEndpoint->IsReflector())
{
currentEndpoint = preferredRelay;
_currentEndpoint = _preferredRelay;
@ -4176,8 +4169,8 @@ void VoIPController::SendRelayPings()
}
if (_currentEndpoint->type == Endpoint::Type::UDP_RELAY && useUDP)
{
constexpr int64_t p2pID = (int64_t)(FOURCC('P', '2', 'P', '4')) << 32;
constexpr int64_t lanID = (int64_t)(FOURCC('L', 'A', 'N', '4')) << 32;
constexpr int64_t p2pID = static_cast<int64_t>(FOURCC('P', '2', 'P', '4')) << 32;
constexpr int64_t lanID = static_cast<int64_t>(FOURCC('L', 'A', 'N', '4')) << 32;
if (endpoints.find(p2pID) != endpoints.end())
{
@ -4359,7 +4352,7 @@ void VoIPController::UpdateAudioBitrate()
for (pair<const int64_t, Endpoint> &_e : endpoints)
{
Endpoint &e = _e.second;
if (e.type == Endpoint::Type::UDP_P2P_INET || e.type == Endpoint::Type::UDP_P2P_LAN)
if (e.IsP2P())
{
e.averageRTT = 0;
e.rtts.Reset();
@ -4511,14 +4504,15 @@ void VoIPController::SendPublicEndpointsRequest()
publicEndpointsReqCount++;
if (publicEndpointsReqCount < 10)
{
messageThread.Post([this] {
if (waitingForRelayPeerInfo)
{
LOGW("Resending peer relay info request");
SendPublicEndpointsRequest();
}
},
5.0);
messageThread.Post(
[this] {
if (waitingForRelayPeerInfo)
{
LOGW("Resending peer relay info request");
SendPublicEndpointsRequest();
}
},
5.0);
}
else
{
@ -4565,125 +4559,3 @@ void VoIPController::TickJitterBufferAndCongestionControl()
}
}
}
#pragma mark - Endpoint
Endpoint::Endpoint(int64_t id, uint16_t port, const IPv4Address &_address, const IPv6Address &_v6address, Type type, unsigned char peerTag[16]) : address(NetworkAddress::IPv4(_address.addr)), v6address(NetworkAddress::IPv6(_v6address.addr))
{
this->id = id;
this->port = port;
this->type = type;
memcpy(this->peerTag, peerTag, 16);
if (type == Type::UDP_RELAY && ServerConfig::GetSharedInstance()->GetBoolean("force_tcp", false))
this->type = Type::TCP_RELAY;
lastPingSeq = 0;
lastPingTime = 0;
averageRTT = 0;
socket = NULL;
udpPongCount = 0;
}
Endpoint::Endpoint(int64_t id, uint16_t port, const NetworkAddress _address, const NetworkAddress _v6address, Type type, unsigned char peerTag[16]) : address(_address), v6address(_v6address)
{
this->id = id;
this->port = port;
this->type = type;
memcpy(this->peerTag, peerTag, 16);
if (type == Type::UDP_RELAY && ServerConfig::GetSharedInstance()->GetBoolean("force_tcp", false))
this->type = Type::TCP_RELAY;
lastPingSeq = 0;
lastPingTime = 0;
averageRTT = 0;
socket = NULL;
udpPongCount = 0;
}
Endpoint::Endpoint() : address(NetworkAddress::Empty()), v6address(NetworkAddress::Empty())
{
lastPingSeq = 0;
lastPingTime = 0;
averageRTT = 0;
socket = NULL;
udpPongCount = 0;
}
const NetworkAddress &Endpoint::GetAddress() const
{
return IsIPv6Only() ? (NetworkAddress &)v6address : (NetworkAddress &)address;
}
NetworkAddress &Endpoint::GetAddress()
{
return IsIPv6Only() ? (NetworkAddress &)v6address : (NetworkAddress &)address;
}
bool Endpoint::IsIPv6Only() const
{
return address.IsEmpty() && !v6address.IsEmpty();
}
int64_t Endpoint::CleanID() const
{
int64_t _id = id;
if (type == Type::TCP_RELAY)
{
_id = _id ^ ((int64_t)FOURCC('T', 'C', 'P', ' ') << 32);
}
if (IsIPv6Only())
{
_id = _id ^ ((int64_t)FOURCC('I', 'P', 'v', '6') << 32);
}
return _id;
}
Endpoint::~Endpoint()
{
if (socket)
{
socket->Close();
}
}
#pragma mark - AudioInputTester
AudioInputTester::AudioInputTester(std::string deviceID) : deviceID(std::move(deviceID))
{
io = audio::AudioIO::Create(deviceID, "default");
if (io->Failed())
{
LOGE("Audio IO failed");
return;
}
input = io->GetInput();
input->SetCallback([](unsigned char *data, size_t size, void *ctx) -> size_t {
reinterpret_cast<AudioInputTester *>(ctx)->Update(reinterpret_cast<int16_t *>(data), size / 2);
return 0;
},
this);
input->Start();
}
AudioInputTester::~AudioInputTester()
{
input->Stop();
delete io;
}
void AudioInputTester::Update(int16_t *samples, size_t count)
{
for (size_t i = 0; i < count; i++)
{
int16_t s = abs(samples[i]);
if (s > maxSample)
maxSample = s;
}
}
float AudioInputTester::GetAndResetLevel()
{
float s = maxSample;
maxSample = 0;
return s / (float)INT16_MAX;
}

View File

@ -4,8 +4,7 @@
// you should have received with this source code distribution.
//
#ifndef __VOIPCONTROLLER_H
#define __VOIPCONTROLLER_H
#pragma once
#ifndef _WIN32
#include <arpa/inet.h>
@ -27,10 +26,12 @@
#include <atomic>
#include "video/ScreamCongestionController.h"
#include "audio/AudioInput.h"
#include "audio/Device.h"
#include "tools/BlockingQueue.h"
#include "audio/AudioOutput.h"
#include "audio/AudioIO.h"
#include "controller/net/JitterBuffer.h"
#include "controller/net/Endpoint.h"
#include "controller/audio/OpusDecoder.h"
#include "controller/audio/OpusEncoder.h"
#include "controller/audio/EchoCanceller.h"
@ -124,95 +125,6 @@ struct CellularCarrierInfo
std::string countryCode;
};
// API compatibility
struct IPv4Address
{
IPv4Address(std::string addr) : addr(addr){};
std::string addr;
};
struct IPv6Address
{
IPv6Address(std::string addr) : addr(addr){};
std::string addr;
};
class Endpoint
{
friend class VoIPController;
friend class VoIPGroupController;
public:
enum Type
{
UDP_P2P_INET = 1,
UDP_P2P_LAN,
UDP_RELAY,
TCP_RELAY
};
Endpoint(int64_t id, uint16_t port, const IPv4Address &address, const IPv6Address &v6address, Type type, unsigned char *peerTag);
Endpoint(int64_t id, uint16_t port, const NetworkAddress address, const NetworkAddress v6address, Type type, unsigned char *peerTag);
Endpoint();
~Endpoint();
const NetworkAddress &GetAddress() const;
NetworkAddress &GetAddress();
bool IsIPv6Only() const;
int64_t CleanID() const;
int64_t id;
uint16_t port;
NetworkAddress address;
NetworkAddress v6address;
Type type;
unsigned char peerTag[16];
private:
double lastPingTime;
uint32_t lastPingSeq;
HistoricBuffer<double, 6> rtts;
HistoricBuffer<double, 4> selfRtts;
std::map<int64_t, double> udpPingTimes;
double averageRTT;
std::shared_ptr<NetworkSocket> socket;
int udpPongCount;
int totalUdpPings = 0;
int totalUdpPingReplies = 0;
};
class AudioDevice
{
public:
std::string id;
std::string displayName;
};
class AudioOutputDevice : public AudioDevice
{
};
class AudioInputDevice : public AudioDevice
{
};
class AudioInputTester
{
public:
AudioInputTester(const std::string deviceID);
~AudioInputTester();
TGVOIP_DISALLOW_COPY_AND_ASSIGN(AudioInputTester);
float GetAndResetLevel();
bool Failed()
{
return io && io->Failed();
}
private:
void Update(int16_t *samples, size_t count);
audio::AudioIO *io = NULL;
audio::AudioInput *input = NULL;
int16_t maxSample = 0;
std::string deviceID;
};
class PacketSender;
namespace video
{
@ -638,7 +550,7 @@ private:
void KDF2(unsigned char *msgKey, size_t x, unsigned char *aesKey, unsigned char *aesIv);
void SendPublicEndpointsRequest();
void SendPublicEndpointsRequest(const Endpoint &relay);
Endpoint &GetEndpointByType(int type);
Endpoint &GetEndpointByType(const Endpoint::Type type);
void SendPacketReliably(unsigned char type, unsigned char *data, size_t len, double retryInterval, double timeout);
uint32_t GenerateOutSeq();
void ActuallySendPacket(NetworkPacket pkt, Endpoint &ep);
@ -862,72 +774,5 @@ public:
#endif
};
class VoIPGroupController : public VoIPController
{
public:
VoIPGroupController(int32_t timeDifference);
virtual ~VoIPGroupController();
void SetGroupCallInfo(unsigned char *encryptionKey, unsigned char *reflectorGroupTag, unsigned char *reflectorSelfTag, unsigned char *reflectorSelfSecret, unsigned char *reflectorSelfTagHash, int32_t selfUserID, NetworkAddress reflectorAddress, NetworkAddress reflectorAddressV6, uint16_t reflectorPort);
void AddGroupCallParticipant(int32_t userID, unsigned char *memberTagHash, unsigned char *serializedStreams, size_t streamsLength);
void RemoveGroupCallParticipant(int32_t userID);
float GetParticipantAudioLevel(int32_t userID);
virtual void SetMicMute(bool mute);
void SetParticipantVolume(int32_t userID, float volume);
void SetParticipantStreams(int32_t userID, unsigned char *serializedStreams, size_t length);
static size_t GetInitialStreams(unsigned char *buf, size_t size);
struct Callbacks : public VoIPController::Callbacks
{
void (*updateStreams)(VoIPGroupController *, unsigned char *, size_t);
void (*participantAudioStateChanged)(VoIPGroupController *, int32_t, bool);
};
void SetCallbacks(Callbacks callbacks);
virtual std::string GetDebugString();
virtual void SetNetworkType(int type);
protected:
virtual void ProcessIncomingPacket(NetworkPacket &packet, Endpoint &srcEndpoint);
virtual void SendInit();
virtual void SendUdpPing(Endpoint &endpoint);
virtual void SendRelayPings();
virtual void SendPacket(unsigned char *data, size_t len, Endpoint &ep, PendingOutgoingPacket &srcPacket);
virtual void WritePacketHeader(uint32_t seq, BufferOutputStream *s, unsigned char type, uint32_t length, PacketSender *sender = NULL);
virtual void OnAudioOutputReady();
private:
int32_t GetCurrentUnixtime();
std::vector<std::shared_ptr<Stream>> DeserializeStreams(BufferInputStream &in);
void SendRecentPacketsRequest();
void SendSpecialReflectorRequest(unsigned char *data, size_t len);
void SerializeAndUpdateOutgoingStreams();
struct GroupCallParticipant
{
int32_t userID;
unsigned char memberTagHash[32];
std::vector<std::shared_ptr<Stream>> streams;
AudioLevelMeter *levelMeter;
};
std::vector<GroupCallParticipant> participants;
unsigned char reflectorSelfTag[16];
unsigned char reflectorSelfSecret[16];
unsigned char reflectorSelfTagHash[32];
int32_t userSelfID;
Endpoint groupReflector;
AudioMixer *audioMixer;
AudioLevelMeter selfLevelMeter;
Callbacks groupCallbacks;
struct PacketIdMapping
{
uint32_t seq;
uint16_t id;
double ackTime;
};
std::vector<PacketIdMapping> recentSentPackets;
Mutex sentPacketsMutex;
Mutex participantsMutex;
int32_t timeDifference;
};
}; // namespace tgvoip
#endif

View File

@ -4,7 +4,7 @@
// you should have received with this source code distribution.
//
#include "VoIPController.h"
#include "VoIPGroupController.h"
#include "tools/logging.h"
#include "VoIPServerConfig.h"
#include "controller/PrivateDefines.h"

75
VoIPGroupController.h Normal file
View File

@ -0,0 +1,75 @@
#pragma once
#include "VoIPController.h"
#include "controller/net/Endpoint.h"
#include "controller/net/NetworkSocket.h"
namespace tgvoip
{
class VoIPGroupController : public VoIPController
{
public:
VoIPGroupController(int32_t timeDifference);
virtual ~VoIPGroupController();
void SetGroupCallInfo(unsigned char *encryptionKey, unsigned char *reflectorGroupTag, unsigned char *reflectorSelfTag, unsigned char *reflectorSelfSecret, unsigned char *reflectorSelfTagHash, int32_t selfUserID, NetworkAddress reflectorAddress, NetworkAddress reflectorAddressV6, uint16_t reflectorPort);
void AddGroupCallParticipant(int32_t userID, unsigned char *memberTagHash, unsigned char *serializedStreams, size_t streamsLength);
void RemoveGroupCallParticipant(int32_t userID);
float GetParticipantAudioLevel(int32_t userID);
virtual void SetMicMute(bool mute);
void SetParticipantVolume(int32_t userID, float volume);
void SetParticipantStreams(int32_t userID, unsigned char *serializedStreams, size_t length);
static size_t GetInitialStreams(unsigned char *buf, size_t size);
struct Callbacks : public VoIPController::Callbacks
{
void (*updateStreams)(VoIPGroupController *, unsigned char *, size_t);
void (*participantAudioStateChanged)(VoIPGroupController *, int32_t, bool);
};
void SetCallbacks(Callbacks callbacks);
virtual std::string GetDebugString();
virtual void SetNetworkType(int type);
protected:
virtual void ProcessIncomingPacket(NetworkPacket &packet, Endpoint &srcEndpoint);
virtual void SendInit();
virtual void SendUdpPing(Endpoint &endpoint);
virtual void SendRelayPings();
virtual void SendPacket(unsigned char *data, size_t len, Endpoint &ep, PendingOutgoingPacket &srcPacket);
virtual void WritePacketHeader(uint32_t seq, BufferOutputStream *s, unsigned char type, uint32_t length, PacketSender *sender = NULL);
virtual void OnAudioOutputReady();
private:
int32_t GetCurrentUnixtime();
std::vector<std::shared_ptr<Stream>> DeserializeStreams(BufferInputStream &in);
void SendRecentPacketsRequest();
void SendSpecialReflectorRequest(unsigned char *data, size_t len);
void SerializeAndUpdateOutgoingStreams();
struct GroupCallParticipant
{
int32_t userID;
unsigned char memberTagHash[32];
std::vector<std::shared_ptr<Stream>> streams;
AudioLevelMeter *levelMeter;
};
std::vector<GroupCallParticipant> participants;
unsigned char reflectorSelfTag[16];
unsigned char reflectorSelfSecret[16];
unsigned char reflectorSelfTagHash[32];
int32_t userSelfID;
Endpoint groupReflector;
AudioMixer *audioMixer;
AudioLevelMeter selfLevelMeter;
Callbacks groupCallbacks;
struct PacketIdMapping
{
uint32_t seq;
uint16_t id;
double ackTime;
};
std::vector<PacketIdMapping> recentSentPackets;
Mutex sentPacketsMutex;
Mutex participantsMutex;
int32_t timeDifference;
};
} // namespace tgvoip

View File

@ -0,0 +1,44 @@
#include "AudioInputTester.h"
#include "../tools/logging.h"
using namespace tgvoip;
AudioInputTester::AudioInputTester(std::string deviceID) : deviceID(std::move(deviceID))
{
io = audio::AudioIO::Create(deviceID, "default");
if (io->Failed())
{
LOGE("Audio IO failed");
return;
}
input = io->GetInput();
input->SetCallback([](unsigned char *data, size_t size, void *ctx) -> size_t {
reinterpret_cast<AudioInputTester *>(ctx)->Update(reinterpret_cast<int16_t *>(data), size / 2);
return 0;
},
this);
input->Start();
}
AudioInputTester::~AudioInputTester()
{
input->Stop();
delete io;
}
void AudioInputTester::Update(int16_t *samples, size_t count)
{
for (size_t i = 0; i < count; i++)
{
int16_t s = abs(samples[i]);
if (s > maxSample)
maxSample = s;
}
}
float AudioInputTester::GetAndResetLevel()
{
float s = maxSample;
maxSample = 0;
return s / (float)INT16_MAX;
}

30
audio/AudioInputTester.h Normal file
View File

@ -0,0 +1,30 @@
#pragma once
#include <string>
#include "../controller/PrivateDefines.h"
#include "AudioIO.h"
#include "AudioInput.h"
namespace tgvoip
{
class AudioInputTester
{
public:
AudioInputTester(const std::string deviceID);
~AudioInputTester();
TGVOIP_DISALLOW_COPY_AND_ASSIGN(AudioInputTester);
float GetAndResetLevel();
bool Failed()
{
return io && io->Failed();
}
private:
void Update(int16_t *samples, size_t count);
audio::AudioIO *io = NULL;
audio::AudioInput *input = NULL;
int16_t maxSample = 0;
std::string deviceID;
};
} // namespace tgvoip

22
audio/Device.h Normal file
View File

@ -0,0 +1,22 @@
#pragma once
#include <string>
namespace tgvoip
{
class AudioDevice
{
public:
std::string id;
std::string displayName;
};
class AudioOutputDevice : public AudioDevice
{
};
class AudioInputDevice : public AudioDevice
{
};
} // namespace tgvoip

View File

@ -43,7 +43,7 @@ protected:
return controller->connectionInitTime;
}
const HistoricBuffer<double, 32> &RTTHistory()
const HistoricBuffer<double, 32> &RTTHistory() const
{
return controller->rttHistory;
}
@ -53,7 +53,7 @@ protected:
return controller->messageThread;
}
const VoIPController::ProtocolInfo &GetProtocolInfo()
const VoIPController::ProtocolInfo &GetProtocolInfo() const
{
return controller->protocolInfo;
}
@ -63,7 +63,7 @@ protected:
controller->SendStreamFlags(stm);
}
const VoIPController::Config &GetConfig()
const VoIPController::Config &GetConfig() const
{
return controller->config;
}

View File

@ -4,28 +4,18 @@
// you should have received with this source code distribution.
//
#include "controller/net/CongestionControl.h"
#include "CongestionControl.h"
#include "VoIPController.h"
#include "tools/logging.h"
#include "VoIPServerConfig.h"
#include "controller/PrivateDefines.h"
#include "../PrivateDefines.h"
#include <math.h>
#include <assert.h>
using namespace tgvoip;
CongestionControl::CongestionControl()
CongestionControl::CongestionControl() : cwnd(static_cast<size_t>(ServerConfig::GetSharedInstance()->GetInt("audio_congestion_window", 1024)))
{
memset(inflightPackets, 0, sizeof(inflightPackets));
tmpRtt = 0;
tmpRttCount = 0;
lastSentSeq = 0;
lastActionTime = 0;
lastActionRtt = 0;
stateTransitionTime = 0;
inflightDataSize = 0;
lossCount = 0;
cwnd = (size_t)ServerConfig::GetSharedInstance()->GetInt("audio_congestion_window", 1024);
}
CongestionControl::~CongestionControl()
@ -59,14 +49,14 @@ double CongestionControl::GetMinimumRTT()
void CongestionControl::PacketAcknowledged(uint32_t seq)
{
for (int i = 0; i < 100; i++)
for (auto &packet : inflightPackets)
{
if (inflightPackets[i].seq == seq && inflightPackets[i].sendTime > 0)
if (packet.seq == seq && packet.sendTime > 0)
{
tmpRtt += (VoIPController::GetCurrentTime() - inflightPackets[i].sendTime);
tmpRtt += (VoIPController::GetCurrentTime() - packet.sendTime);
tmpRttCount++;
inflightPackets[i].sendTime = 0;
inflightDataSize -= inflightPackets[i].size;
packet.sendTime = 0;
inflightDataSize -= packet.size;
break;
}
}
@ -82,8 +72,7 @@ void CongestionControl::PacketSent(uint32_t seq, size_t size)
lastSentSeq = seq;
double smallestSendTime = INFINITY;
tgvoip_congestionctl_packet_t *slot = NULL;
int i;
for (i = 0; i < 100; i++)
for (size_t i = 0; i < inflightPackets.size(); i++)
{
if (inflightPackets[i].sendTime == 0)
{
@ -111,12 +100,12 @@ void CongestionControl::PacketSent(uint32_t seq, size_t size)
void CongestionControl::PacketLost(uint32_t seq)
{
for (int i = 0; i < 100; i++)
for (auto &packet : inflightPackets)
{
if (inflightPackets[i].seq == seq && inflightPackets[i].sendTime > 0)
if (packet.seq == seq && packet.sendTime > 0)
{
inflightPackets[i].sendTime = 0;
inflightDataSize -= inflightPackets[i].size;
packet.sendTime = 0;
inflightDataSize -= packet.size;
lossCount++;
break;
}
@ -132,15 +121,14 @@ void CongestionControl::Tick()
tmpRtt = 0;
tmpRttCount = 0;
}
int i;
for (i = 0; i < 100; i++)
for (auto &packet : inflightPackets)
{
if (inflightPackets[i].sendTime != 0 && VoIPController::GetCurrentTime() - inflightPackets[i].sendTime > 2)
if (packet.sendTime != 0 && VoIPController::GetCurrentTime() - packet.sendTime > TGVOIP_CONCTL_LOST_AFTER)
{
inflightPackets[i].sendTime = 0;
inflightDataSize -= inflightPackets[i].size;
packet.sendTime = 0;
inflightDataSize -= packet.size;
lossCount++;
LOGD("Packet with seq %u was not acknowledged", inflightPackets[i].seq);
LOGD("Packet with seq %u was not acknowledged", packet.seq);
}
}
inflightHistory.Add(inflightDataSize);
@ -150,6 +138,7 @@ int CongestionControl::GetBandwidthControlAction()
{
if (VoIPController::GetCurrentTime() - lastActionTime < 1)
return TGVOIP_CONCTL_ACT_NONE;
size_t inflightAvg = GetInflightDataSize();
size_t max = cwnd + cwnd / 10;
size_t min = cwnd - cwnd / 10;

View File

@ -16,6 +16,8 @@
#define TGVOIP_CONCTL_ACT_DECREASE 2
#define TGVOIP_CONCTL_ACT_NONE 0
#define TGVOIP_CONCTL_LOST_AFTER 2
namespace tgvoip
{
@ -49,16 +51,16 @@ public:
private:
HistoricBuffer<double, 100> rttHistory;
HistoricBuffer<size_t, 30> inflightHistory;
tgvoip_congestionctl_packet_t inflightPackets[100];
uint32_t lossCount;
double tmpRtt;
double lastActionTime;
double lastActionRtt;
double stateTransitionTime;
int tmpRttCount;
uint32_t lastSentSeq;
uint32_t tickCount;
size_t inflightDataSize;
std::array<tgvoip_congestionctl_packet_t, 100> inflightPackets{};
uint32_t lossCount = 0;
double tmpRtt = 0.0;
double lastActionTime = 0;
double lastActionRtt = 0;
double stateTransitionTime = 0;
uint32_t tmpRttCount = 0;
uint32_t lastSentSeq = 0;
uint32_t tickCount = 0;
size_t inflightDataSize = 0;
size_t cwnd;
};
} // namespace tgvoip

View File

@ -0,0 +1,87 @@
//
// libtgvoip is free and unencumbered public domain software.
// For more information, see http://unlicense.org or the UNLICENSE file
// you should have received with this source code distribution.
//
#include "Endpoint.h"
#include "../../VoIPServerConfig.h"
#include "../PrivateDefines.h"
using namespace tgvoip;
Endpoint::Endpoint(int64_t id, uint16_t port, const IPv4Address &_address, const IPv6Address &_v6address, Type type, unsigned char peerTag[16]) : address(NetworkAddress::IPv4(_address.addr)), v6address(NetworkAddress::IPv6(_v6address.addr))
{
this->id = id;
this->port = port;
this->type = type;
memcpy(this->peerTag, peerTag, 16);
if (type == Type::UDP_RELAY && ServerConfig::GetSharedInstance()->GetBoolean("force_tcp", false))
this->type = Type::TCP_RELAY;
lastPingSeq = 0;
lastPingTime = 0;
averageRTT = 0;
socket = NULL;
udpPongCount = 0;
}
Endpoint::Endpoint(int64_t id, uint16_t port, const NetworkAddress _address, const NetworkAddress _v6address, Type type, unsigned char peerTag[16]) : address(_address), v6address(_v6address)
{
this->id = id;
this->port = port;
this->type = type;
memcpy(this->peerTag, peerTag, 16);
if (type == Type::UDP_RELAY && ServerConfig::GetSharedInstance()->GetBoolean("force_tcp", false))
this->type = Type::TCP_RELAY;
lastPingSeq = 0;
lastPingTime = 0;
averageRTT = 0;
socket = NULL;
udpPongCount = 0;
}
Endpoint::Endpoint() : address(NetworkAddress::Empty()), v6address(NetworkAddress::Empty())
{
lastPingSeq = 0;
lastPingTime = 0;
averageRTT = 0;
socket = NULL;
udpPongCount = 0;
}
const NetworkAddress &Endpoint::GetAddress() const
{
return IsIPv6Only() ? (NetworkAddress &)v6address : (NetworkAddress &)address;
}
NetworkAddress &Endpoint::GetAddress()
{
return IsIPv6Only() ? (NetworkAddress &)v6address : (NetworkAddress &)address;
}
bool Endpoint::IsIPv6Only() const
{
return address.IsEmpty() && !v6address.IsEmpty();
}
int64_t Endpoint::CleanID() const
{
int64_t _id = id;
if (type == Type::TCP_RELAY)
{
_id = _id ^ ((int64_t)FOURCC('T', 'C', 'P', ' ') << 32);
}
if (IsIPv6Only())
{
_id = _id ^ ((int64_t)FOURCC('I', 'P', 'v', '6') << 32);
}
return _id;
}
Endpoint::~Endpoint()
{
if (socket)
{
socket->Close();
}
}

67
controller/net/Endpoint.h Normal file
View File

@ -0,0 +1,67 @@
//
// libtgvoip is free and unencumbered public domain software.
// For more information, see http://unlicense.org or the UNLICENSE file
// you should have received with this source code distribution.
//
#pragma once
#include "NetworkSocket.h"
#include <map>
#include <memory>
namespace tgvoip
{
class VoIPGroupController;
class VoIPController;
class Endpoint
{
friend class VoIPController;
friend class VoIPGroupController;
public:
enum Type
{
UDP_P2P_INET = 1,
UDP_P2P_LAN,
UDP_RELAY,
TCP_RELAY
};
Endpoint(int64_t id, uint16_t port, const IPv4Address &address, const IPv6Address &v6address, Type type, unsigned char *peerTag);
Endpoint(int64_t id, uint16_t port, const NetworkAddress address, const NetworkAddress v6address, Type type, unsigned char *peerTag);
Endpoint();
~Endpoint();
const NetworkAddress &GetAddress() const;
NetworkAddress &GetAddress();
bool IsIPv6Only() const;
int64_t CleanID() const;
int64_t id;
uint16_t port;
NetworkAddress address;
NetworkAddress v6address;
Type type;
unsigned char peerTag[16];
const bool IsP2P() const
{
return type == UDP_P2P_INET || type == UDP_P2P_LAN;
}
const bool IsReflector() const
{
return type == UDP_RELAY || type == TCP_RELAY;
}
private:
double lastPingTime;
uint32_t lastPingSeq;
HistoricBuffer<double, 6> rtts;
HistoricBuffer<double, 4> selfRtts;
std::map<int64_t, double> udpPingTimes;
double averageRTT;
std::shared_ptr<NetworkSocket> socket;
int udpPongCount;
int totalUdpPings = 0;
int totalUdpPingReplies = 0;
};
} // namespace tgvoip

View File

@ -16,6 +16,20 @@
namespace tgvoip
{
// API compatibility
struct IPv4Address
{
IPv4Address(std::string addr) : addr(addr){};
std::string addr;
};
struct IPv6Address
{
IPv6Address(std::string addr) : addr(addr){};
std::string addr;
};
enum class NetworkProtocol
{
UDP = 0,

View File

@ -676,6 +676,7 @@ bool NetworkSocketPosix::Select(std::vector<NetworkSocket *> &readFds, std::vect
}
else if (anyFailed)
{
LOGE("Select failed, zeroing out");
FD_ZERO(&readSet);
FD_ZERO(&writeSet);
}

View File

@ -16,6 +16,7 @@
#include <numeric>
#include <array>
#include <limits>
#include <algorithm>
#include <bitset>
#include <stddef.h>
#include "tools/threading.h"
@ -256,7 +257,6 @@ class HistoricBuffer
public:
HistoricBuffer()
{
std::fill(data.begin(), data.end(), static_cast<T>(0));
}
AVG_T Average() const
@ -267,7 +267,7 @@ public:
AVG_T Average(size_t firstN) const
{
AVG_T avg = static_cast<AVG_T>(0);
for (size_t i = 0; i < firstN; i++)
for (size_t i = 0; i < firstN; i++) // Manual iteration required to wrap around array with specific offset
{
avg += (*this)[i];
}
@ -299,24 +299,12 @@ public:
T Min() const
{
T min = std::numeric_limits<T>::max();
for (T i : data)
{
if (i < min)
min = i;
}
return min;
return *std::min_element(data.begin(), data.end());
}
T Max() const
{
T max = std::numeric_limits<T>::min();
for (T i : data)
{
if (i > max)
max = i;
}
return max;
return *std::max_element(data.begin(), data.end());
}
void Reset()
@ -330,8 +318,8 @@ public:
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)
_i = size + _i; // wtf
if (_i < 0) // Wrap around offset a-la posmod
_i = size + _i;
return data[_i];
}
@ -340,8 +328,8 @@ public:
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)
_i = size + _i; // wtf
if (_i < 0) // Wrap around offset a-la posmod
_i = size + _i;
return data[_i];
}
@ -351,7 +339,7 @@ public:
}
private:
std::array<T, size> data;
std::array<T, size> data{};
ptrdiff_t offset = 0;
};