Skip to content

Commit

Permalink
Fix IP options (TTL and ToS) on IPv6 sockets (#423)
Browse files Browse the repository at this point in the history
* set IPv6_UNICAST_HOPS when setting SRTO_IPTTL on IPv6 socket
set IPV6_TCLASS when setting SRTO_TOS on IPv6 socket
  • Loading branch information
jeandube authored and rndi committed Jul 10, 2018
1 parent 2f894b4 commit 9de61aa
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 13 deletions.
6 changes: 4 additions & 2 deletions docs/API.md
Expand Up @@ -446,7 +446,8 @@ inside the library.
| --------------------- | ----- | ------- | --------- | ------ | ------------------ | ------ |
| `SRTO_IPTOS` | 1.0.5 | pre | `int32_t` | | (platform default) | 0..255 |

- IP Type of Service (see IP_TOS option for UDP). Applies to sender only.
- IPv4 Type of Service (see IP_TOS option for IP) or IPv6 Traffic Class (see IPV6_TCLASS
of IPv6) depending on socket address family. Applies to sender only.
- *Sender: user configurable, default: 0xB8*
---

Expand All @@ -465,7 +466,8 @@ regular development.*
| --------------------- | ----- | ------- | --------- | ------ | ------------------ | ------ |
| `SRTO_IPTTL` | 1.0.5 | pre | `int32_t` | hops | (platform default) | 1..255 |

- IP Time To Live (see IP_TTL option for UDP). Applies to sender only.
- IPv4 Time To Live (see IP_TTL option for IP) or IPv6 unicast hops (see IPV6_UNICAST_HOPS for
IPV6) depending on socket address family. Applies to sender only.
- *Sender: user configurable, default: 64*
---

Expand Down
55 changes: 44 additions & 11 deletions srtcore/channel.cpp
Expand Up @@ -100,8 +100,8 @@ m_iIPversion(AF_INET),
m_iSockAddrSize(sizeof(sockaddr_in)),
m_iSocket(),
#ifdef SRT_ENABLE_IPOPTS
m_iIpTTL(-1),
m_iIpToS(-1),
m_iIpTTL(-1), /* IPv4 TTL or IPv6 HOPs [1..255] (-1:undefined) */
m_iIpToS(-1), /* IPv4 Type of Service or IPv6 Traffic Class [0x00..0xff] (-1:undefined) */
#endif
m_iSndBufSize(65536),
m_iRcvBufSize(65536)
Expand Down Expand Up @@ -198,13 +198,32 @@ void CChannel::setUDPSockOpt()
#endif

#ifdef SRT_ENABLE_IPOPTS
if ((-1 != m_iIpTTL)
&& (0 != ::setsockopt(m_iSocket, IPPROTO_IP, IP_TTL, (const char*)&m_iIpTTL, sizeof(m_iIpTTL))))
throw CUDTException(MJ_SETUP, MN_NORES, NET_ERROR);

if ((-1 != m_iIpToS)
&& (0 != ::setsockopt(m_iSocket, IPPROTO_IP, IP_TOS, (const char*)&m_iIpToS, sizeof(m_iIpToS))))
throw CUDTException(MJ_SETUP, MN_NORES, NET_ERROR);
if (-1 != m_iIpTTL)
{
if(m_iIPversion == AF_INET)
{
if(0 != ::setsockopt(m_iSocket, IPPROTO_IP, IP_TTL, (const char*)&m_iIpTTL, sizeof(m_iIpTTL)))
throw CUDTException(MJ_SETUP, MN_NORES, NET_ERROR);
}
else //Assuming AF_INET6
{
if(0 != ::setsockopt(m_iSocket, IPPROTO_IPV6, IPV6_UNICAST_HOPS, (const char*)&m_iIpTTL, sizeof(m_iIpTTL)))
throw CUDTException(MJ_SETUP, MN_NORES, NET_ERROR);
}
}
if (-1 != m_iIpToS)
{
if(m_iIPversion == AF_INET)
{
if(0 != ::setsockopt(m_iSocket, IPPROTO_IP, IP_TOS, (const char*)&m_iIpToS, sizeof(m_iIpToS)))
throw CUDTException(MJ_SETUP, MN_NORES, NET_ERROR);
}
else //Assuming AF_INET6
{
if(0 != ::setsockopt(m_iSocket, IPPROTO_IPV6, IPV6_TCLASS, (const char*)&m_iIpToS, sizeof(m_iIpToS)))
throw CUDTException(MJ_SETUP, MN_NORES, NET_ERROR);
}
}
#endif

timeval tv;
Expand Down Expand Up @@ -271,14 +290,28 @@ void CChannel::setRcvBufSize(int size)
int CChannel::getIpTTL() const
{
socklen_t size = sizeof(m_iIpTTL);
::getsockopt(m_iSocket, IPPROTO_IP, IP_TTL, (char *)&m_iIpTTL, &size);
if (m_iIPversion == AF_INET)
{
::getsockopt(m_iSocket, IPPROTO_IP, IP_TTL, (char *)&m_iIpTTL, &size);
}
else
{
::getsockopt(m_iSocket, IPPROTO_IPV6, IPV6_UNICAST_HOPS, (char *)&m_iIpTTL, &size);
}
return m_iIpTTL;
}

int CChannel::getIpToS() const
{
socklen_t size = sizeof(m_iIpToS);
::getsockopt(m_iSocket, IPPROTO_IP, IP_TOS, (char *)&m_iIpToS, &size);
if(m_iIPversion == AF_INET)
{
::getsockopt(m_iSocket, IPPROTO_IP, IP_TOS, (char *)&m_iIpToS, &size);
}
else
{
::getsockopt(m_iSocket, IPPROTO_IPV6, IPV6_TCLASS, (char *)&m_iIpToS, &size);
}
return m_iIpToS;
}

Expand Down

0 comments on commit 9de61aa

Please sign in to comment.