[libosmocore,v2] src/socket: Adding domain socket support
diff mbox

Message ID 1395504938-23178-1-git-send-email-anayuso@sysmocom.de
State Rejected
Headers show

Commit Message

Alvaro Neira March 22, 2014, 4:15 p.m. UTC
From: Álvaro Neira Ayuso <anayuso@sysmocom.de>

Added some function for adding domain socket support.

Signed-off-by: Alvaro Neira Ayuso <anayuso@sysmocom.de>
---
 include/osmocom/core/socket.h |    6 +++
 src/socket.c                  |  100 +++++++++++++++++++++++++++++++++++++++++
 2 files changed, 106 insertions(+)

Comments

Holger Freyther March 23, 2014, 10:03 p.m. UTC | #1
On Sat, Mar 22, 2014 at 05:15:38PM +0100, Alvaro Neira Ayuso wrote:
> +/*! \brief Initialize a domain socket (including bind/connect)

to follow unix(7) maybe call it UNIX domain socket

> + *  \param[in] type Socket type like SOCK_DGRAM, SOCK_STREAM
> + *  \param[in] proto Protocol like IPPROTO_TCP, IPPROTO_UDP

> + * This function creates a new socket unix, \a

				UNIX domain socket?

> +
> +	if (flags & OSMO_SOCK_F_NONBLOCK) {
> +		if (ioctl(sfd, FIONBIO, (unsigned char *)&on) < 0) {
> +			perror("cannot set this socket unblocking");
> +			close(sfd);
> +			return -EINVAL;
> +		}
> +	}
> +
> +	if (flags & OSMO_SOCK_F_BIND)
> +		listen(sfd, 10);

Do you want to check the return value of listen as well?

> +/*! \brief Initialize a domain socket and fill \ref osmo_fd

		UNIX domain socket


the actual code looks fine. Please fix the comments and send an
updated patch. I would be happy to merge it tomorrow.

Patch
diff mbox

diff --git a/include/osmocom/core/socket.h b/include/osmocom/core/socket.h
index f15a03a..cb1b7a8 100644
--- a/include/osmocom/core/socket.h
+++ b/include/osmocom/core/socket.h
@@ -30,6 +30,12 @@  int osmo_sock_init_sa(struct sockaddr *ss, uint16_t type,
 
 int osmo_sockaddr_is_local(struct sockaddr *addr, unsigned int addrlen);
 
+int osmo_sock_unix_init(uint16_t type, uint8_t proto,
+			const char *socket_path, unsigned int flags);
+
+int osmo_sock_unix_init_ofd(struct osmo_fd *ofd, uint16_t type, uint8_t proto,
+			    const char *socket_path, unsigned int flags);
+
 /*! @} */
 
 #endif /* _OSMOCORE_SOCKET_H */
diff --git a/src/socket.c b/src/socket.c
index 6ff00f0..8e325ba 100644
--- a/src/socket.c
+++ b/src/socket.c
@@ -17,6 +17,7 @@ 
 #include <sys/ioctl.h>
 #include <sys/socket.h>
 #include <sys/types.h>
+#include <sys/un.h>
 
 #include <netinet/in.h>
 
@@ -257,6 +258,105 @@  int osmo_sockaddr_is_local(struct sockaddr *addr, unsigned int addrlen)
 	return 0;
 }
 
+/*! \brief Initialize a domain socket (including bind/connect)
+ *  \param[in] type Socket type like SOCK_DGRAM, SOCK_STREAM
+ *  \param[in] proto Protocol like IPPROTO_TCP, IPPROTO_UDP
+ *  \param[in] socket_path path to identify the socket
+ *  \param[in] flags flags like \ref OSMO_SOCK_F_CONNECT
+ *
+ * This function creates a new socket unix, \a
+ * type and \a proto and optionally binds or connects it, depending on
+ * the value of \a flags parameter.
+ */
+int osmo_sock_unix_init(uint16_t type, uint8_t proto,
+			const char *socket_path, unsigned int flags)
+{
+	struct sockaddr_un local;
+	int sfd, rc, on = 1;
+	unsigned int namelen;
+
+	if ((flags & (OSMO_SOCK_F_BIND | OSMO_SOCK_F_CONNECT)) ==
+		     (OSMO_SOCK_F_BIND | OSMO_SOCK_F_CONNECT))
+		return -EINVAL;
+
+	local.sun_family = AF_UNIX;
+	strncpy(local.sun_path, socket_path, sizeof(local.sun_path));
+	local.sun_path[sizeof(local.sun_path) - 1] = '\0';
+
+#if defined(BSD44SOCKETS) || defined(__UNIXWARE__)
+	local.sun_len = strlen(local.sun_path);
+#endif
+#if defined(BSD44SOCKETS) || defined(SUN_LEN)
+	namelen = SUN_LEN(&local);
+#else
+	namelen = strlen(local.sun_path) +
+		  offsetof(struct sockaddr_un, sun_path);
+#endif
+
+	sfd = socket(AF_UNIX, type, proto);
+	if (sfd < 0)
+		return -1;
+
+	if (flags & OSMO_SOCK_F_CONNECT) {
+		rc = connect(sfd, (struct sockaddr *)&local, namelen);
+		if (rc < 0) {
+			close(sfd);
+			return -1;
+		}
+	} else {
+		unlink(local.sun_path);
+		rc = bind(sfd, (struct sockaddr *)&local, namelen);
+		if  (rc < 0) {
+			close(sfd);
+			return -1;
+		}
+	}
+
+	if (flags & OSMO_SOCK_F_NONBLOCK) {
+		if (ioctl(sfd, FIONBIO, (unsigned char *)&on) < 0) {
+			perror("cannot set this socket unblocking");
+			close(sfd);
+			return -EINVAL;
+		}
+	}
+
+	if (flags & OSMO_SOCK_F_BIND)
+		listen(sfd, 10);
+
+	return sfd;
+}
+
+/*! \brief Initialize a domain socket and fill \ref osmo_fd
+ *  \param[out] ofd file descriptor (will be filled in)
+ *  \param[in] type Socket type like SOCK_DGRAM, SOCK_STREAM
+ *  \param[in] proto Protocol like IPPROTO_TCP, IPPROTO_UDP
+ *  \param[in] socket_path path to identify the socket
+ *  \param[in] flags flags like \ref OSMO_SOCK_F_CONNECT
+ *
+ * This function creates (and optionall binds/connects) a socket using
+ * \ref osmo_sock_unix_init, but also fills the \a ofd structure.
+ */
+int osmo_sock_unix_init_ofd(struct osmo_fd *ofd, uint16_t type, uint8_t proto,
+			    const char *socket_path, unsigned int flags)
+{
+	int sfd, rc;
+
+	sfd = osmo_sock_unix_init(type, proto, socket_path, flags);
+	if (sfd < 0)
+		return sfd;
+
+	ofd->fd = sfd;
+	ofd->when = BSC_FD_READ;
+
+	rc = osmo_fd_register(ofd);
+	if (rc < 0) {
+		close(sfd);
+		return rc;
+	}
+
+	return sfd;
+}
+
 #endif /* HAVE_SYS_SOCKET_H */
 
 /*! @} */