diff --git a/src/udp/udp.c b/src/udp/udp.c index 8e2e53509..ea12efd15 100644 --- a/src/udp/udp.c +++ b/src/udp/udp.c @@ -31,7 +31,14 @@ #include #include #include - +#ifdef WIN32 +typedef UINT32 QOS_FLOWID, *PQOS_FLOWID; +#ifndef QOS_NON_ADAPTIVE_FLOW +#define QOS_NON_ADAPTIVE_FLOW 0x00000002 +#endif +#include +#include +#endif #define DEBUG_MODULE "udp" #define DEBUG_LEVEL 5 @@ -67,6 +74,11 @@ struct udp_sock { bool conn; /**< Connected socket flag */ size_t rxsz; /**< Maximum receive chunk size */ size_t rx_presz; /**< Preallocated rx buffer size */ +#ifdef WIN32 + HANDLE qos; /**< QOS subsystem handle */ + QOS_FLOWID qos_id; /**< QOS IPv4 flow id */ + QOS_FLOWID qos_id6; /**< QOS IPv6 flow id */ +#endif }; /** Defines a UDP helper */ @@ -115,6 +127,15 @@ static void udp_destructor(void *data) list_flush(&us->helpers); +#ifdef WIN32 + if (us->qos && us->qos_id) + (void)QOSRemoveSocketFromFlow(us->qos, 0, us->qos_id, 0); + if (us->qos && us->qos_id6) + (void)QOSRemoveSocketFromFlow(us->qos, 0, us->qos_id6, 0); + if (us->qos) + (void)QOSCloseHandle(us->qos); +#endif + if (-1 != us->fd) { fd_close(us->fd); (void)close(us->fd); @@ -643,10 +664,48 @@ int udp_settos(struct udp_sock *us, uint8_t tos) { int err = 0; int v = tos; - +#ifdef WIN32 + QOS_VERSION qos_version = { 1 , 0 }; + QOS_TRAFFIC_TYPE qos_type = QOSTrafficTypeBestEffort; + if (tos >= 32) /* >= DSCP_CS1 */ + qos_type = QOSTrafficTypeBackground; + if (tos >= 40) /* >= DSCP_AF11 */ + qos_type = QOSTrafficTypeExcellentEffort; + if (tos >= 136) /* >= DSCP_AF41 */ + qos_type = QOSTrafficTypeAudioVideo; + if (tos >= 184) /* >= DSCP_EF */ + qos_type = QOSTrafficTypeVoice; + if (tos >= 224) /* >= DSCP_CS7 */ + qos_type = QOSTrafficTypeControl; +#endif if (!us) return EINVAL; +#ifdef WIN32 + err = QOSCreateHandle(&qos_version, &us->qos); + if (!err) + return GetLastError(); + + us->qos_id = 0; + if (-1 != us->fd) { + err = QOSAddSocketToFlow(us->qos, us->fd, NULL, + qos_type, + QOS_NON_ADAPTIVE_FLOW, + &us->qos_id); + if (!err) + return WSAGetLastError(); + } + + us->qos_id6 = 0; + if (-1 != us->fd6) { + err = QOSAddSocketToFlow(us->qos, us->fd6, NULL, + qos_type, + QOS_NON_ADAPTIVE_FLOW, + &us->qos_id6); + if (!err) + return WSAGetLastError(); + } +#endif err = udp_setsockopt(us, IPPROTO_IP, IP_TOS, &v, sizeof(v)); return err; }