Squashed 'third_party/rawrtc/re/' content from commit f3163ce8b

Change-Id: I6a235e6ac0f03269d951026f9d195da05c40fdab
git-subtree-dir: third_party/rawrtc/re
git-subtree-split: f3163ce8b526a13b35ef71ce4dd6f43585064d8a
diff --git a/src/net/sockopt.c b/src/net/sockopt.c
new file mode 100644
index 0000000..2385a69
--- /dev/null
+++ b/src/net/sockopt.c
@@ -0,0 +1,112 @@
+/**
+ * @file sockopt.c  Networking socket options
+ *
+ * Copyright (C) 2010 Creytiv.com
+ */
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#include <fcntl.h>
+#include <re_types.h>
+#include <re_fmt.h>
+#include <re_net.h>
+
+
+#define DEBUG_MODULE "sockopt"
+#define DEBUG_LEVEL 5
+#include <re_dbg.h>
+
+
+/** Platform independent buffer type cast */
+#ifdef WIN32
+#define BUF_CAST (char *)
+#else
+#define BUF_CAST
+#endif
+
+
+/**
+ * Set socket option blocking or non-blocking
+ *
+ * @param fd       Socket file descriptor
+ * @param blocking true for blocking, false for non-blocking
+ *
+ * @return 0 if success, otherwise errorcode
+ */
+int net_sockopt_blocking_set(int fd, bool blocking)
+{
+#ifdef WIN32
+	unsigned long noblock = !blocking;
+	int err = 0;
+
+	if (0 != ioctlsocket(fd, FIONBIO, &noblock)) {
+		err = WSAGetLastError();
+		DEBUG_WARNING("nonblock set: fd=%d err=%d (%m)\n",
+			      fd, err, err);
+	}
+	return err;
+#else
+	int flags;
+	int err = 0;
+
+	flags = fcntl(fd, F_GETFL);
+	if (-1 == flags) {
+		err = errno;
+		DEBUG_WARNING("sockopt set: fnctl F_GETFL: (%m)\n", err);
+		goto out;
+	}
+
+	if (blocking)
+		flags &= ~O_NONBLOCK;
+	else
+		flags |= O_NONBLOCK;
+
+	if (-1 == fcntl(fd, F_SETFL, flags)) {
+		err = errno;
+		DEBUG_WARNING("sockopt set: fcntl F_SETFL non-block (%m)\n",
+			      err);
+	}
+
+ out:
+	return err;
+#endif
+}
+
+
+/**
+ * Set socket option to reuse address and port
+ *
+ * @param fd     Socket file descriptor
+ * @param reuse  true for reuse, false for no reuse
+ *
+ * @return 0 if success, otherwise errorcode
+ */
+int net_sockopt_reuse_set(int fd, bool reuse)
+{
+	int r = reuse;
+
+#ifdef SO_REUSEADDR
+	if (-1 == setsockopt(fd, SOL_SOCKET, SO_REUSEADDR,
+			     BUF_CAST &r, sizeof(r))) {
+		DEBUG_WARNING("SO_REUSEADDR: %m\n", errno);
+		return errno;
+	}
+#endif
+
+#ifdef SO_REUSEPORT
+	if (-1 == setsockopt(fd, SOL_SOCKET, SO_REUSEPORT,
+			     BUF_CAST &r, sizeof(r))) {
+		DEBUG_INFO("SO_REUSEPORT: %m\n", errno);
+		return errno;
+	}
+#endif
+
+#if !defined(SO_REUSEADDR) && !defined(SO_REUSEPORT)
+	(void)r;
+	(void)fd;
+	(void)reuse;
+	return ENOSYS;
+#else
+	return 0;
+#endif
+}