2 Unix SMB/CIFS implementation.
4 Copyright (C) Stefan Metzmacher 2009
6 ** NOTE! The following LGPL license applies to the tsocket
7 ** library. This does NOT imply that all of Samba is released
10 This library is free software; you can redistribute it and/or
11 modify it under the terms of the GNU Lesser General Public
12 License as published by the Free Software Foundation; either
13 version 3 of the License, or (at your option) any later version.
15 This library is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 Lesser General Public License for more details.
20 You should have received a copy of the GNU Lesser General Public
21 License along with this library; if not, see <http://www.gnu.org/licenses/>.
25 #include "system/filesys.h"
26 #include "system/network.h"
28 #include "tsocket_internal.h"
29 #include "lib/util/iov_buf.h"
30 #include "lib/util/blocking.h"
31 #include "lib/util/util_net.h"
33 static int tsocket_bsd_error_from_errno(int ret
,
51 if (sys_errno
== EINTR
) {
56 if (sys_errno
== EINPROGRESS
) {
61 if (sys_errno
== EAGAIN
) {
66 /* ENOMEM is retryable on Solaris/illumos, and possibly other systems. */
67 if (sys_errno
== ENOMEM
) {
73 if (sys_errno
== EWOULDBLOCK
) {
82 static int tsocket_bsd_common_prepare_fd(int fd
, bool high_fd
)
96 /* first make a fd >= 3 */
106 for (i
=0; i
<num_fds
; i
++) {
115 result
= set_blocking(fd
, false);
120 ok
= smb_set_close_on_exec(fd
);
136 #ifdef HAVE_LINUX_RTNETLINK_H
138 * Get the amount of pending bytes from a netlink socket
140 * For some reason netlink sockets don't support querying the amount of pending
141 * data via ioctl with FIONREAD, which is what we use in tsocket_bsd_pending()
144 * We know we are on Linux as we're using netlink, which means we have a working
145 * MSG_TRUNC flag to recvmsg() as well, so we use that together with MSG_PEEK.
147 static ssize_t
tsocket_bsd_netlink_pending(int fd
)
153 iov
= (struct iovec
) {
155 .iov_len
= sizeof(buf
)
158 msg
= (struct msghdr
) {
163 return recvmsg(fd
, &msg
, MSG_PEEK
| MSG_TRUNC
);
166 static ssize_t
tsocket_bsd_netlink_pending(int fd
)
173 static ssize_t
tsocket_bsd_pending(int fd
)
179 ret
= ioctl(fd
, FIONREAD
, &value
);
185 /* this should not be reached */
198 * if no data is available check if the socket is in error state. For
199 * dgram sockets it's the way to return ICMP error messages of
200 * connected sockets to the caller.
202 ret
= getsockopt(fd
, SOL_SOCKET
, SO_ERROR
, &error
, &len
);
213 static const struct tsocket_address_ops tsocket_address_bsd_ops
;
215 int _tsocket_address_bsd_from_sockaddr(TALLOC_CTX
*mem_ctx
,
216 const struct sockaddr
*sa
,
218 struct tsocket_address
**_addr
,
219 const char *location
)
221 struct tsocket_address
*addr
;
222 struct samba_sockaddr
*bsda
= NULL
;
224 if (sa_socklen
< sizeof(sa
->sa_family
)) {
229 switch (sa
->sa_family
) {
231 if (sa_socklen
> sizeof(struct sockaddr_un
)) {
232 sa_socklen
= sizeof(struct sockaddr_un
);
236 if (sa_socklen
< sizeof(struct sockaddr_in
)) {
240 sa_socklen
= sizeof(struct sockaddr_in
);
244 if (sa_socklen
< sizeof(struct sockaddr_in6
)) {
248 sa_socklen
= sizeof(struct sockaddr_in6
);
252 errno
= EAFNOSUPPORT
;
256 if (sa_socklen
> sizeof(struct sockaddr_storage
)) {
261 addr
= tsocket_address_create(mem_ctx
,
262 &tsocket_address_bsd_ops
,
264 struct samba_sockaddr
,
273 memcpy(&bsda
->u
.ss
, sa
, sa_socklen
);
275 bsda
->sa_socklen
= sa_socklen
;
276 #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
277 bsda
->u
.sa
.sa_len
= bsda
->sa_socklen
;
284 int _tsocket_address_bsd_from_samba_sockaddr(TALLOC_CTX
*mem_ctx
,
285 const struct samba_sockaddr
*xs_addr
,
286 struct tsocket_address
**t_addr
,
287 const char *location
)
289 return _tsocket_address_bsd_from_sockaddr(mem_ctx
,
296 ssize_t
tsocket_address_bsd_sockaddr(const struct tsocket_address
*addr
,
300 struct samba_sockaddr
*bsda
= talloc_get_type(addr
->private_data
,
301 struct samba_sockaddr
);
308 if (sa_socklen
< bsda
->sa_socklen
) {
313 if (sa_socklen
> bsda
->sa_socklen
) {
314 memset(sa
, 0, sa_socklen
);
315 sa_socklen
= bsda
->sa_socklen
;
318 memcpy(sa
, &bsda
->u
.ss
, sa_socklen
);
319 #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
320 sa
->sa_len
= sa_socklen
;
325 bool tsocket_address_is_inet(const struct tsocket_address
*addr
, const char *fam
)
327 struct samba_sockaddr
*bsda
= talloc_get_type(addr
->private_data
,
328 struct samba_sockaddr
);
334 switch (bsda
->u
.sa
.sa_family
) {
336 if (strcasecmp(fam
, "ip") == 0) {
340 if (strcasecmp(fam
, "ipv4") == 0) {
347 if (strcasecmp(fam
, "ip") == 0) {
351 if (strcasecmp(fam
, "ipv6") == 0) {
362 int _tsocket_address_inet_from_strings(TALLOC_CTX
*mem_ctx
,
366 struct tsocket_address
**_addr
,
367 const char *location
)
369 struct addrinfo hints
;
370 struct addrinfo
*result
= NULL
;
376 * we use SOCKET_STREAM here to get just one result
377 * back from getaddrinfo().
379 hints
.ai_socktype
= SOCK_STREAM
;
380 hints
.ai_flags
= AI_NUMERICHOST
| AI_NUMERICSERV
;
382 if (strcasecmp(fam
, "ip") == 0) {
383 hints
.ai_family
= AF_UNSPEC
;
391 } else if (strcasecmp(fam
, "ipv4") == 0) {
392 hints
.ai_family
= AF_INET
;
397 } else if (strcasecmp(fam
, "ipv6") == 0) {
398 hints
.ai_family
= AF_INET6
;
404 errno
= EAFNOSUPPORT
;
408 snprintf(port_str
, sizeof(port_str
), "%u", port
);
410 ret
= getaddrinfo(addr
, port_str
, &hints
, &result
);
421 if (result
->ai_socktype
!= SOCK_STREAM
) {
427 ret
= _tsocket_address_bsd_from_sockaddr(mem_ctx
,
435 freeaddrinfo(result
);
440 char *tsocket_address_inet_addr_string(const struct tsocket_address
*addr
,
443 struct samba_sockaddr
*bsda
= talloc_get_type(addr
->private_data
,
444 struct samba_sockaddr
);
445 char addr_str
[INET6_ADDRSTRLEN
+1];
453 switch (bsda
->u
.sa
.sa_family
) {
455 str
= inet_ntop(bsda
->u
.in
.sin_family
,
456 &bsda
->u
.in
.sin_addr
,
457 addr_str
, sizeof(addr_str
));
461 str
= inet_ntop(bsda
->u
.in6
.sin6_family
,
462 &bsda
->u
.in6
.sin6_addr
,
463 addr_str
, sizeof(addr_str
));
475 return talloc_strdup(mem_ctx
, str
);
478 uint16_t tsocket_address_inet_port(const struct tsocket_address
*addr
)
480 struct samba_sockaddr
*bsda
= talloc_get_type(addr
->private_data
,
481 struct samba_sockaddr
);
489 switch (bsda
->u
.sa
.sa_family
) {
491 port
= ntohs(bsda
->u
.in
.sin_port
);
495 port
= ntohs(bsda
->u
.in6
.sin6_port
);
506 int tsocket_address_inet_set_port(struct tsocket_address
*addr
,
509 struct samba_sockaddr
*bsda
= talloc_get_type(addr
->private_data
,
510 struct samba_sockaddr
);
517 switch (bsda
->u
.sa
.sa_family
) {
519 bsda
->u
.in
.sin_port
= htons(port
);
523 bsda
->u
.in6
.sin6_port
= htons(port
);
534 bool tsocket_address_is_unix(const struct tsocket_address
*addr
)
536 struct samba_sockaddr
*bsda
= talloc_get_type(addr
->private_data
,
537 struct samba_sockaddr
);
543 switch (bsda
->u
.sa
.sa_family
) {
551 int _tsocket_address_unix_from_path(TALLOC_CTX
*mem_ctx
,
553 struct tsocket_address
**_addr
,
554 const char *location
)
556 struct sockaddr_un un
;
564 if (strlen(path
) > sizeof(un
.sun_path
)-1) {
565 errno
= ENAMETOOLONG
;
570 un
.sun_family
= AF_UNIX
;
571 strncpy(un
.sun_path
, path
, sizeof(un
.sun_path
)-1);
573 ret
= _tsocket_address_bsd_from_sockaddr(mem_ctx
,
574 (struct sockaddr
*)p
,
582 char *tsocket_address_unix_path(const struct tsocket_address
*addr
,
585 struct samba_sockaddr
*bsda
= talloc_get_type(addr
->private_data
,
586 struct samba_sockaddr
);
594 switch (bsda
->u
.sa
.sa_family
) {
596 str
= bsda
->u
.un
.sun_path
;
603 return talloc_strdup(mem_ctx
, str
);
606 static char *tsocket_address_bsd_string(const struct tsocket_address
*addr
,
609 struct samba_sockaddr
*bsda
= talloc_get_type(addr
->private_data
,
610 struct samba_sockaddr
);
613 const char *prefix
= NULL
;
616 switch (bsda
->u
.sa
.sa_family
) {
618 return talloc_asprintf(mem_ctx
, "unix:%s",
619 bsda
->u
.un
.sun_path
);
633 addr_str
= tsocket_address_inet_addr_string(addr
, mem_ctx
);
638 port
= tsocket_address_inet_port(addr
);
640 str
= talloc_asprintf(mem_ctx
, "%s:%s:%u",
641 prefix
, addr_str
, port
);
642 talloc_free(addr_str
);
647 static struct tsocket_address
*tsocket_address_bsd_copy(const struct tsocket_address
*addr
,
649 const char *location
)
651 struct samba_sockaddr
*bsda
= talloc_get_type(addr
->private_data
,
652 struct samba_sockaddr
);
653 struct tsocket_address
*copy
;
656 ret
= _tsocket_address_bsd_from_sockaddr(mem_ctx
,
668 static const struct tsocket_address_ops tsocket_address_bsd_ops
= {
670 .string
= tsocket_address_bsd_string
,
671 .copy
= tsocket_address_bsd_copy
,
678 struct tevent_fd
*fde
;
679 bool optimize_recvfrom
;
682 void *readable_private
;
683 void (*readable_handler
)(void *private_data
);
684 void *writeable_private
;
685 void (*writeable_handler
)(void *private_data
);
688 bool tdgram_bsd_optimize_recvfrom(struct tdgram_context
*dgram
,
691 struct tdgram_bsd
*bsds
=
692 talloc_get_type(_tdgram_context_data(dgram
),
697 /* not a bsd socket */
701 old
= bsds
->optimize_recvfrom
;
702 bsds
->optimize_recvfrom
= on
;
707 static void tdgram_bsd_fde_handler(struct tevent_context
*ev
,
708 struct tevent_fd
*fde
,
712 struct tdgram_bsd
*bsds
= talloc_get_type_abort(private_data
,
715 if (flags
& TEVENT_FD_WRITE
) {
716 bsds
->writeable_handler(bsds
->writeable_private
);
719 if (flags
& TEVENT_FD_READ
) {
720 if (!bsds
->readable_handler
) {
721 TEVENT_FD_NOT_READABLE(bsds
->fde
);
724 bsds
->readable_handler(bsds
->readable_private
);
729 static int tdgram_bsd_set_readable_handler(struct tdgram_bsd
*bsds
,
730 struct tevent_context
*ev
,
731 void (*handler
)(void *private_data
),
739 if (!bsds
->readable_handler
) {
742 bsds
->readable_handler
= NULL
;
743 bsds
->readable_private
= NULL
;
748 /* read and write must use the same tevent_context */
749 if (bsds
->event_ptr
!= ev
) {
750 if (bsds
->readable_handler
|| bsds
->writeable_handler
) {
754 bsds
->event_ptr
= NULL
;
755 TALLOC_FREE(bsds
->fde
);
758 if (tevent_fd_get_flags(bsds
->fde
) == 0) {
759 TALLOC_FREE(bsds
->fde
);
761 bsds
->fde
= tevent_add_fd(ev
, bsds
,
762 bsds
->fd
, TEVENT_FD_READ
,
763 tdgram_bsd_fde_handler
,
770 /* cache the event context we're running on */
771 bsds
->event_ptr
= ev
;
772 } else if (!bsds
->readable_handler
) {
773 TEVENT_FD_READABLE(bsds
->fde
);
776 bsds
->readable_handler
= handler
;
777 bsds
->readable_private
= private_data
;
782 static int tdgram_bsd_set_writeable_handler(struct tdgram_bsd
*bsds
,
783 struct tevent_context
*ev
,
784 void (*handler
)(void *private_data
),
792 if (!bsds
->writeable_handler
) {
795 bsds
->writeable_handler
= NULL
;
796 bsds
->writeable_private
= NULL
;
797 TEVENT_FD_NOT_WRITEABLE(bsds
->fde
);
802 /* read and write must use the same tevent_context */
803 if (bsds
->event_ptr
!= ev
) {
804 if (bsds
->readable_handler
|| bsds
->writeable_handler
) {
808 bsds
->event_ptr
= NULL
;
809 TALLOC_FREE(bsds
->fde
);
812 if (tevent_fd_get_flags(bsds
->fde
) == 0) {
813 TALLOC_FREE(bsds
->fde
);
815 bsds
->fde
= tevent_add_fd(ev
, bsds
,
816 bsds
->fd
, TEVENT_FD_WRITE
,
817 tdgram_bsd_fde_handler
,
824 /* cache the event context we're running on */
825 bsds
->event_ptr
= ev
;
826 } else if (!bsds
->writeable_handler
) {
827 TEVENT_FD_WRITEABLE(bsds
->fde
);
830 bsds
->writeable_handler
= handler
;
831 bsds
->writeable_private
= private_data
;
836 struct tdgram_bsd_recvfrom_state
{
837 struct tdgram_context
*dgram
;
841 struct tsocket_address
*src
;
844 static int tdgram_bsd_recvfrom_destructor(struct tdgram_bsd_recvfrom_state
*state
)
846 struct tdgram_bsd
*bsds
= tdgram_context_data(state
->dgram
,
849 tdgram_bsd_set_readable_handler(bsds
, NULL
, NULL
, NULL
);
854 static void tdgram_bsd_recvfrom_handler(void *private_data
);
856 static struct tevent_req
*tdgram_bsd_recvfrom_send(TALLOC_CTX
*mem_ctx
,
857 struct tevent_context
*ev
,
858 struct tdgram_context
*dgram
)
860 struct tevent_req
*req
;
861 struct tdgram_bsd_recvfrom_state
*state
;
862 struct tdgram_bsd
*bsds
= tdgram_context_data(dgram
, struct tdgram_bsd
);
865 req
= tevent_req_create(mem_ctx
, &state
,
866 struct tdgram_bsd_recvfrom_state
);
871 state
->dgram
= dgram
;
872 state
->first_try
= true;
877 talloc_set_destructor(state
, tdgram_bsd_recvfrom_destructor
);
879 if (bsds
->fd
== -1) {
880 tevent_req_error(req
, ENOTCONN
);
886 * this is a fast path, not waiting for the
887 * socket to become explicit readable gains
888 * about 10%-20% performance in benchmark tests.
890 if (bsds
->optimize_recvfrom
) {
892 * We only do the optimization on
893 * recvfrom if the caller asked for it.
895 * This is needed because in most cases
896 * we prefer to flush send buffers before
897 * receiving incoming requests.
899 tdgram_bsd_recvfrom_handler(req
);
900 if (!tevent_req_is_in_progress(req
)) {
905 ret
= tdgram_bsd_set_readable_handler(bsds
, ev
,
906 tdgram_bsd_recvfrom_handler
,
909 tevent_req_error(req
, errno
);
916 tevent_req_post(req
, ev
);
920 static void tdgram_bsd_recvfrom_handler(void *private_data
)
922 struct tevent_req
*req
= talloc_get_type_abort(private_data
,
924 struct tdgram_bsd_recvfrom_state
*state
= tevent_req_data(req
,
925 struct tdgram_bsd_recvfrom_state
);
926 struct tdgram_context
*dgram
= state
->dgram
;
927 struct tdgram_bsd
*bsds
= tdgram_context_data(dgram
, struct tdgram_bsd
);
928 struct samba_sockaddr
*bsda
= NULL
;
934 ret
= tsocket_bsd_netlink_pending(bsds
->fd
);
936 ret
= tsocket_bsd_pending(bsds
->fd
);
939 if (state
->first_try
&& ret
== 0) {
940 state
->first_try
= false;
944 state
->first_try
= false;
946 err
= tsocket_bsd_error_from_errno(ret
, errno
, &retry
);
951 if (tevent_req_error(req
, err
)) {
955 /* note that 'ret' can be 0 here */
956 state
->buf
= talloc_array(state
, uint8_t, ret
);
957 if (tevent_req_nomem(state
->buf
, req
)) {
962 state
->src
= tsocket_address_create(state
,
963 &tsocket_address_bsd_ops
,
965 struct samba_sockaddr
,
966 __location__
"bsd_recvfrom");
967 if (tevent_req_nomem(state
->src
, req
)) {
972 bsda
->sa_socklen
= sizeof(bsda
->u
.ss
);
973 #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
974 bsda
->u
.sa
.sa_len
= bsda
->sa_socklen
;
977 ret
= recvfrom(bsds
->fd
, state
->buf
, state
->len
, 0,
978 &bsda
->u
.sa
, &bsda
->sa_socklen
);
979 err
= tsocket_bsd_error_from_errno(ret
, errno
, &retry
);
984 if (tevent_req_error(req
, err
)) {
989 * Some systems (FreeBSD, see bug #7115) return too much
990 * bytes in tsocket_bsd_pending()/ioctl(fd, FIONREAD, ...),
991 * the return value includes some IP/UDP header bytes,
992 * while recvfrom() just returns the payload.
994 state
->buf
= talloc_realloc(state
, state
->buf
, uint8_t, ret
);
995 if (tevent_req_nomem(state
->buf
, req
)) {
1000 tevent_req_done(req
);
1003 static ssize_t
tdgram_bsd_recvfrom_recv(struct tevent_req
*req
,
1005 TALLOC_CTX
*mem_ctx
,
1007 struct tsocket_address
**src
)
1009 struct tdgram_bsd_recvfrom_state
*state
= tevent_req_data(req
,
1010 struct tdgram_bsd_recvfrom_state
);
1013 ret
= tsocket_simple_int_recv(req
, perrno
);
1015 *buf
= talloc_move(mem_ctx
, &state
->buf
);
1018 *src
= talloc_move(mem_ctx
, &state
->src
);
1022 tevent_req_received(req
);
1026 struct tdgram_bsd_sendto_state
{
1027 struct tdgram_context
*dgram
;
1031 const struct tsocket_address
*dst
;
1036 static int tdgram_bsd_sendto_destructor(struct tdgram_bsd_sendto_state
*state
)
1038 struct tdgram_bsd
*bsds
= tdgram_context_data(state
->dgram
,
1041 tdgram_bsd_set_writeable_handler(bsds
, NULL
, NULL
, NULL
);
1046 static void tdgram_bsd_sendto_handler(void *private_data
);
1048 static struct tevent_req
*tdgram_bsd_sendto_send(TALLOC_CTX
*mem_ctx
,
1049 struct tevent_context
*ev
,
1050 struct tdgram_context
*dgram
,
1053 const struct tsocket_address
*dst
)
1055 struct tevent_req
*req
;
1056 struct tdgram_bsd_sendto_state
*state
;
1057 struct tdgram_bsd
*bsds
= tdgram_context_data(dgram
, struct tdgram_bsd
);
1060 req
= tevent_req_create(mem_ctx
, &state
,
1061 struct tdgram_bsd_sendto_state
);
1066 state
->dgram
= dgram
;
1072 talloc_set_destructor(state
, tdgram_bsd_sendto_destructor
);
1074 if (bsds
->fd
== -1) {
1075 tevent_req_error(req
, ENOTCONN
);
1080 * this is a fast path, not waiting for the
1081 * socket to become explicit writeable gains
1082 * about 10%-20% performance in benchmark tests.
1084 tdgram_bsd_sendto_handler(req
);
1085 if (!tevent_req_is_in_progress(req
)) {
1089 ret
= tdgram_bsd_set_writeable_handler(bsds
, ev
,
1090 tdgram_bsd_sendto_handler
,
1093 tevent_req_error(req
, errno
);
1100 tevent_req_post(req
, ev
);
1104 static void tdgram_bsd_sendto_handler(void *private_data
)
1106 struct tevent_req
*req
= talloc_get_type_abort(private_data
,
1108 struct tdgram_bsd_sendto_state
*state
= tevent_req_data(req
,
1109 struct tdgram_bsd_sendto_state
);
1110 struct tdgram_context
*dgram
= state
->dgram
;
1111 struct tdgram_bsd
*bsds
= tdgram_context_data(dgram
, struct tdgram_bsd
);
1112 struct sockaddr
*sa
= NULL
;
1113 socklen_t sa_socklen
= 0;
1119 struct samba_sockaddr
*bsda
=
1120 talloc_get_type(state
->dst
->private_data
,
1121 struct samba_sockaddr
);
1124 sa_socklen
= bsda
->sa_socklen
;
1127 ret
= sendto(bsds
->fd
, state
->buf
, state
->len
, 0, sa
, sa_socklen
);
1128 err
= tsocket_bsd_error_from_errno(ret
, errno
, &retry
);
1134 if (err
== EMSGSIZE
) {
1135 /* round up in 1K increments */
1136 int bufsize
= ((state
->len
+ 1023) & (~1023));
1138 ret
= setsockopt(bsds
->fd
, SOL_SOCKET
, SO_SNDBUF
, &bufsize
,
1142 * We do the retry here, rather then via the
1143 * handler, as we only want to retry once for
1144 * this condition, so if there is a mismatch
1145 * between what setsockopt() accepts and what can
1146 * actually be sent, we do not end up in a
1150 ret
= sendto(bsds
->fd
, state
->buf
, state
->len
,
1152 err
= tsocket_bsd_error_from_errno(ret
, errno
, &retry
);
1153 if (retry
) { /* retry later */
1159 if (tevent_req_error(req
, err
)) {
1165 tevent_req_done(req
);
1168 static ssize_t
tdgram_bsd_sendto_recv(struct tevent_req
*req
, int *perrno
)
1170 struct tdgram_bsd_sendto_state
*state
= tevent_req_data(req
,
1171 struct tdgram_bsd_sendto_state
);
1174 ret
= tsocket_simple_int_recv(req
, perrno
);
1179 tevent_req_received(req
);
1183 struct tdgram_bsd_disconnect_state
{
1187 static struct tevent_req
*tdgram_bsd_disconnect_send(TALLOC_CTX
*mem_ctx
,
1188 struct tevent_context
*ev
,
1189 struct tdgram_context
*dgram
)
1191 struct tdgram_bsd
*bsds
= tdgram_context_data(dgram
, struct tdgram_bsd
);
1192 struct tevent_req
*req
;
1193 struct tdgram_bsd_disconnect_state
*state
;
1198 req
= tevent_req_create(mem_ctx
, &state
,
1199 struct tdgram_bsd_disconnect_state
);
1204 if (bsds
->fd
== -1) {
1205 tevent_req_error(req
, ENOTCONN
);
1209 TALLOC_FREE(bsds
->fde
);
1210 ret
= close(bsds
->fd
);
1212 err
= tsocket_bsd_error_from_errno(ret
, errno
, &dummy
);
1213 if (tevent_req_error(req
, err
)) {
1217 tevent_req_done(req
);
1219 tevent_req_post(req
, ev
);
1223 static int tdgram_bsd_disconnect_recv(struct tevent_req
*req
,
1228 ret
= tsocket_simple_int_recv(req
, perrno
);
1230 tevent_req_received(req
);
1234 static const struct tdgram_context_ops tdgram_bsd_ops
= {
1237 .recvfrom_send
= tdgram_bsd_recvfrom_send
,
1238 .recvfrom_recv
= tdgram_bsd_recvfrom_recv
,
1240 .sendto_send
= tdgram_bsd_sendto_send
,
1241 .sendto_recv
= tdgram_bsd_sendto_recv
,
1243 .disconnect_send
= tdgram_bsd_disconnect_send
,
1244 .disconnect_recv
= tdgram_bsd_disconnect_recv
,
1247 static int tdgram_bsd_destructor(struct tdgram_bsd
*bsds
)
1249 TALLOC_FREE(bsds
->fde
);
1250 if (bsds
->fd
!= -1) {
1257 static int tdgram_bsd_dgram_socket(const struct tsocket_address
*local
,
1258 const struct tsocket_address
*remote
,
1260 TALLOC_CTX
*mem_ctx
,
1261 struct tdgram_context
**_dgram
,
1262 const char *location
)
1264 struct samba_sockaddr
*lbsda
=
1265 talloc_get_type_abort(local
->private_data
,
1266 struct samba_sockaddr
);
1267 struct samba_sockaddr
*rbsda
= NULL
;
1268 struct tdgram_context
*dgram
;
1269 struct tdgram_bsd
*bsds
;
1272 bool do_bind
= false;
1273 bool do_reuseaddr
= false;
1274 bool do_ipv6only
= false;
1275 bool is_inet
= false;
1276 int sa_fam
= lbsda
->u
.sa
.sa_family
;
1279 rbsda
= talloc_get_type_abort(remote
->private_data
,
1280 struct samba_sockaddr
);
1283 switch (lbsda
->u
.sa
.sa_family
) {
1289 if (lbsda
->u
.un
.sun_path
[0] != 0) {
1290 do_reuseaddr
= true;
1295 if (lbsda
->u
.in
.sin_port
!= 0) {
1296 do_reuseaddr
= true;
1299 if (lbsda
->u
.in
.sin_addr
.s_addr
!= INADDR_ANY
) {
1306 if (lbsda
->u
.in6
.sin6_port
!= 0) {
1307 do_reuseaddr
= true;
1310 if (memcmp(&in6addr_any
,
1311 &lbsda
->u
.in6
.sin6_addr
,
1312 sizeof(in6addr_any
)) != 0) {
1324 if (!do_bind
&& is_inet
&& rbsda
) {
1325 sa_fam
= rbsda
->u
.sa
.sa_family
;
1328 do_ipv6only
= false;
1338 fd
= socket(sa_fam
, SOCK_DGRAM
, 0);
1343 fd
= tsocket_bsd_common_prepare_fd(fd
, true);
1348 dgram
= tdgram_context_create(mem_ctx
,
1354 int saved_errno
= errno
;
1356 errno
= saved_errno
;
1361 talloc_set_destructor(bsds
, tdgram_bsd_destructor
);
1367 ret
= setsockopt(fd
, IPPROTO_IPV6
, IPV6_V6ONLY
,
1368 (const void *)&val
, sizeof(val
));
1370 int saved_errno
= errno
;
1372 errno
= saved_errno
;
1381 ret
= setsockopt(fd
, SOL_SOCKET
, SO_BROADCAST
,
1382 (const void *)&val
, sizeof(val
));
1384 int saved_errno
= errno
;
1386 errno
= saved_errno
;
1394 ret
= setsockopt(fd
, SOL_SOCKET
, SO_REUSEADDR
,
1395 (const void *)&val
, sizeof(val
));
1397 int saved_errno
= errno
;
1399 errno
= saved_errno
;
1405 ret
= bind(fd
, &lbsda
->u
.sa
, lbsda
->sa_socklen
);
1407 int saved_errno
= errno
;
1409 errno
= saved_errno
;
1415 if (rbsda
->u
.sa
.sa_family
!= sa_fam
) {
1421 ret
= connect(fd
, &rbsda
->u
.sa
, rbsda
->sa_socklen
);
1423 int saved_errno
= errno
;
1425 errno
= saved_errno
;
1434 int _tdgram_bsd_existing_socket(TALLOC_CTX
*mem_ctx
,
1436 struct tdgram_context
**_dgram
,
1437 const char *location
)
1439 struct tdgram_context
*dgram
;
1440 struct tdgram_bsd
*bsds
;
1441 #ifdef HAVE_LINUX_RTNETLINK_H
1444 socklen_t sa_len
= sizeof(struct sockaddr
);
1447 dgram
= tdgram_context_create(mem_ctx
,
1457 talloc_set_destructor(bsds
, tdgram_bsd_destructor
);
1461 #ifdef HAVE_LINUX_RTNETLINK_H
1463 * Try to determine the protocol family and remember if it's
1464 * AF_NETLINK. We don't care if this fails.
1466 result
= getsockname(fd
, &sa
, &sa_len
);
1467 if (result
== 0 && sa
.sa_family
== AF_NETLINK
) {
1468 bsds
->netlink
= true;
1475 int _tdgram_inet_udp_socket(const struct tsocket_address
*local
,
1476 const struct tsocket_address
*remote
,
1477 TALLOC_CTX
*mem_ctx
,
1478 struct tdgram_context
**dgram
,
1479 const char *location
)
1481 struct samba_sockaddr
*lbsda
=
1482 talloc_get_type_abort(local
->private_data
,
1483 struct samba_sockaddr
);
1486 switch (lbsda
->u
.sa
.sa_family
) {
1498 ret
= tdgram_bsd_dgram_socket(local
, remote
, false,
1499 mem_ctx
, dgram
, location
);
1504 int _tdgram_inet_udp_broadcast_socket(const struct tsocket_address
*local
,
1505 TALLOC_CTX
*mem_ctx
,
1506 struct tdgram_context
**dgram
,
1507 const char *location
)
1509 struct samba_sockaddr
*lbsda
=
1510 talloc_get_type_abort(local
->private_data
,
1511 struct samba_sockaddr
);
1514 switch (lbsda
->u
.sa
.sa_family
) {
1528 ret
= tdgram_bsd_dgram_socket(local
, NULL
, true,
1529 mem_ctx
, dgram
, location
);
1534 int _tdgram_unix_socket(const struct tsocket_address
*local
,
1535 const struct tsocket_address
*remote
,
1536 TALLOC_CTX
*mem_ctx
,
1537 struct tdgram_context
**dgram
,
1538 const char *location
)
1540 struct samba_sockaddr
*lbsda
=
1541 talloc_get_type_abort(local
->private_data
,
1542 struct samba_sockaddr
);
1545 switch (lbsda
->u
.sa
.sa_family
) {
1553 ret
= tdgram_bsd_dgram_socket(local
, remote
, false,
1554 mem_ctx
, dgram
, location
);
1559 struct tstream_bsd
{
1563 struct tevent_fd
*fde
;
1564 bool optimize_readv
;
1566 void *readable_private
;
1567 void (*readable_handler
)(void *private_data
);
1568 void *writeable_private
;
1569 void (*writeable_handler
)(void *private_data
);
1572 bool tstream_bsd_optimize_readv(struct tstream_context
*stream
,
1575 struct tstream_bsd
*bsds
=
1576 talloc_get_type(_tstream_context_data(stream
),
1577 struct tstream_bsd
);
1581 /* not a bsd socket */
1585 old
= bsds
->optimize_readv
;
1586 bsds
->optimize_readv
= on
;
1591 static void tstream_bsd_fde_handler(struct tevent_context
*ev
,
1592 struct tevent_fd
*fde
,
1596 struct tstream_bsd
*bsds
= talloc_get_type_abort(private_data
,
1597 struct tstream_bsd
);
1599 if (flags
& TEVENT_FD_WRITE
) {
1600 bsds
->writeable_handler(bsds
->writeable_private
);
1603 if (flags
& TEVENT_FD_READ
) {
1604 if (!bsds
->readable_handler
) {
1605 if (bsds
->writeable_handler
) {
1606 bsds
->writeable_handler(bsds
->writeable_private
);
1609 TEVENT_FD_NOT_READABLE(bsds
->fde
);
1612 bsds
->readable_handler(bsds
->readable_private
);
1617 static int tstream_bsd_set_readable_handler(struct tstream_bsd
*bsds
,
1618 struct tevent_context
*ev
,
1619 void (*handler
)(void *private_data
),
1627 if (!bsds
->readable_handler
) {
1630 bsds
->readable_handler
= NULL
;
1631 bsds
->readable_private
= NULL
;
1636 /* read and write must use the same tevent_context */
1637 if (bsds
->event_ptr
!= ev
) {
1638 if (bsds
->readable_handler
|| bsds
->writeable_handler
) {
1642 bsds
->event_ptr
= NULL
;
1643 TALLOC_FREE(bsds
->fde
);
1646 if (tevent_fd_get_flags(bsds
->fde
) == 0) {
1647 TALLOC_FREE(bsds
->fde
);
1649 bsds
->fde
= tevent_add_fd(ev
, bsds
,
1650 bsds
->fd
, TEVENT_FD_READ
,
1651 tstream_bsd_fde_handler
,
1658 /* cache the event context we're running on */
1659 bsds
->event_ptr
= ev
;
1660 } else if (!bsds
->readable_handler
) {
1661 TEVENT_FD_READABLE(bsds
->fde
);
1664 bsds
->readable_handler
= handler
;
1665 bsds
->readable_private
= private_data
;
1670 static int tstream_bsd_set_writeable_handler(struct tstream_bsd
*bsds
,
1671 struct tevent_context
*ev
,
1672 void (*handler
)(void *private_data
),
1680 if (!bsds
->writeable_handler
) {
1683 bsds
->writeable_handler
= NULL
;
1684 bsds
->writeable_private
= NULL
;
1685 TEVENT_FD_NOT_WRITEABLE(bsds
->fde
);
1690 /* read and write must use the same tevent_context */
1691 if (bsds
->event_ptr
!= ev
) {
1692 if (bsds
->readable_handler
|| bsds
->writeable_handler
) {
1696 bsds
->event_ptr
= NULL
;
1697 TALLOC_FREE(bsds
->fde
);
1700 if (tevent_fd_get_flags(bsds
->fde
) == 0) {
1701 TALLOC_FREE(bsds
->fde
);
1703 bsds
->fde
= tevent_add_fd(ev
, bsds
,
1705 TEVENT_FD_READ
| TEVENT_FD_WRITE
,
1706 tstream_bsd_fde_handler
,
1713 /* cache the event context we're running on */
1714 bsds
->event_ptr
= ev
;
1715 } else if (!bsds
->writeable_handler
) {
1716 uint16_t flags
= tevent_fd_get_flags(bsds
->fde
);
1717 flags
|= TEVENT_FD_READ
| TEVENT_FD_WRITE
;
1718 tevent_fd_set_flags(bsds
->fde
, flags
);
1721 bsds
->writeable_handler
= handler
;
1722 bsds
->writeable_private
= private_data
;
1727 static ssize_t
tstream_bsd_pending_bytes(struct tstream_context
*stream
)
1729 struct tstream_bsd
*bsds
= tstream_context_data(stream
,
1730 struct tstream_bsd
);
1733 if (bsds
->fd
== -1) {
1738 ret
= tsocket_bsd_pending(bsds
->fd
);
1743 struct tstream_bsd_readv_state
{
1744 struct tstream_context
*stream
;
1746 struct iovec
*vector
;
1752 static int tstream_bsd_readv_destructor(struct tstream_bsd_readv_state
*state
)
1754 struct tstream_bsd
*bsds
= tstream_context_data(state
->stream
,
1755 struct tstream_bsd
);
1757 tstream_bsd_set_readable_handler(bsds
, NULL
, NULL
, NULL
);
1762 static void tstream_bsd_readv_handler(void *private_data
);
1764 static struct tevent_req
*tstream_bsd_readv_send(TALLOC_CTX
*mem_ctx
,
1765 struct tevent_context
*ev
,
1766 struct tstream_context
*stream
,
1767 struct iovec
*vector
,
1770 struct tevent_req
*req
;
1771 struct tstream_bsd_readv_state
*state
;
1772 struct tstream_bsd
*bsds
= tstream_context_data(stream
, struct tstream_bsd
);
1775 req
= tevent_req_create(mem_ctx
, &state
,
1776 struct tstream_bsd_readv_state
);
1781 state
->stream
= stream
;
1782 /* we make a copy of the vector so that we can modify it */
1783 state
->vector
= talloc_array(state
, struct iovec
, count
);
1784 if (tevent_req_nomem(state
->vector
, req
)) {
1787 memcpy(state
->vector
, vector
, sizeof(struct iovec
)*count
);
1788 state
->count
= count
;
1791 talloc_set_destructor(state
, tstream_bsd_readv_destructor
);
1793 if (bsds
->fd
== -1) {
1794 tevent_req_error(req
, ENOTCONN
);
1799 * this is a fast path, not waiting for the
1800 * socket to become explicit readable gains
1801 * about 10%-20% performance in benchmark tests.
1803 if (bsds
->optimize_readv
) {
1805 * We only do the optimization on
1806 * readv if the caller asked for it.
1808 * This is needed because in most cases
1809 * we prefer to flush send buffers before
1810 * receiving incoming requests.
1812 tstream_bsd_readv_handler(req
);
1813 if (!tevent_req_is_in_progress(req
)) {
1818 ret
= tstream_bsd_set_readable_handler(bsds
, ev
,
1819 tstream_bsd_readv_handler
,
1822 tevent_req_error(req
, errno
);
1829 tevent_req_post(req
, ev
);
1833 static void tstream_bsd_readv_handler(void *private_data
)
1835 struct tevent_req
*req
= talloc_get_type_abort(private_data
,
1837 struct tstream_bsd_readv_state
*state
= tevent_req_data(req
,
1838 struct tstream_bsd_readv_state
);
1839 struct tstream_context
*stream
= state
->stream
;
1840 struct tstream_bsd
*bsds
= tstream_context_data(stream
, struct tstream_bsd
);
1846 ret
= readv(bsds
->fd
, state
->vector
, state
->count
);
1848 /* propagate end of file */
1849 tevent_req_error(req
, EPIPE
);
1852 err
= tsocket_bsd_error_from_errno(ret
, errno
, &retry
);
1857 if (tevent_req_error(req
, err
)) {
1863 _count
= state
->count
; /* tstream has size_t count, readv has int */
1864 ok
= iov_advance(&state
->vector
, &_count
, ret
);
1865 state
->count
= _count
;
1868 tevent_req_error(req
, EINVAL
);
1872 if (state
->count
> 0) {
1873 /* we have more to read */
1877 tevent_req_done(req
);
1880 static int tstream_bsd_readv_recv(struct tevent_req
*req
,
1883 struct tstream_bsd_readv_state
*state
= tevent_req_data(req
,
1884 struct tstream_bsd_readv_state
);
1887 ret
= tsocket_simple_int_recv(req
, perrno
);
1892 tevent_req_received(req
);
1896 struct tstream_bsd_writev_state
{
1897 struct tstream_context
*stream
;
1899 struct iovec
*vector
;
1905 static int tstream_bsd_writev_destructor(struct tstream_bsd_writev_state
*state
)
1907 struct tstream_bsd
*bsds
= tstream_context_data(state
->stream
,
1908 struct tstream_bsd
);
1910 tstream_bsd_set_writeable_handler(bsds
, NULL
, NULL
, NULL
);
1915 static void tstream_bsd_writev_handler(void *private_data
);
1917 static struct tevent_req
*tstream_bsd_writev_send(TALLOC_CTX
*mem_ctx
,
1918 struct tevent_context
*ev
,
1919 struct tstream_context
*stream
,
1920 const struct iovec
*vector
,
1923 struct tevent_req
*req
;
1924 struct tstream_bsd_writev_state
*state
;
1925 struct tstream_bsd
*bsds
= tstream_context_data(stream
, struct tstream_bsd
);
1928 req
= tevent_req_create(mem_ctx
, &state
,
1929 struct tstream_bsd_writev_state
);
1934 state
->stream
= stream
;
1935 /* we make a copy of the vector so that we can modify it */
1936 state
->vector
= talloc_array(state
, struct iovec
, count
);
1937 if (tevent_req_nomem(state
->vector
, req
)) {
1940 memcpy(state
->vector
, vector
, sizeof(struct iovec
)*count
);
1941 state
->count
= count
;
1944 talloc_set_destructor(state
, tstream_bsd_writev_destructor
);
1946 if (bsds
->fd
== -1) {
1947 tevent_req_error(req
, ENOTCONN
);
1952 * this is a fast path, not waiting for the
1953 * socket to become explicit writeable gains
1954 * about 10%-20% performance in benchmark tests.
1956 tstream_bsd_writev_handler(req
);
1957 if (!tevent_req_is_in_progress(req
)) {
1961 ret
= tstream_bsd_set_writeable_handler(bsds
, ev
,
1962 tstream_bsd_writev_handler
,
1965 tevent_req_error(req
, errno
);
1972 tevent_req_post(req
, ev
);
1976 static void tstream_bsd_writev_handler(void *private_data
)
1978 struct tevent_req
*req
= talloc_get_type_abort(private_data
,
1980 struct tstream_bsd_writev_state
*state
= tevent_req_data(req
,
1981 struct tstream_bsd_writev_state
);
1982 struct tstream_context
*stream
= state
->stream
;
1983 struct tstream_bsd
*bsds
= tstream_context_data(stream
, struct tstream_bsd
);
1989 ret
= writev(bsds
->fd
, state
->vector
, state
->count
);
1991 /* propagate end of file */
1992 tevent_req_error(req
, EPIPE
);
1995 err
= tsocket_bsd_error_from_errno(ret
, errno
, &retry
);
2000 if (tevent_req_error(req
, err
)) {
2006 _count
= state
->count
; /* tstream has size_t count, writev has int */
2007 ok
= iov_advance(&state
->vector
, &_count
, ret
);
2008 state
->count
= _count
;
2011 tevent_req_error(req
, EINVAL
);
2015 if (state
->count
> 0) {
2016 /* we have more to read */
2020 tevent_req_done(req
);
2023 static int tstream_bsd_writev_recv(struct tevent_req
*req
, int *perrno
)
2025 struct tstream_bsd_writev_state
*state
= tevent_req_data(req
,
2026 struct tstream_bsd_writev_state
);
2029 ret
= tsocket_simple_int_recv(req
, perrno
);
2034 tevent_req_received(req
);
2038 struct tstream_bsd_disconnect_state
{
2042 static struct tevent_req
*tstream_bsd_disconnect_send(TALLOC_CTX
*mem_ctx
,
2043 struct tevent_context
*ev
,
2044 struct tstream_context
*stream
)
2046 struct tstream_bsd
*bsds
= tstream_context_data(stream
, struct tstream_bsd
);
2047 struct tevent_req
*req
;
2048 struct tstream_bsd_disconnect_state
*state
;
2053 req
= tevent_req_create(mem_ctx
, &state
,
2054 struct tstream_bsd_disconnect_state
);
2059 if (bsds
->fd
== -1) {
2060 tevent_req_error(req
, ENOTCONN
);
2064 TALLOC_FREE(bsds
->fde
);
2065 ret
= close(bsds
->fd
);
2067 err
= tsocket_bsd_error_from_errno(ret
, errno
, &dummy
);
2068 if (tevent_req_error(req
, err
)) {
2072 tevent_req_done(req
);
2074 tevent_req_post(req
, ev
);
2078 static int tstream_bsd_disconnect_recv(struct tevent_req
*req
,
2083 ret
= tsocket_simple_int_recv(req
, perrno
);
2085 tevent_req_received(req
);
2089 static const struct tstream_context_ops tstream_bsd_ops
= {
2092 .pending_bytes
= tstream_bsd_pending_bytes
,
2094 .readv_send
= tstream_bsd_readv_send
,
2095 .readv_recv
= tstream_bsd_readv_recv
,
2097 .writev_send
= tstream_bsd_writev_send
,
2098 .writev_recv
= tstream_bsd_writev_recv
,
2100 .disconnect_send
= tstream_bsd_disconnect_send
,
2101 .disconnect_recv
= tstream_bsd_disconnect_recv
,
2104 static int tstream_bsd_destructor(struct tstream_bsd
*bsds
)
2106 TALLOC_FREE(bsds
->fde
);
2107 if (bsds
->fd
!= -1) {
2114 int _tstream_bsd_existing_socket(TALLOC_CTX
*mem_ctx
,
2116 struct tstream_context
**_stream
,
2117 const char *location
)
2119 struct tstream_context
*stream
;
2120 struct tstream_bsd
*bsds
;
2122 stream
= tstream_context_create(mem_ctx
,
2132 talloc_set_destructor(bsds
, tstream_bsd_destructor
);
2138 struct tstream_bsd_connect_state
{
2140 struct tevent_fd
*fde
;
2141 struct tstream_conext
*stream
;
2142 struct tsocket_address
*local
;
2145 static int tstream_bsd_connect_destructor(struct tstream_bsd_connect_state
*state
)
2147 TALLOC_FREE(state
->fde
);
2148 if (state
->fd
!= -1) {
2156 static void tstream_bsd_connect_fde_handler(struct tevent_context
*ev
,
2157 struct tevent_fd
*fde
,
2159 void *private_data
);
2161 static struct tevent_req
*tstream_bsd_connect_send(TALLOC_CTX
*mem_ctx
,
2162 struct tevent_context
*ev
,
2164 const struct tsocket_address
*local
,
2165 const struct tsocket_address
*remote
)
2167 struct tevent_req
*req
;
2168 struct tstream_bsd_connect_state
*state
;
2169 struct samba_sockaddr
*lbsda
=
2170 talloc_get_type_abort(local
->private_data
,
2171 struct samba_sockaddr
);
2172 struct samba_sockaddr
*lrbsda
= NULL
;
2173 struct samba_sockaddr
*rbsda
=
2174 talloc_get_type_abort(remote
->private_data
,
2175 struct samba_sockaddr
);
2177 bool do_bind
= false;
2178 bool do_reuseaddr
= false;
2179 bool do_ipv6only
= false;
2180 bool is_inet
= false;
2181 int sa_fam
= lbsda
->u
.sa
.sa_family
;
2183 req
= tevent_req_create(mem_ctx
, &state
,
2184 struct tstream_bsd_connect_state
);
2191 talloc_set_destructor(state
, tstream_bsd_connect_destructor
);
2193 /* give the wrappers a chance to report an error */
2194 if (sys_errno
!= 0) {
2195 tevent_req_error(req
, sys_errno
);
2199 switch (lbsda
->u
.sa
.sa_family
) {
2201 if (lbsda
->u
.un
.sun_path
[0] != 0) {
2202 do_reuseaddr
= true;
2207 if (lbsda
->u
.in
.sin_port
!= 0) {
2208 do_reuseaddr
= true;
2211 if (lbsda
->u
.in
.sin_addr
.s_addr
!= INADDR_ANY
) {
2218 if (lbsda
->u
.in6
.sin6_port
!= 0) {
2219 do_reuseaddr
= true;
2222 if (memcmp(&in6addr_any
,
2223 &lbsda
->u
.in6
.sin6_addr
,
2224 sizeof(in6addr_any
)) != 0) {
2232 tevent_req_error(req
, EINVAL
);
2236 if (!do_bind
&& is_inet
) {
2237 sa_fam
= rbsda
->u
.sa
.sa_family
;
2240 do_ipv6only
= false;
2251 state
->local
= tsocket_address_create(state
,
2252 &tsocket_address_bsd_ops
,
2254 struct samba_sockaddr
,
2255 __location__
"bsd_connect");
2256 if (tevent_req_nomem(state
->local
, req
)) {
2260 ZERO_STRUCTP(lrbsda
);
2261 lrbsda
->sa_socklen
= sizeof(lrbsda
->u
.ss
);
2262 #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
2263 lrbsda
->u
.sa
.sa_len
= lrbsda
->sa_socklen
;
2267 state
->fd
= socket(sa_fam
, SOCK_STREAM
, 0);
2268 if (state
->fd
== -1) {
2269 tevent_req_error(req
, errno
);
2273 state
->fd
= tsocket_bsd_common_prepare_fd(state
->fd
, true);
2274 if (state
->fd
== -1) {
2275 tevent_req_error(req
, errno
);
2283 ret
= setsockopt(state
->fd
, IPPROTO_IPV6
, IPV6_V6ONLY
,
2284 (const void *)&val
, sizeof(val
));
2286 tevent_req_error(req
, errno
);
2295 ret
= setsockopt(state
->fd
, SOL_SOCKET
, SO_REUSEADDR
,
2296 (const void *)&val
, sizeof(val
));
2298 tevent_req_error(req
, errno
);
2304 ret
= bind(state
->fd
, &lbsda
->u
.sa
, lbsda
->sa_socklen
);
2306 tevent_req_error(req
, errno
);
2311 if (rbsda
->u
.sa
.sa_family
!= sa_fam
) {
2312 tevent_req_error(req
, EINVAL
);
2316 ret
= connect(state
->fd
, &rbsda
->u
.sa
, rbsda
->sa_socklen
);
2318 if (errno
== EINPROGRESS
) {
2321 tevent_req_error(req
, errno
);
2325 if (!state
->local
) {
2326 tevent_req_done(req
);
2330 if (lrbsda
!= NULL
) {
2331 ret
= getsockname(state
->fd
,
2333 &lrbsda
->sa_socklen
);
2335 tevent_req_error(req
, errno
);
2340 tevent_req_done(req
);
2346 * Note for historic reasons TEVENT_FD_WRITE is not enough
2347 * to get notified for POLLERR or EPOLLHUP even if they
2348 * come together with POLLOUT. That means we need to
2349 * use TEVENT_FD_READ in addition until we have
2352 state
->fde
= tevent_add_fd(ev
, state
,
2354 TEVENT_FD_READ
| TEVENT_FD_WRITE
,
2355 tstream_bsd_connect_fde_handler
,
2357 if (tevent_req_nomem(state
->fde
, req
)) {
2364 tevent_req_post(req
, ev
);
2368 static void tstream_bsd_connect_fde_handler(struct tevent_context
*ev
,
2369 struct tevent_fd
*fde
,
2373 struct tevent_req
*req
= talloc_get_type_abort(private_data
,
2375 struct tstream_bsd_connect_state
*state
= tevent_req_data(req
,
2376 struct tstream_bsd_connect_state
);
2377 struct samba_sockaddr
*lrbsda
= NULL
;
2380 socklen_t len
= sizeof(error
);
2384 ret
= getsockopt(state
->fd
, SOL_SOCKET
, SO_ERROR
, &error
, &len
);
2391 err
= tsocket_bsd_error_from_errno(ret
, errno
, &retry
);
2396 if (tevent_req_error(req
, err
)) {
2400 if (!state
->local
) {
2401 tevent_req_done(req
);
2405 lrbsda
= talloc_get_type_abort(state
->local
->private_data
,
2406 struct samba_sockaddr
);
2408 ret
= getsockname(state
->fd
, &lrbsda
->u
.sa
, &lrbsda
->sa_socklen
);
2410 tevent_req_error(req
, errno
);
2414 tevent_req_done(req
);
2417 static int tstream_bsd_connect_recv(struct tevent_req
*req
,
2419 TALLOC_CTX
*mem_ctx
,
2420 struct tstream_context
**stream
,
2421 struct tsocket_address
**local
,
2422 const char *location
)
2424 struct tstream_bsd_connect_state
*state
= tevent_req_data(req
,
2425 struct tstream_bsd_connect_state
);
2428 ret
= tsocket_simple_int_recv(req
, perrno
);
2430 ret
= _tstream_bsd_existing_socket(mem_ctx
,
2438 TALLOC_FREE(state
->fde
);
2442 *local
= talloc_move(mem_ctx
, &state
->local
);
2447 tevent_req_received(req
);
2451 struct tevent_req
* tstream_inet_tcp_connect_send(TALLOC_CTX
*mem_ctx
,
2452 struct tevent_context
*ev
,
2453 const struct tsocket_address
*local
,
2454 const struct tsocket_address
*remote
)
2456 struct samba_sockaddr
*lbsda
=
2457 talloc_get_type_abort(local
->private_data
,
2458 struct samba_sockaddr
);
2459 struct tevent_req
*req
;
2462 switch (lbsda
->u
.sa
.sa_family
) {
2474 req
= tstream_bsd_connect_send(mem_ctx
, ev
, sys_errno
, local
, remote
);
2479 int _tstream_inet_tcp_connect_recv(struct tevent_req
*req
,
2481 TALLOC_CTX
*mem_ctx
,
2482 struct tstream_context
**stream
,
2483 struct tsocket_address
**local
,
2484 const char *location
)
2486 return tstream_bsd_connect_recv(req
, perrno
,
2487 mem_ctx
, stream
, local
,
2491 struct tevent_req
* tstream_unix_connect_send(TALLOC_CTX
*mem_ctx
,
2492 struct tevent_context
*ev
,
2493 const struct tsocket_address
*local
,
2494 const struct tsocket_address
*remote
)
2496 struct samba_sockaddr
*lbsda
=
2497 talloc_get_type_abort(local
->private_data
,
2498 struct samba_sockaddr
);
2499 struct tevent_req
*req
;
2502 switch (lbsda
->u
.sa
.sa_family
) {
2510 req
= tstream_bsd_connect_send(mem_ctx
, ev
, sys_errno
, local
, remote
);
2515 int _tstream_unix_connect_recv(struct tevent_req
*req
,
2517 TALLOC_CTX
*mem_ctx
,
2518 struct tstream_context
**stream
,
2519 const char *location
)
2521 return tstream_bsd_connect_recv(req
, perrno
,
2522 mem_ctx
, stream
, NULL
,
2526 int _tstream_unix_socketpair(TALLOC_CTX
*mem_ctx1
,
2527 struct tstream_context
**_stream1
,
2528 TALLOC_CTX
*mem_ctx2
,
2529 struct tstream_context
**_stream2
,
2530 const char *location
)
2536 struct tstream_context
*stream1
= NULL
;
2537 struct tstream_context
*stream2
= NULL
;
2539 ret
= socketpair(AF_UNIX
, SOCK_STREAM
, 0, fds
);
2546 fd1
= tsocket_bsd_common_prepare_fd(fd1
, true);
2548 int sys_errno
= errno
;
2554 fd2
= tsocket_bsd_common_prepare_fd(fd2
, true);
2556 int sys_errno
= errno
;
2562 ret
= _tstream_bsd_existing_socket(mem_ctx1
,
2567 int sys_errno
= errno
;
2574 ret
= _tstream_bsd_existing_socket(mem_ctx2
,
2579 int sys_errno
= errno
;
2580 talloc_free(stream1
);
2586 *_stream1
= stream1
;
2587 *_stream2
= stream2
;