Skip to content
Merged
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
32 changes: 21 additions & 11 deletions src/socket.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ void CSocket::Init ( const quint16 iNewPortNumber, const quint16 iNewQosNumber,
}
#endif

#if !defined( Q_OS_DARWIN ) && !defined( Q_OS_WIN )
#if !defined( Q_OS_BSD4 ) && !defined( Q_OS_WIN )
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we need a guidance note on where these are defined and how - specifically for Jamulus - they should be used. (Not part of this PR, obviously.)

// set the QoS for IPv4 as well, as this is a dual-protocol socket
if ( setsockopt ( UdpSocket, IPPROTO_IP, IP_TOS, (const char*) &tos, sizeof ( tos ) ) == -1 )
{
Expand Down Expand Up @@ -272,44 +272,54 @@ CSocket::~CSocket()
#endif
}

#if defined( Q_OS_DARWIN )
// sendto_ipv4_with_tos - helper function for macOS to set TOS when sending IPv4 over IPv6 socket
#if defined( Q_OS_BSD4 )
Comment thread
ann0see marked this conversation as resolved.
// sendto_ipv4_with_tos - helper function for macOS and FreeBSD to set TOS when sending IPv4 over IPv6 socket
static ssize_t sendto_ipv4_with_tos ( int fd, const void* buf, size_t len, int flags, const struct sockaddr* dest, socklen_t destlen, int tos )
{
// For a description of 'struct cmsghdr' and the 'CMSG_xxx' macros, see 'man 3 cmsg' on a Linux machine.
// The macOS man pages are less descriptive, but the API is the same, being based on the BSD socket interface.

# if defined( Q_OS_FREEBSD )
using tos_cmsg_type = unsigned char;
# else
using tos_cmsg_type = int;
# endif

// The cmsg buffer is only set up once (tos doesn't change) so can be static
static union
{
unsigned char cbuf[CMSG_SPACE ( sizeof ( int ) )];
unsigned char cbuf[CMSG_SPACE ( sizeof ( tos_cmsg_type ) )];
struct cmsghdr h;
} u;
static socklen_t clen = 0;

if ( clen == 0 )
{
// set up the cmsg buffer
memset ( u.cbuf, 0, sizeof ( u.cbuf ) );
memset ( &u, 0, sizeof ( u ) );
Comment thread
pljones marked this conversation as resolved.

u.h.cmsg_level = IPPROTO_IP;
u.h.cmsg_type = IP_TOS;
u.h.cmsg_len = CMSG_LEN ( sizeof ( int ) );
memcpy ( CMSG_DATA ( &u.h ), &tos, sizeof ( int ) );
clen = (socklen_t) u.h.cmsg_len;
u.h.cmsg_len = CMSG_LEN ( sizeof ( tos_cmsg_type ) );

tos_cmsg_type tosvalue = static_cast<tos_cmsg_type> ( tos & 0xFF );
memcpy ( CMSG_DATA ( &u.h ), &tosvalue, sizeof ( tosvalue ) );
clen = CMSG_SPACE ( sizeof ( tos_cmsg_type ) );
}

struct iovec iov;
memset ( &iov, 0, sizeof ( iov ) );
iov.iov_base = const_cast<void*> ( buf );
iov.iov_len = len;

struct msghdr msg;
memset ( &msg, 0, sizeof ( msg ) );

msg.msg_name = const_cast<sockaddr*> ( dest );
msg.msg_namelen = destlen;
msg.msg_iov = &iov;
msg.msg_iovlen = 1;
msg.msg_control = (void*) u.cbuf;
msg.msg_control = u.cbuf;
msg.msg_controllen = clen;

return sendmsg ( fd, &msg, flags );
Expand Down Expand Up @@ -355,8 +365,8 @@ void CSocket::SendPacket ( const CVector<uint8_t>& vecbySendBuf, const CHostAddr
addr[2] = htonl ( 0xFFFF );
addr[3] = htonl ( HostAddr.InetAddr.toIPv4Address() );

#if defined( Q_OS_DARWIN )
// In macOS we need to set TOS explicitly when sending IPv4 over IPv6 socket
#if defined( Q_OS_BSD4 )
// In macOS and FreeBSD we need to set TOS explicitly when sending IPv4 over IPv6 socket
status = sendto_ipv4_with_tos ( UdpSocket,
(const char*) &( (CVector<uint8_t>) vecbySendBuf )[0],
iVecSizeOut,
Expand Down
Loading