socket-util: New function xset_nonblocking().
[openvswitch] / lib / socket-util.c
index 3b21256f7ea4ecf6221161389b4178e2818a572d..939cd90ff8a8eef55cb809a775c424dadad9d4ac 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, 2009, 2010, 2011, 2012 Nicira Networks.
+ * Copyright (c) 2008, 2009, 2010, 2011, 2012 Nicira, Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -17,6 +17,7 @@
 #include <config.h>
 #include "socket-util.h"
 #include <arpa/inet.h>
+#include <assert.h>
 #include <errno.h>
 #include <fcntl.h>
 #include <net/if.h>
@@ -81,6 +82,29 @@ set_nonblocking(int fd)
     }
 }
 
+void
+xset_nonblocking(int fd)
+{
+    if (set_nonblocking(fd)) {
+        exit(EXIT_FAILURE);
+    }
+}
+
+static int
+set_dscp(int fd, uint8_t dscp)
+{
+    if (dscp > 63) {
+        return EINVAL;
+    }
+
+    dscp = dscp << 2;
+    if (setsockopt(fd, IPPROTO_IP, IP_TOS, &dscp, sizeof dscp)) {
+        return errno;
+    }
+
+    return 0;
+}
+
 static bool
 rlim_is_finite(rlim_t limit)
 {
@@ -368,12 +392,11 @@ bind_unix_socket(int fd, struct sockaddr *sun, socklen_t sun_len)
 /* Creates a Unix domain socket in the given 'style' (either SOCK_DGRAM or
  * SOCK_STREAM) that is bound to '*bind_path' (if 'bind_path' is non-null) and
  * connected to '*connect_path' (if 'connect_path' is non-null).  If 'nonblock'
- * is true, the socket is made non-blocking.  If 'passcred' is true, the socket
- * is configured to receive SCM_CREDENTIALS control messages.
+ * is true, the socket is made non-blocking.
  *
  * Returns the socket's fd if successful, otherwise a negative errno value. */
 int
-make_unix_socket(int style, bool nonblock, bool passcred OVS_UNUSED,
+make_unix_socket(int style, bool nonblock,
                  const char *bind_path, const char *connect_path)
 {
     int error;
@@ -441,16 +464,6 @@ make_unix_socket(int style, bool nonblock, bool passcred OVS_UNUSED,
         }
     }
 
-#ifdef SCM_CREDENTIALS
-    if (passcred) {
-        int enable = 1;
-        if (setsockopt(fd, SOL_SOCKET, SO_PASSCRED, &enable, sizeof(enable))) {
-            error = errno;
-            goto error;
-        }
-    }
-#endif
-
     return fd;
 
 error:
@@ -546,7 +559,9 @@ exit:
  * If 'sinp' is non-null, then on success the target address is stored into
  * '*sinp'.
  *
- * 'dscp' becomes the DSCP bits in the IP headers for the new connection. */
+ * 'dscp' becomes the DSCP bits in the IP headers for the new connection.  It
+ * should be in the range [0, 63] and will automatically be shifted to the
+ * appropriately place in the IP tos field. */
 int
 inet_open_active(int style, const char *target, uint16_t default_port,
                  struct sockaddr_in *sinp, int *fdp, uint8_t dscp)
@@ -573,12 +588,12 @@ inet_open_active(int style, const char *target, uint16_t default_port,
         goto exit;
     }
 
-    /* The socket options set here ensure that the TOS bits are set during
-     * the connection establishment.  If set after connect(), the handshake
-     * SYN frames will be sent with a TOS of 0. */
-    if (setsockopt(fd, IPPROTO_IP, IP_TOS, &dscp, sizeof dscp)) {
-        VLOG_ERR("%s: socket: %s", target, strerror(errno));
-        error = errno;
+    /* The dscp bits must be configured before connect() to ensure that the TOS
+     * field is set during the connection establishment.  If set after
+     * 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, strerror(error));
         goto exit;
     }
 
@@ -669,7 +684,9 @@ exit:
  * If 'sinp' is non-null, then on success the bound address is stored into
  * '*sinp'.
  *
- * 'dscp' becomes the DSCP bits in the IP headers for the new connection. */
+ * 'dscp' becomes the DSCP bits in the IP headers for the new connection.  It
+ * should be in the range [0, 63] and will automatically be shifted to the
+ * appropriately place in the IP tos field. */
 int
 inet_open_passive(int style, const char *target, int default_port,
                   struct sockaddr_in *sinp, uint8_t dscp)
@@ -707,12 +724,12 @@ inet_open_passive(int style, const char *target, int default_port,
         goto error;
     }
 
-    /* The socket options set here ensure that the TOS bits are set during
-     * the connection establishment.  If set after connect(), the handshake
-     * SYN frames will be sent with a TOS of 0. */
-    if (setsockopt(fd, IPPROTO_IP, IP_TOS, &dscp, sizeof dscp)) {
-        VLOG_ERR("%s: socket: %s", target, strerror(errno));
-        error = errno;
+    /* The dscp bits must be configured before connect() to ensure that the TOS
+     * field is set during the connection establishment.  If set after
+     * 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, strerror(error));
         goto error;
     }