diff --git a/src/tcp/tcp.c b/src/tcp/tcp.c index 889713e51..75280e17e 100644 --- a/src/tcp/tcp.c +++ b/src/tcp/tcp.c @@ -1450,12 +1450,23 @@ int tcp_settos(struct tcp_sock *ts, uint32_t tos) { int err = 0; int v = tos; + struct sa sa; if (!ts) return EINVAL; ts->tos = tos; - err = tcp_sock_setopt(ts, IPPROTO_IP, IP_TOS, &v, sizeof(v)); + err = tcp_local_get(ts, &sa); + if (err) + return err; + + if (sa_af(&sa) == AF_INET) { + err = tcp_sock_setopt(ts, IPPROTO_IP, IP_TOS, &v, sizeof(v)); + } + else if (sa_af(&sa) == AF_INET6) { + err = tcp_sock_setopt(ts, IPPROTO_IPV6, IPV6_TCLASS, &v, + sizeof(v)); + } return err; } @@ -1465,16 +1476,29 @@ int tcp_conn_settos(struct tcp_conn *tc, uint32_t tos) { int err = 0; int v = tos; + struct sa sa; if (!tc) return EINVAL; tc->tos = tos; - if (tc->fdc != RE_BAD_SOCK) { + if (tc->fdc == RE_BAD_SOCK) + return err; + + err = tcp_conn_local_get(tc, &sa); + if (err) + return err; + + if (sa_af(&sa) == AF_INET) { if (0 != setsockopt(tc->fdc, IPPROTO_IP, IP_TOS, BUF_CAST &v, sizeof(v))) err = RE_ERRNO_SOCK; } + else if (sa_af(&sa) == AF_INET6) { + if (0 != setsockopt(tc->fdc, IPPROTO_IPV6, IPV6_TCLASS, + BUF_CAST &v, sizeof(v))) + err = RE_ERRNO_SOCK; + } return err; } diff --git a/src/udp/udp.c b/src/udp/udp.c index 7a7f9cb52..f4cca84b0 100644 --- a/src/udp/udp.c +++ b/src/udp/udp.c @@ -628,6 +628,7 @@ int udp_settos(struct udp_sock *us, uint8_t tos) { int err = 0; int v = tos; + struct sa sa; #ifdef WIN32 QOS_VERSION qos_version = { 1 , 0 }; QOS_TRAFFIC_TYPE qos_type = QOSTrafficTypeBestEffort; @@ -660,7 +661,18 @@ int udp_settos(struct udp_sock *us, uint8_t tos) return WSAGetLastError(); } #endif - err = udp_setsockopt(us, IPPROTO_IP, IP_TOS, &v, sizeof(v)); + err = udp_local_get(us, &sa); + if (err) + return err; + + if (sa_af(&sa) == AF_INET) { + err = udp_setsockopt(us, IPPROTO_IP, IP_TOS, &v, sizeof(v)); + } + else if (sa_af(&sa) == AF_INET6) { + err = udp_setsockopt(us, IPPROTO_IPV6, IPV6_TCLASS, &v, + sizeof(v)); + } + return err; }