[PATCH 1/3] libcommon: add make_sock_stream_connect()

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 at gnumonks.org pablo at gnumonks.org
Tue Apr 19 17:47:45 UTC 2011


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

This patch adds make_sock_stream_connect() which allows to perform
a non-blocking connect to some host and port.

This only support TCP by now, but it could be easily extensible
to support other stream-based layer 4 protocols.
---
 openbsc/include/openbsc/socket.h |    2 +
 openbsc/src/libcommon/socket.c   |   54 ++++++++++++++++++++++++++++++++++++++
 2 files changed, 56 insertions(+), 0 deletions(-)

diff --git a/openbsc/include/openbsc/socket.h b/openbsc/include/openbsc/socket.h
index 87ef37f..af5f729 100644
--- a/openbsc/include/openbsc/socket.h
+++ b/openbsc/include/openbsc/socket.h
@@ -11,4 +11,6 @@ int make_sock(struct bsc_fd *bfd, int proto,
 	      uint32_t ip, uint16_t port, int priv_nr,
 	      int (*cb)(struct bsc_fd *fd, unsigned int what), void *data);
 
+int make_sock_stream_connect(struct bsc_fd *bfd, int proto, struct in_addr addr, uint16_t port, int priv_nr, int (*cb)(struct bsc_fd *fd, unsigned int what), void *data);
+
 #endif /* _BSC_SOCKET_H */
diff --git a/openbsc/src/libcommon/socket.c b/openbsc/src/libcommon/socket.c
index dd25dd7..f4a533d 100644
--- a/openbsc/src/libcommon/socket.c
+++ b/openbsc/src/libcommon/socket.c
@@ -107,3 +107,57 @@ int make_sock(struct bsc_fd *bfd, int proto,
 	}
 	return 0;
 }
+
+/* this function performs a non-blocking stream connect. */
+int make_sock_stream_connect(struct bsc_fd *bfd, int proto,
+			     struct in_addr addr, uint16_t port, int priv_nr,
+			     int (*cb)(struct bsc_fd *fd, unsigned int what),
+			     void *data)
+{
+	int ret, flags, type;
+	struct sockaddr_in saddr;
+
+	switch (proto) {
+	case IPPROTO_TCP:
+		type = SOCK_STREAM;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	bfd->fd = socket(AF_INET, type, proto);
+	bfd->cb = cb;
+	/* non-blocking connect() confirms by setting BSC_FD_READ. */
+	bfd->when = BSC_FD_READ | BSC_FD_WRITE;
+	bfd->data = data;
+	bfd->priv_nr = priv_nr;
+
+	if (bfd->fd < 0) {
+		LOGP(DINP, LOGL_ERROR, "could not create socket.\n");
+		return -EIO;
+	}
+	flags = fcntl(bfd->fd, F_GETFL, 0);
+	if (fcntl(bfd->fd, F_SETFL, flags | O_NONBLOCK) < 0) {
+		LOGP(DINP, LOGL_ERROR, "could not fcntl.\n");
+		return -EIO;
+	}
+	memset(&saddr, 0, sizeof(addr));
+	saddr.sin_family = AF_INET;
+	saddr.sin_port = port;
+	memcpy(&saddr.sin_addr, &addr, sizeof(struct in_addr));
+
+	ret = connect(bfd->fd, (struct sockaddr *) &saddr, sizeof(saddr));
+	if (ret < 0 && errno != EINPROGRESS) {
+		LOGP(DINP, LOGL_ERROR, "could not connect socket %s\n",
+			strerror(errno));
+		close(bfd->fd);
+		return -EIO;
+	}
+	ret = bsc_register_fd(bfd);
+	if (ret < 0) {
+		perror("register_listen_fd");
+		close(bfd->fd);
+		return ret;
+	}
+	return 0;
+}
-- 
1.7.2.3





More information about the OpenBSC mailing list