From patchwork Sat Mar 22 16:15:38 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Alvaro Neira X-Patchwork-Id: 332842 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from ganesha.gnumonks.org (ganesha.gnumonks.org [IPv6:2001:780:45:1d:225:90ff:fe52:c662]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 35C102C0082 for ; Sun, 23 Mar 2014 02:17:55 +1100 (EST) Received: from localhost ([127.0.0.1] helo=ganesha.gnumonks.org) by ganesha.gnumonks.org with esmtp (Exim 4.72) (envelope-from ) id 1WRNg6-0003AM-MY; Sat, 22 Mar 2014 16:17:42 +0100 Received: from mail.sysmocom.de ([144.76.43.93]) by ganesha.gnumonks.org with esmtp (Exim 4.72) (envelope-from ) id 1WRNeJ-0003AE-F4 for openbsc@lists.osmocom.org; Sat, 22 Mar 2014 16:15:53 +0100 Received: from localhost.localdomain (tmo-109-153.customers.d1-online.com [80.187.109.153]) by mail.sysmocom.de (Postfix) with ESMTPA id B080017BB7 for ; Sat, 22 Mar 2014 15:15:48 +0000 (UTC) From: Alvaro Neira Ayuso To: openbsc@lists.osmocom.org Subject: [libosmocore PATCH v2] src/socket: Adding domain socket support Date: Sat, 22 Mar 2014 17:15:38 +0100 Message-Id: <1395504938-23178-1-git-send-email-anayuso@sysmocom.de> X-Mailer: git-send-email 1.7.10.4 In-Reply-To: <20140227111627.14179.94135.stgit@Ph0enix> References: <20140227111627.14179.94135.stgit@Ph0enix> MIME-Version: 1.0 X-Spam-Score: 0.0 (/) X-BeenThere: openbsc@lists.osmocom.org X-Mailman-Version: 2.1.13 Precedence: list List-Id: Development of the OpenBSC GSM base station controller List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: openbsc-bounces@lists.osmocom.org Errors-To: openbsc-bounces@lists.osmocom.org From: Álvaro Neira Ayuso Added some function for adding domain socket support. Signed-off-by: Alvaro Neira Ayuso --- include/osmocom/core/socket.h | 6 +++ src/socket.c | 100 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 106 insertions(+) diff --git a/include/osmocom/core/socket.h b/include/osmocom/core/socket.h index f15a03a..cb1b7a8 100644 --- a/include/osmocom/core/socket.h +++ b/include/osmocom/core/socket.h @@ -30,6 +30,12 @@ int osmo_sock_init_sa(struct sockaddr *ss, uint16_t type, int osmo_sockaddr_is_local(struct sockaddr *addr, unsigned int addrlen); +int osmo_sock_unix_init(uint16_t type, uint8_t proto, + const char *socket_path, unsigned int flags); + +int osmo_sock_unix_init_ofd(struct osmo_fd *ofd, uint16_t type, uint8_t proto, + const char *socket_path, unsigned int flags); + /*! @} */ #endif /* _OSMOCORE_SOCKET_H */ diff --git a/src/socket.c b/src/socket.c index 6ff00f0..8e325ba 100644 --- a/src/socket.c +++ b/src/socket.c @@ -17,6 +17,7 @@ #include #include #include +#include #include @@ -257,6 +258,105 @@ int osmo_sockaddr_is_local(struct sockaddr *addr, unsigned int addrlen) return 0; } +/*! \brief Initialize a domain socket (including bind/connect) + * \param[in] type Socket type like SOCK_DGRAM, SOCK_STREAM + * \param[in] proto Protocol like IPPROTO_TCP, IPPROTO_UDP + * \param[in] socket_path path to identify the socket + * \param[in] flags flags like \ref OSMO_SOCK_F_CONNECT + * + * This function creates a new socket unix, \a + * type and \a proto and optionally binds or connects it, depending on + * the value of \a flags parameter. + */ +int osmo_sock_unix_init(uint16_t type, uint8_t proto, + const char *socket_path, unsigned int flags) +{ + struct sockaddr_un local; + int sfd, rc, on = 1; + unsigned int namelen; + + if ((flags & (OSMO_SOCK_F_BIND | OSMO_SOCK_F_CONNECT)) == + (OSMO_SOCK_F_BIND | OSMO_SOCK_F_CONNECT)) + return -EINVAL; + + local.sun_family = AF_UNIX; + strncpy(local.sun_path, socket_path, sizeof(local.sun_path)); + local.sun_path[sizeof(local.sun_path) - 1] = '\0'; + +#if defined(BSD44SOCKETS) || defined(__UNIXWARE__) + local.sun_len = strlen(local.sun_path); +#endif +#if defined(BSD44SOCKETS) || defined(SUN_LEN) + namelen = SUN_LEN(&local); +#else + namelen = strlen(local.sun_path) + + offsetof(struct sockaddr_un, sun_path); +#endif + + sfd = socket(AF_UNIX, type, proto); + if (sfd < 0) + return -1; + + if (flags & OSMO_SOCK_F_CONNECT) { + rc = connect(sfd, (struct sockaddr *)&local, namelen); + if (rc < 0) { + close(sfd); + return -1; + } + } else { + unlink(local.sun_path); + rc = bind(sfd, (struct sockaddr *)&local, namelen); + if (rc < 0) { + close(sfd); + return -1; + } + } + + if (flags & OSMO_SOCK_F_NONBLOCK) { + if (ioctl(sfd, FIONBIO, (unsigned char *)&on) < 0) { + perror("cannot set this socket unblocking"); + close(sfd); + return -EINVAL; + } + } + + if (flags & OSMO_SOCK_F_BIND) + listen(sfd, 10); + + return sfd; +} + +/*! \brief Initialize a domain socket and fill \ref osmo_fd + * \param[out] ofd file descriptor (will be filled in) + * \param[in] type Socket type like SOCK_DGRAM, SOCK_STREAM + * \param[in] proto Protocol like IPPROTO_TCP, IPPROTO_UDP + * \param[in] socket_path path to identify the socket + * \param[in] flags flags like \ref OSMO_SOCK_F_CONNECT + * + * This function creates (and optionall binds/connects) a socket using + * \ref osmo_sock_unix_init, but also fills the \a ofd structure. + */ +int osmo_sock_unix_init_ofd(struct osmo_fd *ofd, uint16_t type, uint8_t proto, + const char *socket_path, unsigned int flags) +{ + int sfd, rc; + + sfd = osmo_sock_unix_init(type, proto, socket_path, flags); + if (sfd < 0) + return sfd; + + ofd->fd = sfd; + ofd->when = BSC_FD_READ; + + rc = osmo_fd_register(ofd); + if (rc < 0) { + close(sfd); + return rc; + } + + return sfd; +} + #endif /* HAVE_SYS_SOCKET_H */ /*! @} */