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
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.
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.
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/>.
24 /*******************************************************************
25 Map a text hostname or IP address (IPv4 or IPv6) into a
26 struct sockaddr_storage. Takes a flag which allows it to
27 prefer an IPv4 address (needed for DC's).
28 ******************************************************************/
30 static bool interpret_string_addr_pref(struct sockaddr_storage *pss,
35 struct addrinfo *res = NULL;
36 #if defined(HAVE_IPV6)
37 char addr[INET6_ADDRSTRLEN];
38 unsigned int scope_id = 0;
40 if (strchr_m(str, ':')) {
41 char *p = strchr_m(str, '%');
44 * Cope with link-local.
45 * This is IP:v6:addr%ifname.
48 if (p && (p > str) && ((scope_id = if_nametoindex(p+1)) != 0)) {
50 MIN(PTR_DIFF(p,str)+1,
59 if (!interpret_string_addr_internal(&res, str, flags|AI_ADDRCONFIG)) {
69 for (p = res; p; p = p->ai_next) {
70 if (p->ai_family == AF_INET) {
71 memcpy(pss, p->ai_addr, p->ai_addrlen);
76 /* Copy the first sockaddr. */
77 memcpy(pss, res->ai_addr, res->ai_addrlen);
80 /* Copy the first sockaddr. */
81 memcpy(pss, res->ai_addr, res->ai_addrlen);
84 #if defined(HAVE_IPV6)
85 if (pss->ss_family == AF_INET6 && scope_id) {
86 struct sockaddr_in6 *ps6 = (struct sockaddr_in6 *)pss;
87 if (IN6_IS_ADDR_LINKLOCAL(&ps6->sin6_addr) &&
88 ps6->sin6_scope_id == 0) {
89 ps6->sin6_scope_id = scope_id;
98 /*******************************************************************
99 Map a text hostname or IP address (IPv4 or IPv6) into a
100 struct sockaddr_storage. Address agnostic version.
101 ******************************************************************/
103 bool interpret_string_addr(struct sockaddr_storage *pss,
107 return interpret_string_addr_pref(pss,
113 /*******************************************************************
114 Map a text hostname or IP address (IPv4 or IPv6) into a
115 struct sockaddr_storage. Version that prefers IPv4.
116 ******************************************************************/
118 bool interpret_string_addr_prefer_ipv4(struct sockaddr_storage *pss,
122 return interpret_string_addr_pref(pss,
128 /*******************************************************************
129 Set an address to INADDR_ANY.
130 ******************************************************************/
132 void zero_sockaddr(struct sockaddr_storage *pss)
134 memset(pss, '\0', sizeof(*pss));
135 /* Ensure we're at least a valid sockaddr-storage. */
136 pss->ss_family = AF_INET;
139 /****************************************************************************
140 Get a port number in host byte order from a sockaddr_storage.
141 ****************************************************************************/
143 uint16_t get_sockaddr_port(const struct sockaddr_storage *pss)
147 if (pss->ss_family != AF_INET) {
148 #if defined(HAVE_IPV6)
150 const struct sockaddr_in6 *sa6 =
151 (const struct sockaddr_in6 *)pss;
152 port = ntohs(sa6->sin6_port);
155 const struct sockaddr_in *sa =
156 (const struct sockaddr_in *)pss;
157 port = ntohs(sa->sin_port);
162 /****************************************************************************
163 Print out an IPv4 or IPv6 address from a struct sockaddr_storage.
164 ****************************************************************************/
166 static char *print_sockaddr_len(char *dest,
168 const struct sockaddr *psa,
174 (void)sys_getnameinfo(psa,
182 /****************************************************************************
183 Print out an IPv4 or IPv6 address from a struct sockaddr_storage.
184 ****************************************************************************/
186 char *print_sockaddr(char *dest,
188 const struct sockaddr_storage *psa)
190 return print_sockaddr_len(dest, destlen, (struct sockaddr *)psa,
191 sizeof(struct sockaddr_storage));
194 /****************************************************************************
195 Print out a canonical IPv4 or IPv6 address from a struct sockaddr_storage.
196 ****************************************************************************/
198 char *print_canonical_sockaddr(TALLOC_CTX *ctx,
199 const struct sockaddr_storage *pss)
201 char addr[INET6_ADDRSTRLEN];
205 /* Linux getnameinfo() man pages says port is unitialized if
206 service name is NULL. */
208 ret = sys_getnameinfo((const struct sockaddr *)pss,
209 sizeof(struct sockaddr_storage),
217 if (pss->ss_family != AF_INET) {
218 #if defined(HAVE_IPV6)
219 dest = talloc_asprintf(ctx, "[%s]", addr);
224 dest = talloc_asprintf(ctx, "%s", addr);
230 /****************************************************************************
231 Return the string of an IP address (IPv4 or IPv6).
232 ****************************************************************************/
234 static const char *get_socket_addr(int fd, char *addr_buf, size_t addr_len)
236 struct sockaddr_storage sa;
237 socklen_t length = sizeof(sa);
239 /* Ok, returning a hard coded IPv4 address
240 * is bogus, but it's just as bogus as a
241 * zero IPv6 address. No good choice here.
244 strlcpy(addr_buf, "0.0.0.0", addr_len);
250 if (getsockname(fd, (struct sockaddr *)&sa, &length) < 0) {
251 DEBUG(0,("getsockname failed. Error was %s\n",
256 return print_sockaddr_len(addr_buf, addr_len, (struct sockaddr *)&sa, length);
259 /****************************************************************************
260 Return the port number we've bound to on a socket.
261 ****************************************************************************/
263 int get_socket_port(int fd)
265 struct sockaddr_storage sa;
266 socklen_t length = sizeof(sa);
272 if (getsockname(fd, (struct sockaddr *)&sa, &length) < 0) {
273 DEBUG(0,("getpeername failed. Error was %s\n",
278 #if defined(HAVE_IPV6)
279 if (sa.ss_family == AF_INET6) {
280 return ntohs(((struct sockaddr_in6 *)&sa)->sin6_port);
283 if (sa.ss_family == AF_INET) {
284 return ntohs(((struct sockaddr_in *)&sa)->sin_port);
289 const char *client_name(int fd)
291 return get_peer_name(fd,false);
294 const char *client_addr(int fd, char *addr, size_t addrlen)
296 return get_peer_addr(fd,addr,addrlen);
299 const char *client_socket_addr(int fd, char *addr, size_t addr_len)
301 return get_socket_addr(fd, addr, addr_len);
305 /* Not currently used. JRA. */
306 int client_socket_port(int fd)
308 return get_socket_port(fd);
312 /****************************************************************************
313 Accessor functions to make thread-safe code easier later...
314 ****************************************************************************/
316 void set_smb_read_error(enum smb_read_errors *pre,
317 enum smb_read_errors newerr)
324 void cond_set_smb_read_error(enum smb_read_errors *pre,
325 enum smb_read_errors newerr)
327 if (pre && *pre == SMB_READ_OK) {
332 /****************************************************************************
333 Determine if a file descriptor is in fact a socket.
334 ****************************************************************************/
336 bool is_a_socket(int fd)
341 return(getsockopt(fd, SOL_SOCKET, SO_TYPE, (char *)&v, &l) == 0);
344 enum SOCK_OPT_TYPES {OPT_BOOL,OPT_INT,OPT_ON};
346 typedef struct smb_socket_option {
354 static const smb_socket_option socket_options[] = {
355 {"SO_KEEPALIVE", SOL_SOCKET, SO_KEEPALIVE, 0, OPT_BOOL},
356 {"SO_REUSEADDR", SOL_SOCKET, SO_REUSEADDR, 0, OPT_BOOL},
357 {"SO_BROADCAST", SOL_SOCKET, SO_BROADCAST, 0, OPT_BOOL},
359 {"TCP_NODELAY", IPPROTO_TCP, TCP_NODELAY, 0, OPT_BOOL},
362 {"TCP_KEEPCNT", IPPROTO_TCP, TCP_KEEPCNT, 0, OPT_INT},
365 {"TCP_KEEPIDLE", IPPROTO_TCP, TCP_KEEPIDLE, 0, OPT_INT},
368 {"TCP_KEEPINTVL", IPPROTO_TCP, TCP_KEEPINTVL, 0, OPT_INT},
370 #ifdef IPTOS_LOWDELAY
371 {"IPTOS_LOWDELAY", IPPROTO_IP, IP_TOS, IPTOS_LOWDELAY, OPT_ON},
373 #ifdef IPTOS_THROUGHPUT
374 {"IPTOS_THROUGHPUT", IPPROTO_IP, IP_TOS, IPTOS_THROUGHPUT, OPT_ON},
377 {"SO_REUSEPORT", SOL_SOCKET, SO_REUSEPORT, 0, OPT_BOOL},
380 {"SO_SNDBUF", SOL_SOCKET, SO_SNDBUF, 0, OPT_INT},
383 {"SO_RCVBUF", SOL_SOCKET, SO_RCVBUF, 0, OPT_INT},
386 {"SO_SNDLOWAT", SOL_SOCKET, SO_SNDLOWAT, 0, OPT_INT},
389 {"SO_RCVLOWAT", SOL_SOCKET, SO_RCVLOWAT, 0, OPT_INT},
392 {"SO_SNDTIMEO", SOL_SOCKET, SO_SNDTIMEO, 0, OPT_INT},
395 {"SO_RCVTIMEO", SOL_SOCKET, SO_RCVTIMEO, 0, OPT_INT},
398 {"TCP_FASTACK", IPPROTO_TCP, TCP_FASTACK, 0, OPT_INT},
401 {"TCP_QUICKACK", IPPROTO_TCP, TCP_QUICKACK, 0, OPT_BOOL},
405 /****************************************************************************
406 Print socket options.
407 ****************************************************************************/
409 static void print_socket_options(int s)
413 const smb_socket_option *p = &socket_options[0];
415 /* wrapped in if statement to prevent streams
416 * leak in SCO Openserver 5.0 */
417 /* reported on samba-technical --jerry */
418 if ( DEBUGLEVEL >= 5 ) {
419 DEBUG(5,("Socket options:\n"));
420 for (; p->name != NULL; p++) {
421 if (getsockopt(s, p->level, p->option,
422 (void *)&value, &vlen) == -1) {
423 DEBUGADD(5,("\tCould not test socket option %s.\n",
426 DEBUGADD(5,("\t%s = %d\n",
433 /****************************************************************************
434 Set user socket options.
435 ****************************************************************************/
437 void set_socket_options(int fd, const char *options)
439 TALLOC_CTX *ctx = talloc_stackframe();
442 while (next_token_talloc(ctx, &options, &tok," \t,")) {
446 bool got_value = false;
448 if ((p = strchr_m(tok,'='))) {
454 for (i=0;socket_options[i].name;i++)
455 if (strequal(socket_options[i].name,tok))
458 if (!socket_options[i].name) {
459 DEBUG(0,("Unknown socket option %s\n",tok));
463 switch (socket_options[i].opttype) {
466 ret = setsockopt(fd,socket_options[i].level,
467 socket_options[i].option,
468 (char *)&value,sizeof(int));
473 DEBUG(0,("syntax error - %s "
474 "does not take a value\n",tok));
477 int on = socket_options[i].value;
478 ret = setsockopt(fd,socket_options[i].level,
479 socket_options[i].option,
480 (char *)&on,sizeof(int));
486 /* be aware that some systems like Solaris return
487 * EINVAL to a setsockopt() call when the client
488 * sent a RST previously - no need to worry */
489 DEBUG(2,("Failed to set socket option %s (Error %s)\n",
490 tok, strerror(errno) ));
495 print_socket_options(fd);
498 /****************************************************************************
500 ****************************************************************************/
502 ssize_t read_udp_v4_socket(int fd,
505 struct sockaddr_storage *psa)
508 socklen_t socklen = sizeof(*psa);
509 struct sockaddr_in *si = (struct sockaddr_in *)psa;
511 memset((char *)psa,'\0',socklen);
513 ret = (ssize_t)sys_recvfrom(fd,buf,len,0,
514 (struct sockaddr *)psa,&socklen);
516 /* Don't print a low debug error for a non-blocking socket. */
517 if (errno == EAGAIN) {
518 DEBUG(10,("read_udp_v4_socket: returned EAGAIN\n"));
520 DEBUG(2,("read_udp_v4_socket: failed. errno=%s\n",
526 if (psa->ss_family != AF_INET) {
527 DEBUG(2,("read_udp_v4_socket: invalid address family %d "
528 "(not IPv4)\n", (int)psa->ss_family));
532 DEBUG(10,("read_udp_v4_socket: ip %s port %d read: %lu\n",
533 inet_ntoa(si->sin_addr),
535 (unsigned long)ret));
540 /****************************************************************************
541 Read data from a socket with a timout in msec.
542 mincount = if timeout, minimum to read before returning
543 maxcount = number to be read.
544 time_out = timeout in milliseconds
545 ****************************************************************************/
547 NTSTATUS read_socket_with_timeout(int fd, char *buf,
548 size_t mincnt, size_t maxcnt,
549 unsigned int time_out,
556 struct timeval timeout;
557 char addr[INET6_ADDRSTRLEN];
560 /* just checking .... */
570 while (nread < mincnt) {
571 readret = sys_recv(fd, buf + nread, maxcnt - nread, 0);
574 DEBUG(5,("read_socket_with_timeout: "
575 "blocking read. EOF from client.\n"));
576 return NT_STATUS_END_OF_FILE;
581 if (fd == get_client_fd()) {
582 /* Try and give an error message
583 * saying what client failed. */
584 DEBUG(0,("read_socket_with_timeout: "
585 "client %s read error = %s.\n",
586 get_peer_addr(fd,addr,sizeof(addr)),
587 strerror(save_errno) ));
589 DEBUG(0,("read_socket_with_timeout: "
590 "read error = %s.\n",
591 strerror(save_errno) ));
593 return map_nt_error_from_unix(save_errno);
600 /* Most difficult - timeout read */
601 /* If this is ever called on a disk file and
602 mincnt is greater then the filesize then
603 system performance will suffer severely as
604 select always returns true on disk files */
606 /* Set initial timeout */
607 timeout.tv_sec = (time_t)(time_out / 1000);
608 timeout.tv_usec = (long)(1000 * (time_out % 1000));
610 for (nread=0; nread < mincnt; ) {
614 selrtn = sys_select_intr(fd+1,&fds,NULL,NULL,&timeout);
619 /* something is wrong. Maybe the socket is dead? */
620 if (fd == get_client_fd()) {
621 /* Try and give an error message saying
622 * what client failed. */
623 DEBUG(0,("read_socket_with_timeout: timeout "
624 "read for client %s. select error = %s.\n",
625 get_peer_addr(fd,addr,sizeof(addr)),
626 strerror(save_errno) ));
628 DEBUG(0,("read_socket_with_timeout: timeout "
629 "read. select error = %s.\n",
630 strerror(save_errno) ));
632 return map_nt_error_from_unix(save_errno);
635 /* Did we timeout ? */
637 DEBUG(10,("read_socket_with_timeout: timeout read. "
638 "select timed out.\n"));
639 return NT_STATUS_IO_TIMEOUT;
642 readret = sys_recv(fd, buf+nread, maxcnt-nread, 0);
645 /* we got EOF on the file descriptor */
646 DEBUG(5,("read_socket_with_timeout: timeout read. "
647 "EOF from client.\n"));
648 return NT_STATUS_END_OF_FILE;
653 /* the descriptor is probably dead */
654 if (fd == get_client_fd()) {
655 /* Try and give an error message
656 * saying what client failed. */
657 DEBUG(0,("read_socket_with_timeout: timeout "
658 "read to client %s. read error = %s.\n",
659 get_peer_addr(fd,addr,sizeof(addr)),
660 strerror(save_errno) ));
662 DEBUG(0,("read_socket_with_timeout: timeout "
663 "read. read error = %s.\n",
664 strerror(save_errno) ));
666 return map_nt_error_from_unix(errno);
673 /* Return the number we got */
680 /****************************************************************************
681 Read data from the client, reading exactly N bytes.
682 ****************************************************************************/
684 NTSTATUS read_data(int fd, char *buffer, size_t N)
686 return read_socket_with_timeout(fd, buffer, N, N, 0, NULL);
689 /****************************************************************************
690 Write all data from an iov array
691 ****************************************************************************/
693 ssize_t write_data_iov(int fd, const struct iovec *orig_iov, int iovcnt)
699 struct iovec *iov_copy, *iov;
702 for (i=0; i<iovcnt; i++) {
703 to_send += orig_iov[i].iov_len;
706 thistime = sys_writev(fd, orig_iov, iovcnt);
707 if ((thistime <= 0) || (thistime == to_send)) {
713 * We could not send everything in one call. Make a copy of iov that
714 * we can mess with. We keep a copy of the array start in iov_copy for
715 * the TALLOC_FREE, because we're going to modify iov later on,
716 * discarding elements.
719 iov_copy = (struct iovec *)TALLOC_MEMDUP(
720 talloc_tos(), orig_iov, sizeof(struct iovec) * iovcnt);
722 if (iov_copy == NULL) {
728 while (sent < to_send) {
730 * We have to discard "thistime" bytes from the beginning
731 * iov array, "thistime" contains the number of bytes sent
734 while (thistime > 0) {
735 if (thistime < iov[0].iov_len) {
737 (char *)iov[0].iov_base + thistime;
738 iov[0].iov_base = (void *)new_base;
739 iov[0].iov_len -= thistime;
742 thistime -= iov[0].iov_len;
747 thistime = sys_writev(fd, iov, iovcnt);
754 TALLOC_FREE(iov_copy);
758 /****************************************************************************
760 ****************************************************************************/
762 ssize_t write_data(int fd, const char *buffer, size_t N)
767 iov.iov_base = CONST_DISCARD(void *, buffer);
770 ret = write_data_iov(fd, &iov, 1);
775 if (fd == get_client_fd()) {
776 char addr[INET6_ADDRSTRLEN];
778 * Try and give an error message saying what client failed.
780 DEBUG(0, ("write_data: write failure in writing to client %s. "
781 "Error %s\n", get_peer_addr(fd,addr,sizeof(addr)),
784 DEBUG(0,("write_data: write failure. Error = %s\n",
791 /****************************************************************************
792 Send a keepalive packet (rfc1002).
793 ****************************************************************************/
795 bool send_keepalive(int client)
797 unsigned char buf[4];
799 buf[0] = SMBkeepalive;
800 buf[1] = buf[2] = buf[3] = 0;
802 return(write_data(client,(char *)buf,4) == 4);
805 /****************************************************************************
806 Read 4 bytes of a smb packet and return the smb length of the packet.
807 Store the result in the buffer.
808 This version of the function will return a length of zero on receiving
810 Timeout is in milliseconds.
811 ****************************************************************************/
813 NTSTATUS read_smb_length_return_keepalive(int fd, char *inbuf,
814 unsigned int timeout,
820 status = read_socket_with_timeout(fd, inbuf, 4, 4, timeout, NULL);
822 if (!NT_STATUS_IS_OK(status)) {
826 *len = smb_len(inbuf);
827 msg_type = CVAL(inbuf,0);
829 if (msg_type == SMBkeepalive) {
830 DEBUG(5,("Got keepalive packet\n"));
833 DEBUG(10,("got smb length of %lu\n",(unsigned long)(*len)));
838 /****************************************************************************
839 Read 4 bytes of a smb packet and return the smb length of the packet.
840 Store the result in the buffer. This version of the function will
841 never return a session keepalive (length of zero).
842 Timeout is in milliseconds.
843 ****************************************************************************/
845 NTSTATUS read_smb_length(int fd, char *inbuf, unsigned int timeout,
848 uint8_t msgtype = SMBkeepalive;
850 while (msgtype == SMBkeepalive) {
853 status = read_smb_length_return_keepalive(fd, inbuf, timeout,
855 if (!NT_STATUS_IS_OK(status)) {
859 msgtype = CVAL(inbuf, 0);
862 DEBUG(10,("read_smb_length: got smb length of %lu\n",
863 (unsigned long)len));
868 /****************************************************************************
869 Read an smb from a fd.
870 The timeout is in milliseconds.
871 This function will return on receipt of a session keepalive packet.
872 maxlen is the max number of bytes to return, not including the 4 byte
873 length. If zero it means buflen limit.
874 Doesn't check the MAC on signed packets.
875 ****************************************************************************/
877 NTSTATUS receive_smb_raw(int fd, char *buffer, size_t buflen, unsigned int timeout,
878 size_t maxlen, size_t *p_len)
883 status = read_smb_length_return_keepalive(fd,buffer,timeout,&len);
885 if (!NT_STATUS_IS_OK(status)) {
886 DEBUG(10, ("receive_smb_raw: %s!\n", nt_errstr(status)));
891 DEBUG(0,("Invalid packet length! (%lu bytes).\n",
892 (unsigned long)len));
893 return NT_STATUS_INVALID_PARAMETER;
898 len = MIN(len,maxlen);
901 status = read_socket_with_timeout(
902 fd, buffer+4, len, len, timeout, &len);
904 if (!NT_STATUS_IS_OK(status)) {
908 /* not all of samba3 properly checks for packet-termination
909 * of strings. This ensures that we don't run off into
911 SSVAL(buffer+4,len, 0);
918 /****************************************************************************
919 Open a socket of the specified type, port, and address for incoming data.
920 ****************************************************************************/
922 int open_socket_in(int type,
925 const struct sockaddr_storage *psock,
928 struct sockaddr_storage sock;
930 socklen_t slen = sizeof(struct sockaddr_in);
934 #if defined(HAVE_IPV6)
935 if (sock.ss_family == AF_INET6) {
936 ((struct sockaddr_in6 *)&sock)->sin6_port = htons(port);
937 slen = sizeof(struct sockaddr_in6);
940 if (sock.ss_family == AF_INET) {
941 ((struct sockaddr_in *)&sock)->sin_port = htons(port);
944 res = socket(sock.ss_family, type, 0 );
947 dbgtext( "open_socket_in(): socket() call failed: " );
948 dbgtext( "%s\n", strerror( errno ) );
953 /* This block sets/clears the SO_REUSEADDR and possibly SO_REUSEPORT. */
955 int val = rebind ? 1 : 0;
956 if( setsockopt(res,SOL_SOCKET,SO_REUSEADDR,
957 (char *)&val,sizeof(val)) == -1 ) {
958 if( DEBUGLVL( dlevel ) ) {
959 dbgtext( "open_socket_in(): setsockopt: " );
960 dbgtext( "SO_REUSEADDR = %s ",
961 val?"true":"false" );
962 dbgtext( "on port %d failed ", port );
963 dbgtext( "with error = %s\n", strerror(errno) );
967 if( setsockopt(res,SOL_SOCKET,SO_REUSEPORT,
968 (char *)&val,sizeof(val)) == -1 ) {
969 if( DEBUGLVL( dlevel ) ) {
970 dbgtext( "open_socket_in(): setsockopt: ");
971 dbgtext( "SO_REUSEPORT = %s ",
973 dbgtext( "on port %d failed ", port);
974 dbgtext( "with error = %s\n", strerror(errno));
977 #endif /* SO_REUSEPORT */
980 /* now we've got a socket - we need to bind it */
981 if (bind(res, (struct sockaddr *)&sock, slen) == -1 ) {
982 if( DEBUGLVL(dlevel) && (port == SMB_PORT1 ||
983 port == SMB_PORT2 || port == NMB_PORT) ) {
984 char addr[INET6_ADDRSTRLEN];
985 print_sockaddr(addr, sizeof(addr),
987 dbgtext( "bind failed on port %d ", port);
988 dbgtext( "socket_addr = %s.\n", addr);
989 dbgtext( "Error = %s\n", strerror(errno));
995 DEBUG( 10, ( "bind succeeded on port %d\n", port ) );
999 struct open_socket_out_state {
1001 struct event_context *ev;
1002 struct sockaddr_storage ss;
1008 static void open_socket_out_connected(struct tevent_req *subreq);
1010 static int open_socket_out_state_destructor(struct open_socket_out_state *s)
1018 /****************************************************************************
1019 Create an outgoing socket. timeout is in milliseconds.
1020 **************************************************************************/
1022 struct tevent_req *open_socket_out_send(TALLOC_CTX *mem_ctx,
1023 struct event_context *ev,
1024 const struct sockaddr_storage *pss,
1028 char addr[INET6_ADDRSTRLEN];
1029 struct tevent_req *result, *subreq;
1030 struct open_socket_out_state *state;
1033 result = tevent_req_create(mem_ctx, &state,
1034 struct open_socket_out_state);
1035 if (result == NULL) {
1041 state->wait_nsec = 10000;
1044 state->fd = socket(state->ss.ss_family, SOCK_STREAM, 0);
1045 if (state->fd == -1) {
1046 status = map_nt_error_from_unix(errno);
1049 talloc_set_destructor(state, open_socket_out_state_destructor);
1051 if (!tevent_req_set_endtime(
1052 result, ev, timeval_current_ofs(0, timeout*1000))) {
1056 #if defined(HAVE_IPV6)
1057 if (pss->ss_family == AF_INET6) {
1058 struct sockaddr_in6 *psa6;
1059 psa6 = (struct sockaddr_in6 *)&state->ss;
1060 psa6->sin6_port = htons(port);
1061 if (psa6->sin6_scope_id == 0
1062 && IN6_IS_ADDR_LINKLOCAL(&psa6->sin6_addr)) {
1063 setup_linklocal_scope_id(
1064 (struct sockaddr *)&(state->ss));
1066 state->salen = sizeof(struct sockaddr_in6);
1069 if (pss->ss_family == AF_INET) {
1070 struct sockaddr_in *psa;
1071 psa = (struct sockaddr_in *)&state->ss;
1072 psa->sin_port = htons(port);
1073 state->salen = sizeof(struct sockaddr_in);
1076 if (pss->ss_family == AF_UNIX) {
1077 state->salen = sizeof(struct sockaddr_un);
1080 print_sockaddr(addr, sizeof(addr), &state->ss);
1081 DEBUG(3,("Connecting to %s at port %u\n", addr, (unsigned int)port));
1083 subreq = async_connect_send(state, state->ev, state->fd,
1084 (struct sockaddr *)&state->ss,
1086 if ((subreq == NULL)
1087 || !tevent_req_set_endtime(
1089 timeval_current_ofs(0, state->wait_nsec))) {
1092 tevent_req_set_callback(subreq, open_socket_out_connected, result);
1096 tevent_req_nterror(result, status);
1097 return tevent_req_post(result, ev);
1099 TALLOC_FREE(result);
1103 static void open_socket_out_connected(struct tevent_req *subreq)
1105 struct tevent_req *req =
1106 tevent_req_callback_data(subreq, struct tevent_req);
1107 struct open_socket_out_state *state =
1108 tevent_req_data(req, struct open_socket_out_state);
1112 ret = async_connect_recv(subreq, &sys_errno);
1113 TALLOC_FREE(subreq);
1115 tevent_req_done(req);
1121 (sys_errno == ETIMEDOUT) ||
1123 (sys_errno == EINPROGRESS) ||
1124 (sys_errno == EALREADY) ||
1125 (sys_errno == EAGAIN)) {
1131 if (state->wait_nsec < 250000) {
1132 state->wait_nsec *= 1.5;
1135 subreq = async_connect_send(state, state->ev, state->fd,
1136 (struct sockaddr *)&state->ss,
1138 if (tevent_req_nomem(subreq, req)) {
1141 if (!tevent_req_set_endtime(
1143 timeval_current_ofs(0, state->wait_nsec))) {
1144 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
1147 tevent_req_set_callback(subreq, open_socket_out_connected, req);
1152 if (sys_errno == EISCONN) {
1153 tevent_req_done(req);
1159 tevent_req_nterror(req, map_nt_error_from_unix(sys_errno));
1162 NTSTATUS open_socket_out_recv(struct tevent_req *req, int *pfd)
1164 struct open_socket_out_state *state =
1165 tevent_req_data(req, struct open_socket_out_state);
1168 if (tevent_req_is_nterror(req, &status)) {
1173 return NT_STATUS_OK;
1176 NTSTATUS open_socket_out(const struct sockaddr_storage *pss, uint16_t port,
1177 int timeout, int *pfd)
1179 TALLOC_CTX *frame = talloc_stackframe();
1180 struct event_context *ev;
1181 struct tevent_req *req;
1182 NTSTATUS status = NT_STATUS_NO_MEMORY;
1184 ev = event_context_init(frame);
1189 req = open_socket_out_send(frame, ev, pss, port, timeout);
1193 if (!tevent_req_poll(req, ev)) {
1194 status = NT_STATUS_INTERNAL_ERROR;
1197 status = open_socket_out_recv(req, pfd);
1203 struct open_socket_out_defer_state {
1204 struct event_context *ev;
1205 struct sockaddr_storage ss;
1211 static void open_socket_out_defer_waited(struct tevent_req *subreq);
1212 static void open_socket_out_defer_connected(struct tevent_req *subreq);
1214 struct tevent_req *open_socket_out_defer_send(TALLOC_CTX *mem_ctx,
1215 struct event_context *ev,
1216 struct timeval wait_time,
1217 const struct sockaddr_storage *pss,
1221 struct tevent_req *req, *subreq;
1222 struct open_socket_out_defer_state *state;
1224 req = tevent_req_create(mem_ctx, &state,
1225 struct open_socket_out_defer_state);
1232 state->timeout = timeout;
1234 subreq = tevent_wakeup_send(
1236 timeval_current_ofs(wait_time.tv_sec, wait_time.tv_usec));
1237 if (subreq == NULL) {
1240 tevent_req_set_callback(subreq, open_socket_out_defer_waited, req);
1247 static void open_socket_out_defer_waited(struct tevent_req *subreq)
1249 struct tevent_req *req = tevent_req_callback_data(
1250 subreq, struct tevent_req);
1251 struct open_socket_out_defer_state *state = tevent_req_data(
1252 req, struct open_socket_out_defer_state);
1255 ret = tevent_wakeup_recv(subreq);
1256 TALLOC_FREE(subreq);
1258 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
1262 subreq = open_socket_out_send(state, state->ev, &state->ss,
1263 state->port, state->timeout);
1264 if (tevent_req_nomem(subreq, req)) {
1267 tevent_req_set_callback(subreq, open_socket_out_defer_connected, req);
1270 static void open_socket_out_defer_connected(struct tevent_req *subreq)
1272 struct tevent_req *req = tevent_req_callback_data(
1273 subreq, struct tevent_req);
1274 struct open_socket_out_defer_state *state = tevent_req_data(
1275 req, struct open_socket_out_defer_state);
1278 status = open_socket_out_recv(subreq, &state->fd);
1279 TALLOC_FREE(subreq);
1280 if (!NT_STATUS_IS_OK(status)) {
1281 tevent_req_nterror(req, status);
1284 tevent_req_done(req);
1287 NTSTATUS open_socket_out_defer_recv(struct tevent_req *req, int *pfd)
1289 struct open_socket_out_defer_state *state = tevent_req_data(
1290 req, struct open_socket_out_defer_state);
1293 if (tevent_req_is_nterror(req, &status)) {
1298 return NT_STATUS_OK;
1301 /*******************************************************************
1302 Create an outgoing TCP socket to the first addr that connects.
1304 This is for simultaneous connection attempts to port 445 and 139 of a host
1305 or for simultatneous connection attempts to multiple DCs at once. We return
1306 a socket fd of the first successful connection.
1308 @param[in] addrs list of Internet addresses and ports to connect to
1309 @param[in] num_addrs number of address/port pairs in the addrs list
1310 @param[in] timeout time after which we stop waiting for a socket connection
1311 to succeed, given in milliseconds
1312 @param[out] fd_index the entry in addrs which we successfully connected to
1313 @param[out] fd fd of the open and connected socket
1314 @return true on a successful connection, false if all connection attempts
1315 failed or we timed out
1316 *******************************************************************/
1318 bool open_any_socket_out(struct sockaddr_storage *addrs, int num_addrs,
1319 int timeout, int *fd_index, int *fd)
1321 int i, resulting_index, res;
1325 fd_set r_fds, wr_fds;
1329 int connect_loop = 10000; /* 10 milliseconds */
1331 timeout *= 1000; /* convert to microseconds */
1333 sockets = SMB_MALLOC_ARRAY(int, num_addrs);
1335 if (sockets == NULL)
1338 resulting_index = -1;
1340 for (i=0; i<num_addrs; i++)
1343 for (i=0; i<num_addrs; i++) {
1344 sockets[i] = socket(addrs[i].ss_family, SOCK_STREAM, 0);
1347 set_blocking(sockets[i], false);
1351 good_connect = false;
1353 for (i=0; i<num_addrs; i++) {
1354 const struct sockaddr * a =
1355 (const struct sockaddr *)&(addrs[i]);
1357 if (sockets[i] == -1)
1360 if (sys_connect(sockets[i], a) == 0) {
1361 /* Rather unlikely as we are non-blocking, but it
1362 * might actually happen. */
1363 resulting_index = i;
1367 if (errno == EINPROGRESS || errno == EALREADY ||
1371 errno == EAGAIN || errno == EINTR) {
1372 /* These are the error messages that something is
1374 good_connect = true;
1375 } else if (errno != 0) {
1376 /* There was a direct error */
1382 if (!good_connect) {
1383 /* All of the connect's resulted in real error conditions */
1387 /* Lets see if any of the connect attempts succeeded */
1393 for (i=0; i<num_addrs; i++) {
1394 if (sockets[i] == -1)
1396 FD_SET(sockets[i], &wr_fds);
1397 FD_SET(sockets[i], &r_fds);
1398 if (sockets[i]>maxfd)
1403 tv.tv_usec = connect_loop;
1405 res = sys_select_intr(maxfd+1, &r_fds, &wr_fds, NULL, &tv);
1413 for (i=0; i<num_addrs; i++) {
1415 if (sockets[i] == -1)
1418 /* Stevens, Network Programming says that if there's a
1419 * successful connect, the socket is only writable. Upon an
1420 * error, it's both readable and writable. */
1422 if (FD_ISSET(sockets[i], &r_fds) &&
1423 FD_ISSET(sockets[i], &wr_fds)) {
1424 /* readable and writable, so it's an error */
1430 if (!FD_ISSET(sockets[i], &r_fds) &&
1431 FD_ISSET(sockets[i], &wr_fds)) {
1432 /* Only writable, so it's connected */
1433 resulting_index = i;
1440 timeout -= connect_loop;
1443 connect_loop *= 1.5;
1444 if (connect_loop > timeout)
1445 connect_loop = timeout;
1449 for (i=0; i<num_addrs; i++) {
1450 if (i == resulting_index)
1452 if (sockets[i] >= 0)
1456 if (resulting_index >= 0) {
1457 *fd_index = resulting_index;
1458 *fd = sockets[*fd_index];
1459 set_blocking(*fd, true);
1464 return (resulting_index >= 0);
1466 /****************************************************************************
1467 Open a connected UDP socket to host on port
1468 **************************************************************************/
1470 int open_udp_socket(const char *host, int port)
1472 struct sockaddr_storage ss;
1475 if (!interpret_string_addr(&ss, host, 0)) {
1476 DEBUG(10,("open_udp_socket: can't resolve name %s\n",
1481 res = socket(ss.ss_family, SOCK_DGRAM, 0);
1486 #if defined(HAVE_IPV6)
1487 if (ss.ss_family == AF_INET6) {
1488 struct sockaddr_in6 *psa6;
1489 psa6 = (struct sockaddr_in6 *)&ss;
1490 psa6->sin6_port = htons(port);
1491 if (psa6->sin6_scope_id == 0
1492 && IN6_IS_ADDR_LINKLOCAL(&psa6->sin6_addr)) {
1493 setup_linklocal_scope_id(
1494 (struct sockaddr *)&ss);
1498 if (ss.ss_family == AF_INET) {
1499 struct sockaddr_in *psa;
1500 psa = (struct sockaddr_in *)&ss;
1501 psa->sin_port = htons(port);
1504 if (sys_connect(res,(struct sockaddr *)&ss)) {
1512 /*******************************************************************
1513 Return the IP addr of the remote end of a socket as a string.
1514 Optionally return the struct sockaddr_storage.
1515 ******************************************************************/
1517 static const char *get_peer_addr_internal(int fd,
1519 size_t addr_buf_len,
1520 struct sockaddr *pss,
1523 struct sockaddr_storage ss;
1524 socklen_t length = sizeof(ss);
1526 strlcpy(addr_buf,"0.0.0.0",addr_buf_len);
1533 pss = (struct sockaddr *)&ss;
1537 if (getpeername(fd, (struct sockaddr *)pss, plength) < 0) {
1538 DEBUG(0,("getpeername failed. Error was %s\n",
1543 print_sockaddr_len(addr_buf,
1550 /*******************************************************************
1551 Matchname - determine if host name matches IP address. Used to
1552 confirm a hostname lookup to prevent spoof attacks.
1553 ******************************************************************/
1555 static bool matchname(const char *remotehost,
1556 const struct sockaddr *pss,
1559 struct addrinfo *res = NULL;
1560 struct addrinfo *ailist = NULL;
1561 char addr_buf[INET6_ADDRSTRLEN];
1562 bool ret = interpret_string_addr_internal(&ailist,
1564 AI_ADDRCONFIG|AI_CANONNAME);
1566 if (!ret || ailist == NULL) {
1567 DEBUG(3,("matchname: getaddrinfo failed for "
1570 gai_strerror(ret) ));
1575 * Make sure that getaddrinfo() returns the "correct" host name.
1578 if (ailist->ai_canonname == NULL ||
1579 (!strequal(remotehost, ailist->ai_canonname) &&
1580 !strequal(remotehost, "localhost"))) {
1581 DEBUG(0,("matchname: host name/name mismatch: %s != %s\n",
1583 ailist->ai_canonname ?
1584 ailist->ai_canonname : "(NULL)"));
1585 freeaddrinfo(ailist);
1589 /* Look up the host address in the address list we just got. */
1590 for (res = ailist; res; res = res->ai_next) {
1591 if (!res->ai_addr) {
1594 if (sockaddr_equal((const struct sockaddr *)res->ai_addr,
1595 (struct sockaddr *)pss)) {
1596 freeaddrinfo(ailist);
1602 * The host name does not map to the original host address. Perhaps
1603 * someone has compromised a name server. More likely someone botched
1604 * it, but that could be dangerous, too.
1607 DEBUG(0,("matchname: host name/address mismatch: %s != %s\n",
1608 print_sockaddr_len(addr_buf,
1612 ailist->ai_canonname ? ailist->ai_canonname : "(NULL)"));
1615 freeaddrinfo(ailist);
1620 /*******************************************************************
1621 Deal with the singleton cache.
1622 ******************************************************************/
1624 struct name_addr_pair {
1625 struct sockaddr_storage ss;
1629 /*******************************************************************
1630 Lookup a name/addr pair. Returns memory allocated from memcache.
1631 ******************************************************************/
1633 static bool lookup_nc(struct name_addr_pair *nc)
1639 if (!memcache_lookup(
1640 NULL, SINGLETON_CACHE,
1641 data_blob_string_const_null("get_peer_name"),
1646 memcpy(&nc->ss, tmp.data, sizeof(nc->ss));
1647 nc->name = (const char *)tmp.data + sizeof(nc->ss);
1651 /*******************************************************************
1652 Save a name/addr pair.
1653 ******************************************************************/
1655 static void store_nc(const struct name_addr_pair *nc)
1658 size_t namelen = strlen(nc->name);
1660 tmp = data_blob(NULL, sizeof(nc->ss) + namelen + 1);
1664 memcpy(tmp.data, &nc->ss, sizeof(nc->ss));
1665 memcpy(tmp.data+sizeof(nc->ss), nc->name, namelen+1);
1667 memcache_add(NULL, SINGLETON_CACHE,
1668 data_blob_string_const_null("get_peer_name"),
1670 data_blob_free(&tmp);
1673 /*******************************************************************
1674 Return the DNS name of the remote end of a socket.
1675 ******************************************************************/
1677 const char *get_peer_name(int fd, bool force_lookup)
1679 struct name_addr_pair nc;
1680 char addr_buf[INET6_ADDRSTRLEN];
1681 struct sockaddr_storage ss;
1682 socklen_t length = sizeof(ss);
1685 char name_buf[MAX_DNS_NAME_LENGTH];
1686 char tmp_name[MAX_DNS_NAME_LENGTH];
1688 /* reverse lookups can be *very* expensive, and in many
1689 situations won't work because many networks don't link dhcp
1690 with dns. To avoid the delay we avoid the lookup if
1692 if (!lp_hostname_lookups() && (force_lookup == false)) {
1693 length = sizeof(nc.ss);
1694 nc.name = get_peer_addr_internal(fd, addr_buf, sizeof(addr_buf),
1695 (struct sockaddr *)&nc.ss, &length);
1698 return nc.name ? nc.name : "UNKNOWN";
1703 memset(&ss, '\0', sizeof(ss));
1704 p = get_peer_addr_internal(fd, addr_buf, sizeof(addr_buf), (struct sockaddr *)&ss, &length);
1706 /* it might be the same as the last one - save some DNS work */
1707 if (sockaddr_equal((struct sockaddr *)&ss, (struct sockaddr *)&nc.ss)) {
1708 return nc.name ? nc.name : "UNKNOWN";
1711 /* Not the same. We need to lookup. */
1716 /* Look up the remote host name. */
1717 ret = sys_getnameinfo((struct sockaddr *)&ss,
1726 DEBUG(1,("get_peer_name: getnameinfo failed "
1727 "for %s with error %s\n",
1729 gai_strerror(ret)));
1730 strlcpy(name_buf, p, sizeof(name_buf));
1732 if (!matchname(name_buf, (struct sockaddr *)&ss, length)) {
1733 DEBUG(0,("Matchname failed on %s %s\n",name_buf,p));
1734 strlcpy(name_buf,"UNKNOWN",sizeof(name_buf));
1738 /* can't pass the same source and dest strings in when you
1739 use --enable-developer or the clobber_region() call will
1742 strlcpy(tmp_name, name_buf, sizeof(tmp_name));
1743 alpha_strcpy(name_buf, tmp_name, "_-.", sizeof(name_buf));
1744 if (strstr(name_buf,"..")) {
1745 strlcpy(name_buf, "UNKNOWN", sizeof(name_buf));
1753 return nc.name ? nc.name : "UNKNOWN";
1756 /*******************************************************************
1757 Return the IP addr of the remote end of a socket as a string.
1758 ******************************************************************/
1760 const char *get_peer_addr(int fd, char *addr, size_t addr_len)
1762 return get_peer_addr_internal(fd, addr, addr_len, NULL, NULL);
1765 /*******************************************************************
1766 Create protected unix domain socket.
1768 Some unixes cannot set permissions on a ux-dom-sock, so we
1769 have to make sure that the directory contains the protection
1770 permissions instead.
1771 ******************************************************************/
1773 int create_pipe_sock(const char *socket_dir,
1774 const char *socket_name,
1777 #ifdef HAVE_UNIXSOCKET
1778 struct sockaddr_un sunaddr;
1784 old_umask = umask(0);
1786 /* Create the socket directory or reuse the existing one */
1788 if (lstat(socket_dir, &st) == -1) {
1789 if (errno == ENOENT) {
1790 /* Create directory */
1791 if (mkdir(socket_dir, dir_perms) == -1) {
1792 DEBUG(0, ("error creating socket directory "
1793 "%s: %s\n", socket_dir,
1798 DEBUG(0, ("lstat failed on socket directory %s: %s\n",
1799 socket_dir, strerror(errno)));
1803 /* Check ownership and permission on existing directory */
1804 if (!S_ISDIR(st.st_mode)) {
1805 DEBUG(0, ("socket directory %s isn't a directory\n",
1809 if ((st.st_uid != sec_initial_uid()) ||
1810 ((st.st_mode & 0777) != dir_perms)) {
1811 DEBUG(0, ("invalid permissions on socket directory "
1812 "%s\n", socket_dir));
1817 /* Create the socket file */
1819 sock = socket(AF_UNIX, SOCK_STREAM, 0);
1822 DEBUG(0, ("create_pipe_sock: socket error %s\n",
1827 if (asprintf(&path, "%s/%s", socket_dir, socket_name) == -1) {
1832 memset(&sunaddr, 0, sizeof(sunaddr));
1833 sunaddr.sun_family = AF_UNIX;
1834 strlcpy(sunaddr.sun_path, path, sizeof(sunaddr.sun_path));
1836 if (bind(sock, (struct sockaddr *)&sunaddr, sizeof(sunaddr)) == -1) {
1837 DEBUG(0, ("bind failed on pipe socket %s: %s\n", path,
1842 if (listen(sock, 5) == -1) {
1843 DEBUG(0, ("listen failed on pipe socket %s: %s\n", path,
1863 DEBUG(0, ("create_pipe_sock: No Unix sockets on this system\n"));
1865 #endif /* HAVE_UNIXSOCKET */
1868 /****************************************************************************
1869 Get my own canonical name, including domain.
1870 ****************************************************************************/
1872 const char *get_mydnsfullname(void)
1874 struct addrinfo *res = NULL;
1875 char my_hostname[HOST_NAME_MAX];
1879 if (memcache_lookup(NULL, SINGLETON_CACHE,
1880 data_blob_string_const_null("get_mydnsfullname"),
1882 SMB_ASSERT(tmp.length > 0);
1883 return (const char *)tmp.data;
1886 /* get my host name */
1887 if (gethostname(my_hostname, sizeof(my_hostname)) == -1) {
1888 DEBUG(0,("get_mydnsfullname: gethostname failed\n"));
1892 /* Ensure null termination. */
1893 my_hostname[sizeof(my_hostname)-1] = '\0';
1895 ret = interpret_string_addr_internal(&res,
1897 AI_ADDRCONFIG|AI_CANONNAME);
1899 if (!ret || res == NULL) {
1900 DEBUG(3,("get_mydnsfullname: getaddrinfo failed for "
1903 gai_strerror(ret) ));
1908 * Make sure that getaddrinfo() returns the "correct" host name.
1911 if (res->ai_canonname == NULL) {
1912 DEBUG(3,("get_mydnsfullname: failed to get "
1913 "canonical name for %s\n",
1919 /* This copies the data, so we must do a lookup
1920 * afterwards to find the value to return.
1923 memcache_add(NULL, SINGLETON_CACHE,
1924 data_blob_string_const_null("get_mydnsfullname"),
1925 data_blob_string_const_null(res->ai_canonname));
1927 if (!memcache_lookup(NULL, SINGLETON_CACHE,
1928 data_blob_string_const_null("get_mydnsfullname"),
1930 tmp = data_blob_talloc(talloc_tos(), res->ai_canonname,
1931 strlen(res->ai_canonname) + 1);
1936 return (const char *)tmp.data;
1939 /************************************************************
1941 ************************************************************/
1943 bool is_myname_or_ipaddr(const char *s)
1945 TALLOC_CTX *ctx = talloc_tos();
1946 char addr[INET6_ADDRSTRLEN];
1948 const char *dnsname;
1949 char *servername = NULL;
1955 /* Santize the string from '\\name' */
1956 name = talloc_strdup(ctx, s);
1961 servername = strrchr_m(name, '\\' );
1968 /* Optimize for the common case */
1969 if (strequal(servername, global_myname())) {
1973 /* Check for an alias */
1974 if (is_myname(servername)) {
1978 /* Check for loopback */
1979 if (strequal(servername, "127.0.0.1") ||
1980 strequal(servername, "::1")) {
1984 if (strequal(servername, "localhost")) {
1988 /* Maybe it's my dns name */
1989 dnsname = get_mydnsfullname();
1990 if (dnsname && strequal(servername, dnsname)) {
1994 /* Handle possible CNAME records - convert to an IP addr. */
1995 if (!is_ipaddress(servername)) {
1996 /* Use DNS to resolve the name, but only the first address */
1997 struct sockaddr_storage ss;
1998 if (interpret_string_addr(&ss, servername, 0)) {
1999 print_sockaddr(addr,
2006 /* Maybe its an IP address? */
2007 if (is_ipaddress(servername)) {
2008 struct sockaddr_storage ss;
2009 struct iface_struct *nics;
2012 if (!interpret_string_addr(&ss, servername, AI_NUMERICHOST)) {
2016 if (ismyaddr((struct sockaddr *)&ss)) {
2020 if (is_zero_addr((struct sockaddr *)&ss) ||
2021 is_loopback_addr((struct sockaddr *)&ss)) {
2025 n = get_interfaces(talloc_tos(), &nics);
2026 for (i=0; i<n; i++) {
2027 if (sockaddr_equal((struct sockaddr *)&nics[i].ip, (struct sockaddr *)&ss)) {
2039 struct getaddrinfo_state {
2041 const char *service;
2042 const struct addrinfo *hints;
2043 struct addrinfo *res;
2047 static void getaddrinfo_do(void *private_data);
2048 static void getaddrinfo_done(struct tevent_req *subreq);
2050 struct tevent_req *getaddrinfo_send(TALLOC_CTX *mem_ctx,
2051 struct tevent_context *ev,
2052 struct fncall_context *ctx,
2054 const char *service,
2055 const struct addrinfo *hints)
2057 struct tevent_req *req, *subreq;
2058 struct getaddrinfo_state *state;
2060 req = tevent_req_create(mem_ctx, &state, struct getaddrinfo_state);
2066 state->service = service;
2067 state->hints = hints;
2069 subreq = fncall_send(state, ev, ctx, getaddrinfo_do, state);
2070 if (tevent_req_nomem(subreq, req)) {
2071 return tevent_req_post(req, ev);
2073 tevent_req_set_callback(subreq, getaddrinfo_done, req);
2077 static void getaddrinfo_do(void *private_data)
2079 struct getaddrinfo_state *state =
2080 (struct getaddrinfo_state *)private_data;
2082 state->ret = getaddrinfo(state->node, state->service, state->hints,
2086 static void getaddrinfo_done(struct tevent_req *subreq)
2088 struct tevent_req *req = tevent_req_callback_data(
2089 subreq, struct tevent_req);
2092 ret = fncall_recv(subreq, &err);
2093 TALLOC_FREE(subreq);
2095 tevent_req_error(req, err);
2098 tevent_req_done(req);
2101 int getaddrinfo_recv(struct tevent_req *req, struct addrinfo **res)
2103 struct getaddrinfo_state *state = tevent_req_data(
2104 req, struct getaddrinfo_state);
2107 if (tevent_req_is_unix_error(req, &err)) {
2115 if (state->ret == 0) {