Change in libosmo-netif[master]: stream: Add support for AF_UNIX sockets

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/.

pespin gerrit-no-reply at lists.osmocom.org
Wed Dec 1 17:18:36 UTC 2021


pespin has uploaded this change for review. ( https://gerrit.osmocom.org/c/libosmo-netif/+/26434 )


Change subject: stream: Add support for AF_UNIX sockets
......................................................................

stream: Add support for AF_UNIX sockets

Change-Id: I5237a8121be05a9a31a39ca38a6a139062f258c4
---
M include/osmocom/netif/stream.h
M src/stream.c
2 files changed, 223 insertions(+), 72 deletions(-)



  git pull ssh://gerrit.osmocom.org:29418/libosmo-netif refs/changes/34/26434/1

diff --git a/include/osmocom/netif/stream.h b/include/osmocom/netif/stream.h
index 331dec1..b82dff1 100644
--- a/include/osmocom/netif/stream.h
+++ b/include/osmocom/netif/stream.h
@@ -25,6 +25,8 @@
 int osmo_stream_srv_link_set_addrs(struct osmo_stream_srv_link *link, const char **addr, size_t addrcnt);
 void osmo_stream_srv_link_set_port(struct osmo_stream_srv_link *link, uint16_t port);
 void osmo_stream_srv_link_set_proto(struct osmo_stream_srv_link *link, uint16_t proto);
+int osmo_stream_srv_link_set_type(struct osmo_stream_srv_link *link, int type);
+int osmo_stream_srv_link_set_domain(struct osmo_stream_srv_link *link, int domain);
 void osmo_stream_srv_link_set_accept_cb(struct osmo_stream_srv_link *link, int (*accept_cb)(struct osmo_stream_srv_link *link, int fd));
 void osmo_stream_srv_link_set_data(struct osmo_stream_srv_link *link, void *data);
 void *osmo_stream_srv_link_get_data(struct osmo_stream_srv_link *link);
@@ -57,6 +59,8 @@
 void osmo_stream_cli_set_addr(struct osmo_stream_cli *cli, const char *addr);
 int osmo_stream_cli_set_addrs(struct osmo_stream_cli *cli, const char **addr, size_t addrcnt);
 void osmo_stream_cli_set_port(struct osmo_stream_cli *cli, uint16_t port);
+int osmo_stream_cli_set_type(struct osmo_stream_cli *cli, int type);
+int osmo_stream_cli_set_domain(struct osmo_stream_cli *cli, int domain);
 void osmo_stream_cli_set_proto(struct osmo_stream_cli *cli, uint16_t proto);
 void osmo_stream_cli_set_local_addr(struct osmo_stream_cli *cli, const char *addr);
 int osmo_stream_cli_set_local_addrs(struct osmo_stream_cli *cli, const char **addr, size_t addrcnt);
diff --git a/src/stream.c b/src/stream.c
index 309aafe..1b3d0fb 100644
--- a/src/stream.c
+++ b/src/stream.c
@@ -256,6 +256,8 @@
 	char				*local_addr[OSMO_STREAM_MAX_ADDRS];
 	uint8_t			 	local_addrcnt;
 	uint16_t			local_port;
+	int				sk_domain;
+	int				sk_type;
 	uint16_t			proto;
 	int (*connect_cb)(struct osmo_stream_cli *srv);
 	int (*disconnect_cb)(struct osmo_stream_cli *srv);
@@ -349,20 +351,26 @@
 
 	LOGSCLI(cli, LOGL_DEBUG, "sending %u bytes of data\n", msgb_length(msg));
 
-	switch (cli->proto) {
-#ifdef HAVE_LIBSCTP
-	case IPPROTO_SCTP:
-		memset(&sinfo, 0, sizeof(sinfo));
-		sinfo.sinfo_ppid = htonl(msgb_sctp_ppid(msg));
-		sinfo.sinfo_stream = msgb_sctp_stream(msg);
-		ret = sctp_send(cli->ofd.fd, msg->data, msgb_length(msg),
-				&sinfo, MSG_NOSIGNAL);
+	switch (cli->sk_domain) {
+	case AF_UNIX:
+		ret = send(cli->ofd.fd, msg->data, msg->len, 0);
 		break;
-#endif
-	case IPPROTO_TCP:
 	default:
-		ret = send(cli->ofd.fd, msg->data, msgb_length(msg), 0);
-		break;
+		switch (cli->proto) {
+#ifdef HAVE_LIBSCTP
+		case IPPROTO_SCTP:
+			memset(&sinfo, 0, sizeof(sinfo));
+			sinfo.sinfo_ppid = htonl(msgb_sctp_ppid(msg));
+			sinfo.sinfo_stream = msgb_sctp_stream(msg);
+			ret = sctp_send(cli->ofd.fd, msg->data, msgb_length(msg),
+					&sinfo, MSG_NOSIGNAL);
+			break;
+#endif
+		case IPPROTO_TCP:
+		default:
+			ret = send(cli->ofd.fd, msg->data, msgb_length(msg), 0);
+			break;
+		}
 	}
 	if (ret < 0) {
 		if (errno == EPIPE || errno == ENOTCONN) {
@@ -395,15 +403,20 @@
 
 		LOGSCLI(cli, LOGL_DEBUG, "connection done.\n");
 		cli->state = STREAM_CLI_STATE_CONNECTED;
-		if (cli->proto == IPPROTO_SCTP) {
+		switch (cli->sk_domain) {
+		case AF_UNIX:
+			break;
+		default:
+			if (cli->proto == IPPROTO_SCTP) {
 #ifdef SO_NOSIGPIPE
-			int val = 1;
+				int val = 1;
 
-			ret = setsockopt(ofd->fd, SOL_SOCKET, SO_NOSIGPIPE, (void*)&val, sizeof(val));
-			if (ret < 0)
-				LOGSCLI(cli, LOGL_DEBUG, "Failed setting SO_NOSIGPIPE: %s\n", strerror(errno));
+				ret = setsockopt(ofd->fd, SOL_SOCKET, SO_NOSIGPIPE, (void*)&val, sizeof(val));
+				if (ret < 0)
+					LOGSCLI(cli, LOGL_DEBUG, "Failed setting SO_NOSIGPIPE: %s\n", strerror(errno));
 #endif
-			sctp_sock_activate_events(ofd->fd);
+				sctp_sock_activate_events(ofd->fd);
+			}
 		}
 		if (cli->connect_cb)
 			cli->connect_cb(cli);
@@ -441,6 +454,8 @@
 	if (!cli)
 		return NULL;
 
+	cli->sk_domain = AF_UNSPEC;
+	cli->sk_type = SOCK_STREAM;
 	cli->proto = IPPROTO_TCP;
 	cli->ofd.fd = -1;
 	cli->ofd.priv_nr = 0;	/* XXX */
@@ -557,6 +572,46 @@
 	cli->flags |= OSMO_STREAM_CLI_F_RECONF;
 }
 
+/*! \brief Set the socket type for the stream server link
+ *  \param[in] cli Stream Client to modify
+ *  \param[in] type Socket Type (like SOCK_STREAM (default), SOCK_SEQPACKET, ...)
+ *  \returns zero on success, negative on error.
+ */
+int osmo_stream_cli_set_type(struct osmo_stream_cli *cli, int type)
+{
+	switch (type) {
+	case SOCK_STREAM:
+	case SOCK_SEQPACKET:
+		break;
+	default:
+		return -ENOTSUP;
+	}
+	cli->sk_type = type;
+	cli->flags |= OSMO_STREAM_CLI_F_RECONF;
+	return 0;
+}
+
+/*! \brief Set the socket type for the stream server link
+ *  \param[in] cli Stream Client to modify
+ *  \param[in] type Socket Domain (like AF_UNSPEC (default for IP), AF_UNIX, AF_INET, ...)
+ *  \returns zero on success, negative on error.
+ */
+int osmo_stream_cli_set_domain(struct osmo_stream_cli *cli, int domain)
+{
+	switch (domain) {
+	case AF_UNSPEC:
+	case AF_INET:
+	case AF_INET6:
+	case AF_UNIX:
+		break;
+	default:
+		return -ENOTSUP;
+	}
+	cli->sk_domain = domain;
+	cli->flags |= OSMO_STREAM_CLI_F_RECONF;
+	return 0;
+}
+
 /*! \brief Set the reconnect time of the stream client socket
  *  \param[in] cli Stream Client to modify
  *  \param[in] timeout Re-connect timeout in seconds or negative value to disable auto-reconnection */
@@ -731,21 +786,29 @@
 
 	cli->flags &= ~OSMO_STREAM_CLI_F_RECONF;
 
-
-	switch (cli->proto) {
-#ifdef HAVE_LIBSCTP
-	case IPPROTO_SCTP:
-		ret = osmo_sock_init2_multiaddr(AF_UNSPEC, SOCK_STREAM, cli->proto,
-						(const char **)cli->local_addr, cli->local_addrcnt, cli->local_port,
-						(const char **)cli->addr, cli->addrcnt, cli->port,
-						OSMO_SOCK_F_CONNECT|OSMO_SOCK_F_BIND|OSMO_SOCK_F_NONBLOCK);
+	switch (cli->sk_domain) {
+	case AF_UNIX:
+		ret = osmo_sock_unix_init(cli->sk_type, 0, cli->addr[0], OSMO_SOCK_F_CONNECT|OSMO_SOCK_F_BIND|OSMO_SOCK_F_NONBLOCK);
 		break;
-#endif
+	case AF_INET:
+	case AF_INET6:
+	case AF_UNSPEC:
 	default:
-		ret = osmo_sock_init2(AF_UNSPEC, SOCK_STREAM, cli->proto,
-				      cli->local_addr[0], cli->local_port,
-				      cli->addr[0], cli->port,
-				      OSMO_SOCK_F_CONNECT|OSMO_SOCK_F_BIND|OSMO_SOCK_F_NONBLOCK);
+		switch (cli->proto) {
+#ifdef HAVE_LIBSCTP
+		case IPPROTO_SCTP:
+			ret = osmo_sock_init2_multiaddr(cli->sk_domain, cli->sk_type, cli->proto,
+							(const char **)cli->local_addr, cli->local_addrcnt, cli->local_port,
+							(const char **)cli->addr, cli->addrcnt, cli->port,
+							OSMO_SOCK_F_CONNECT|OSMO_SOCK_F_BIND|OSMO_SOCK_F_NONBLOCK);
+			break;
+#endif
+		default:
+			ret = osmo_sock_init2(cli->sk_domain, cli->sk_type, cli->proto,
+					      cli->local_addr[0], cli->local_port,
+					      cli->addr[0], cli->port,
+					      OSMO_SOCK_F_CONNECT|OSMO_SOCK_F_BIND|OSMO_SOCK_F_NONBLOCK);
+		}
 	}
 
 	if (ret < 0) {
@@ -827,6 +890,8 @@
 	char			*addr[OSMO_STREAM_MAX_ADDRS];
 	uint8_t			addrcnt;
 	uint16_t		port;
+	int			sk_domain;
+	int			sk_type;
 	uint16_t		proto;
 	int (*accept_cb)(struct osmo_stream_srv_link *srv, int fd);
 	void			*data;
@@ -838,7 +903,7 @@
 	int ret;
 	int sock_fd;
 	char addrstr[128];
-	bool is_ipv6;
+	bool is_ipv6 = false;
 	struct sockaddr_storage sa;
 	socklen_t sa_len = sizeof(sa);
 	struct osmo_stream_srv_link *link = ofd->data;
@@ -849,19 +914,35 @@
 			"peer, reason=`%s'\n", strerror(errno));
 		return ret;
 	}
-	is_ipv6 = ((struct sockaddr *)&sa)->sa_family == AF_INET6;
-	LOGP(DLINP, LOGL_DEBUG, "accept()ed new link from %s to port %u\n",
-		inet_ntop(is_ipv6 ? AF_INET6 : AF_INET,
-			  is_ipv6 ? (void*)&(((struct sockaddr_in6 *)&sa)->sin6_addr) :
-				    (void*)&(((struct sockaddr_in *)&sa)->sin_addr),
-			  addrstr, sizeof(addrstr)),
-		link->port);
 	sock_fd = ret;
 
-	if (link->proto == IPPROTO_SCTP) {
-		ret = sctp_sock_activate_events(sock_fd);
-		if (ret < 0)
-			goto error_close_socket;
+	is_ipv6 = false;
+	switch (((struct sockaddr *)&sa)->sa_family) {
+	case AF_UNIX:
+		LOGP(DLINP, LOGL_DEBUG, "accept()ed new link on fd %d\n",
+		     sock_fd);
+		break;
+	case AF_INET6:
+		is_ipv6 = true;
+		/* fall through */
+	case AF_INET:
+		LOGP(DLINP, LOGL_DEBUG, "accept()ed new link from %s to port %u\n",
+			inet_ntop(is_ipv6 ? AF_INET6 : AF_INET,
+				  is_ipv6 ? (void*)&(((struct sockaddr_in6 *)&sa)->sin6_addr) :
+					    (void*)&(((struct sockaddr_in *)&sa)->sin_addr),
+				  addrstr, sizeof(addrstr)),
+			link->port);
+
+		if (link->proto == IPPROTO_SCTP) {
+			ret = sctp_sock_activate_events(sock_fd);
+			if (ret < 0)
+				goto error_close_socket;
+		}
+		break;
+	default:
+		LOGP(DLINP, LOGL_DEBUG, "accept()ed unexpected address family %d\n",
+		     ((struct sockaddr *)&sa)->sa_family);
+		goto error_close_socket;
 	}
 
 	if (link->flags & OSMO_STREAM_SRV_F_NODELAY) {
@@ -899,6 +980,8 @@
 	if (!link)
 		return NULL;
 
+	link->sk_domain = AF_UNSPEC;
+	link->sk_type = SOCK_STREAM;
 	link->proto = IPPROTO_TCP;
 	osmo_fd_setup(&link->ofd, -1, OSMO_FD_READ | OSMO_FD_WRITE, osmo_stream_srv_fd_cb, link, 0);
 
@@ -978,6 +1061,47 @@
 	link->flags |= OSMO_STREAM_SRV_F_RECONF;
 }
 
+
+/*! \brief Set the socket type for the stream server link
+ *  \param[in] link Stream Server Link to modify
+ *  \param[in] type Socket Type (like SOCK_STREAM (default), SOCK_SEQPACKET, ...)
+ *  \returns zero on success, negative on error.
+ */
+int osmo_stream_srv_link_set_type(struct osmo_stream_srv_link *link, int type)
+{
+	switch (type) {
+	case SOCK_STREAM:
+	case SOCK_SEQPACKET:
+		break;
+	default:
+		return -ENOTSUP;
+	}
+	link->sk_type = type;
+	link->flags |= OSMO_STREAM_SRV_F_RECONF;
+	return 0;
+}
+
+/*! \brief Set the socket type for the stream server link
+ *  \param[in] link Stream Server Link to modify
+ *  \param[in] type Socket Domain (like AF_UNSPEC (default for IP), AF_UNIX, AF_INET, ...)
+ *  \returns zero on success, negative on error.
+ */
+int osmo_stream_srv_link_set_domain(struct osmo_stream_srv_link *link, int domain)
+{
+	switch (domain) {
+	case AF_UNSPEC:
+	case AF_INET:
+	case AF_INET6:
+	case AF_UNIX:
+		break;
+	default:
+		return -ENOTSUP;
+	}
+	link->sk_domain = domain;
+	link->flags |= OSMO_STREAM_SRV_F_RECONF;
+	return 0;
+}
+
 /*! \brief Set application private data of the stream server link
  *  \param[in] link Stream Server Link to modify
  *  \param[in] data User-specific data (available in call-back functions) */
@@ -1060,17 +1184,28 @@
 
 	link->flags &= ~OSMO_STREAM_SRV_F_RECONF;
 
-	switch (link->proto) {
+	switch (link->sk_domain) {
+		case AF_UNIX:
+			ret = osmo_sock_unix_init(link->sk_type, 0, link->addr[0], OSMO_SOCK_F_BIND);
+			break;
+		case AF_UNSPEC:
+		case AF_INET:
+		case AF_INET6:
+			switch (link->proto) {
 #ifdef HAVE_LIBSCTP
-	case IPPROTO_SCTP:
-		ret = osmo_sock_init2_multiaddr(AF_UNSPEC, SOCK_STREAM, link->proto,
-						(const char **)link->addr, link->addrcnt, link->port,
-						NULL, 0, 0, OSMO_SOCK_F_BIND);
-		break;
+			case IPPROTO_SCTP:
+				ret = osmo_sock_init2_multiaddr(link->sk_domain, link->sk_type, link->proto,
+								(const char **)link->addr, link->addrcnt, link->port,
+								NULL, 0, 0, OSMO_SOCK_F_BIND);
+				break;
 #endif
-	default:
-		ret = osmo_sock_init(AF_UNSPEC, SOCK_STREAM, link->proto,
-					link->addr[0], link->port, OSMO_SOCK_F_BIND);
+			default:
+				ret = osmo_sock_init(link->sk_domain, link->sk_type, link->proto,
+						     link->addr[0], link->port, OSMO_SOCK_F_BIND);
+			}
+			break;
+		default:
+			ret = -ENOTSUP;
 	}
 	if (ret < 0)
 		return ret;
@@ -1144,20 +1279,26 @@
 	llist_del(lh);
 	msg = llist_entry(lh, struct msgb, list);
 
-	switch (conn->srv->proto) {
-#ifdef HAVE_LIBSCTP
-	case IPPROTO_SCTP:
-		memset(&sinfo, 0, sizeof(sinfo));
-		sinfo.sinfo_ppid = htonl(msgb_sctp_ppid(msg));
-		sinfo.sinfo_stream = msgb_sctp_stream(msg);
-		ret = sctp_send(conn->ofd.fd, msg->data, msgb_length(msg),
-				&sinfo, MSG_NOSIGNAL);
-		break;
-#endif
-	case IPPROTO_TCP:
-	default:
+	switch (conn->srv->sk_domain) {
+	case AF_UNIX:
 		ret = send(conn->ofd.fd, msg->data, msg->len, 0);
 		break;
+	default:
+		switch (conn->srv->proto) {
+#ifdef HAVE_LIBSCTP
+		case IPPROTO_SCTP:
+			memset(&sinfo, 0, sizeof(sinfo));
+			sinfo.sinfo_ppid = htonl(msgb_sctp_ppid(msg));
+			sinfo.sinfo_stream = msgb_sctp_stream(msg);
+			ret = sctp_send(conn->ofd.fd, msg->data, msgb_length(msg),
+					&sinfo, MSG_NOSIGNAL);
+			break;
+#endif
+		case IPPROTO_TCP:
+		default:
+			ret = send(conn->ofd.fd, msg->data, msg->len, 0);
+			break;
+		}
 	}
 	if (ret < 0) {
 		LOGP(DLINP, LOGL_ERROR, "error to send\n");
@@ -1352,16 +1493,22 @@
 	if (!msg)
 		return -EINVAL;
 
-	switch (conn->srv->proto) {
-#ifdef HAVE_LIBSCTP
-	case IPPROTO_SCTP:
-		ret = _sctp_recvmsg_wrapper(conn->ofd.fd, msg);
-		break;
-#endif
-	case IPPROTO_TCP:
-	default:
+	switch (conn->srv->sk_domain) {
+	case AF_UNIX:
 		ret = recv(conn->ofd.fd, msgb_data(msg), msgb_tailroom(msg), 0);
 		break;
+	default:
+		switch (conn->srv->proto) {
+#ifdef HAVE_LIBSCTP
+		case IPPROTO_SCTP:
+			ret = _sctp_recvmsg_wrapper(conn->ofd.fd, msg);
+			break;
+#endif
+		case IPPROTO_TCP:
+		default:
+			ret = recv(conn->ofd.fd, msgb_data(msg), msgb_tailroom(msg), 0);
+			break;
+		}
 	}
 
 	if (ret < 0) {

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

Gerrit-Project: libosmo-netif
Gerrit-Branch: master
Gerrit-Change-Id: I5237a8121be05a9a31a39ca38a6a139062f258c4
Gerrit-Change-Number: 26434
Gerrit-PatchSet: 1
Gerrit-Owner: pespin <pespin at sysmocom.de>
Gerrit-Reviewer: Arran Cudbard-bell <a.cudbardb at freeradius.org>
Gerrit-Reviewer: daniel <dwillmann at sysmocom.de>
Gerrit-Reviewer: laforge <laforge at osmocom.org>
Gerrit-MessageType: newchange
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.osmocom.org/pipermail/gerrit-log/attachments/20211201/820746e1/attachment.htm>


More information about the gerrit-log mailing list