LCOV - code coverage report
Current view: top level - source3/lib - util_sock.c (source / functions) Hit Total Coverage
Test: coverage report for master 2f515e9b Lines: 246 535 46.0 %
Date: 2024-04-21 15:09:00 Functions: 16 27 59.3 %

          Line data    Source code
       1             : /*
       2             :    Unix SMB/CIFS implementation.
       3             :    Samba utility functions
       4             :    Copyright (C) Andrew Tridgell 1992-1998
       5             :    Copyright (C) Tim Potter      2000-2001
       6             :    Copyright (C) Jeremy Allison  1992-2007
       7             : 
       8             :    This program is free software; you can redistribute it and/or modify
       9             :    it under the terms of the GNU General Public License as published by
      10             :    the Free Software Foundation; either version 3 of the License, or
      11             :    (at your option) any later version.
      12             : 
      13             :    This program is distributed in the hope that it will be useful,
      14             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      15             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      16             :    GNU General Public License for more details.
      17             : 
      18             :    You should have received a copy of the GNU General Public License
      19             :    along with this program.  If not, see <http://www.gnu.org/licenses/>.
      20             : */
      21             : 
      22             : #include "includes.h"
      23             : #include "system/filesys.h"
      24             : #include "../lib/util/memcache.h"
      25             : #include "../lib/async_req/async_sock.h"
      26             : #include "../lib/util/select.h"
      27             : #include "lib/socket/interfaces.h"
      28             : #include "../lib/util/tevent_unix.h"
      29             : #include "../lib/util/tevent_ntstatus.h"
      30             : #include "../lib/tsocket/tsocket.h"
      31             : #include "lib/util/sys_rw.h"
      32             : #include "lib/util/sys_rw_data.h"
      33             : #include "source3/lib/util_tsock.h"
      34             : 
      35             : /****************************************************************************
      36             :  Determine if a file descriptor is in fact a socket.
      37             : ****************************************************************************/
      38             : 
      39          43 : bool is_a_socket(int fd)
      40             : {
      41           0 :         int v;
      42           0 :         socklen_t l;
      43          43 :         l = sizeof(int);
      44          43 :         return(getsockopt(fd, SOL_SOCKET, SO_TYPE, (char *)&v, &l) == 0);
      45             : }
      46             : 
      47             : /****************************************************************************
      48             :  Read data from a file descriptor with a timeout in msec.
      49             :  mincount = if timeout, minimum to read before returning
      50             :  maxcount = number to be read.
      51             :  time_out = timeout in milliseconds
      52             :  NB. This can be called with a non-socket fd, don't change
      53             :  sys_read() to sys_recv() or other socket call.
      54             : ****************************************************************************/
      55             : 
      56     1366120 : NTSTATUS read_fd_with_timeout(int fd, char *buf,
      57             :                                   size_t mincnt, size_t maxcnt,
      58             :                                   unsigned int time_out,
      59             :                                   size_t *size_ret)
      60             : {
      61       17253 :         int pollrtn;
      62       17253 :         ssize_t readret;
      63     1366120 :         size_t nread = 0;
      64             : 
      65             :         /* just checking .... */
      66     1366120 :         if (maxcnt <= 0)
      67           0 :                 return NT_STATUS_OK;
      68             : 
      69             :         /* Blocking read */
      70     1366120 :         if (time_out == 0) {
      71     1366120 :                 if (mincnt == 0) {
      72           0 :                         mincnt = maxcnt;
      73             :                 }
      74             : 
      75     2941277 :                 while (nread < mincnt) {
      76     1581013 :                         readret = sys_read(fd, buf + nread, maxcnt - nread);
      77             : 
      78     1581013 :                         if (readret == 0) {
      79        5846 :                                 DEBUG(5,("read_fd_with_timeout: "
      80             :                                         "blocking read. EOF from client.\n"));
      81        5846 :                                 return NT_STATUS_END_OF_FILE;
      82             :                         }
      83             : 
      84     1575167 :                         if (readret == -1) {
      85          10 :                                 return map_nt_error_from_unix(errno);
      86             :                         }
      87     1575157 :                         nread += readret;
      88             :                 }
      89     1360264 :                 goto done;
      90             :         }
      91             : 
      92             :         /* Most difficult - timeout read */
      93             :         /* If this is ever called on a disk file and
      94             :            mincnt is greater then the filesize then
      95             :            system performance will suffer severely as
      96             :            select always returns true on disk files */
      97             : 
      98           0 :         for (nread=0; nread < mincnt; ) {
      99           0 :                 int revents;
     100             : 
     101           0 :                 pollrtn = poll_intr_one_fd(fd, POLLIN|POLLHUP, time_out,
     102             :                                            &revents);
     103             : 
     104             :                 /* Check if error */
     105           0 :                 if (pollrtn == -1) {
     106           0 :                         return map_nt_error_from_unix(errno);
     107             :                 }
     108             : 
     109             :                 /* Did we timeout ? */
     110           0 :                 if ((pollrtn == 0) ||
     111           0 :                     ((revents & (POLLIN|POLLHUP|POLLERR)) == 0)) {
     112           0 :                         DEBUG(10,("read_fd_with_timeout: timeout read. "
     113             :                                 "select timed out.\n"));
     114           0 :                         return NT_STATUS_IO_TIMEOUT;
     115             :                 }
     116             : 
     117           0 :                 readret = sys_read(fd, buf+nread, maxcnt-nread);
     118             : 
     119           0 :                 if (readret == 0) {
     120             :                         /* we got EOF on the file descriptor */
     121           0 :                         DEBUG(5,("read_fd_with_timeout: timeout read. "
     122             :                                 "EOF from client.\n"));
     123           0 :                         return NT_STATUS_END_OF_FILE;
     124             :                 }
     125             : 
     126           0 :                 if (readret == -1) {
     127           0 :                         return map_nt_error_from_unix(errno);
     128             :                 }
     129             : 
     130           0 :                 nread += readret;
     131             :         }
     132             : 
     133           0 :  done:
     134             :         /* Return the number we got */
     135     1360264 :         if (size_ret) {
     136           0 :                 *size_ret = nread;
     137             :         }
     138     1360264 :         return NT_STATUS_OK;
     139             : }
     140             : 
     141             : /****************************************************************************
     142             :  Read data from an fd, reading exactly N bytes.
     143             :  NB. This can be called with a non-socket fd, don't add dependencies
     144             :  on socket calls.
     145             : ****************************************************************************/
     146             : 
     147           0 : NTSTATUS read_data_ntstatus(int fd, char *buffer, size_t N)
     148             : {
     149           0 :         return read_fd_with_timeout(fd, buffer, N, N, 0, NULL);
     150             : }
     151             : 
     152             : /****************************************************************************
     153             :  Read 4 bytes of a smb packet and return the smb length of the packet.
     154             :  Store the result in the buffer.
     155             :  This version of the function will return a length of zero on receiving
     156             :  a keepalive packet.
     157             :  Timeout is in milliseconds.
     158             : ****************************************************************************/
     159             : 
     160      685988 : NTSTATUS read_smb_length_return_keepalive(int fd, char *inbuf,
     161             :                                           unsigned int timeout,
     162             :                                           size_t *len)
     163             : {
     164        8693 :         int msg_type;
     165        8693 :         NTSTATUS status;
     166             : 
     167      685988 :         status = read_fd_with_timeout(fd, inbuf, 4, 4, timeout, NULL);
     168             : 
     169      685988 :         if (!NT_STATUS_IS_OK(status)) {
     170        5856 :                 return status;
     171             :         }
     172             : 
     173      680132 :         *len = smb_len(inbuf);
     174      680132 :         msg_type = CVAL(inbuf,0);
     175             : 
     176      680132 :         if (msg_type == NBSSkeepalive) {
     177           0 :                 DEBUG(5,("Got keepalive packet\n"));
     178             :         }
     179             : 
     180      680132 :         DEBUG(10,("got smb length of %lu\n",(unsigned long)(*len)));
     181             : 
     182      680132 :         return NT_STATUS_OK;
     183             : }
     184             : 
     185             : /****************************************************************************
     186             :  Read an smb from a fd.
     187             :  The timeout is in milliseconds.
     188             :  This function will return on receipt of a session keepalive packet.
     189             :  maxlen is the max number of bytes to return, not including the 4 byte
     190             :  length. If zero it means buflen limit.
     191             :  Doesn't check the MAC on signed packets.
     192             : ****************************************************************************/
     193             : 
     194           0 : NTSTATUS receive_smb_raw(int fd, char *buffer, size_t buflen, unsigned int timeout,
     195             :                          size_t maxlen, size_t *p_len)
     196             : {
     197           0 :         size_t len;
     198           0 :         NTSTATUS status;
     199             : 
     200           0 :         status = read_smb_length_return_keepalive(fd,buffer,timeout,&len);
     201             : 
     202           0 :         if (!NT_STATUS_IS_OK(status)) {
     203           0 :                 DEBUG(0, ("read_fd_with_timeout failed, read "
     204             :                           "error = %s.\n", nt_errstr(status)));
     205           0 :                 return status;
     206             :         }
     207             : 
     208           0 :         if (len > buflen) {
     209           0 :                 DEBUG(0,("Invalid packet length! (%lu bytes).\n",
     210             :                                         (unsigned long)len));
     211           0 :                 return NT_STATUS_INVALID_PARAMETER;
     212             :         }
     213             : 
     214           0 :         if(len > 0) {
     215           0 :                 if (maxlen) {
     216           0 :                         len = MIN(len,maxlen);
     217             :                 }
     218             : 
     219           0 :                 status = read_fd_with_timeout(
     220             :                         fd, buffer+4, len, len, timeout, &len);
     221             : 
     222           0 :                 if (!NT_STATUS_IS_OK(status)) {
     223           0 :                         DEBUG(0, ("read_fd_with_timeout failed, read error = "
     224             :                                   "%s.\n", nt_errstr(status)));
     225           0 :                         return status;
     226             :                 }
     227             : 
     228             :                 /* not all of samba3 properly checks for packet-termination
     229             :                  * of strings. This ensures that we don't run off into
     230             :                  * empty space. */
     231           0 :                 SSVAL(buffer+4,len, 0);
     232             :         }
     233             : 
     234           0 :         *p_len = len;
     235           0 :         return NT_STATUS_OK;
     236             : }
     237             : 
     238             : /*
     239             :  * Open a socket of the specified type, port, and address for incoming data.
     240             :  *
     241             :  * Return sock or -errno
     242             :  */
     243             : 
     244         751 : int open_socket_in(
     245             :         int type,
     246             :         const struct sockaddr_storage *paddr,
     247             :         uint16_t port,
     248             :         bool rebind)
     249             : {
     250         751 :         struct samba_sockaddr addr = {
     251             :                 .sa_socklen = sizeof(struct sockaddr_storage),
     252             :                 .u.ss = *paddr,
     253             :         };
     254         751 :         int ret, sock = -1;
     255         751 :         int val = rebind ? 1 : 0;
     256           0 :         bool ok;
     257             : 
     258         751 :         switch (addr.u.sa.sa_family) {
     259          80 :         case AF_INET6:
     260          80 :                 addr.sa_socklen = sizeof(struct sockaddr_in6);
     261          80 :                 break;
     262         671 :         case AF_INET:
     263         671 :                 addr.sa_socklen = sizeof(struct sockaddr_in);
     264         671 :                 break;
     265             :         }
     266             : 
     267         751 :         ok = samba_sockaddr_set_port(&addr, port);
     268         751 :         if (!ok) {
     269           0 :                 ret = -EINVAL;
     270           0 :                 DBG_DEBUG("samba_sockaddr_set_port failed\n");
     271           0 :                 goto fail;
     272             :         }
     273             : 
     274         751 :         sock = socket(addr.u.ss.ss_family, type, 0 );
     275         751 :         if (sock == -1) {
     276           0 :                 ret = -errno;
     277           0 :                 DBG_DEBUG("socket() failed: %s\n", strerror(errno));
     278           0 :                 goto fail;
     279             :         }
     280             : 
     281         751 :         ret = setsockopt(
     282             :                 sock, SOL_SOCKET, SO_REUSEADDR, (char *)&val, sizeof(val));
     283         751 :         if (ret == -1) {
     284           0 :                 ret = -errno;
     285           0 :                 DBG_DEBUG("setsockopt(SO_REUSEADDR) failed: %s\n",
     286             :                           strerror(errno));
     287           0 :                 goto fail;
     288             :         }
     289             : 
     290             : #ifdef SO_REUSEPORT
     291         751 :         ret = setsockopt(
     292             :                 sock, SOL_SOCKET, SO_REUSEPORT, (char *)&val, sizeof(val));
     293         751 :         if (ret == -1) {
     294           0 :                 ret = -errno;
     295           0 :                 DBG_DEBUG("setsockopt(SO_REUSEPORT) failed: %s\n",
     296             :                           strerror(errno));
     297           0 :                 goto fail;
     298             :         }
     299             : #endif /* SO_REUSEPORT */
     300             : 
     301             : #ifdef HAVE_IPV6
     302             :         /*
     303             :          * As IPV6_V6ONLY is the default on some systems,
     304             :          * we better try to be consistent and always use it.
     305             :          *
     306             :          * This also avoids using IPv4 via AF_INET6 sockets
     307             :          * and makes sure %I never resolves to a '::ffff:192.168.0.1'
     308             :          * string.
     309             :          */
     310         751 :         if (addr.u.ss.ss_family == AF_INET6) {
     311             : 
     312          80 :                 val = 1;
     313             : 
     314          80 :                 ret = setsockopt(
     315             :                         sock,
     316             :                         IPPROTO_IPV6,
     317             :                         IPV6_V6ONLY,
     318             :                         (const void *)&val,
     319             :                         sizeof(val));
     320          80 :                 if (ret == -1) {
     321           0 :                         ret = -errno;
     322           0 :                         DBG_DEBUG("setsockopt(IPV6_V6ONLY) failed: %s\n",
     323             :                                   strerror(errno));
     324           0 :                         goto fail;
     325             :                 }
     326             :         }
     327             : #endif
     328             : 
     329             :         /* now we've got a socket - we need to bind it */
     330         751 :         ret = bind(sock, &addr.u.sa, addr.sa_socklen);
     331         751 :         if (ret == -1) {
     332           0 :                 char addrstr[INET6_ADDRSTRLEN];
     333             : 
     334           0 :                 ret = -errno;
     335             : 
     336           0 :                 print_sockaddr(addrstr, sizeof(addrstr), &addr.u.ss);
     337           0 :                 DBG_DEBUG("bind for %s port %"PRIu16" failed: %s\n",
     338             :                           addrstr,
     339             :                           port,
     340             :                           strerror(-ret));
     341           0 :                 goto fail;
     342             :         }
     343             : 
     344         751 :         DBG_DEBUG("bind succeeded on port %"PRIu16"\n", port);
     345             : 
     346         751 :         return sock;
     347             : 
     348           0 : fail:
     349           0 :         if (sock != -1) {
     350           0 :                 close(sock);
     351           0 :                 sock = -1;
     352             :         }
     353           0 :         return ret;
     354             :  }
     355             : 
     356             : struct open_socket_out_state {
     357             :         int fd;
     358             :         struct tevent_context *ev;
     359             :         struct sockaddr_storage ss;
     360             :         socklen_t salen;
     361             :         uint16_t port;
     362             :         struct tevent_req *connect_subreq;
     363             : };
     364             : 
     365             : static void open_socket_out_connected(struct tevent_req *subreq);
     366             : 
     367       36956 : static void open_socket_out_cleanup(struct tevent_req *req,
     368             :                                     enum tevent_req_state req_state)
     369             : {
     370           0 :         struct open_socket_out_state *state =
     371       36956 :                 tevent_req_data(req, struct open_socket_out_state);
     372             : 
     373             :         /*
     374             :          * Make sure that the async_connect_send subreq has a chance to reset
     375             :          * fcntl before the socket goes away.
     376             :          */
     377       36956 :         TALLOC_FREE(state->connect_subreq);
     378             : 
     379       36956 :         if (req_state == TEVENT_REQ_DONE) {
     380             :                 /*
     381             :                  * we keep the socket open for the caller to use
     382             :                  */
     383       18474 :                 return;
     384             :         }
     385             : 
     386       18482 :         if (state->fd != -1) {
     387           4 :                 close(state->fd);
     388           4 :                 state->fd = -1;
     389             :         }
     390             : }
     391             : 
     392             : /****************************************************************************
     393             :  Create an outgoing socket. timeout is in milliseconds.
     394             : **************************************************************************/
     395             : 
     396       18478 : struct tevent_req *open_socket_out_send(TALLOC_CTX *mem_ctx,
     397             :                                         struct tevent_context *ev,
     398             :                                         const struct sockaddr_storage *pss,
     399             :                                         uint16_t port,
     400             :                                         int timeout)
     401             : {
     402           0 :         char addr[INET6_ADDRSTRLEN];
     403           0 :         struct tevent_req *req;
     404           0 :         struct open_socket_out_state *state;
     405           0 :         NTSTATUS status;
     406             : 
     407       18478 :         req = tevent_req_create(mem_ctx, &state,
     408             :                                 struct open_socket_out_state);
     409       18478 :         if (req == NULL) {
     410           0 :                 return NULL;
     411             :         }
     412       18478 :         state->ev = ev;
     413       18478 :         state->ss = *pss;
     414       18478 :         state->port = port;
     415       18478 :         state->salen = -1;
     416             : 
     417       18478 :         state->fd = socket(state->ss.ss_family, SOCK_STREAM, 0);
     418       18478 :         if (state->fd == -1) {
     419           0 :                 status = map_nt_error_from_unix(errno);
     420           0 :                 tevent_req_nterror(req, status);
     421           0 :                 return tevent_req_post(req, ev);
     422             :         }
     423             : 
     424       18478 :         tevent_req_set_cleanup_fn(req, open_socket_out_cleanup);
     425             : 
     426       18478 :         if ((timeout != 0) &&
     427       18478 :             !tevent_req_set_endtime(
     428             :                     req, ev, timeval_current_ofs_msec(timeout))) {
     429           0 :                 tevent_req_oom(req);
     430           0 :                 return tevent_req_post(req, ev);
     431             :         }
     432             : 
     433             : #if defined(HAVE_IPV6)
     434       18478 :         if (pss->ss_family == AF_INET6) {
     435           0 :                 struct sockaddr_in6 *psa6;
     436         176 :                 psa6 = (struct sockaddr_in6 *)&state->ss;
     437         176 :                 psa6->sin6_port = htons(port);
     438         176 :                 if (psa6->sin6_scope_id == 0
     439         176 :                     && IN6_IS_ADDR_LINKLOCAL(&psa6->sin6_addr)) {
     440           0 :                         setup_linklocal_scope_id(
     441           0 :                                 (struct sockaddr *)&(state->ss));
     442             :                 }
     443         176 :                 state->salen = sizeof(struct sockaddr_in6);
     444             :         }
     445             : #endif
     446       18478 :         if (pss->ss_family == AF_INET) {
     447           0 :                 struct sockaddr_in *psa;
     448       18302 :                 psa = (struct sockaddr_in *)&state->ss;
     449       18302 :                 psa->sin_port = htons(port);
     450       18302 :                 state->salen = sizeof(struct sockaddr_in);
     451             :         }
     452             : 
     453       18478 :         if (pss->ss_family == AF_UNIX) {
     454           0 :                 state->salen = sizeof(struct sockaddr_un);
     455             :         }
     456             : 
     457       18478 :         print_sockaddr(addr, sizeof(addr), &state->ss);
     458       18478 :         DEBUG(3,("Connecting to %s at port %u\n", addr,       (unsigned int)port));
     459             : 
     460       36956 :         state->connect_subreq = async_connect_send(
     461       18478 :                 state, state->ev, state->fd, (struct sockaddr *)&state->ss,
     462       18478 :                 state->salen, NULL, NULL, NULL);
     463       18478 :         if (tevent_req_nomem(state->connect_subreq, NULL)) {
     464           0 :                 return tevent_req_post(req, ev);
     465             :         }
     466       18478 :         tevent_req_set_callback(state->connect_subreq,
     467             :                                 open_socket_out_connected, req);
     468       18478 :         return req;
     469             : }
     470             : 
     471       18478 : static void open_socket_out_connected(struct tevent_req *subreq)
     472             : {
     473           0 :         struct tevent_req *req =
     474       18478 :                 tevent_req_callback_data(subreq, struct tevent_req);
     475           0 :         struct open_socket_out_state *state =
     476       18478 :                 tevent_req_data(req, struct open_socket_out_state);
     477           0 :         int ret;
     478           0 :         int sys_errno;
     479             : 
     480       18478 :         ret = async_connect_recv(subreq, &sys_errno);
     481       18478 :         TALLOC_FREE(subreq);
     482       18478 :         state->connect_subreq = NULL;
     483       18478 :         if (ret == 0) {
     484       18474 :                 tevent_req_done(req);
     485       18474 :                 return;
     486             :         }
     487             : 
     488           4 :         tevent_req_nterror(req, map_nt_error_from_unix(sys_errno));
     489             : }
     490             : 
     491       18478 : NTSTATUS open_socket_out_recv(struct tevent_req *req, int *pfd)
     492             : {
     493           0 :         struct open_socket_out_state *state =
     494       18478 :                 tevent_req_data(req, struct open_socket_out_state);
     495           0 :         NTSTATUS status;
     496             : 
     497       18478 :         if (tevent_req_is_nterror(req, &status)) {
     498           4 :                 tevent_req_received(req);
     499           4 :                 return status;
     500             :         }
     501       18474 :         *pfd = state->fd;
     502       18474 :         state->fd = -1;
     503       18474 :         tevent_req_received(req);
     504       18474 :         return NT_STATUS_OK;
     505             : }
     506             : 
     507             : /**
     508             : * @brief open a socket
     509             : *
     510             : * @param pss a struct sockaddr_storage defining the address to connect to
     511             : * @param port to connect to
     512             : * @param timeout in MILLISECONDS
     513             : * @param pfd file descriptor returned
     514             : *
     515             : * @return NTSTATUS code
     516             : */
     517         437 : NTSTATUS open_socket_out(const struct sockaddr_storage *pss, uint16_t port,
     518             :                          int timeout, int *pfd)
     519             : {
     520         437 :         TALLOC_CTX *frame = talloc_stackframe();
     521           0 :         struct tevent_context *ev;
     522           0 :         struct tevent_req *req;
     523         437 :         NTSTATUS status = NT_STATUS_NO_MEMORY;
     524             : 
     525         437 :         ev = samba_tevent_context_init(frame);
     526         437 :         if (ev == NULL) {
     527           0 :                 goto fail;
     528             :         }
     529             : 
     530         437 :         req = open_socket_out_send(frame, ev, pss, port, timeout);
     531         437 :         if (req == NULL) {
     532           0 :                 goto fail;
     533             :         }
     534         437 :         if (!tevent_req_poll(req, ev)) {
     535           0 :                 status = NT_STATUS_INTERNAL_ERROR;
     536           0 :                 goto fail;
     537             :         }
     538         437 :         status = open_socket_out_recv(req, pfd);
     539         437 :  fail:
     540         437 :         TALLOC_FREE(frame);
     541         437 :         return status;
     542             : }
     543             : 
     544             : struct open_socket_out_defer_state {
     545             :         struct tevent_context *ev;
     546             :         struct sockaddr_storage ss;
     547             :         uint16_t port;
     548             :         int timeout;
     549             :         int fd;
     550             : };
     551             : 
     552             : static void open_socket_out_defer_waited(struct tevent_req *subreq);
     553             : static void open_socket_out_defer_connected(struct tevent_req *subreq);
     554             : 
     555           0 : struct tevent_req *open_socket_out_defer_send(TALLOC_CTX *mem_ctx,
     556             :                                               struct tevent_context *ev,
     557             :                                               struct timeval wait_time,
     558             :                                               const struct sockaddr_storage *pss,
     559             :                                               uint16_t port,
     560             :                                               int timeout)
     561             : {
     562           0 :         struct tevent_req *req, *subreq;
     563           0 :         struct open_socket_out_defer_state *state;
     564             : 
     565           0 :         req = tevent_req_create(mem_ctx, &state,
     566             :                                 struct open_socket_out_defer_state);
     567           0 :         if (req == NULL) {
     568           0 :                 return NULL;
     569             :         }
     570           0 :         state->ev = ev;
     571           0 :         state->ss = *pss;
     572           0 :         state->port = port;
     573           0 :         state->timeout = timeout;
     574             : 
     575           0 :         subreq = tevent_wakeup_send(
     576             :                 state, ev,
     577           0 :                 timeval_current_ofs(wait_time.tv_sec, wait_time.tv_usec));
     578           0 :         if (subreq == NULL) {
     579           0 :                 goto fail;
     580             :         }
     581           0 :         tevent_req_set_callback(subreq, open_socket_out_defer_waited, req);
     582           0 :         return req;
     583           0 :  fail:
     584           0 :         TALLOC_FREE(req);
     585           0 :         return NULL;
     586             : }
     587             : 
     588           0 : static void open_socket_out_defer_waited(struct tevent_req *subreq)
     589             : {
     590           0 :         struct tevent_req *req = tevent_req_callback_data(
     591             :                 subreq, struct tevent_req);
     592           0 :         struct open_socket_out_defer_state *state = tevent_req_data(
     593             :                 req, struct open_socket_out_defer_state);
     594           0 :         bool ret;
     595             : 
     596           0 :         ret = tevent_wakeup_recv(subreq);
     597           0 :         TALLOC_FREE(subreq);
     598           0 :         if (!ret) {
     599           0 :                 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
     600           0 :                 return;
     601             :         }
     602             : 
     603           0 :         subreq = open_socket_out_send(state, state->ev, &state->ss,
     604           0 :                                       state->port, state->timeout);
     605           0 :         if (tevent_req_nomem(subreq, req)) {
     606           0 :                 return;
     607             :         }
     608           0 :         tevent_req_set_callback(subreq, open_socket_out_defer_connected, req);
     609             : }
     610             : 
     611           0 : static void open_socket_out_defer_connected(struct tevent_req *subreq)
     612             : {
     613           0 :         struct tevent_req *req = tevent_req_callback_data(
     614             :                 subreq, struct tevent_req);
     615           0 :         struct open_socket_out_defer_state *state = tevent_req_data(
     616             :                 req, struct open_socket_out_defer_state);
     617           0 :         NTSTATUS status;
     618             : 
     619           0 :         status = open_socket_out_recv(subreq, &state->fd);
     620           0 :         TALLOC_FREE(subreq);
     621           0 :         if (!NT_STATUS_IS_OK(status)) {
     622           0 :                 tevent_req_nterror(req, status);
     623           0 :                 return;
     624             :         }
     625           0 :         tevent_req_done(req);
     626             : }
     627             : 
     628           0 : NTSTATUS open_socket_out_defer_recv(struct tevent_req *req, int *pfd)
     629             : {
     630           0 :         struct open_socket_out_defer_state *state = tevent_req_data(
     631             :                 req, struct open_socket_out_defer_state);
     632           0 :         NTSTATUS status;
     633             : 
     634           0 :         if (tevent_req_is_nterror(req, &status)) {
     635           0 :                 return status;
     636             :         }
     637           0 :         *pfd = state->fd;
     638           0 :         state->fd = -1;
     639           0 :         return NT_STATUS_OK;
     640             : }
     641             : 
     642             : /*******************************************************************
     643             :  Return the IP addr of the remote end of a socket as a string.
     644             :  Optionally return the struct sockaddr_storage.
     645             :  ******************************************************************/
     646             : 
     647           0 : static const char *get_peer_addr_internal(int fd,
     648             :                                 char *addr_buf,
     649             :                                 size_t addr_buf_len,
     650             :                                 struct sockaddr *pss,
     651             :                                 socklen_t *plength)
     652             : {
     653           0 :         struct sockaddr_storage ss;
     654           0 :         socklen_t length = sizeof(ss);
     655             : 
     656           0 :         strlcpy(addr_buf,"0.0.0.0",addr_buf_len);
     657             : 
     658           0 :         if (fd == -1) {
     659           0 :                 return addr_buf;
     660             :         }
     661             : 
     662           0 :         if (pss == NULL) {
     663           0 :                 pss = (struct sockaddr *)&ss;
     664           0 :                 plength = &length;
     665             :         }
     666             : 
     667           0 :         if (getpeername(fd, (struct sockaddr *)pss, plength) < 0) {
     668           0 :                 int level = (errno == ENOTCONN) ? 2 : 0;
     669           0 :                 DEBUG(level, ("getpeername failed. Error was %s\n",
     670             :                                strerror(errno)));
     671           0 :                 return addr_buf;
     672             :         }
     673             : 
     674           0 :         print_sockaddr_len(addr_buf,
     675             :                         addr_buf_len,
     676             :                         pss,
     677             :                         *plength);
     678           0 :         return addr_buf;
     679             : }
     680             : 
     681             : /*******************************************************************
     682             :  Matchname - determine if host name matches IP address. Used to
     683             :  confirm a hostname lookup to prevent spoof attacks.
     684             : ******************************************************************/
     685             : 
     686           0 : static bool matchname(const char *remotehost,
     687             :                 const struct sockaddr *pss,
     688             :                 socklen_t len)
     689             : {
     690           0 :         struct addrinfo *res = NULL;
     691           0 :         struct addrinfo *ailist = NULL;
     692           0 :         char addr_buf[INET6_ADDRSTRLEN];
     693           0 :         bool ret = interpret_string_addr_internal(&ailist,
     694             :                         remotehost,
     695             :                         AI_ADDRCONFIG|AI_CANONNAME);
     696             : 
     697           0 :         if (!ret || ailist == NULL) {
     698           0 :                 DEBUG(3,("matchname: getaddrinfo failed for "
     699             :                         "name %s [%s]\n",
     700             :                         remotehost,
     701             :                         gai_strerror(ret) ));
     702           0 :                 return false;
     703             :         }
     704             : 
     705             :         /*
     706             :          * Make sure that getaddrinfo() returns the "correct" host name.
     707             :          */
     708             : 
     709           0 :         if (ailist->ai_canonname == NULL ||
     710           0 :                 (!strequal(remotehost, ailist->ai_canonname) &&
     711           0 :                  !strequal(remotehost, "localhost"))) {
     712           0 :                 DEBUG(0,("matchname: host name/name mismatch: %s != %s\n",
     713             :                          remotehost,
     714             :                          ailist->ai_canonname ?
     715             :                                  ailist->ai_canonname : "(NULL)"));
     716           0 :                 freeaddrinfo(ailist);
     717           0 :                 return false;
     718             :         }
     719             : 
     720             :         /* Look up the host address in the address list we just got. */
     721           0 :         for (res = ailist; res; res = res->ai_next) {
     722           0 :                 if (!res->ai_addr) {
     723           0 :                         continue;
     724             :                 }
     725           0 :                 if (sockaddr_equal((const struct sockaddr *)res->ai_addr,
     726             :                                         (const struct sockaddr *)pss)) {
     727           0 :                         freeaddrinfo(ailist);
     728           0 :                         return true;
     729             :                 }
     730             :         }
     731             : 
     732             :         /*
     733             :          * The host name does not map to the original host address. Perhaps
     734             :          * someone has compromised a name server. More likely someone botched
     735             :          * it, but that could be dangerous, too.
     736             :          */
     737             : 
     738           0 :         DEBUG(0,("matchname: host name/address mismatch: %s != %s\n",
     739             :                 print_sockaddr_len(addr_buf,
     740             :                         sizeof(addr_buf),
     741             :                         pss,
     742             :                         len),
     743             :                  ailist->ai_canonname ? ailist->ai_canonname : "(NULL)"));
     744             : 
     745           0 :         if (ailist) {
     746           0 :                 freeaddrinfo(ailist);
     747             :         }
     748           0 :         return false;
     749             : }
     750             : 
     751             : /*******************************************************************
     752             :  Deal with the singleton cache.
     753             : ******************************************************************/
     754             : 
     755             : struct name_addr_pair {
     756             :         struct sockaddr_storage ss;
     757             :         const char *name;
     758             : };
     759             : 
     760             : /*******************************************************************
     761             :  Lookup a name/addr pair. Returns memory allocated from memcache.
     762             : ******************************************************************/
     763             : 
     764       33843 : static bool lookup_nc(struct name_addr_pair *nc)
     765             : {
     766         894 :         DATA_BLOB tmp;
     767             : 
     768       33843 :         ZERO_STRUCTP(nc);
     769             : 
     770       33843 :         if (!memcache_lookup(
     771             :                         NULL, SINGLETON_CACHE,
     772             :                         data_blob_string_const_null("get_peer_name"),
     773             :                         &tmp)) {
     774        1174 :                 return false;
     775             :         }
     776             : 
     777       32669 :         memcpy(&nc->ss, tmp.data, sizeof(nc->ss));
     778       32669 :         nc->name = (const char *)tmp.data + sizeof(nc->ss);
     779       32669 :         return true;
     780             : }
     781             : 
     782             : /*******************************************************************
     783             :  Save a name/addr pair.
     784             : ******************************************************************/
     785             : 
     786       33843 : static void store_nc(const struct name_addr_pair *nc)
     787             : {
     788         894 :         DATA_BLOB tmp;
     789       33843 :         size_t namelen = strlen(nc->name);
     790             : 
     791       33843 :         tmp = data_blob(NULL, sizeof(nc->ss) + namelen + 1);
     792       33843 :         if (!tmp.data) {
     793           0 :                 return;
     794             :         }
     795       33843 :         memcpy(tmp.data, &nc->ss, sizeof(nc->ss));
     796       33843 :         memcpy(tmp.data+sizeof(nc->ss), nc->name, namelen+1);
     797             : 
     798       33843 :         memcache_add(NULL, SINGLETON_CACHE,
     799             :                         data_blob_string_const_null("get_peer_name"),
     800             :                         tmp);
     801       33843 :         data_blob_free(&tmp);
     802             : }
     803             : 
     804             : /*******************************************************************
     805             :  Return the IP addr of the remote end of a socket as a string.
     806             :  ******************************************************************/
     807             : 
     808           0 : const char *get_peer_addr(int fd, char *addr, size_t addr_len)
     809             : {
     810           0 :         return get_peer_addr_internal(fd, addr, addr_len, NULL, NULL);
     811             : }
     812             : 
     813       33843 : int get_remote_hostname(const struct tsocket_address *remote_address,
     814             :                         char **name,
     815             :                         TALLOC_CTX *mem_ctx)
     816             : {
     817         894 :         char name_buf[MAX_DNS_NAME_LENGTH];
     818         894 :         char tmp_name[MAX_DNS_NAME_LENGTH];
     819         894 :         struct name_addr_pair nc;
     820         894 :         struct sockaddr_storage ss;
     821         894 :         ssize_t len;
     822         894 :         int rc;
     823             : 
     824       33843 :         if (!lp_hostname_lookups()) {
     825       33843 :                 nc.name = tsocket_address_inet_addr_string(remote_address,
     826             :                                                            mem_ctx);
     827       33843 :                 if (nc.name == NULL) {
     828           0 :                         return -1;
     829             :                 }
     830             : 
     831       33843 :                 len = tsocket_address_bsd_sockaddr(remote_address,
     832             :                                                    (struct sockaddr *) &nc.ss,
     833             :                                                    sizeof(struct sockaddr_storage));
     834       33843 :                 if (len < 0) {
     835           0 :                         return -1;
     836             :                 }
     837             : 
     838       33843 :                 store_nc(&nc);
     839       33843 :                 lookup_nc(&nc);
     840             : 
     841       33843 :                 if (nc.name == NULL) {
     842        1174 :                         *name = talloc_strdup(mem_ctx, "UNKNOWN");
     843             :                 } else {
     844       32669 :                         *name = talloc_strdup(mem_ctx, nc.name);
     845             :                 }
     846       33843 :                 return 0;
     847             :         }
     848             : 
     849           0 :         lookup_nc(&nc);
     850             : 
     851           0 :         ZERO_STRUCT(ss);
     852             : 
     853           0 :         len = tsocket_address_bsd_sockaddr(remote_address,
     854             :                                            (struct sockaddr *) &ss,
     855             :                                            sizeof(struct sockaddr_storage));
     856           0 :         if (len < 0) {
     857           0 :                 return -1;
     858             :         }
     859             : 
     860             :         /* it might be the same as the last one - save some DNS work */
     861           0 :         if (sockaddr_equal((struct sockaddr *)&ss, (struct sockaddr *)&nc.ss)) {
     862           0 :                 if (nc.name == NULL) {
     863           0 :                         *name = talloc_strdup(mem_ctx, "UNKNOWN");
     864             :                 } else {
     865           0 :                         *name = talloc_strdup(mem_ctx, nc.name);
     866             :                 }
     867           0 :                 return 0;
     868             :         }
     869             : 
     870             :         /* Look up the remote host name. */
     871           0 :         rc = sys_getnameinfo((struct sockaddr *) &ss,
     872             :                              len,
     873             :                              name_buf,
     874             :                              sizeof(name_buf),
     875             :                              NULL,
     876             :                              0,
     877             :                              0);
     878           0 :         if (rc < 0) {
     879           0 :                 char *p;
     880             : 
     881           0 :                 p = tsocket_address_inet_addr_string(remote_address, mem_ctx);
     882           0 :                 if (p == NULL) {
     883           0 :                         return -1;
     884             :                 }
     885             : 
     886           0 :                 DEBUG(1,("getnameinfo failed for %s with error %s\n",
     887             :                          p,
     888             :                          gai_strerror(rc)));
     889           0 :                 strlcpy(name_buf, p, sizeof(name_buf));
     890             : 
     891           0 :                 TALLOC_FREE(p);
     892             :         } else {
     893           0 :                 if (!matchname(name_buf, (struct sockaddr *)&ss, len)) {
     894           0 :                         DEBUG(0,("matchname failed on %s\n", name_buf));
     895           0 :                         strlcpy(name_buf, "UNKNOWN", sizeof(name_buf));
     896             :                 }
     897             :         }
     898             : 
     899           0 :         strlcpy(tmp_name, name_buf, sizeof(tmp_name));
     900           0 :         alpha_strcpy(name_buf, tmp_name, "_-.", sizeof(name_buf));
     901           0 :         if (strstr(name_buf,"..")) {
     902           0 :                 strlcpy(name_buf, "UNKNOWN", sizeof(name_buf));
     903             :         }
     904             : 
     905           0 :         nc.name = name_buf;
     906           0 :         nc.ss = ss;
     907             : 
     908           0 :         store_nc(&nc);
     909           0 :         lookup_nc(&nc);
     910             : 
     911           0 :         if (nc.name == NULL) {
     912           0 :                 *name = talloc_strdup(mem_ctx, "UNKNOWN");
     913             :         } else {
     914           0 :                 *name = talloc_strdup(mem_ctx, nc.name);
     915             :         }
     916             : 
     917           0 :         return 0;
     918             : }
     919             : 
     920             : /*******************************************************************
     921             :  Create protected unix domain socket.
     922             : 
     923             :  Some unixes cannot set permissions on a ux-dom-sock, so we
     924             :  have to make sure that the directory contains the protection
     925             :  permissions instead.
     926             :  ******************************************************************/
     927             : 
     928        1816 : int create_pipe_sock(const char *socket_dir,
     929             :                      const char *socket_name,
     930             :                      mode_t dir_perms)
     931             : {
     932             : #ifdef HAVE_UNIXSOCKET
     933           2 :         struct sockaddr_un sunaddr;
     934           2 :         bool ok;
     935        1816 :         int sock = -1;
     936           2 :         mode_t old_umask;
     937        1816 :         char *path = NULL;
     938           2 :         size_t path_len;
     939             : 
     940        1816 :         old_umask = umask(0);
     941             : 
     942        1816 :         ok = directory_create_or_exist_strict(socket_dir,
     943             :                                               sec_initial_uid(),
     944             :                                               dir_perms);
     945        1816 :         if (!ok) {
     946           0 :                 goto out_close;
     947             :         }
     948             : 
     949             :         /* Create the socket file */
     950        1816 :         sock = socket(AF_UNIX, SOCK_STREAM, 0);
     951             : 
     952        1816 :         if (sock == -1) {
     953           0 :                 DEBUG(0, ("create_pipe_sock: socket error %s\n",
     954             :                         strerror(errno) ));
     955           0 :                 goto out_close;
     956             :         }
     957             : 
     958        1816 :         if (asprintf(&path, "%s/%s", socket_dir, socket_name) == -1) {
     959           0 :                 goto out_close;
     960             :         }
     961             : 
     962        1816 :         unlink(path);
     963        1816 :         memset(&sunaddr, 0, sizeof(sunaddr));
     964        1816 :         sunaddr.sun_family = AF_UNIX;
     965             : 
     966        1816 :         path_len = strlcpy(sunaddr.sun_path, path, sizeof(sunaddr.sun_path));
     967        1816 :         if (path_len > sizeof(sunaddr.sun_path)) {
     968           0 :                 DBG_ERR("Refusing to attempt to create pipe socket "
     969             :                         "%s.  Path is longer than permitted for a "
     970             :                         "unix domain socket.  It would truncate to "
     971             :                         "%s\n",
     972             :                         path,
     973             :                         sunaddr.sun_path);
     974           0 :                 goto out_close;
     975             :         }
     976             : 
     977        1816 :         if (bind(sock, (struct sockaddr *)&sunaddr, sizeof(sunaddr)) == -1) {
     978           0 :                 DEBUG(0, ("bind failed on pipe socket %s: %s\n", path,
     979             :                         strerror(errno)));
     980           0 :                 goto out_close;
     981             :         }
     982             : 
     983        1816 :         SAFE_FREE(path);
     984             : 
     985        1816 :         umask(old_umask);
     986        1816 :         return sock;
     987             : 
     988           0 : out_close:
     989           0 :         SAFE_FREE(path);
     990           0 :         if (sock != -1)
     991           0 :                 close(sock);
     992             : 
     993           0 :         umask(old_umask);
     994           0 :         return -1;
     995             : 
     996             : #else
     997             :         DEBUG(0, ("create_pipe_sock: No Unix sockets on this system\n"));
     998             :         return -1;
     999             : #endif /* HAVE_UNIXSOCKET */
    1000             : }
    1001             : 
    1002             : /****************************************************************************
    1003             :  Get my own canonical name, including domain.
    1004             : ****************************************************************************/
    1005             : 
    1006      120100 : const char *get_mydnsfullname(void)
    1007             : {
    1008      120100 :         struct addrinfo *res = NULL;
    1009           0 :         char my_hostname[HOST_NAME_MAX];
    1010           0 :         bool ret;
    1011           0 :         DATA_BLOB tmp;
    1012             : 
    1013      120100 :         if (memcache_lookup(NULL, SINGLETON_CACHE,
    1014             :                         data_blob_string_const_null("get_mydnsfullname"),
    1015             :                         &tmp)) {
    1016       96350 :                 SMB_ASSERT(tmp.length > 0);
    1017       96350 :                 return (const char *)tmp.data;
    1018             :         }
    1019             : 
    1020             :         /* get my host name */
    1021       23750 :         if (gethostname(my_hostname, sizeof(my_hostname)) == -1) {
    1022           0 :                 DEBUG(0,("get_mydnsfullname: gethostname failed\n"));
    1023           0 :                 return NULL;
    1024             :         }
    1025             : 
    1026             :         /* Ensure null termination. */
    1027       23750 :         my_hostname[sizeof(my_hostname)-1] = '\0';
    1028             : 
    1029       23750 :         ret = interpret_string_addr_internal(&res,
    1030             :                                 my_hostname,
    1031             :                                 AI_ADDRCONFIG|AI_CANONNAME);
    1032             : 
    1033       23750 :         if (!ret || res == NULL) {
    1034           0 :                 DEBUG(3,("get_mydnsfullname: getaddrinfo failed for "
    1035             :                         "name %s [%s]\n",
    1036             :                         my_hostname,
    1037             :                         gai_strerror(ret) ));
    1038           0 :                 return NULL;
    1039             :         }
    1040             : 
    1041             :         /*
    1042             :          * Make sure that getaddrinfo() returns the "correct" host name.
    1043             :          */
    1044             : 
    1045       23750 :         if (res->ai_canonname == NULL) {
    1046           0 :                 DEBUG(3,("get_mydnsfullname: failed to get "
    1047             :                         "canonical name for %s\n",
    1048             :                         my_hostname));
    1049           0 :                 freeaddrinfo(res);
    1050           0 :                 return NULL;
    1051             :         }
    1052             : 
    1053             :         /* This copies the data, so we must do a lookup
    1054             :          * afterwards to find the value to return.
    1055             :          */
    1056             : 
    1057       23750 :         memcache_add(NULL, SINGLETON_CACHE,
    1058             :                         data_blob_string_const_null("get_mydnsfullname"),
    1059       23750 :                         data_blob_string_const_null(res->ai_canonname));
    1060             : 
    1061       23750 :         if (!memcache_lookup(NULL, SINGLETON_CACHE,
    1062             :                         data_blob_string_const_null("get_mydnsfullname"),
    1063             :                         &tmp)) {
    1064        2392 :                 tmp = data_blob_talloc(talloc_tos(), res->ai_canonname,
    1065             :                                 strlen(res->ai_canonname) + 1);
    1066             :         }
    1067             : 
    1068       23750 :         freeaddrinfo(res);
    1069             : 
    1070       23750 :         return (const char *)tmp.data;
    1071             : }
    1072             : 
    1073             : /************************************************************
    1074             :  Is this my ip address ?
    1075             : ************************************************************/
    1076             : 
    1077        3037 : static bool is_my_ipaddr(const char *ipaddr_str)
    1078             : {
    1079           0 :         struct sockaddr_storage ss;
    1080           0 :         struct iface_struct *nics;
    1081           0 :         int i, n;
    1082             : 
    1083        3037 :         if (!interpret_string_addr(&ss, ipaddr_str, AI_NUMERICHOST)) {
    1084           0 :                 return false;
    1085             :         }
    1086             : 
    1087        3037 :         if (is_zero_addr(&ss)) {
    1088           0 :                 return false;
    1089             :         }
    1090             : 
    1091        3373 :         if (ismyaddr((struct sockaddr *)&ss) ||
    1092         336 :                         is_loopback_addr((struct sockaddr *)&ss)) {
    1093        2701 :                 return true;
    1094             :         }
    1095             : 
    1096         336 :         n = get_interfaces(talloc_tos(), &nics);
    1097        1680 :         for (i=0; i<n; i++) {
    1098        1344 :                 if (sockaddr_equal((struct sockaddr *)&nics[i].ip, (struct sockaddr *)&ss)) {
    1099           0 :                         TALLOC_FREE(nics);
    1100           0 :                         return true;
    1101             :                 }
    1102             :         }
    1103         336 :         TALLOC_FREE(nics);
    1104         336 :         return false;
    1105             : }
    1106             : 
    1107             : /************************************************************
    1108             :  Is this my name ?
    1109             : ************************************************************/
    1110             : 
    1111       16061 : bool is_myname_or_ipaddr(const char *s)
    1112             : {
    1113       16061 :         TALLOC_CTX *ctx = talloc_tos();
    1114       16061 :         char *name = NULL;
    1115           0 :         const char *dnsname;
    1116       16061 :         char *servername = NULL;
    1117             : 
    1118       16061 :         if (!s) {
    1119           0 :                 return false;
    1120             :         }
    1121             : 
    1122             :         /* Sanitize the string from '\\name' */
    1123       16061 :         name = talloc_strdup(ctx, s);
    1124       16061 :         if (!name) {
    1125           0 :                 return false;
    1126             :         }
    1127             : 
    1128       16061 :         servername = strrchr_m(name, '\\' );
    1129       16061 :         if (!servername) {
    1130       16061 :                 servername = name;
    1131             :         } else {
    1132           0 :                 servername++;
    1133             :         }
    1134             : 
    1135             :         /* Optimize for the common case */
    1136       16061 :         if (strequal(servername, lp_netbios_name())) {
    1137       13121 :                 return true;
    1138             :         }
    1139             : 
    1140             :         /* Check for an alias */
    1141        2940 :         if (is_myname(servername)) {
    1142           4 :                 return true;
    1143             :         }
    1144             : 
    1145             :         /* Check for loopback */
    1146        5872 :         if (strequal(servername, "127.0.0.1") ||
    1147        2936 :                         strequal(servername, "::1")) {
    1148           0 :                 return true;
    1149             :         }
    1150             : 
    1151        2936 :         if (strequal(servername, "localhost")) {
    1152           0 :                 return true;
    1153             :         }
    1154             : 
    1155             :         /* Maybe it's my dns name */
    1156        2936 :         dnsname = get_mydnsfullname();
    1157        2936 :         if (dnsname && strequal(servername, dnsname)) {
    1158          55 :                 return true;
    1159             :         }
    1160             : 
    1161             :         /* Maybe its an IP address? */
    1162        2881 :         if (is_ipaddress(servername)) {
    1163        2701 :                 return is_my_ipaddr(servername);
    1164             :         }
    1165             : 
    1166             :         /* Handle possible CNAME records - convert to an IP addr. list. */
    1167             :         {
    1168             :                 /* Use DNS to resolve the name, check all addresses. */
    1169         180 :                 struct addrinfo *p = NULL;
    1170         180 :                 struct addrinfo *res = NULL;
    1171             : 
    1172         180 :                 if (!interpret_string_addr_internal(&res,
    1173             :                                 servername,
    1174             :                                 AI_ADDRCONFIG)) {
    1175          12 :                         return false;
    1176             :                 }
    1177             : 
    1178         504 :                 for (p = res; p; p = p->ai_next) {
    1179           0 :                         char addr[INET6_ADDRSTRLEN];
    1180           0 :                         struct sockaddr_storage ss;
    1181             : 
    1182         336 :                         ZERO_STRUCT(ss);
    1183         336 :                         memcpy(&ss, p->ai_addr, p->ai_addrlen);
    1184         336 :                         print_sockaddr(addr,
    1185             :                                         sizeof(addr),
    1186             :                                         &ss);
    1187         336 :                         if (is_my_ipaddr(addr)) {
    1188           0 :                                 freeaddrinfo(res);
    1189           0 :                                 return true;
    1190             :                         }
    1191             :                 }
    1192         168 :                 freeaddrinfo(res);
    1193             :         }
    1194             : 
    1195             :         /* No match */
    1196         168 :         return false;
    1197             : }
    1198             : 
    1199           0 : int poll_one_fd(int fd, int events, int timeout, int *revents)
    1200             : {
    1201           0 :         struct pollfd pfd;
    1202           0 :         int ret;
    1203             : 
    1204           0 :         pfd.fd = fd;
    1205           0 :         pfd.events = events;
    1206             : 
    1207           0 :         ret = poll(&pfd, 1, timeout);
    1208             : 
    1209             :         /*
    1210             :          * Assign whatever poll did, even in the ret<=0 case.
    1211             :          */
    1212           0 :         *revents = pfd.revents;
    1213             : 
    1214           0 :         return ret;
    1215             : }
    1216             : 
    1217           0 : int poll_intr_one_fd(int fd, int events, int timeout, int *revents)
    1218             : {
    1219           0 :         struct pollfd pfd;
    1220           0 :         int ret;
    1221             : 
    1222           0 :         pfd.fd = fd;
    1223           0 :         pfd.events = events;
    1224             : 
    1225           0 :         ret = sys_poll_intr(&pfd, 1, timeout);
    1226           0 :         if (ret <= 0) {
    1227           0 :                 *revents = 0;
    1228           0 :                 return ret;
    1229             :         }
    1230           0 :         *revents = pfd.revents;
    1231           0 :         return 1;
    1232             : }

Generated by: LCOV version 1.14