Merged revisions 292085 via svnmerge from
authorDavid Vossel <dvossel@digium.com>
Mon, 18 Oct 2010 16:03:24 +0000 (16:03 +0000)
committerDavid Vossel <dvossel@digium.com>
Mon, 18 Oct 2010 16:03:24 +0000 (16:03 +0000)
https://origsvn.digium.com/svn/asterisk/branches/1.8

........
  r292085 | dvossel | 2010-10-18 11:02:17 -0500 (Mon, 18 Oct 2010) | 7 lines

  Fixes qos settings for sockets bound to any IPv6 or IPv4 address.

  (closes issue #18099)
  Reported by: jamesnet
  Patches:
        issues_18099_v3.diff uploaded by dvossel (license 671
........

git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@292086 65c4cc65-6c06-0410-ace0-fbb531ad65f3

main/netsock2.c

index ed5964d..d4a0f98 100644 (file)
@@ -454,21 +454,34 @@ ssize_t ast_sendto(int sockfd, const void *buf, size_t len, int flags,
 int ast_set_qos(int sockfd, int tos, int cos, const char *desc)
 {
        int res;
-       int proto_type = IPPROTO_IP; /* ipv4 values by default */
-       int dscp_field = IP_TOS;
+       int set_tos;
+       int set_tclass;
        struct ast_sockaddr addr;
 
-       /* if this is IPv6 we need to set the TCLASS instead of TOS */
-       if (!ast_getsockname(sockfd, &addr) && ast_sockaddr_is_ipv6(&addr)) {
-               proto_type = IPPROTO_IPV6;
-               dscp_field = IPV6_TCLASS;
+       /* If the sock address is IPv6, the TCLASS field must be set. */
+       set_tclass = !ast_getsockname(sockfd, &addr) && ast_sockaddr_is_ipv6(&addr) ? 1 : 0;
+
+       /* If the the sock address is IPv4 or (IPv6 set to any address [::]) set TOS bits */
+       set_tos = (!set_tclass || (set_tclass && ast_sockaddr_is_any(&addr))) ? 1 : 0;
+
+       if (set_tos) {
+               if ((res = setsockopt(sockfd, IPPROTO_IP, IP_TOS, &tos, sizeof(tos)))) {
+                       ast_log(LOG_WARNING, "Unable to set %s DSCP TOS value to %d (may be you have no "
+                               "root privileges): %s\n", desc, tos, strerror(errno));
+               } else if (tos) {
+                       ast_verb(2, "Using %s TOS bits %d\n", desc, tos);
+               }
        }
 
-       if ((res = setsockopt(sockfd, proto_type, dscp_field, &tos, sizeof(tos)))) {
-               ast_log(LOG_WARNING, "Unable to set %s TOS to %d (may be you have no "
-                       "root privileges): %s\n", desc, tos, strerror(errno));
-       } else if (tos) {
-               ast_verb(2, "Using %s TOS bits %d\n", desc, tos);
+       if (set_tclass) {
+               if (!ast_getsockname(sockfd, &addr) && ast_sockaddr_is_ipv6(&addr)) {
+                       if ((res = setsockopt(sockfd, IPPROTO_IPV6, IPV6_TCLASS, &tos, sizeof(tos)))) {
+                               ast_log(LOG_WARNING, "Unable to set %s DSCP TCLASS field to %d (may be you have no "
+                                       "root privileges): %s\n", desc, tos, strerror(errno));
+                       } else if (tos) {
+                               ast_verb(2, "Using %s TOS bits %d in TCLASS field.\n", desc, tos);
+                       }
+               }
        }
 
 #ifdef linux