[PATCH] socket: add OSMO_SOCK_F_[CONNECT|BIND|NON_BLOCK] flags

This is merely a historical archive of years 2008-2021, before the migration to mailman3.

A maintained and still updated list archive can be found at https://lists.osmocom.org/hyperkitty/list/OpenBSC@lists.osmocom.org/.

Pablo Neira Ayuso pablo at netfilter.org
Sun Jun 12 14:31:12 UTC 2011


From: Pablo Neira Ayuso <pablo at gnumonks.org>

This extends the socket infrastructure in libosmocore to allow
to create non-blocking sockets.

Basically, it replaces the connect0_bind1 parameter by one
flags parameter.
---
 include/osmocom/core/socket.h |   11 ++++++++---
 src/gsmtap_util.c             |    6 ++++--
 src/socket.c                  |   38 ++++++++++++++++++++++++++++----------
 3 files changed, 40 insertions(+), 15 deletions(-)

diff --git a/include/osmocom/core/socket.h b/include/osmocom/core/socket.h
index b2601c7..612b12c 100644
--- a/include/osmocom/core/socket.h
+++ b/include/osmocom/core/socket.h
@@ -5,14 +5,19 @@
 
 struct sockaddr;
 
+/* flags for osmo_sock_init. */
+#define OSMO_SOCK_F_CONNECT	(1 << 0)
+#define OSMO_SOCK_F_BIND	(1 << 1)
+#define OSMO_SOCK_F_NONBLOCK	(1 << 2)
+
 int osmo_sock_init(uint16_t family, uint16_t type, uint8_t proto,
-		   const char *host, uint16_t port, int connect0_bind1);
+		   const char *host, uint16_t port, unsigned int flags);
 
 int osmo_sock_init_ofd(struct osmo_fd *ofd, int family, int type, int proto,
-			const char *host, uint16_t port, int connect0_bind1);
+			const char *host, uint16_t port, unsigned int flags);
 
 int osmo_sock_init_sa(struct sockaddr *ss, uint16_t type,
-		      uint8_t proto, int connect0_bind1);
+		      uint8_t proto, unsigned int flags);
 
 /* determine if the given address is a local address */
 int osmo_sockaddr_is_local(struct sockaddr *addr, unsigned int addrlen);
diff --git a/src/gsmtap_util.c b/src/gsmtap_util.c
index eddde04..47fa37d 100644
--- a/src/gsmtap_util.c
+++ b/src/gsmtap_util.c
@@ -124,7 +124,8 @@ int gsmtap_source_init_fd(const char *host, uint16_t port)
 	if (host == NULL)
 		host = "localhost";
 
-	return osmo_sock_init(AF_UNSPEC, SOCK_DGRAM, IPPROTO_UDP, host, port, 0);
+	return osmo_sock_init(AF_UNSPEC, SOCK_DGRAM, IPPROTO_UDP, host, port,
+				OSMO_SOCK_F_CONNECT);
 }
 
 int gsmtap_source_add_sink_fd(int gsmtap_fd)
@@ -138,7 +139,8 @@ int gsmtap_source_add_sink_fd(int gsmtap_fd)
 		return rc;
 
 	if (osmo_sockaddr_is_local((struct sockaddr *)&ss, ss_len) == 1) {
-		rc = osmo_sock_init_sa((struct sockaddr *)&ss, SOCK_DGRAM, IPPROTO_UDP, 1);
+		rc = osmo_sock_init_sa((struct sockaddr *)&ss, SOCK_DGRAM,
+					IPPROTO_UDP, OSMO_SOCK_F_BIND);
 		if (rc >= 0)
 			return rc;
 	}
diff --git a/src/socket.c b/src/socket.c
index 0be98b9..f1fcccd 100644
--- a/src/socket.c
+++ b/src/socket.c
@@ -6,6 +6,7 @@
 #include <osmocom/core/select.h>
 #include <osmocom/core/socket.h>
 
+#include <sys/ioctl.h>
 #include <sys/socket.h>
 #include <sys/types.h>
 
