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