Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

[core] Carry over also the interface number with PKTINFO #2982

Draft
wants to merge 3 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 13 additions & 6 deletions srtcore/channel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -662,12 +662,19 @@ void srt::CChannel::getPeerAddr(sockaddr_any& w_addr) const
w_addr.len = namelen;
}

int srt::CChannel::sendto(const sockaddr_any& addr, CPacket& packet, const sockaddr_any& source_addr SRT_ATR_UNUSED) const
int srt::CChannel::sendto(const sockaddr_any& addr, CPacket& packet, const CNetworkInterface& source_ni SRT_ATR_UNUSED) const
{
#if ENABLE_HEAVY_LOGGING
ostringstream dsrc;
#ifdef SRT_ENABLE_PKTINFO
dsrc << " sourceIP=" << (m_bBindMasked && !source_addr.isany() ? source_addr.str() : "default");
if (m_bBindMasked && !source_ni.address.isany())
{
dsrc << " sourceNI=" << source_ni.str();
}
else
{
dsrc << " sourceNI=default";
}
#endif

LOGC(kslog.Debug,
Expand Down Expand Up @@ -750,15 +757,15 @@ int srt::CChannel::sendto(const sockaddr_any& addr, CPacket& packet, const socka
// Note that even if PKTINFO is desired, the first caller's packet will be sent
// without ancillary info anyway because there's no "peer" yet to know where to send it.
char mh_crtl_buf[sizeof(CMSGNodeIPv4) + sizeof(CMSGNodeIPv6)];
if (m_bBindMasked && source_addr.family() != AF_UNSPEC && !source_addr.isany())
if (m_bBindMasked && source_ni.address.family() != AF_UNSPEC && !source_ni.address.isany())
{
if (!setSourceAddress(mh, mh_crtl_buf, source_addr))
if (!setSourceAddress(mh, mh_crtl_buf, source_ni))
{
LOGC(kslog.Error, log << "CChannel::setSourceAddress: source address invalid family #" << source_addr.family() << ", NOT setting.");
LOGC(kslog.Error, log << "CChannel::setSourceAddress: source address invalid family #" << source_ni.address.family() << ", NOT setting.");
}
else
{
HLOGC(kslog.Debug, log << "CChannel::setSourceAddress: setting as " << source_addr.str());
HLOGC(kslog.Debug, log << "CChannel::setSourceAddress: setting as " << source_ni.str());
have_set_src = true;
}
}
Expand Down
26 changes: 13 additions & 13 deletions srtcore/channel.h
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ class CChannel
/// @param [in] src source address to sent on an outgoing packet (if not ANY)
/// @return Actual size of data sent.

int sendto(const sockaddr_any& addr, srt::CPacket& packet, const sockaddr_any& src) const;
int sendto(const sockaddr_any& addr, srt::CPacket& packet, const CNetworkInterface& src) const;

/// Receive a packet from the channel and record the source address.
/// @param [in] addr pointer to the source address.
Expand Down Expand Up @@ -205,7 +205,7 @@ class CChannel
cmsghdr hdr;
};

sockaddr_any getTargetAddress(const msghdr& msg) const
CNetworkInterface getTargetAddress(const msghdr& msg) const
{
// Loop through IP header messages
cmsghdr* cmsg;
Expand All @@ -219,33 +219,33 @@ class CChannel
{
in_pktinfo dest_ip;
memcpy(&dest_ip, CMSG_DATA(cmsg), sizeof(struct in_pktinfo));
return sockaddr_any(dest_ip.ipi_addr, 0);
return CNetworkInterface(dest_ip.ipi_addr, dest_ip.ipi_ifindex);
}

if (cmsg->cmsg_level == IPPROTO_IPV6 && cmsg->cmsg_type == IPV6_PKTINFO)
{
in6_pktinfo dest_ip;
memcpy(&dest_ip, CMSG_DATA(cmsg), sizeof(struct in6_pktinfo));
return sockaddr_any(dest_ip.ipi6_addr, 0);
return CNetworkInterface(dest_ip.ipi6_addr, dest_ip.ipi6_ifindex);
}
}

// Fallback for an error
return sockaddr_any(m_BindAddr.family());
return CNetworkInterface();
}

// IMPORTANT!!! This function shall be called EXCLUSIVELY just before
// calling ::sendmsg function. It uses a static buffer to supply data
// for the call, and it's stated that only one thread is trying to
// use a CChannel object in sending mode.
bool setSourceAddress(msghdr& mh, char *buf, const sockaddr_any& adr) const
bool setSourceAddress(msghdr& mh, char *buf, const CNetworkInterface& ni) const
{
// In contrast to an advice followed on the net, there's no case of putting
// both IPv4 and IPv6 ancillary data, case we could have them. Only one
// IP version is used and it's the version as found in @a adr, which should
// be the version used for binding.

if (adr.family() == AF_INET)
if (ni.address.family() == AF_INET)
{
mh.msg_control = (void *) buf;
mh.msg_controllen = CMSG_SPACE(sizeof(struct in_pktinfo));
Expand All @@ -254,16 +254,16 @@ class CChannel
cmsg_send->cmsg_level = IPPROTO_IP;
cmsg_send->cmsg_type = IP_PKTINFO;
cmsg_send->cmsg_len = CMSG_LEN(sizeof(struct in_pktinfo));

in_pktinfo pktinfo;
pktinfo.ipi_ifindex = 0;
pktinfo.ipi_spec_dst = adr.sin.sin_addr;
pktinfo.ipi_ifindex = ni.interface_index;
pktinfo.ipi_spec_dst = ni.address.sin.sin_addr;
memcpy(CMSG_DATA(cmsg_send), &pktinfo, sizeof(in_pktinfo));

return true;
}

if (adr.family() == AF_INET6)
if (ni.address.family() == AF_INET6)
{
mh.msg_control = buf;
mh.msg_controllen = CMSG_SPACE(sizeof(struct in6_pktinfo));
Expand All @@ -274,8 +274,8 @@ class CChannel
cmsg_send->cmsg_len = CMSG_LEN(sizeof(in6_pktinfo));

in6_pktinfo* pktinfo = (in6_pktinfo*) CMSG_DATA(cmsg_send);
pktinfo->ipi6_ifindex = 0;
pktinfo->ipi6_addr = adr.sin6.sin6_addr;
pktinfo->ipi6_ifindex = ni.interface_index;
pktinfo->ipi6_addr = ni.address.sin6.sin6_addr;

return true;
}
Expand Down
32 changes: 31 additions & 1 deletion srtcore/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ modified by
#define INC_SRT_COMMON_H

#include <memory>
#include <exception>
#include <cstdlib>
#include <cstdio>
#ifndef _WIN32
Expand Down Expand Up @@ -95,7 +96,36 @@ modified by
#define SRT_STATIC_ASSERT(cond, msg)
#endif

#include <exception>
namespace srt
{

struct CNetworkInterface
{
sockaddr_any address;
int interface_index;

template<class InAddrType>
CNetworkInterface(const InAddrType& sa, int index)
: address(sa, 0)
, interface_index(index)
{
}

CNetworkInterface() // blank fallback
: address(AF_UNSPEC)
, interface_index(0)
{
}

std::string str() const
{
std::ostringstream buf;
buf << address.str() << "/" << interface_index;
return buf.str();
}
};

}

namespace srt_logging
{
Expand Down
6 changes: 3 additions & 3 deletions srtcore/core.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3651,7 +3651,7 @@ void srt::CUDT::startConnect(const sockaddr_any& serv_addr, int32_t forced_isn)
EConnectStatus cst = CONN_CONTINUE;
// This is a temporary place to store the DESTINATION IP from the incoming packet.
// We can't record this address yet until the cookie-confirmation is done, for safety reasons.
sockaddr_any use_source_adr(serv_addr.family());
CNetworkInterface use_source_adr;

while (!m_bClosing)
{
Expand Down Expand Up @@ -9591,7 +9591,7 @@ bool srt::CUDT::isRetransmissionAllowed(const time_point& tnow SRT_ATR_UNUSED)
return true;
}

bool srt::CUDT::packData(CPacket& w_packet, steady_clock::time_point& w_nexttime, sockaddr_any& w_src_addr)
bool srt::CUDT::packData(CPacket& w_packet, steady_clock::time_point& w_nexttime, CNetworkInterface& w_src_addr)
{
int payload = 0;
bool probe = false;
Expand Down Expand Up @@ -11063,7 +11063,7 @@ int srt::CUDT::processConnectRequest(const sockaddr_any& addr, CPacket& packet)
// because this happens still in the frames of the listener socket. Only
// when processing switches to the newly spawned accepted socket can the
// address be recorded in its m_SourceAddr field.
sockaddr_any use_source_addr = packet.udpDestAddr();
CNetworkInterface use_source_addr = packet.udpDestAddr();

// REQUEST:INDUCTION.
// Set a cookie, a target ID, and send back the same as
Expand Down
4 changes: 2 additions & 2 deletions srtcore/core.h
Original file line number Diff line number Diff line change
Expand Up @@ -1124,7 +1124,7 @@ class CUDT
///
/// @retval true A packet was extracted for sending, the socket should be rechecked at @a nexttime
/// @retval false Nothing was extracted for sending, @a nexttime should be ignored
bool packData(CPacket& packet, time_point& nexttime, sockaddr_any& src_addr);
bool packData(CPacket& packet, time_point& nexttime, CNetworkInterface& src_addr);

int processData(CUnit* unit);

Expand Down Expand Up @@ -1220,7 +1220,7 @@ class CUDT
CSndQueue* m_pSndQueue; // packet sending queue
CRcvQueue* m_pRcvQueue; // packet receiving queue
sockaddr_any m_PeerAddr; // peer address
sockaddr_any m_SourceAddr; // override UDP source address with this one when sending
CNetworkInterface m_SourceAddr; // override UDP source address with this one when sending
uint32_t m_piSelfIP[4]; // local UDP IP address
CSNode* m_pSNode; // node information for UDT list used in snd queue
CRNode* m_pRNode; // node information for UDT list used in rcv queue
Expand Down
4 changes: 2 additions & 2 deletions srtcore/packet.h
Original file line number Diff line number Diff line change
Expand Up @@ -307,7 +307,7 @@ class CPacket
/// @return packet header field [2] (bit 0~31, bit 0-26 if SRT_DEBUG_TSBPD_WRAP).
uint32_t getMsgTimeStamp() const;

sockaddr_any udpDestAddr() const { return m_DestAddr; }
CNetworkInterface udpDestAddr() const { return m_DestAddr; }

#ifdef SRT_DEBUG_TSBPD_WRAP // Receiver
static const uint32_t MAX_TIMESTAMP = 0x07FFFFFF; // 27 bit fast wraparound for tests (~2m15s)
Expand Down Expand Up @@ -346,7 +346,7 @@ class CPacket

int32_t m_extra_pad;
bool m_data_owned;
sockaddr_any m_DestAddr;
CNetworkInterface m_DestAddr;
size_t m_zCapacity;

protected:
Expand Down
4 changes: 2 additions & 2 deletions srtcore/queue.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -579,7 +579,7 @@ void* srt::CSndQueue::worker(void* param)
// pack a packet from the socket
CPacket pkt;
steady_clock::time_point next_send_time;
sockaddr_any source_addr;
CNetworkInterface source_addr;
const bool res = u->packData((pkt), (next_send_time), (source_addr));

// Check if extracted anything to send
Expand All @@ -603,7 +603,7 @@ void* srt::CSndQueue::worker(void* param)
return NULL;
}

int srt::CSndQueue::sendto(const sockaddr_any& addr, CPacket& w_packet, const sockaddr_any& src)
int srt::CSndQueue::sendto(const sockaddr_any& addr, CPacket& w_packet, const CNetworkInterface& src)
{
// send out the packet immediately (high priority), this is a control packet
// NOTE: w_packet is passed by mutable reference because this function will do
Expand Down
6 changes: 5 additions & 1 deletion srtcore/queue.h
Original file line number Diff line number Diff line change
Expand Up @@ -420,7 +420,7 @@ class CSndQueue
/// @param [in,ref] packet packet to be sent out
/// @param [in] src The source IP address (details above)
/// @return Size of data sent out.
int sendto(const sockaddr_any& addr, CPacket& packet, const sockaddr_any& src);
int sendto(const sockaddr_any& addr, CPacket& packet, const CNetworkInterface& src);

/// Get the IP TTL.
/// @param [in] ttl IP Time To Live.
Expand Down Expand Up @@ -592,6 +592,10 @@ struct CMultiplexer
, m_pRcvQueue(NULL)
, m_pChannel(NULL)
, m_pTimer(NULL)
, m_iPort(0)
, m_iIPversion(AF_UNSPEC)
, m_iRefCount(1)
, m_iID(-1)
{
}

Expand Down
Loading