@@ -18,12 +19,16 @@
 #include <ifaddrs.h>
 
 int osmo_sock_init(uint16_t family, uint16_t type, uint8_t proto,
-		   const char *host, uint16_t port, int connect0_bind1)
+		   const char *host, uint16_t port, unsigned int flags)
 {
 	struct addrinfo hints, *result, *rp;
 	int sfd, rc, on = 1;
 	char portbuf[16];
 
+	if ((flags & (OSMO_SOCK_F_BIND | OSMO_SOCK_F_CONNECT)) ==
+		     (OSMO_SOCK_F_BIND | OSMO_SOCK_F_CONNECT))
+		return -EINVAL;
+
 	sprintf(portbuf, "%u", port);
 	memset(&hints, 0, sizeof(struct addrinfo));
 	hints.ai_family = family;
@@ -31,7 +36,7 @@ int osmo_sock_init(uint16_t family, uint16_t type, uint8_t proto,
 	hints.ai_flags = 0;
 	hints.ai_protocol = proto;
 
-	if (connect0_bind1)
+	if (flags & OSMO_SOCK_F_BIND)
 		hints.ai_flags |= AI_PASSIVE;
 
 	rc = getaddrinfo(host, portbuf, &hints, &result);
@@ -44,10 +49,24 @@ int osmo_sock_init(uint16_t family, uint16_t type, uint8_t proto,
 		sfd = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol);
 		if (sfd == -1)
 			continue;
-		if (connect0_bind1 == 0) {
-			if (connect(sfd, rp->ai_addr, rp->ai_addrlen) != -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_CONNECT) {
+			rc = connect(sfd, rp->ai_addr, rp->ai_addrlen);
+			if (rc != -1 || (rc == -1 && errno == EINPROGRESS))
 				break;
 		} else {
+			rc = setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR,
+							&on, sizeof(on));
+			if (rc < 0) {
+				perror("cannot setsockopt socket");
+				break;
+			}
 			if (bind(sfd, rp->ai_addr, rp->ai_addrlen) != -1)
 				break;
 		}
@@ -63,7 +82,7 @@ int osmo_sock_init(uint16_t family, uint16_t type, uint8_t proto,
 	setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
 
 	/* Make sure to call 'listen' on a bound, connection-oriented sock */
-	if (connect0_bind1 == 1) {
+	if (flags & OSMO_SOCK_F_BIND) {
 		switch (type) {
 		case SOCK_STREAM:
 		case SOCK_SEQPACKET:
@@ -75,11 +94,11 @@ int osmo_sock_init(uint16_t family, uint16_t type, uint8_t proto,
 }
 
 int osmo_sock_init_ofd(struct osmo_fd *ofd, int family, int type, int proto,
-			const char *host, uint16_t port, int connect0_bind1)
+			const char *host, uint16_t port, unsigned int flags)
 {
 	int sfd, rc;
 
-	sfd = osmo_sock_init(family, type, proto, host, port, connect0_bind1);
+	sfd = osmo_sock_init(family, type, proto, host, port, flags);
 	if (sfd < 0)
 		return sfd;
 
@@ -96,7 +115,7 @@ int osmo_sock_init_ofd(struct osmo_fd *ofd, int family, int type, int proto,
 }
 
 int osmo_sock_init_sa(struct sockaddr *ss, uint16_t type,
-		      uint8_t proto, int connect0_bind1)
+		      uint8_t proto, unsigned int flags)
 {
 	char host[NI_MAXHOST];
 	uint16_t port;
@@ -127,8 +146,7 @@ int osmo_sock_init_sa(struct sockaddr *ss, uint16_t type,
 		return s;
 	}
 
-	return osmo_sock_init(ss->sa_family, type, proto, host,
-			      port, connect0_bind1);
+	return osmo_sock_init(ss->sa_family, type, proto, host, port, flags);
 }
 
 static int sockaddr_equal(const struct sockaddr *a,





More information about the OpenBSC mailing list