From: Jennifer Richards Date: Wed, 11 Apr 2018 23:25:32 +0000 (-0400) Subject: Factor out identical tids_listen/trps_listen functions into shared copy X-Git-Tag: 3.4.0~1^2~49^2~10 X-Git-Url: http://www.project-moonshot.org/gitweb/?p=trust_router.git;a=commitdiff_plain;h=94592a29e9388e9fcf4871cb3f63bb1143d498ad Factor out identical tids_listen/trps_listen functions into shared copy --- diff --git a/Makefile.am b/Makefile.am index 845ce17..63a327a 100644 --- a/Makefile.am +++ b/Makefile.am @@ -20,7 +20,8 @@ common_srcs = common/tr_name.c \ common/tr_rp.c \ common/tr_idp.c \ common/tr_filter.c \ - common/tr_gss.c + common/tr_gss.c \ + common/tr_socket.c tid_srcs = tid/tid_resp.c \ tid/tid_req.c \ diff --git a/common/tr_socket.c b/common/tr_socket.c new file mode 100644 index 0000000..f05003a --- /dev/null +++ b/common/tr_socket.c @@ -0,0 +1,137 @@ +/* + * Copyright (c) 2016-2018, JANET(UK) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of JANET(UK) nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include +#include +#include +#include + +#include +#include + +/** + * Open sockets on all interface addresses + * + * Uses getaddrinfo() to find all TCP addresses and opens sockets in + * non-blocking modes. Binds to most max_fd sockets and stores file descriptors + * in fd_out. Unused entries in fd_out are not modified. Returns the actual + * number of sockets opened. + * + * @param port port to listen on + * @param fd_out output array, at least max_fd long + * @param max_fd maximum number of file descriptors to write + * @return number of file descriptors written into the output array + */ +ssize_t listen_on_all_addrs(unsigned int port, int *fd_out, size_t max_fd) +{ + int rc = 0; + int conn = -1; + int optval = 1; + int gai_retval = 0; + struct addrinfo *ai=NULL; + struct addrinfo *ai_head=NULL; + struct addrinfo hints={ + .ai_flags=AI_PASSIVE, + .ai_family=AF_UNSPEC, + .ai_socktype=SOCK_STREAM, + .ai_protocol=IPPROTO_TCP + }; + char *port_str=NULL; + size_t n_opened=0; + + port_str=talloc_asprintf(NULL, "%d", port); + if (port_str==NULL) { + tr_err("listen_on_all_addrs: unable to allocate port"); + return -1; + } + + gai_retval = getaddrinfo(NULL, port_str, &hints, &ai_head); + talloc_free(port_str); + if (gai_retval != 0) { + tr_err("listen_on_all_addrs: getaddrinfo() failed (%s)", gai_strerror(gai_retval)); + return -1; + } + tr_debug("listen_on_all_addrs: got address info"); + + /* TODO: listen on all ports - I don't recall what this means (jlr, 4/11/2018) */ + for (ai=ai_head,n_opened=0; (ai!=NULL)&&(n_openedai_next) { + if (0 > (conn = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol))) { + tr_debug("listen_on_all_addrs: unable to open socket"); + continue; + } + + optval=1; + if (0!=setsockopt(conn, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval))) + tr_debug("tids_listen: unable to set SO_REUSEADDR"); /* not fatal? */ + + if (ai->ai_family==AF_INET6) { + /* don't allow IPv4-mapped IPv6 addresses (per RFC4942, not sure + * if still relevant) */ + if (0!=setsockopt(conn, IPPROTO_IPV6, IPV6_V6ONLY, &optval, sizeof(optval))) { + tr_debug("listen_on_all_addrs: unable to set IPV6_V6ONLY, skipping interface"); + close(conn); + continue; + } + } + + rc=bind(conn, ai->ai_addr, ai->ai_addrlen); + if (rc<0) { + tr_debug("listen_on_all_addrs: unable to bind to socket"); + close(conn); + continue; + } + + if (0>listen(conn, 512)) { + tr_debug("listen_on_all_addrs: unable to listen on bound socket"); + close(conn); + continue; + } + + /* ok, this one worked. Save it */ + fd_out[n_opened++]=conn; + } + freeaddrinfo(ai_head); + + if (n_opened==0) { + tr_debug("listen_on_all_addrs: no addresses available for listening."); + return -1; + } + + tr_debug("listen_on_all_addrs: monitoring interface listening on port %d on %d socket%s", + port, + n_opened, + (n_opened==1)?"":"s"); + + return n_opened; +} diff --git a/include/tr_socket.h b/include/tr_socket.h new file mode 100644 index 0000000..33648c1 --- /dev/null +++ b/include/tr_socket.h @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2018, JANET(UK) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of JANET(UK) nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#ifndef TRUST_ROUTER_TR_SOCKET_H +#define TRUST_ROUTER_TR_SOCKET_H + +#include + +ssize_t listen_on_all_addrs(unsigned int port, int *fd_out, size_t max_fd); + +#endif //TRUST_ROUTER_TR_SOCKET_H diff --git a/tid/tids.c b/tid/tids.c index c1c9bcb..0cd5cf9 100644 --- a/tid/tids.c +++ b/tid/tids.c @@ -32,7 +32,6 @@ * */ -#include #include #include #include @@ -41,7 +40,7 @@ #include #include #include -#include +#include #include #include #include @@ -49,6 +48,7 @@ #include #include #include +#include static TID_RESP *tids_create_response (TIDS_INSTANCE *tids, TID_REQ *req) { @@ -84,83 +84,6 @@ cleanup: return resp; } -static int tids_listen(TIDS_INSTANCE *tids, int port, int *fd_out, size_t max_fd) -{ - int rc = 0; - int conn = -1; - int optval = 1; - struct addrinfo *ai=NULL; - struct addrinfo *ai_head=NULL; - struct addrinfo hints={.ai_flags=AI_PASSIVE, - .ai_family=AF_UNSPEC, - .ai_socktype=SOCK_STREAM, - .ai_protocol=IPPROTO_TCP}; - char *port_str=NULL; - size_t n_opened=0; - - tr_debug("tids_listen: started!"); - port_str=talloc_asprintf(NULL, "%d", port); - if (port_str==NULL) { - tr_debug("tids_listen: unable to allocate port."); - return -1; - } - - tr_debug("getaddrinfo()=%d", getaddrinfo(NULL, port_str, &hints, &ai_head)); - talloc_free(port_str); - tr_debug("tids_listen: got address info"); - - /* TODO: listen on all ports */ - for (ai=ai_head,n_opened=0; (ai!=NULL)&&(n_openedai_next) { - if (0 > (conn = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol))) { - tr_debug("tids_listen: unable to open socket."); - continue; - } - - optval=1; - if (0!=setsockopt(conn, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval))) - tr_debug("tids_listen: unable to set SO_REUSEADDR."); /* not fatal? */ - - if (ai->ai_family==AF_INET6) { - /* don't allow IPv4-mapped IPv6 addresses (per RFC4942, not sure - * if still relevant) */ - if (0!=setsockopt(conn, IPPROTO_IPV6, IPV6_V6ONLY, &optval, sizeof(optval))) { - tr_debug("tids_listen: unable to set IPV6_V6ONLY. Skipping interface."); - close(conn); - continue; - } - } - - rc=bind(conn, ai->ai_addr, ai->ai_addrlen); - if (rc<0) { - tr_debug("tids_listen: unable to bind to socket."); - close(conn); - continue; - } - - if (0>listen(conn, 512)) { - tr_debug("tids_listen: unable to listen on bound socket."); - close(conn); - continue; - } - - /* ok, this one worked. Save it */ - fd_out[n_opened++]=conn; - } - freeaddrinfo(ai_head); - - if (n_opened==0) { - tr_debug("tids_listen: no addresses available for listening."); - return -1; - } - - tr_debug("tids_listen: TRP Server listening on port %d on %d socket%s", - port, - n_opened, - (n_opened==1)?"":"s"); - - return n_opened; -} - /* returns EACCES if authorization is denied */ static int tids_auth_cb(gss_name_t clientName, gss_buffer_t displayName, void *data) @@ -430,7 +353,8 @@ int tids_get_listener(TIDS_INSTANCE *tids, size_t ii=0; tids->tids_port = port; - n_fd=tids_listen(tids, port, fd_out, max_fd); + n_fd=listen_on_all_addrs(port, fd_out, max_fd); + if (n_fd<=0) tr_err("tids_get_listener: Error opening port %d"); else { diff --git a/trp/trps.c b/trp/trps.c index ebc365d..a4ebe81 100644 --- a/trp/trps.c +++ b/trp/trps.c @@ -51,6 +51,7 @@ #include #include #include +#include static int trps_destructor(void *object) { @@ -276,82 +277,6 @@ TRP_RC trps_send_msg(TRPS_INSTANCE *trps, TRP_PEER *peer, const char *msg) return rc; } -/* Listens on all interfaces. Returns number of sockets opened. Their - * descriptors are stored in *fd_out, which should point to space for - * up to max_fd of them. */ -static size_t trps_listen(TRPS_INSTANCE *trps, int port, int *fd_out, size_t max_fd) -{ - int rc = 0; - int conn = -1; - int optval=0; - struct addrinfo *ai=NULL; - struct addrinfo *ai_head=NULL; - struct addrinfo hints={.ai_flags=AI_PASSIVE, - .ai_family=AF_UNSPEC, - .ai_socktype=SOCK_STREAM, - .ai_protocol=IPPROTO_TCP}; - char *port_str=NULL; - size_t n_opened=0; - - port_str=talloc_asprintf(NULL, "%d", port); - if (port_str==NULL) { - tr_debug("trps_listen: unable to allocate port."); - return -1; - } - getaddrinfo(NULL, port_str, &hints, &ai_head); - talloc_free(port_str); - - for (ai=ai_head,n_opened=0; (ai!=NULL)&&(n_openedai_next) { - if (0 > (conn = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol))) { - tr_debug("trps_listen: unable to open socket."); - continue; - } - - optval=1; - if (0!=setsockopt(conn, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval))) - tr_debug("trps_listen: unable to set SO_REUSEADDR."); /* not fatal? */ - - if (ai->ai_family==AF_INET6) { - /* don't allow IPv4-mapped IPv6 addresses (per RFC4942, not sure - * if still relevant) */ - if (0!=setsockopt(conn, IPPROTO_IPV6, IPV6_V6ONLY, &optval, sizeof(optval))) { - tr_debug("trps_listen: unable to set IPV6_V6ONLY. Skipping interface."); - close(conn); - continue; - } - } - - rc=bind(conn, ai->ai_addr, ai->ai_addrlen); - if (rc<0) { - tr_debug("trps_listen: unable to bind to socket."); - close(conn); - continue; - } - - if (0>listen(conn, 512)) { - tr_debug("trps_listen: unable to listen on bound socket."); - close(conn); - continue; - } - - /* ok, this one worked. Save it */ - fd_out[n_opened++]=conn; - } - freeaddrinfo(ai_head); - - if (n_opened==0) { - tr_debug("trps_listen: no addresses available for listening."); - return -1; - } - - tr_debug("trps_listen: TRP Server listening on port %d on %d socket%s", - port, - n_opened, - (n_opened==1)?"":"s"); - - return n_opened; -} - /* get the currently selected route if available */ TRP_ROUTE *trps_get_route(TRPS_INSTANCE *trps, TR_NAME *comm, TR_NAME *realm, TR_NAME *peer) { @@ -462,7 +387,8 @@ int trps_get_listener(TRPS_INSTANCE *trps, size_t n_fd=0; size_t ii=0; - n_fd=trps_listen(trps, port, fd_out, max_fd); + n_fd=listen_on_all_addrs(port, fd_out, max_fd); + if (n_fd==0) tr_err("trps_get_listener: Error opening port %d."); else {