- more RTP manipulation abilities + cleanups

This commit is contained in:
2023-03-13 17:27:58 +03:00
parent 5bbdec8452
commit 1b41ac9e16
11 changed files with 146 additions and 125 deletions

View File

@@ -15,5 +15,5 @@ add_library(helper_lib ${HELPER_LIB_SOURCES})
set_property(TARGET helper_lib PROPERTY MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
# Private include directories
target_include_directories(helper_lib PRIVATE ../../libs/ ../../engine ../)
target_include_directories(helper_lib PUBLIC ../../libs/ ../../engine ../ .)
target_compile_definitions(helper_lib PRIVATE -D_CRT_SECURE_NO_WARNINGS -D_UNICODE)

View File

@@ -11,15 +11,36 @@
#define MPLS_STACK_MASK (0x00000100)
#define MPLS_STACK_SHIFT (8)
NetworkFrame::PacketData NetworkFrame::GetUdpPayloadForEthernet(NetworkFrame::PacketData& packet, InternetAddress& source, InternetAddress& destination)
NetworkFrame::Payload NetworkFrame::GetUdpPayloadForRaw(const Packet& data)
{
PacketData result(packet);
const Ip4Header* ip4 = reinterpret_cast<const Ip4Header*>(data.mData);
const EthernetHeader* ethernet = reinterpret_cast<const EthernetHeader*>(packet.mData);
if (ip4->mProtocol != IPPROTO_UDP && ip4->mProtocol != 0)
return Payload();
switch (ip4->version())
{
case 4:
return GetUdpPayloadForIp4(data);
case 6:
return GetUdpPayloadForIp6(data);
default:
return Payload();
}
}
NetworkFrame::Payload NetworkFrame::GetUdpPayloadForEthernet(const Packet& data)
{
Packet result(data);
const EthernetHeader* ethernet = reinterpret_cast<const EthernetHeader*>(data.mData);
// Skip ethernet header
packet.mData += sizeof(EthernetHeader);
packet.mLength -= sizeof(EthernetHeader);
result.mData += sizeof(EthernetHeader);
result.mLength -= sizeof(EthernetHeader);
// See if there is Vlan header
uint16_t proto = 0;
@@ -28,9 +49,9 @@ NetworkFrame::PacketData NetworkFrame::GetUdpPayloadForEthernet(NetworkFrame::Pa
// Skip 1 or more VLAN headers
do
{
const VlanHeader* vlan = reinterpret_cast<const VlanHeader*>(packet.mData);
packet.mData += sizeof(VlanHeader);
packet.mLength -= sizeof(VlanHeader);
const VlanHeader* vlan = reinterpret_cast<const VlanHeader*>(result.mData);
result.mData += sizeof(VlanHeader);
result.mLength -= sizeof(VlanHeader);
proto = ntohs(vlan->mData);
}
while (proto == 0x8100);
@@ -43,10 +64,10 @@ NetworkFrame::PacketData NetworkFrame::GetUdpPayloadForEthernet(NetworkFrame::Pa
case ETHERTYPE_MPLS_MC:
// Parse MPLS here until marker "bottom of mpls stack"
for(bool bottomOfStack = false; !bottomOfStack;
bottomOfStack = ((ntohl(*(uint32_t*)(packet.mData - 4)) & MPLS_STACK_MASK) >> MPLS_STACK_SHIFT) != 0)
bottomOfStack = ((ntohl(*(uint32_t*)(result.mData - 4)) & MPLS_STACK_MASK) >> MPLS_STACK_SHIFT) != 0)
{
packet.mData += 4;
packet.mLength -=4;
result.mData += 4;
result.mLength -=4;
}
break;
@@ -59,86 +80,86 @@ NetworkFrame::PacketData NetworkFrame::GetUdpPayloadForEthernet(NetworkFrame::Pa
break;
}
const Ip4Header* ip4 = reinterpret_cast<const Ip4Header*>(packet.mData);
const Ip4Header* ip4 = reinterpret_cast<const Ip4Header*>(result.mData);
if (ip4->mProtocol != IPPROTO_UDP && ip4->mProtocol != 0)
return PacketData();
return Payload();
switch (ip4->version())
{
case 4:
return GetUdpPayloadForIp4(packet, source, destination);
return GetUdpPayloadForIp4(result);
case 6:
return GetUdpPayloadForIp6(packet, source, destination);
return GetUdpPayloadForIp6(result);
default:
return PacketData();
return Payload();
}
}
NetworkFrame::PacketData NetworkFrame::GetUdpPayloadForSLL(NetworkFrame::PacketData& packet, InternetAddress& source, InternetAddress& destination)
NetworkFrame::Payload NetworkFrame::GetUdpPayloadForSLL(const Packet& data)
{
PacketData result(packet);
Packet result(data);
if (packet.mLength < 16)
return PacketData();
if (result.mLength < 16)
return Payload();
const LinuxSllHeader* sll = reinterpret_cast<const LinuxSllHeader*>(packet.mData);
const LinuxSllHeader* sll = reinterpret_cast<const LinuxSllHeader*>(result.mData);
packet.mData += sizeof(LinuxSllHeader);
packet.mLength -= sizeof(LinuxSllHeader);
result.mData += sizeof(LinuxSllHeader);
result.mLength -= sizeof(LinuxSllHeader);
switch (ntohs(sll->mProtocolType))
{
case 0x0800:
return GetUdpPayloadForIp4(packet, source, destination);
return GetUdpPayloadForIp4(result);
case 0x86DD:
return GetUdpPayloadForIp6(packet, source, destination);
return GetUdpPayloadForIp6(result);
default:
return PacketData();
return Payload();
}
}
NetworkFrame::PacketData NetworkFrame::GetUdpPayloadForLoopback(NetworkFrame::PacketData& packet, InternetAddress& source, InternetAddress& destination)
NetworkFrame::Payload NetworkFrame::GetUdpPayloadForLoopback(const Packet& data)
{
PacketData result(packet);
Packet result(data);
if (packet.mLength < 16)
return PacketData();
if (result.mLength < 16)
return Payload();
struct LoopbackHeader
{
uint32_t mProtocolType;
};
const LoopbackHeader* lh = reinterpret_cast<const LoopbackHeader*>(packet.mData);
const LoopbackHeader* lh = reinterpret_cast<const LoopbackHeader*>(result.mData);
packet.mData += sizeof(LoopbackHeader);
packet.mLength -= sizeof(LoopbackHeader);
result.mData += sizeof(LoopbackHeader);
result.mLength -= sizeof(LoopbackHeader);
switch (lh->mProtocolType)
{
case AF_INET:
return GetUdpPayloadForIp4(packet, source, destination);
return GetUdpPayloadForIp4(result);
case AF_INET6:
return GetUdpPayloadForIp6(packet, source, destination);
return GetUdpPayloadForIp6(result);
default:
return PacketData();
return Payload();
}
}
NetworkFrame::PacketData NetworkFrame::GetUdpPayloadForIp4(NetworkFrame::PacketData& packet, InternetAddress& source, InternetAddress& destination)
NetworkFrame::Payload NetworkFrame::GetUdpPayloadForIp4(const Packet& data)
{
PacketData result(packet);
const Ip4Header* ip4 = reinterpret_cast<const Ip4Header*>(packet.mData);
Packet result(data);
const Ip4Header* ip4 = reinterpret_cast<const Ip4Header*>(data.mData);
if (ip4->mProtocol != IPPROTO_UDP && ip4->mProtocol != 0)
return PacketData(nullptr, 0);
return Payload();
result.mData += ip4->headerLength();
result.mLength -= ip4->headerLength();
@@ -152,13 +173,15 @@ NetworkFrame::PacketData NetworkFrame::GetUdpPayloadForIp4(NetworkFrame::PacketD
if (length - sizeof(UdpHeader) < (size_t)result.mLength)
result.mLength = length - sizeof(UdpHeader);
source.setIp(ip4->mSource);
source.setPort(ntohs(udp->mSourcePort));
InternetAddress addr_source;
addr_source.setIp(ip4->mSource);
addr_source.setPort(ntohs(udp->mSourcePort));
destination.setIp(ip4->mDestination);
destination.setPort(ntohs(udp->mDestinationPort));
InternetAddress addr_dest;
addr_dest.setIp(ip4->mDestination);
addr_dest.setPort(ntohs(udp->mDestinationPort));
return result;
return {.data = result, .source = addr_source, .dest = addr_dest};
}
struct Ip6Header
@@ -188,10 +211,10 @@ struct Ip6Header
struct in6_addr dst_ip;
};
NetworkFrame::PacketData NetworkFrame::GetUdpPayloadForIp6(NetworkFrame::PacketData& packet, InternetAddress& source, InternetAddress& destination)
NetworkFrame::Payload NetworkFrame::GetUdpPayloadForIp6(const Packet& data)
{
PacketData result(packet);
const Ip6Header* ip6 = reinterpret_cast<const Ip6Header*>(packet.mData);
Packet result(data);
const Ip6Header* ip6 = reinterpret_cast<const Ip6Header*>(result.mData);
/*if (ip6->mProtocol != IPPROTO_UDP && ip4->mProtocol != 0)
return PacketData(nullptr, 0);
*/
@@ -203,18 +226,13 @@ NetworkFrame::PacketData NetworkFrame::GetUdpPayloadForIp6(NetworkFrame::PacketD
result.mData += sizeof(UdpHeader);
result.mLength -= sizeof(UdpHeader);
/*
if (result.mLength != ntohs(udp->mDatagramLength))
return PacketData(nullptr, 0);
*/
InternetAddress addr_source;
addr_source.setIp(ip6->src_ip);
addr_source.setPort(ntohs(udp->mSourcePort));
source.setIp(ip6->src_ip);
source.setPort(ntohs(udp->mSourcePort));
//std::cout << source.toStdString() << " - ";
InternetAddress addr_dest;
addr_dest.setIp(ip6->dst_ip);
addr_dest.setPort(ntohs(udp->mDestinationPort));
destination.setIp(ip6->dst_ip);
destination.setPort(ntohs(udp->mDestinationPort));
//std::cout << destination.toStdString() << std::endl;
return result;
return {.data = result, .source = addr_source, .dest = addr_dest};
}

View File

@@ -7,25 +7,38 @@
class NetworkFrame
{
public:
struct PacketData
struct Packet
{
const uint8_t* mData;
size_t mLength;
PacketData(const uint8_t* data, size_t length)
Packet(const uint8_t* data, size_t length)
:mData(data), mLength(length)
{}
PacketData()
Packet()
:mData(nullptr), mLength(0)
{}
bool is_empty() const
{
return mData == nullptr || mLength == 0;
}
};
static PacketData GetUdpPayloadForEthernet(PacketData& packet, InternetAddress& source, InternetAddress& destination);
static PacketData GetUdpPayloadForIp4(PacketData& packet, InternetAddress& source, InternetAddress& destination);
static PacketData GetUdpPayloadForIp6(PacketData& packet, InternetAddress& source, InternetAddress& destination);
static PacketData GetUdpPayloadForSLL(PacketData& packet, InternetAddress& source, InternetAddress& destination);
static PacketData GetUdpPayloadForLoopback(PacketData& packet, InternetAddress& source, InternetAddress& destination);
struct Payload
{
Packet data;
InternetAddress source;
InternetAddress dest;
};
static Payload GetUdpPayloadForEthernet(const Packet& data);
static Payload GetUdpPayloadForIp4(const Packet& data);
static Payload GetUdpPayloadForIp6(const Packet& data);
static Payload GetUdpPayloadForSLL(const Packet& data);
static Payload GetUdpPayloadForLoopback(const Packet& data);
static Payload GetUdpPayloadForRaw(const Packet& data);
struct EthernetHeader
{

View File

@@ -80,6 +80,14 @@ unsigned RtpHelper::findSsrc(const void* buffer, size_t length)
return reinterpret_cast<const RtcpHeader*>(buffer)->ssrc;
}
void RtpHelper::setSsrc(void* buffer, size_t length, uint32_t ssrc)
{
if (isRtp(buffer, length))
reinterpret_cast<RtpHeader*>(buffer)->ssrc = ssrc;
else
reinterpret_cast<RtcpHeader*>(buffer)->ssrc = ssrc;
}
int RtpHelper::findPtype(const void* buffer, size_t length)
{
if (isRtp(buffer, length))

View File

@@ -36,13 +36,14 @@ struct RtpPair
class RtpHelper
{
public:
static bool isRtp(const void* buffer, size_t length);
static int findPtype(const void* buffer, size_t length);
static int findPacketNo(const void* buffer, size_t length);
static bool isRtpOrRtcp(const void* buffer, size_t length);
static bool isRtcp(const void* buffer, size_t length);
static bool isRtp(const void* buffer, size_t length);
static int findPtype(const void* buffer, size_t length);
static int findPacketNo(const void* buffer, size_t length);
static bool isRtpOrRtcp(const void* buffer, size_t length);
static bool isRtcp(const void* buffer, size_t length);
static unsigned findSsrc(const void* buffer, size_t length);
static int findPayloadLength(const void* buffer, size_t length);
static void setSsrc(void* buffer, size_t length, uint32_t ssrc);
static int findPayloadLength(const void* buffer, size_t length);
};
#if defined(USE_RTPDUMP)

View File

@@ -1,4 +1,4 @@
/* Copyright(C) 2007-2017 VoIPobjects (voipobjects.com)
/* Copyright(C) 2007-2023 VoIPobjects (voipobjects.com)
* 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
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
@@ -8,6 +8,7 @@
#include <iomanip>
#include <memory.h>
#include <algorithm>
#include <inttypes.h>
#ifdef TARGET_WIN
# include <WinSock2.h>
@@ -92,11 +93,7 @@ int StringHelper::toInt(const char *s, int defaultValue, bool* isOk)
uint64_t StringHelper::toUint64(const char* s, uint64_t def, bool *isOk)
{
uint64_t result = def;
#if defined(TARGET_WIN)
if (sscanf(s, "%I64d", &result) != 1)
#else
if (sscanf(s, "%llu", &result) != 1)
#endif
if (sscanf(s, "%" SCNu64, &result) != 1)
{
if (isOk)
*isOk = false;

View File

@@ -7,13 +7,6 @@ set (CMAKE_CXX_STANDARD_REQUIRED ON)
# Produce PIC code always
set (CMAKE_POSITION_INDEPENDENT_CODE ON)
# Set of variables to control references to codecs
set (USE_AMR_CODEC OFF CACHE BOOL "Use AMR codec. Requires libraries.")
set (USE_EVS_CODEC OFF CACHE BOOL "Use EVS codec." )
set (USE_OPUS_CODEC OFF CACHE BOOL "Use Opus codec." )
set (USE_PVQA_LIB OFF CACHE BOOL "Build with Sevana PVQA library" )
set (USE_AQUA_LIB OFF CACHE BOOL "Build with Sevana AQuA library" )
set (SOURCES
MT_Statistics.cpp
MT_WebRtc.cpp
@@ -47,19 +40,21 @@ set (SOURCES
)
if (USE_AMR_CODEC)
message("AMR NB and WB codecs will be included.")
message("Media: AMR NB and WB codecs will be included.")
add_definitions(-DUSE_AMR_CODEC)
set(SOURCES ${SOURCES} MT_AmrCodec.cpp MT_AmrCodec.h)
set (SOURCES ${SOURCES} MT_AmrCodec.cpp MT_AmrCodec.h)
set (LIBS_CODEC)
endif()
if (USE_EVS_CODEC)
message("EVS codec will be included.")
message("Media: EVS codec will be included.")
add_definitions (-DUSE_EVS_CODEC)
set (SOURCES ${SOURCES} MT_EvsCodec.cpp MT_EvsCodec.h)
set (LIBS_CODEC evs)
endif()
if (USE_OPUS_CODEC)
message("Opus codec will be included.")
message("Media: Opus codec will be included.")
add_definitions(-DUSE_OPUS_CODEC)
endif()
@@ -75,14 +70,19 @@ endif()
if (CMAKE_SYSTEM MATCHES "Windows*")
# Windows Specific flags - MSVC expected
add_definitions(-D_CRT_SECURE_NO_WARNINGS -DHAVE_WINSOCK2_H
-D_SILENCE_STDEXT_HASH_DEPRECATION_WARNINGS -DUNICODE -D_UNICODE )
add_definitions(
-D_CRT_SECURE_NO_WARNINGS
-DHAVE_WINSOCK2_H
-D_SILENCE_STDEXT_HASH_DEPRECATION_WARNINGS
-DUNICODE
-D_UNICODE )
endif()
add_library(media_lib ${SOURCES})
# Dependency on ice_stack - Linux build requires it
target_link_libraries(media_lib ice_stack)
# Codec libraries as well
target_link_libraries(media_lib ice_stack ${LIBS_CODEC})
set_property(TARGET media_lib PROPERTY
MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")