Merge branch 'mainstream'
[sliver-openvswitch.git] / lib / socket-util.c
index eec2713..f7d2d0f 100644 (file)
@@ -108,14 +108,31 @@ int
 set_dscp(int fd, uint8_t dscp)
 {
     int val;
+    bool success;
 
     if (dscp > 63) {
         return EINVAL;
     }
 
+    /* Note: this function is used for both of IPv4 and IPv6 sockets */
+    success = false;
     val = dscp << 2;
     if (setsockopt(fd, IPPROTO_IP, IP_TOS, &val, sizeof val)) {
-        return sock_errno();
+        if (sock_errno() != ENOPROTOOPT) {
+            return sock_errno();
+        }
+    } else {
+        success = true;
+    }
+    if (setsockopt(fd, IPPROTO_IPV6, IPV6_TCLASS, &val, sizeof val)) {
+        if (sock_errno() != ENOPROTOOPT) {
+            return sock_errno();
+        }
+    } else {
+        success = true;
+    }
+    if (!success) {
+        return ENOPROTOOPT;
     }
 
     return 0;
@@ -250,6 +267,7 @@ check_connection_completion(int fd)
     }
 }
 
+#ifndef _WIN32
 /* Drain all the data currently in the receive queue of a datagram socket (and
  * possibly additional data).  There is no way to know how many packets are in
  * the receive queue, but we do know that the total number of bytes queued does
@@ -275,7 +293,8 @@ drain_rcvbuf(int fd)
          * On other Unix-like OSes, MSG_TRUNC has no effect in the flags
          * argument. */
         char buffer[LINUX_DATAPATH ? 1 : 2048];
-        ssize_t n_bytes = recv(fd, buffer, sizeof buffer, MSG_TRUNC);
+        ssize_t n_bytes = recv(fd, buffer, sizeof buffer,
+                               MSG_TRUNC | MSG_DONTWAIT);
         if (n_bytes <= 0 || n_bytes >= rcvbuf) {
             break;
         }
@@ -283,6 +302,7 @@ drain_rcvbuf(int fd)
     }
     return 0;
 }
+#endif
 
 /* Returns the size of socket 'sock''s receive buffer (SO_RCVBUF), or a
  * negative errno value if an error occurs. */
@@ -750,7 +770,7 @@ inet_open_active(int style, const char *target, uint16_t default_port,
      * connect(), the handshake SYN frames will be sent with a TOS of 0. */
     error = set_dscp(fd, dscp);
     if (error) {
-        VLOG_ERR("%s: socket: %s", target, sock_strerror(error));
+        VLOG_ERR("%s: set_dscp: %s", target, sock_strerror(error));
         goto exit;
     }
 
@@ -887,7 +907,7 @@ inet_open_passive(int style, const char *target, int default_port,
      * connect(), the handshake SYN frames will be sent with a TOS of 0. */
     error = set_dscp(fd, dscp);
     if (error) {
-        VLOG_ERR("%s: socket: %s", target, sock_strerror(error));
+        VLOG_ERR("%s: set_dscp: %s", target, sock_strerror(error));
         goto error;
     }
 
@@ -1027,6 +1047,7 @@ get_mtime(const char *file_name, struct timespec *mtime)
     }
 }
 
+#ifndef _WIN32
 void
 xpipe(int fds[2])
 {
@@ -1042,6 +1063,7 @@ xpipe_nonblocking(int fds[2])
     xset_nonblocking(fds[0]);
     xset_nonblocking(fds[1]);
 }
+#endif
 
 static int
 getsockopt_int(int fd, int level, int option, const char *optname, int *valuep)