- source codes cleanups and minor fixes

This commit is contained in:
Dmytro Bogovych 2025-04-16 09:58:06 +03:00
parent a0b7cdcd99
commit 8d0c8ba4de
4 changed files with 182 additions and 173 deletions

View File

@ -62,6 +62,8 @@ std::vector<short>& RtpBuffer::Packet::pcm()
RtpBuffer::RtpBuffer(Statistics& stat) RtpBuffer::RtpBuffer(Statistics& stat)
:mStat(stat) :mStat(stat)
{ {
if (mStat.mPacketLoss)
std::cout << "Warning: packet loss is not zero" << std::endl;
} }
RtpBuffer::~RtpBuffer() RtpBuffer::~RtpBuffer()
@ -203,6 +205,7 @@ RtpBuffer::FetchResult RtpBuffer::fetch(ResultList& rl)
// Save it as last packet however - to not confuse loss packet counter // Save it as last packet however - to not confuse loss packet counter
mFetchedPacket = mPacketList.front(); mFetchedPacket = mPacketList.front();
mLastSeqno = mPacketList.front()->rtp()->GetExtendedSequenceNumber();
// Erase from packet list // Erase from packet list
mPacketList.erase(mPacketList.begin()); mPacketList.erase(mPacketList.begin());
@ -212,47 +215,48 @@ RtpBuffer::FetchResult RtpBuffer::fetch(ResultList& rl)
} }
if (total < mLow) if (total < mLow)
{
// Still not prebuffered
result = FetchResult::NoPacket; result = FetchResult::NoPacket;
}
else else
{ {
// Did we fetch any packet before ?
bool is_fetched_packet = mFetchedPacket.get() != nullptr; bool is_fetched_packet = mFetchedPacket.get() != nullptr;
if (is_fetched_packet) if (is_fetched_packet)
is_fetched_packet &= mFetchedPacket->rtp().get() != nullptr; is_fetched_packet &= mFetchedPacket->rtp().get() != nullptr;
if (is_fetched_packet) if (mLastSeqno.has_value())
{ {
if (mPacketList.empty()) if (mPacketList.empty())
{ {
result = FetchResult::NoPacket; result = FetchResult::NoPacket;
mStat.mPacketLoss++; // Don't increase counter of lost packets here; maybe it is DTX
} }
else else
{ {
// Current sequence number ? // Current sequence number ?
unsigned seqno = mPacketList.front()->rtp()->GetExtendedSequenceNumber(); uint32_t seqno = mPacketList.front()->rtp()->GetExtendedSequenceNumber();
// Gap between new packet and previous on // Gap between new packet and previous on
int gap = (int64_t)seqno - (int64_t)mFetchedPacket->rtp()->GetExtendedSequenceNumber() - 1; int gap = (int64_t)seqno - (int64_t)*mLastSeqno - 1;
gap = std::min(gap, 127); gap = std::min(gap, 127);
if (gap > 0 && mPacketList.empty()) if (gap > 0)
{ {
// std::cout << "Increase the packet loss for SSRC " << std::hex << mSsrc << std::endl;
mStat.mPacketLoss++;
//mStat.mLoss[gap]++;
mLastSeqno = *mLastSeqno + 1;
result = FetchResult::Gap; result = FetchResult::Gap;
mStat.mPacketLoss += gap;
mStat.mLoss[gap]++;
} }
else else
{ {
if (gap > 0)
{
mStat.mPacketLoss += gap;
mStat.mLoss[gap]++;
}
result = FetchResult::RegularPacket; result = FetchResult::RegularPacket;
rl.push_back(mPacketList.front()); rl.push_back(mPacketList.front());
// Save last returned normal packet // Save last returned normal packet
mFetchedPacket = mPacketList.front(); mFetchedPacket = mPacketList.front();
mLastSeqno = mPacketList.front()->rtp()->GetExtendedSequenceNumber();
// Remove returned packet from the list // Remove returned packet from the list
mPacketList.erase(mPacketList.begin()); mPacketList.erase(mPacketList.begin());
@ -262,7 +266,7 @@ RtpBuffer::FetchResult RtpBuffer::fetch(ResultList& rl)
else else
{ {
// See if prebuffer limit is reached // See if prebuffer limit is reached
if (findTimelength() >= mPrebuffer) if (findTimelength() >= mPrebuffer && !mPacketList.empty())
{ {
// Normal packet will be returned // Normal packet will be returned
result = FetchResult::RegularPacket; result = FetchResult::RegularPacket;
@ -272,6 +276,7 @@ RtpBuffer::FetchResult RtpBuffer::fetch(ResultList& rl)
// Remember returned packet // Remember returned packet
mFetchedPacket = mPacketList.front(); mFetchedPacket = mPacketList.front();
mLastSeqno = mPacketList.front()->rtp()->GetExtendedSequenceNumber();
// Remove returned packet from buffer list // Remove returned packet from buffer list
mPacketList.erase(mPacketList.begin()); mPacketList.erase(mPacketList.begin());
@ -402,10 +407,11 @@ size_t decode_packet(Codec& codec, RTPPacket& p, void* output_buffer, size_t out
return result; return result;
} }
bool AudioReceiver::add(const std::shared_ptr<jrtplib::RTPPacket>& p, Codec** codec) bool AudioReceiver::add(const std::shared_ptr<jrtplib::RTPPacket>& p, Codec** detectedCodec)
{ {
// Estimate time length // Estimate time length
int time_length = 0, int time_length = 0,
samplerate = 8000,
payloadLength = p->GetPayloadLength(), payloadLength = p->GetPayloadLength(),
ptype = p->GetPayloadType(); ptype = p->GetPayloadType();
@ -414,34 +420,43 @@ bool AudioReceiver::add(const std::shared_ptr<jrtplib::RTPPacket>& p, Codec** co
mStat.mCodecCount[ptype]++; mStat.mCodecCount[ptype]++;
// Check if codec can be handled // Check if codec can be handled
Codec* codec = nullptr;
CodecMap::iterator codecIter = mCodecMap.find(ptype); CodecMap::iterator codecIter = mCodecMap.find(ptype);
if (codecIter == mCodecMap.end()) if (codecIter == mCodecMap.end())
{ {
ICELogMedia(<< "Cannot find codec in available codecs"); time_length = 10;
return false; // Reject packet with unknown payload type
} }
// Check if codec is creating lazily
if (!codecIter->second)
{
codecIter->second = mCodecList.createCodecByPayloadType(ptype);
}
// Return pointer to codec if needed.get()
if (codec)
*codec = codecIter->second.get();
if (mStat.mCodecName.empty())
mStat.mCodecName = codecIter->second->name();
if (!codecIter->second->rtpLength())
time_length = codecIter->second->frameTime();
else else
time_length = lround(double(payloadLength) / codecIter->second->rtpLength() * codecIter->second->frameTime()); {
// Check if codec is creating lazily
if (!codecIter->second)
{
codecIter->second = mCodecList.createCodecByPayloadType(ptype);
}
codec = codecIter->second.get();
// Return pointer to codec if needed.get()
if (detectedCodec)
*detectedCodec = codec;
if (mStat.mCodecName.empty() && codec)
mStat.mCodecName = codec->name();
if (!codec)
time_length = 10;
else
if (!codec->rtpLength())
time_length = codec->frameTime();
else
time_length = lround(double(payloadLength) / codec->rtpLength() * codec->frameTime());
if (codec)
samplerate = codec->samplerate();
}
// Process jitter // Process jitter
mJitterStats.process(p.get(), codecIter->second->samplerate()); mJitterStats.process(p.get(), samplerate);
mStat.mJitter = static_cast<float>(mJitterStats.get()); mStat.mJitter = static_cast<float>(mJitterStats.get());
// Check if packet is CNG // Check if packet is CNG
@ -453,20 +468,20 @@ bool AudioReceiver::add(const std::shared_ptr<jrtplib::RTPPacket>& p, Codec** co
{ {
// It will cause statistics to report about bad RTP packet // It will cause statistics to report about bad RTP packet
// I have to replay last packet payload here to avoid report about lost packet // I have to replay last packet payload here to avoid report about lost packet
mBuffer.add(p, time_length, codecIter->second->samplerate()); mBuffer.add(p, time_length, samplerate);
return false; return false;
} }
// Queue packet to buffer // Queue packet to buffer
auto packet = mBuffer.add(p, time_length, codecIter->second->samplerate()).get(); auto packet = mBuffer.add(p, time_length, samplerate).get();
if (packet) if (packet)
{ {
// Check if early decoding configured // Check if early decoding configured
if (mEarlyDecode && *codec) if (mEarlyDecode && codec)
{ {
// Move data to packet buffer // Move data to packet buffer
size_t available = decode_packet(**codec, *p, mDecodedFrame, sizeof mDecodedFrame); size_t available = decode_packet(*codec, *p, mDecodedFrame, sizeof mDecodedFrame);
if (available > 0) if (available > 0)
{ {
packet->pcm().resize(available / 2); packet->pcm().resize(available / 2);
@ -549,7 +564,6 @@ AudioReceiver::DecodeResult AudioReceiver::getAudio(Audio::DataWindow& output, i
case RtpBuffer::FetchResult::RegularPacket: case RtpBuffer::FetchResult::RegularPacket:
mFailedCount = 0; mFailedCount = 0;
for (std::shared_ptr<RtpBuffer::Packet>& p: rl) for (std::shared_ptr<RtpBuffer::Packet>& p: rl)
{ {
assert(p); assert(p);

View File

@ -1,4 +1,4 @@
/* Copyright(C) 2007-2017 VoIPobjects (voipobjects.com) /* Copyright(C) 2007-2025 VoIPobjects (voipobjects.com)
* This Source Code Form is subject to the terms of the Mozilla Public * This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this * License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
@ -8,22 +8,16 @@
#include "MT_Stream.h" #include "MT_Stream.h"
#include "MT_CodecList.h" #include "MT_CodecList.h"
#include "MT_AudioCodec.h"
#include "MT_CngHelper.h" #include "MT_CngHelper.h"
#include "../helper/HL_Pointer.h"
#include "../helper/HL_Sync.h" #include "../helper/HL_Sync.h"
#include "../helper/HL_Optional.hpp"
#include "jrtplib/src/rtppacket.h" #include "jrtplib/src/rtppacket.h"
#include "jrtplib/src/rtcppacket.h"
#include "jrtplib/src/rtpsourcedata.h" #include "jrtplib/src/rtpsourcedata.h"
#include "../audio/Audio_DataWindow.h" #include "../audio/Audio_DataWindow.h"
#include "../audio/Audio_Resampler.h" #include "../audio/Audio_Resampler.h"
#include <map> #include <optional>
// #define DUMP_DECODED
namespace MT namespace MT
{ {
@ -101,6 +95,7 @@ namespace MT
bool mFirstPacketWillGo = true; bool mFirstPacketWillGo = true;
jrtplib::RTPSourceStats mRtpStats; jrtplib::RTPSourceStats mRtpStats;
std::shared_ptr<Packet> mFetchedPacket; std::shared_ptr<Packet> mFetchedPacket;
std::optional<uint32_t> mLastSeqno;
// To calculate average interval between packet add. It is close to jitter but more useful in debugging. // To calculate average interval between packet add. It is close to jitter but more useful in debugging.
float mLastAddTime = 0.0; float mLastAddTime = 0.0;

View File

@ -423,7 +423,7 @@ PCodec CodecList::createCodecByPayloadType(int payloadType)
if (factory->payloadType() == payloadType) if (factory->payloadType() == payloadType)
return factory->create(); return factory->create();
} }
return PCodec(); return {};
} }
CodecListPriority::CodecListPriority() CodecListPriority::CodecListPriority()

View File

@ -68,7 +68,7 @@ NetworkAddress NetworkAddress::parse(const std::string& s)
if (ip4Pos == std::string::npos && ip6Pos == std::string::npos) if (ip4Pos == std::string::npos && ip6Pos == std::string::npos)
{ {
// Parse usual IP[:port] pair // Parse usual IP[:port] pair
std::string::size_type cp = s.find(":"); std::string::size_type cp = s.find_last_of(":");
if (cp == std::string::npos) if (cp == std::string::npos)
result.setIp(cp); result.setIp(cp);
else else
@ -116,7 +116,7 @@ NetworkAddress::NetworkAddress(int stunType)
} }
NetworkAddress::NetworkAddress(const in6_addr& addr6, unsigned short port) NetworkAddress::NetworkAddress(const in6_addr& addr6, unsigned short port)
:mInitialized(true), mRelayed(false) :mInitialized(true), mRelayed(false)
{ {
memset(&mAddr6, 0, sizeof(mAddr6)); memset(&mAddr6, 0, sizeof(mAddr6));
mAddr4.sin_family = AF_INET6; mAddr4.sin_family = AF_INET6;
@ -125,7 +125,7 @@ NetworkAddress::NetworkAddress(const in6_addr& addr6, unsigned short port)
} }
NetworkAddress::NetworkAddress(const in_addr& addr4, unsigned short port) NetworkAddress::NetworkAddress(const in_addr& addr4, unsigned short port)
:mInitialized(true), mRelayed(false) :mInitialized(true), mRelayed(false)
{ {
memset(&mAddr6, 0, sizeof(mAddr6)); memset(&mAddr6, 0, sizeof(mAddr6));
mAddr4.sin_family = AF_INET; mAddr4.sin_family = AF_INET;
@ -168,7 +168,7 @@ void NetworkAddress::setStunType(unsigned char st)
} }
NetworkAddress::NetworkAddress(const std::string& ip, unsigned short port) NetworkAddress::NetworkAddress(const std::string& ip, unsigned short port)
:mInitialized(true), mRelayed(false) :mInitialized(true), mRelayed(false)
{ {
memset(&mAddr6, 0, sizeof(mAddr6)); memset(&mAddr6, 0, sizeof(mAddr6));
setIp(ip); setIp(ip);
@ -186,42 +186,42 @@ NetworkAddress::NetworkAddress(const char *ip, unsigned short port)
} }
NetworkAddress::NetworkAddress(uint32_t ip_4, uint16_t port) NetworkAddress::NetworkAddress(uint32_t ip_4, uint16_t port)
:mInitialized(true), mRelayed(false) :mInitialized(true), mRelayed(false)
{ {
memset(&mAddr6, 0, sizeof(mAddr6)); memset(&mAddr6, 0, sizeof(mAddr6));
mAddr4.sin_family = AF_INET; mAddr4.sin_family = AF_INET;
mAddr4.sin_addr.s_addr = ip_4; mAddr4.sin_addr.s_addr = ip_4;
mAddr4.sin_port = port; mAddr4.sin_port = port;
} }
NetworkAddress::NetworkAddress(const uint8_t* ip_6, uint16_t port) NetworkAddress::NetworkAddress(const uint8_t* ip_6, uint16_t port)
:mInitialized(true), mRelayed(false) :mInitialized(true), mRelayed(false)
{ {
memset(&mAddr6, 0, sizeof(mAddr6)); memset(&mAddr6, 0, sizeof(mAddr6));
mAddr6.sin6_family = AF_INET6; mAddr6.sin6_family = AF_INET6;
memmove(&mAddr6.sin6_addr, ip_6, sizeof(mAddr6.sin6_addr)); memmove(&mAddr6.sin6_addr, ip_6, sizeof(mAddr6.sin6_addr));
mAddr6.sin6_port = port; mAddr6.sin6_port = port;
} }
NetworkAddress::NetworkAddress(const sockaddr& addr, size_t addrLen) NetworkAddress::NetworkAddress(const sockaddr& addr, size_t addrLen)
:mInitialized(true), mRelayed(false) :mInitialized(true), mRelayed(false)
{ {
switch (addr.sa_family) switch (addr.sa_family)
{ {
case AF_INET6: case AF_INET6:
memset(&mAddr6, 0, sizeof(mAddr6)); memset(&mAddr6, 0, sizeof(mAddr6));
memcpy(&mAddr6, &addr, addrLen); memcpy(&mAddr6, &addr, addrLen);
break; break;
case AF_INET: case AF_INET:
memset(&mAddr4, 0, sizeof(mAddr4)); memset(&mAddr4, 0, sizeof(mAddr4));
memcpy(&mAddr4, &addr, addrLen); memcpy(&mAddr4, &addr, addrLen);
break; break;
} }
} }
NetworkAddress::NetworkAddress(const NetworkAddress& src) NetworkAddress::NetworkAddress(const NetworkAddress& src)
:mInitialized(src.mInitialized), mRelayed(src.mRelayed) :mInitialized(src.mInitialized), mRelayed(src.mRelayed)
{ {
memset(&mAddr6, 0, sizeof(mAddr6)); memset(&mAddr6, 0, sizeof(mAddr6));
if (src.mAddr4.sin_family == AF_INET) if (src.mAddr4.sin_family == AF_INET)
@ -373,15 +373,15 @@ void NetworkAddress::setIp(unsigned long ip)
void NetworkAddress::setIp(const in_addr& ip) void NetworkAddress::setIp(const in_addr& ip)
{ {
//memset(&mAddr4, 0, sizeof mAddr4); //memset(&mAddr4, 0, sizeof mAddr4);
mAddr4.sin_family = AF_INET; mAddr4.sin_family = AF_INET;
mAddr4.sin_addr = ip; mAddr4.sin_addr = ip;
} }
void NetworkAddress::setIp(const in6_addr& ip) void NetworkAddress::setIp(const in6_addr& ip)
{ {
mAddr6.sin6_family = AF_INET6; mAddr6.sin6_family = AF_INET6;
mAddr6.sin6_addr = ip; mAddr6.sin6_addr = ip;
} }
// 10.0.0.0 - 10.255.255.255 // 10.0.0.0 - 10.255.255.255
// 172.16.0.0 - 172.31.255.255 // 172.16.0.0 - 172.31.255.255
@ -390,54 +390,54 @@ void NetworkAddress::setIp(const in6_addr& ip)
bool NetworkAddress::isSameLAN(const NetworkAddress& a1, const NetworkAddress& a2) bool NetworkAddress::isSameLAN(const NetworkAddress& a1, const NetworkAddress& a2)
{ {
if (a1.family() != a2.family()) if (a1.family() != a2.family())
return false; return false;
if (a1.family() == AF_INET) if (a1.family() == AF_INET)
{ {
sockaddr_in* s1 = a1.sockaddr4(); sockaddr_in* s1 = a1.sockaddr4();
sockaddr_in* s2 = a2.sockaddr4(); sockaddr_in* s2 = a2.sockaddr4();
#ifdef TARGET_WIN #ifdef TARGET_WIN
unsigned b1_0 = (s1->sin_addr.S_un.S_addr >> 0) & 0xFF; unsigned b1_0 = (s1->sin_addr.S_un.S_addr >> 0) & 0xFF;
unsigned b1_1 = (s1->sin_addr.S_un.S_addr >> 8) & 0xFF; unsigned b1_1 = (s1->sin_addr.S_un.S_addr >> 8) & 0xFF;
unsigned b2_0 = (s2->sin_addr.S_un.S_addr >> 0) & 0xFF; unsigned b2_0 = (s2->sin_addr.S_un.S_addr >> 0) & 0xFF;
unsigned b2_1 = (s2->sin_addr.S_un.S_addr >> 8) & 0xFF; unsigned b2_1 = (s2->sin_addr.S_un.S_addr >> 8) & 0xFF;
#else #else
unsigned b1_0 = (s1->sin_addr.s_addr >> 0) & 0xFF; unsigned b1_0 = (s1->sin_addr.s_addr >> 0) & 0xFF;
unsigned b1_1 = (s1->sin_addr.s_addr >> 8) & 0xFF; unsigned b1_1 = (s1->sin_addr.s_addr >> 8) & 0xFF;
unsigned b2_0 = (s2->sin_addr.s_addr >> 0) & 0xFF; unsigned b2_0 = (s2->sin_addr.s_addr >> 0) & 0xFF;
unsigned b2_1 = (s2->sin_addr.s_addr >> 8) & 0xFF; unsigned b2_1 = (s2->sin_addr.s_addr >> 8) & 0xFF;
if (b1_0 == b2_0 && b1_0 == 192 && if (b1_0 == b2_0 && b1_0 == 192 &&
b1_1 == b2_1 && b1_1 == 168) b1_1 == b2_1 && b1_1 == 168)
return true; return true;
if (b1_0 == b2_0 && b1_0 == 10) if (b1_0 == b2_0 && b1_0 == 10)
return true; return true;
if (b1_0 == b2_0 && b1_0 == 172 && if (b1_0 == b2_0 && b1_0 == 172 &&
b1_1 == b2_1 && (b1_1 < 32)) b1_1 == b2_1 && (b1_1 < 32))
return true; return true;
#endif #endif
} }
return false; return false;
} }
void NetworkAddress::setPort(unsigned short port) void NetworkAddress::setPort(unsigned short port)
{ {
switch(mAddr4.sin_family) switch(mAddr4.sin_family)
{ {
case AF_INET: case AF_INET:
mAddr4.sin_port = htons(port); mAddr4.sin_port = htons(port);
mInitialized = true; mInitialized = true;
break; break;
case AF_INET6: case AF_INET6:
mAddr6.sin6_port = htons(port); mAddr6.sin6_port = htons(port);
mInitialized = true; mInitialized = true;
break; break;
default: default:
assert(0); assert(0);
} }
} }
@ -518,13 +518,13 @@ std::string NetworkAddress::toStdString() const
std::string NetworkAddress::toBriefStdString() const std::string NetworkAddress::toBriefStdString() const
{ {
if (!mInitialized) if (!mInitialized)
return ""; return "";
char temp[128]; char temp[128];
sprintf(temp, "%s:%u", ip().c_str(), (unsigned int)port()); sprintf(temp, "%s:%u", ip().c_str(), (unsigned int)port());
return temp; return temp;
} }
#ifdef WIN32 #ifdef WIN32
@ -541,7 +541,7 @@ std::wstring NetworkAddress::toStdWString() const
#endif #endif
static const unsigned char localhost6[] = static const unsigned char localhost6[] =
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 }; { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 };
bool NetworkAddress::isLoopback() const bool NetworkAddress::isLoopback() const
{ {
@ -589,27 +589,27 @@ bool NetworkAddress::isLAN() const
switch (mAddr4.sin_family) switch (mAddr4.sin_family)
{ {
case AF_INET: case AF_INET:
{ {
unsigned char b1 = mAddr4.sin_addr.s_addr & 0xFF; unsigned char b1 = mAddr4.sin_addr.s_addr & 0xFF;
unsigned char b2 = (mAddr4.sin_addr.s_addr >> 8) & 0xFF; unsigned char b2 = (mAddr4.sin_addr.s_addr >> 8) & 0xFF;
if (b1 == 192 && b2 == 168) if (b1 == 192 && b2 == 168)
return true; return true;
if (b1 == 10) if (b1 == 10)
return true; return true;
if (b1 == 172 && (b2 >= 16 && b2 <= 31)) if (b1 == 172 && (b2 >= 16 && b2 <= 31))
return true; return true;
// Link local addresses are not routable so report them here // Link local addresses are not routable so report them here
if (b1 == 169 && b2 == 254) if (b1 == 169 && b2 == 254)
return true; return true;
return false; return false;
} }
case AF_INET6: case AF_INET6:
return false; return false;
default: default:
assert(0); assert(0);
@ -624,24 +624,24 @@ bool NetworkAddress::isLinkLocal() const
switch (mAddr4.sin_family) switch (mAddr4.sin_family)
{ {
case AF_INET: case AF_INET:
{ {
unsigned char b1 = mAddr4.sin_addr.s_addr & 0xFF; unsigned char b1 = mAddr4.sin_addr.s_addr & 0xFF;
unsigned char b2 = (mAddr4.sin_addr.s_addr >> 8) & 0xFF; unsigned char b2 = (mAddr4.sin_addr.s_addr >> 8) & 0xFF;
// Link local addresses are not routable so report them here // Link local addresses are not routable so report them here
if (b1 == 169 && b2 == 254) if (b1 == 169 && b2 == 254)
return true; return true;
//if (b1 == 100 && (b2 >= 64 && b2 <= 127)) //if (b1 == 100 && (b2 >= 64 && b2 <= 127))
// return true; // return true;
return false;
} return false;
}
case AF_INET6: case AF_INET6:
#ifdef WIN32 #ifdef WIN32
return (mAddr6.sin6_addr.u.Byte[0] == 0xFE && mAddr6.sin6_addr.u.Byte[1] == 0x80); return (mAddr6.sin6_addr.u.Byte[0] == 0xFE && mAddr6.sin6_addr.u.Byte[1] == 0x80);
#else #else
return IN6_IS_ADDR_LINKLOCAL(&mAddr6.sin6_addr); return IN6_IS_ADDR_LINKLOCAL(&mAddr6.sin6_addr);
#endif #endif
@ -668,17 +668,17 @@ bool NetworkAddress::isZero() const
return false; return false;
switch (mAddr4.sin_family) switch (mAddr4.sin_family)
{ {
case AF_INET: case AF_INET:
return mAddr4.sin_addr.s_addr == 0; return mAddr4.sin_addr.s_addr == 0;
case AF_INET6: case AF_INET6:
#ifdef WIN32 #ifdef WIN32
return !mAddr6.sin6_addr.u.Word[0] && !mAddr6.sin6_addr.u.Word[1] && return !mAddr6.sin6_addr.u.Word[0] && !mAddr6.sin6_addr.u.Word[1] &&
!mAddr6.sin6_addr.u.Word[2] && !mAddr6.sin6_addr.u.Word[3] && !mAddr6.sin6_addr.u.Word[2] && !mAddr6.sin6_addr.u.Word[3] &&
!mAddr6.sin6_addr.u.Word[4] && !mAddr6.sin6_addr.u.Word[5] && !mAddr6.sin6_addr.u.Word[4] && !mAddr6.sin6_addr.u.Word[5] &&
!mAddr6.sin6_addr.u.Word[6] && !mAddr6.sin6_addr.u.Word[7]; !mAddr6.sin6_addr.u.Word[6] && !mAddr6.sin6_addr.u.Word[7];
#else #else
return IN6_IS_ADDR_UNSPECIFIED(&mAddr6.sin6_addr); return IN6_IS_ADDR_UNSPECIFIED(&mAddr6.sin6_addr);
#endif #endif
} }
return false; return false;
@ -795,30 +795,30 @@ bool NetworkAddress::isSame(const NetworkAddress& a1, const NetworkAddress& a2)
// Compare address families // Compare address families
if (a1.mAddr4.sin_family != a2.mAddr4.sin_family) if (a1.mAddr4.sin_family != a2.mAddr4.sin_family)
return false; return false;
if (a1.mRelayed != a2.mRelayed) if (a1.mRelayed != a2.mRelayed)
return false; return false;
switch (a1.mAddr4.sin_family) switch (a1.mAddr4.sin_family)
{ {
case AF_INET: case AF_INET:
return a1.mAddr4.sin_addr.s_addr == a2.mAddr4.sin_addr.s_addr && a1.mAddr4.sin_port == a2.mAddr4.sin_port; return a1.mAddr4.sin_addr.s_addr == a2.mAddr4.sin_addr.s_addr && a1.mAddr4.sin_port == a2.mAddr4.sin_port;
case AF_INET6: case AF_INET6:
return memcmp(&a1.mAddr6.sin6_addr, &a2.mAddr6.sin6_addr, sizeof(a1.mAddr6.sin6_addr)) == 0 && return memcmp(&a1.mAddr6.sin6_addr, &a2.mAddr6.sin6_addr, sizeof(a1.mAddr6.sin6_addr)) == 0 &&
a1.mAddr6.sin6_port == a2.mAddr6.sin6_port; a1.mAddr6.sin6_port == a2.mAddr6.sin6_port;
default: default:
assert(0); assert(0);
} }
return false; return false;
} }
NetworkAddress& NetworkAddress::operator = (const NetworkAddress& src) NetworkAddress& NetworkAddress::operator = (const NetworkAddress& src)
{ {
this->mInitialized = src.mInitialized; this->mInitialized = src.mInitialized;
this->mRelayed = src.mRelayed; this->mRelayed = src.mRelayed;
this->mAddr6 = src.mAddr6; this->mAddr6 = src.mAddr6;
return *this; return *this;
} }