int s, dscp = 0, n;
#ifdef IP_RECVTOS
int on = 1;
-#endif
+#endif /* IP_RECVTOS */
memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_INET;
on = 1;
if (setsockopt(s, IPPROTO_IP, IP_RECVTOS, &on, sizeof(on)) == 0)
dscp_result |= ISC_NET_DSCPRECVV4;
-#endif
+#endif /* IP_RECVTOS */
+
#ifdef ISC_NET_BSD44MSGHDR
+
#ifndef ISC_CMSG_IP_TOS
#ifdef __APPLE__
#define ISC_CMSG_IP_TOS 0 /* As of 10.8.2. */
-#else
+#else /* ! __APPLE__ */
#define ISC_CMSG_IP_TOS 1
-#endif
-#endif
+#endif /* ! __APPLE__ */
+#endif /* ! ISC_CMSG_IP_TOS */
+
#if ISC_CMSG_IP_TOS
if (cmsgsend(s, IPPROTO_IP, IP_TOS, res0))
dscp_result |= ISC_NET_DSCPPKTV4;
-#endif
-#endif
+#endif /* ISC_CMSG_IP_TOS */
+
+#endif /* ISC_NET_BSD44MSGHDR */
+
freeaddrinfo(res0);
close(s);
-#endif
+
+#endif /* IP_TOS */
}
static void
int s, dscp = 0, n;
#if defined(IPV6_RECVTCLASS)
int on = 1;
-#endif
+#endif /* IPV6_RECVTCLASS */
memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_INET6;
on = 1;
if (setsockopt(s, IPPROTO_IPV6, IPV6_RECVTCLASS, &on, sizeof(on)) == 0)
dscp_result |= ISC_NET_DSCPRECVV6;
-#endif
+#endif /* IPV6_RECVTCLASS */
+
#ifdef ISC_NET_BSD44MSGHDR
if (cmsgsend(s, IPPROTO_IPV6, IPV6_TCLASS, res0))
dscp_result |= ISC_NET_DSCPPKTV6;
-#endif
+#endif /* ISC_NET_BSD44MSGHDR */
+
freeaddrinfo(res0);
close(s);
-#endif
-#endif
-#endif
+
+#endif /* IPV6_TCLASS */
+#endif /* WANT_IPV6 */
+#endif /* ISC_PLATFORM_HAVEIPV6 */
}
static void
connecting : 1, /* connect pending */
bound : 1, /* bound to local addr */
dupped : 1,
- active : 1; /* currently active */
+ active : 1, /* currently active */
+ pktdscp : 1; /* per packet dscp */
#ifdef ISC_NET_RECVOVERFLOW
unsigned char overflow; /* used for MSG_TRUNC fake */
isc_sockfdwatch_t fdwatchcb;
int fdwatchflags;
isc_task_t *fdwatchtask;
- int dscp;
+ unsigned int dscp;
};
#define SOCKET_MANAGER_MAGIC ISC_MAGIC('I', 'O', 'm', 'g')
memmove(CMSG_DATA(cmsgp), &use_min_mtu, sizeof(use_min_mtu));
#endif
}
- if (isc_dscp_check_value != -1) {
+
+ if (isc_dscp_check_value > -1) {
if (sock->type == isc_sockettype_udp)
INSIST((int)dev->dscp == isc_dscp_check_value);
- if (sock->type == isc_sockettype_tcp)
- INSIST(sock->dscp == isc_dscp_check_value);
+ else if (sock->type == isc_sockettype_tcp)
+ INSIST((int)sock->dscp == isc_dscp_check_value);
}
if ((sock->type == isc_sockettype_udp) &&
{
int dscp = (dev->dscp << 2) & 0xff;
+ INSIST(dev->dscp < 0x40 && dev->dscp >= 0);
+
#ifdef IP_TOS
- if (sock->pf == AF_INET &&
- ((isc_net_probedscp() & ISC_NET_DSCPPKTV4) != 0))
- {
+ if (sock->pf == AF_INET && sock->pktdscp) {
cmsgp = (struct cmsghdr *)(sock->sendcmsgbuf +
msg->msg_controllen);
msg->msg_control = (void *)sock->sendcmsgbuf;
cmsgp->cmsg_type = IP_TOS;
cmsgp->cmsg_len = cmsg_len(sizeof(char));
*(unsigned char*)CMSG_DATA(cmsgp) = dscp;
- } else if (sock->pf == AF_INET) {
+ } else if (sock->pf == AF_INET && sock->dscp != dev->dscp) {
if (setsockopt(sock->fd, IPPROTO_IP, IP_TOS,
(void *)&dscp, sizeof(int)) < 0)
{
ISC_MSG_FAILED,
"failed"),
strbuf);
- }
+ } else
+ sock->dscp = dscp;
}
#endif
#if defined(IPPROTO_IPV6) && defined(IPV6_TCLASS)
- if (sock->pf == AF_INET6 &&
- ((isc_net_probedscp() & ISC_NET_DSCPPKTV6) != 0))
- {
+ if (sock->pf == AF_INET6 && sock->pktdscp) {
cmsgp = (struct cmsghdr *)(sock->sendcmsgbuf +
msg->msg_controllen);
msg->msg_control = (void *)sock->sendcmsgbuf;
cmsgp->cmsg_type = IPV6_TCLASS;
cmsgp->cmsg_len = cmsg_len(sizeof(dscp));
memmove(CMSG_DATA(cmsgp), &dscp, sizeof(dscp));
- } else if (sock->pf == AF_INET6) {
+ } else if (sock->pf == AF_INET6 && sock->dscp != dev->dscp) {
if (setsockopt(sock->fd, IPPROTO_IPV6, IPV6_TCLASS,
(void *)&dscp, sizeof(int)) < 0) {
char strbuf[ISC_STRERRORSIZE];
ISC_MSG_FAILED,
"failed"),
strbuf);
- }
+ } else
+ sock->dscp = dscp;
}
#endif
}
sock->manager = manager;
sock->type = type;
sock->fd = -1;
- sock->dscp = -1;
+ sock->dscp = 0; /* TOS/TCLASS is zero until set. */
sock->dupped = 0;
sock->statsindex = NULL;
sock->connected = 0;
sock->connecting = 0;
sock->bound = 0;
+ sock->pktdscp = 0;
/*
* Initialize the lock.
case isc_sockettype_udp:
sock->statsindex =
(pf == AF_INET) ? udp4statsindex : udp6statsindex;
+#define DCSPPKT(pf) ((pf == AF_INET) ? ISC_NET_DSCPPKTV4 : ISC_NET_DSCPPKTV6)
+ sock->pktdscp = (isc_net_probedscp() & DCSPPKT(pf)) != 0;
break;
case isc_sockettype_tcp:
sock->statsindex =
/*
* Ensure DSCP settings are inherited across accept.
*/
- if (sock->dscp != -1)
- setdscp(NEWCONNSOCK(dev), sock->dscp);
+ setdscp(NEWCONNSOCK(dev), sock->dscp);
/*
* Save away the remote address
if (dscp < 0)
return;
+ /* The DSCP value must not be changed once it has been set. */
if (isc_dscp_check_value != -1)
INSIST(dscp == isc_dscp_check_value);
#endif