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>