Add DSCP support for POSIX platforms.
This CL only includes the necessary changes in PhysicalSocketServer,
and doesn't include the Java or Objective C API.
Note that this is doing exactly the same thing as UDPSocketPosix
in chromium.
BUG=webrtc:5658
Change-Id: I295455eaccba2a83cdd1bc55848f325c310f8d32
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/168260
Reviewed-by: Harald Alvestrand <hta@webrtc.org>
Reviewed-by: Qingsi Wang <qingsi@webrtc.org>
Commit-Queue: Taylor <deadbeef@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#30478}
diff --git a/rtc_base/physical_socket_server.cc b/rtc_base/physical_socket_server.cc
index bd6a324..08947e1 100644
--- a/rtc_base/physical_socket_server.cc
+++ b/rtc_base/physical_socket_server.cc
@@ -140,6 +140,7 @@
Close();
s_ = ::socket(family, type, 0);
udp_ = (SOCK_DGRAM == type);
+ family_ = family;
UpdateLastError();
if (udp_) {
SetEnabledEvents(DE_READ | DE_WRITE);
@@ -289,10 +290,18 @@
return -1;
socklen_t optlen = sizeof(*value);
int ret = ::getsockopt(s_, slevel, sopt, (SockOptArg)value, &optlen);
- if (ret != -1 && opt == OPT_DONTFRAGMENT) {
+ if (ret == -1) {
+ return -1;
+ }
+ if (opt == OPT_DONTFRAGMENT) {
#if defined(WEBRTC_LINUX) && !defined(WEBRTC_ANDROID)
*value = (*value != IP_PMTUDISC_DONT) ? 1 : 0;
#endif
+ } else if (opt == OPT_DSCP) {
+#if defined(WEBRTC_POSIX)
+ // unshift DSCP value to get six most significant bits of IP DiffServ field
+ *value >>= 2;
+#endif
}
return ret;
}
@@ -306,7 +315,18 @@
#if defined(WEBRTC_LINUX) && !defined(WEBRTC_ANDROID)
value = (value) ? IP_PMTUDISC_DO : IP_PMTUDISC_DONT;
#endif
+ } else if (opt == OPT_DSCP) {
+#if defined(WEBRTC_POSIX)
+ // shift DSCP value to fit six most significant bits of IP DiffServ field
+ value <<= 2;
+#endif
}
+#if defined(WEBRTC_POSIX)
+ if (sopt == IPV6_TCLASS) {
+ // Set the IPv4 option in all cases to support dual-stack sockets.
+ ::setsockopt(s_, IPPROTO_IP, IP_TOS, (SockOptArg)&value, sizeof(value));
+ }
+#endif
return ::setsockopt(s_, slevel, sopt, (SockOptArg)&value, sizeof(value));
}
@@ -554,8 +574,19 @@
*sopt = TCP_NODELAY;
break;
case OPT_DSCP:
+#if defined(WEBRTC_POSIX)
+ if (family_ == AF_INET6) {
+ *slevel = IPPROTO_IPV6;
+ *sopt = IPV6_TCLASS;
+ } else {
+ *slevel = IPPROTO_IP;
+ *sopt = IP_TOS;
+ }
+ break;
+#else
RTC_LOG(LS_WARNING) << "Socket::OPT_DSCP not supported.";
return -1;
+#endif
case OPT_RTP_SENDTIME_EXTN_ID:
return -1; // No logging is necessary as this not a OS socket option.
default: