Change in libosmocore[master]: socket.c: introduce osmo_sock_init3 & osmo_sock_init3_ofd

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/gerrit-log@lists.osmocom.org/.

lynxis lazus gerrit-no-reply at lists.osmocom.org
Sun Jul 5 09:27:36 UTC 2020


lynxis lazus has uploaded this change for review. ( https://gerrit.osmocom.org/c/libosmocore/+/19143 )


Change subject: socket.c: introduce osmo_sock_init3 & osmo_sock_init3_ofd
......................................................................

socket.c: introduce osmo_sock_init3 & osmo_sock_init3_ofd

osmo_sock_init3() takes osmo_sockaddr* as local and remote endpoints
to setup a socket.

Change-Id: I1eece543e3241ef0e095eb63bb831f7c15a16794
---
M include/osmocom/core/socket.h
M src/socket.c
2 files changed, 124 insertions(+), 0 deletions(-)



  git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/43/19143/1

diff --git a/include/osmocom/core/socket.h b/include/osmocom/core/socket.h
index bc60dfc..6bfcc4c 100644
--- a/include/osmocom/core/socket.h
+++ b/include/osmocom/core/socket.h
@@ -66,6 +66,15 @@
 			const char *local_host, uint16_t local_port,
 			const char *remote_host, uint16_t remote_port, unsigned int flags);
 
+int osmo_sock_init3(uint16_t type, uint8_t proto,
+		    const struct osmo_sockaddr *local,
+		    const struct osmo_sockaddr *remote,
+		    unsigned int flags);
+
+int osmo_sock_init3_ofd(struct osmo_fd *ofd, int type, int proto,
+			const struct osmo_sockaddr *local,
+			const struct osmo_sockaddr *remote, unsigned int flags);
+
 int osmo_sock_init_sa(struct sockaddr *ss, uint16_t type,
 		      uint8_t proto, unsigned int flags);
 
diff --git a/src/socket.c b/src/socket.c
index 359e24d..c7fd28b 100644
--- a/src/socket.c
+++ b/src/socket.c
@@ -34,6 +34,7 @@
 #include <osmocom/core/logging.h>
 #include <osmocom/core/select.h>
 #include <osmocom/core/socket.h>
+#include <osmocom/core/sockaddr_str.h>
 #include <osmocom/core/talloc.h>
 #include <osmocom/core/utils.h>
 
@@ -153,6 +154,28 @@
 	return sfd;
 }
 
+static int socket_helper_sa(const struct osmo_sockaddr *addr, uint16_t type, uint8_t proto, unsigned int flags)
+{
+	int sfd, on = 1;
+
+	sfd = socket(addr->u.sa.sa_family, type, proto);
+	if (sfd == -1) {
+		LOGP(DLGLOBAL, LOGL_ERROR,
+			"unable to create socket: %s\n", strerror(errno));
+		return sfd;
+	}
+	if (flags & OSMO_SOCK_F_NONBLOCK) {
+		if (ioctl(sfd, FIONBIO, (unsigned char *)&on) < 0) {
+			LOGP(DLGLOBAL, LOGL_ERROR,
+				"cannot set this socket unblocking: %s\n",
+				strerror(errno));
+			close(sfd);
+			sfd = -EINVAL;
+		}
+	}
+	return sfd;
+}
+
 #ifdef HAVE_LIBSCTP
 /* Fill buf with a string representation of the address set, in the form:
  * buf_len == 0: "()"
@@ -422,6 +445,91 @@
 	return sfd;
 }
 
+#define OSMO_SOCKADDR_TO_STR(sockaddr) \
+	struct osmo_sockaddr_str sastr; \
+	rc = osmo_sockaddr_str_from_sockaddr(&sastr, &sockaddr->u.sas); \
+	if (rc) \
+		strcpy(sastr.ip, "Invalid IP")
+
+int osmo_sock_init3(uint16_t type, uint8_t proto,
+		    const struct osmo_sockaddr *local,
+		    const struct osmo_sockaddr *remote,
+		    unsigned int flags)
+{
+	int sfd = -1, rc, on = 1;
+
+	if ((flags & (OSMO_SOCK_F_BIND | OSMO_SOCK_F_CONNECT)) == 0) {
+		LOGP(DLGLOBAL, LOGL_ERROR, "invalid: you have to specify either "
+			"BIND or CONNECT flags\n");
+		return -EINVAL;
+	}
+
+	/* figure out local side of socket */
+	if (flags & OSMO_SOCK_F_BIND) {
+		sfd = socket_helper_sa(local, type, proto, flags);
+		if (sfd < 0) {
+			OSMO_SOCKADDR_TO_STR(local);
+			LOGP(DLGLOBAL, LOGL_ERROR, "no suitable local addr found for: %s:%u\n",
+				sastr.ip, sastr.port);
+			return -ENODEV;
+		}
+
+		if (proto != IPPROTO_UDP || flags & OSMO_SOCK_F_UDP_REUSEADDR) {
+			rc = setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR,
+					&on, sizeof(on));
+			if (rc < 0) {
+				OSMO_SOCKADDR_TO_STR(local);
+				LOGP(DLGLOBAL, LOGL_ERROR,
+				     "cannot setsockopt socket:"
+				     " %s:%u: %s\n",
+				     sastr.ip, sastr.port,
+				     strerror(errno));
+				close(sfd);
+				return rc;
+			}
+		}
+
+		if (bind(sfd, &local->u.sa, sizeof(struct osmo_sockaddr)) == -1) {
+			OSMO_SOCKADDR_TO_STR(local);
+			LOGP(DLGLOBAL, LOGL_ERROR, "unable to bind socket: %s:%u: %s\n",
+			     sastr.ip, sastr.port, strerror(errno));
+			close(sfd);
+		}
+	}
+
+	/* Reached this point, if OSMO_SOCK_F_BIND then sfd is valid (>=0) or it
+	   was already closed and func returned. If OSMO_SOCK_F_BIND is not
+	   set, then sfd = -1 */
+
+	/* figure out remote side of socket */
+	if (flags & OSMO_SOCK_F_CONNECT) {
+		if (sfd < 0) {
+			sfd = socket_helper_sa(remote, type, proto, flags);
+			if (sfd < 0) {
+				return sfd;
+			}
+		}
+
+		rc = connect(sfd, &remote->u.sa, sizeof(struct osmo_sockaddr));
+		if (rc != 0 && errno != EINPROGRESS) {
+			OSMO_SOCKADDR_TO_STR(local);
+			LOGP(DLGLOBAL, LOGL_ERROR, "unable to connect socket: %s:%u: %s\n",
+			     sastr.ip, sastr.port, strerror(errno));
+			close(sfd);
+			return rc;
+		}
+	}
+
+
+	rc = osmo_sock_init_tail(sfd, type, flags);
+	if (rc < 0) {
+		close(sfd);
+		sfd = -1;
+	}
+
+	return sfd;
+}
+
 #ifdef HAVE_LIBSCTP
 
 
@@ -809,6 +917,13 @@
 					local_port, remote_host, remote_port, flags));
 }
 
+int osmo_sock_init3_ofd(struct osmo_fd *ofd, int type, int proto,
+			const struct osmo_sockaddr *local,
+			const struct osmo_sockaddr *remote, unsigned int flags)
+{
+	return osmo_fd_init_ofd(ofd, osmo_sock_init3(type, proto, local, remote, flags));
+}
+
 /*! Initialize a socket and fill \ref sockaddr
  *  \param[out] ss socket address (will be filled in)
  *  \param[in] type Socket type like SOCK_DGRAM, SOCK_STREAM

-- 
To view, visit https://gerrit.osmocom.org/c/libosmocore/+/19143
To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings

Gerrit-Project: libosmocore
Gerrit-Branch: master
Gerrit-Change-Id: I1eece543e3241ef0e095eb63bb831f7c15a16794
Gerrit-Change-Number: 19143
Gerrit-PatchSet: 1
Gerrit-Owner: lynxis lazus <lynxis at fe80.eu>
Gerrit-MessageType: newchange
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.osmocom.org/pipermail/gerrit-log/attachments/20200705/d306d9ae/attachment.htm>


More information about the gerrit-log mailing list