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"
32 static int tsocket_bsd_error_from_errno(int ret,
50 if (sys_errno == EINTR) {
55 if (sys_errno == EINPROGRESS) {
60 if (sys_errno == EAGAIN) {
65 /* ENOMEM is retryable on Solaris/illumos, and possibly other systems. */
66 if (sys_errno == ENOMEM) {
72 if (sys_errno == EWOULDBLOCK) {
81 static int tsocket_bsd_common_prepare_fd(int fd, bool high_fd)
95 /* first make a fd >= 3 */
105 for (i=0; i<num_fds; i++) {
114 result = set_blocking(fd, false);
119 ok = smb_set_close_on_exec(fd);
135 #ifdef HAVE_LINUX_RTNETLINK_H
137 * Get the amount of pending bytes from a netlink socket
139 * For some reason netlink sockets don't support querying the amount of pending
140 * data via ioctl with FIONREAD, which is what we use in tsocket_bsd_pending()
143 * We know we are on Linux as we're using netlink, which means we have a working
144 * MSG_TRUNC flag to recvmsg() as well, so we use that together with MSG_PEEK.
146 static ssize_t tsocket_bsd_netlink_pending(int fd)
152 iov = (struct iovec) {
154 .iov_len = sizeof(buf)
157 msg = (struct msghdr) {
162 return recvmsg(fd, &msg, MSG_PEEK | MSG_TRUNC);
165 static ssize_t tsocket_bsd_netlink_pending(int fd)
172 static ssize_t tsocket_bsd_pending(int fd)
178 ret = ioctl(fd, FIONREAD, &value);
184 /* this should not be reached */
197 * if no data is available check if the socket is in error state. For
198 * dgram sockets it's the way to return ICMP error messages of
199 * connected sockets to the caller.
201 ret = getsockopt(fd, SOL_SOCKET, SO_ERROR, &error, &len);
212 static const struct tsocket_address_ops tsocket_address_bsd_ops;
214 struct tsocket_address_bsd {
215 socklen_t sa_socklen;
218 struct sockaddr_in in;
220 struct sockaddr_in6 in6;
222 struct sockaddr_un un;
223 struct sockaddr_storage ss;
227 int _tsocket_address_bsd_from_sockaddr(TALLOC_CTX *mem_ctx,
228 const struct sockaddr *sa,
230 struct tsocket_address **_addr,
231 const char *location)
233 struct tsocket_address *addr;
234 struct tsocket_address_bsd *bsda;
236 if (sa_socklen < sizeof(sa->sa_family)) {
241 switch (sa->sa_family) {
243 if (sa_socklen > sizeof(struct sockaddr_un)) {
244 sa_socklen = sizeof(struct sockaddr_un);
248 if (sa_socklen < sizeof(struct sockaddr_in)) {
252 sa_socklen = sizeof(struct sockaddr_in);
256 if (sa_socklen < sizeof(struct sockaddr_in6)) {
260 sa_socklen = sizeof(struct sockaddr_in6);
264 errno = EAFNOSUPPORT;
268 if (sa_socklen > sizeof(struct sockaddr_storage)) {
273 addr = tsocket_address_create(mem_ctx,
274 &tsocket_address_bsd_ops,
276 struct tsocket_address_bsd,
285 memcpy(&bsda->u.ss, sa, sa_socklen);
287 bsda->sa_socklen = sa_socklen;
288 #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
289 bsda->u.sa.sa_len = bsda->sa_socklen;
296 ssize_t tsocket_address_bsd_sockaddr(const struct tsocket_address *addr,
300 struct tsocket_address_bsd *bsda = talloc_get_type(addr->private_data,
301 struct tsocket_address_bsd);
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 tsocket_address_bsd *bsda = talloc_get_type(addr->private_data,
328 struct tsocket_address_bsd);
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 tsocket_address_bsd *bsda = talloc_get_type(addr->private_data,
444 struct tsocket_address_bsd);
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 tsocket_address_bsd *bsda = talloc_get_type(addr->private_data,
481 struct tsocket_address_bsd);
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 tsocket_address_bsd *bsda = talloc_get_type(addr->private_data,
510 struct tsocket_address_bsd);
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 tsocket_address_bsd *bsda = talloc_get_type(addr->private_data,
537 struct tsocket_address_bsd);
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 tsocket_address_bsd *bsda = talloc_get_type(addr->private_data,
586 struct tsocket_address_bsd);
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 tsocket_address_bsd *bsda = talloc_get_type(addr->private_data,
610 struct tsocket_address_bsd);
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 tsocket_address_bsd *bsda = talloc_get_type(addr->private_data,
652 struct tsocket_address_bsd);
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 tsocket_address_bsd *bsda;
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 tsocket_address_bsd,
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;
1120 struct tsocket_address_bsd *bsda =
1121 talloc_get_type(state->dst->private_data,
1122 struct tsocket_address_bsd);
1125 sa_socklen = bsda->sa_socklen;
1129 flags |= MSG_NOSIGNAL;
1131 ret = sendto(bsds->fd, state->buf, state->len, flags, sa, sa_socklen);
1132 err = tsocket_bsd_error_from_errno(ret, errno, &retry);
1138 if (err == EMSGSIZE) {
1139 /* round up in 1K increments */
1140 int bufsize = ((state->len + 1023) & (~1023));
1142 ret = setsockopt(bsds->fd, SOL_SOCKET, SO_SNDBUF, &bufsize,
1146 * We do the retry here, rather then via the
1147 * handler, as we only want to retry once for
1148 * this condition, so if there is a mismatch
1149 * between what setsockopt() accepts and what can
1150 * actually be sent, we do not end up in a
1154 ret = sendto(bsds->fd, state->buf, state->len,
1156 err = tsocket_bsd_error_from_errno(ret, errno, &retry);
1157 if (retry) { /* retry later */
1163 if (tevent_req_error(req, err)) {
1169 tevent_req_done(req);
1172 static ssize_t tdgram_bsd_sendto_recv(struct tevent_req *req, int *perrno)
1174 struct tdgram_bsd_sendto_state *state = tevent_req_data(req,
1175 struct tdgram_bsd_sendto_state);
1178 ret = tsocket_simple_int_recv(req, perrno);
1183 tevent_req_received(req);
1187 struct tdgram_bsd_disconnect_state {
1191 static struct tevent_req *tdgram_bsd_disconnect_send(TALLOC_CTX *mem_ctx,
1192 struct tevent_context *ev,
1193 struct tdgram_context *dgram)
1195 struct tdgram_bsd *bsds = tdgram_context_data(dgram, struct tdgram_bsd);
1196 struct tevent_req *req;
1197 struct tdgram_bsd_disconnect_state *state;
1202 req = tevent_req_create(mem_ctx, &state,
1203 struct tdgram_bsd_disconnect_state);
1208 if (bsds->fd == -1) {
1209 tevent_req_error(req, ENOTCONN);
1213 TALLOC_FREE(bsds->fde);
1214 ret = close(bsds->fd);
1216 err = tsocket_bsd_error_from_errno(ret, errno, &dummy);
1217 if (tevent_req_error(req, err)) {
1221 tevent_req_done(req);
1223 tevent_req_post(req, ev);
1227 static int tdgram_bsd_disconnect_recv(struct tevent_req *req,
1232 ret = tsocket_simple_int_recv(req, perrno);
1234 tevent_req_received(req);
1238 static const struct tdgram_context_ops tdgram_bsd_ops = {
1241 .recvfrom_send = tdgram_bsd_recvfrom_send,
1242 .recvfrom_recv = tdgram_bsd_recvfrom_recv,
1244 .sendto_send = tdgram_bsd_sendto_send,
1245 .sendto_recv = tdgram_bsd_sendto_recv,
1247 .disconnect_send = tdgram_bsd_disconnect_send,
1248 .disconnect_recv = tdgram_bsd_disconnect_recv,
1251 static int tdgram_bsd_destructor(struct tdgram_bsd *bsds)
1253 TALLOC_FREE(bsds->fde);
1254 if (bsds->fd != -1) {
1261 static int tdgram_bsd_dgram_socket(const struct tsocket_address *local,
1262 const struct tsocket_address *remote,
1264 TALLOC_CTX *mem_ctx,
1265 struct tdgram_context **_dgram,
1266 const char *location)
1268 struct tsocket_address_bsd *lbsda =
1269 talloc_get_type_abort(local->private_data,
1270 struct tsocket_address_bsd);
1271 struct tsocket_address_bsd *rbsda = NULL;
1272 struct tdgram_context *dgram;
1273 struct tdgram_bsd *bsds;
1276 bool do_bind = false;
1277 bool do_reuseaddr = false;
1278 bool do_ipv6only = false;
1279 bool is_inet = false;
1280 int sa_fam = lbsda->u.sa.sa_family;
1283 rbsda = talloc_get_type_abort(remote->private_data,
1284 struct tsocket_address_bsd);
1287 switch (lbsda->u.sa.sa_family) {
1293 if (lbsda->u.un.sun_path[0] != 0) {
1294 do_reuseaddr = true;
1299 if (lbsda->u.in.sin_port != 0) {
1300 do_reuseaddr = true;
1303 if (lbsda->u.in.sin_addr.s_addr != INADDR_ANY) {
1310 if (lbsda->u.in6.sin6_port != 0) {
1311 do_reuseaddr = true;
1314 if (memcmp(&in6addr_any,
1315 &lbsda->u.in6.sin6_addr,
1316 sizeof(in6addr_any)) != 0) {
1328 if (!do_bind && is_inet && rbsda) {
1329 sa_fam = rbsda->u.sa.sa_family;
1332 do_ipv6only = false;
1342 fd = socket(sa_fam, SOCK_DGRAM, 0);
1347 fd = tsocket_bsd_common_prepare_fd(fd, true);
1352 dgram = tdgram_context_create(mem_ctx,
1358 int saved_errno = errno;
1360 errno = saved_errno;
1365 talloc_set_destructor(bsds, tdgram_bsd_destructor);
1371 ret = setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY,
1372 (const void *)&val, sizeof(val));
1374 int saved_errno = errno;
1376 errno = saved_errno;
1385 ret = setsockopt(fd, SOL_SOCKET, SO_BROADCAST,
1386 (const void *)&val, sizeof(val));
1388 int saved_errno = errno;
1390 errno = saved_errno;
1398 ret = setsockopt(fd, SOL_SOCKET, SO_REUSEADDR,
1399 (const void *)&val, sizeof(val));
1401 int saved_errno = errno;
1403 errno = saved_errno;
1409 ret = bind(fd, &lbsda->u.sa, lbsda->sa_socklen);
1411 int saved_errno = errno;
1413 errno = saved_errno;
1419 if (rbsda->u.sa.sa_family != sa_fam) {
1425 ret = connect(fd, &rbsda->u.sa, rbsda->sa_socklen);
1427 int saved_errno = errno;
1429 errno = saved_errno;
1438 int _tdgram_bsd_existing_socket(TALLOC_CTX *mem_ctx,
1440 struct tdgram_context **_dgram,
1441 const char *location)
1443 struct tdgram_context *dgram;
1444 struct tdgram_bsd *bsds;
1445 #ifdef HAVE_LINUX_RTNETLINK_H
1448 socklen_t sa_len = sizeof(struct sockaddr);
1451 dgram = tdgram_context_create(mem_ctx,
1461 talloc_set_destructor(bsds, tdgram_bsd_destructor);
1465 #ifdef HAVE_LINUX_RTNETLINK_H
1467 * Try to determine the protocol family and remember if it's
1468 * AF_NETLINK. We don't care if this fails.
1470 result = getsockname(fd, &sa, &sa_len);
1471 if (result == 0 && sa.sa_family == AF_NETLINK) {
1472 bsds->netlink = true;
1479 int _tdgram_inet_udp_socket(const struct tsocket_address *local,
1480 const struct tsocket_address *remote,
1481 TALLOC_CTX *mem_ctx,
1482 struct tdgram_context **dgram,
1483 const char *location)
1485 struct tsocket_address_bsd *lbsda =
1486 talloc_get_type_abort(local->private_data,
1487 struct tsocket_address_bsd);
1490 switch (lbsda->u.sa.sa_family) {
1502 ret = tdgram_bsd_dgram_socket(local, remote, false,
1503 mem_ctx, dgram, location);
1508 int _tdgram_inet_udp_broadcast_socket(const struct tsocket_address *local,
1509 TALLOC_CTX *mem_ctx,
1510 struct tdgram_context **dgram,
1511 const char *location)
1513 struct tsocket_address_bsd *lbsda =
1514 talloc_get_type_abort(local->private_data,
1515 struct tsocket_address_bsd);
1518 switch (lbsda->u.sa.sa_family) {
1532 ret = tdgram_bsd_dgram_socket(local, NULL, true,
1533 mem_ctx, dgram, location);
1538 int _tdgram_unix_socket(const struct tsocket_address *local,
1539 const struct tsocket_address *remote,
1540 TALLOC_CTX *mem_ctx,
1541 struct tdgram_context **dgram,
1542 const char *location)
1544 struct tsocket_address_bsd *lbsda =
1545 talloc_get_type_abort(local->private_data,
1546 struct tsocket_address_bsd);
1549 switch (lbsda->u.sa.sa_family) {
1557 ret = tdgram_bsd_dgram_socket(local, remote, false,
1558 mem_ctx, dgram, location);
1563 struct tstream_bsd {
1567 struct tevent_fd *fde;
1568 bool optimize_readv;
1570 void *readable_private;
1571 void (*readable_handler)(void *private_data);
1572 void *writeable_private;
1573 void (*writeable_handler)(void *private_data);
1576 bool tstream_bsd_optimize_readv(struct tstream_context *stream,
1579 struct tstream_bsd *bsds =
1580 talloc_get_type(_tstream_context_data(stream),
1581 struct tstream_bsd);
1585 /* not a bsd socket */
1589 old = bsds->optimize_readv;
1590 bsds->optimize_readv = on;
1595 static void tstream_bsd_fde_handler(struct tevent_context *ev,
1596 struct tevent_fd *fde,
1600 struct tstream_bsd *bsds = talloc_get_type_abort(private_data,
1601 struct tstream_bsd);
1603 if (flags & TEVENT_FD_WRITE) {
1604 bsds->writeable_handler(bsds->writeable_private);
1607 if (flags & TEVENT_FD_READ) {
1608 if (!bsds->readable_handler) {
1609 if (bsds->writeable_handler) {
1610 bsds->writeable_handler(bsds->writeable_private);
1613 TEVENT_FD_NOT_READABLE(bsds->fde);
1616 bsds->readable_handler(bsds->readable_private);
1621 static int tstream_bsd_set_readable_handler(struct tstream_bsd *bsds,
1622 struct tevent_context *ev,
1623 void (*handler)(void *private_data),
1631 if (!bsds->readable_handler) {
1634 bsds->readable_handler = NULL;
1635 bsds->readable_private = NULL;
1640 /* read and write must use the same tevent_context */
1641 if (bsds->event_ptr != ev) {
1642 if (bsds->readable_handler || bsds->writeable_handler) {
1646 bsds->event_ptr = NULL;
1647 TALLOC_FREE(bsds->fde);
1650 if (tevent_fd_get_flags(bsds->fde) == 0) {
1651 TALLOC_FREE(bsds->fde);
1653 bsds->fde = tevent_add_fd(ev, bsds,
1654 bsds->fd, TEVENT_FD_READ,
1655 tstream_bsd_fde_handler,
1662 /* cache the event context we're running on */
1663 bsds->event_ptr = ev;
1664 } else if (!bsds->readable_handler) {
1665 TEVENT_FD_READABLE(bsds->fde);
1668 bsds->readable_handler = handler;
1669 bsds->readable_private = private_data;
1674 static int tstream_bsd_set_writeable_handler(struct tstream_bsd *bsds,
1675 struct tevent_context *ev,
1676 void (*handler)(void *private_data),
1684 if (!bsds->writeable_handler) {
1687 bsds->writeable_handler = NULL;
1688 bsds->writeable_private = NULL;
1689 TEVENT_FD_NOT_WRITEABLE(bsds->fde);
1694 /* read and write must use the same tevent_context */
1695 if (bsds->event_ptr != ev) {
1696 if (bsds->readable_handler || bsds->writeable_handler) {
1700 bsds->event_ptr = NULL;
1701 TALLOC_FREE(bsds->fde);
1704 if (tevent_fd_get_flags(bsds->fde) == 0) {
1705 TALLOC_FREE(bsds->fde);
1707 bsds->fde = tevent_add_fd(ev, bsds,
1709 TEVENT_FD_READ | TEVENT_FD_WRITE,
1710 tstream_bsd_fde_handler,
1717 /* cache the event context we're running on */
1718 bsds->event_ptr = ev;
1719 } else if (!bsds->writeable_handler) {
1720 uint16_t flags = tevent_fd_get_flags(bsds->fde);
1721 flags |= TEVENT_FD_READ | TEVENT_FD_WRITE;
1722 tevent_fd_set_flags(bsds->fde, flags);
1725 bsds->writeable_handler = handler;
1726 bsds->writeable_private = private_data;
1731 static ssize_t tstream_bsd_pending_bytes(struct tstream_context *stream)
1733 struct tstream_bsd *bsds = tstream_context_data(stream,
1734 struct tstream_bsd);
1737 if (bsds->fd == -1) {
1742 ret = tsocket_bsd_pending(bsds->fd);
1747 struct tstream_bsd_readv_state {
1748 struct tstream_context *stream;
1750 struct iovec *vector;
1756 static int tstream_bsd_readv_destructor(struct tstream_bsd_readv_state *state)
1758 struct tstream_bsd *bsds = tstream_context_data(state->stream,
1759 struct tstream_bsd);
1761 tstream_bsd_set_readable_handler(bsds, NULL, NULL, NULL);
1766 static void tstream_bsd_readv_handler(void *private_data);
1768 static struct tevent_req *tstream_bsd_readv_send(TALLOC_CTX *mem_ctx,
1769 struct tevent_context *ev,
1770 struct tstream_context *stream,
1771 struct iovec *vector,
1774 struct tevent_req *req;
1775 struct tstream_bsd_readv_state *state;
1776 struct tstream_bsd *bsds = tstream_context_data(stream, struct tstream_bsd);
1779 req = tevent_req_create(mem_ctx, &state,
1780 struct tstream_bsd_readv_state);
1785 state->stream = stream;
1786 /* we make a copy of the vector so that we can modify it */
1787 state->vector = talloc_array(state, struct iovec, count);
1788 if (tevent_req_nomem(state->vector, req)) {
1791 memcpy(state->vector, vector, sizeof(struct iovec)*count);
1792 state->count = count;
1795 talloc_set_destructor(state, tstream_bsd_readv_destructor);
1797 if (bsds->fd == -1) {
1798 tevent_req_error(req, ENOTCONN);
1803 * this is a fast path, not waiting for the
1804 * socket to become explicit readable gains
1805 * about 10%-20% performance in benchmark tests.
1807 if (bsds->optimize_readv) {
1809 * We only do the optimization on
1810 * readv if the caller asked for it.
1812 * This is needed because in most cases
1813 * we prefer to flush send buffers before
1814 * receiving incoming requests.
1816 tstream_bsd_readv_handler(req);
1817 if (!tevent_req_is_in_progress(req)) {
1822 ret = tstream_bsd_set_readable_handler(bsds, ev,
1823 tstream_bsd_readv_handler,
1826 tevent_req_error(req, errno);
1833 tevent_req_post(req, ev);
1837 static void tstream_bsd_readv_handler(void *private_data)
1839 struct tevent_req *req = talloc_get_type_abort(private_data,
1841 struct tstream_bsd_readv_state *state = tevent_req_data(req,
1842 struct tstream_bsd_readv_state);
1843 struct tstream_context *stream = state->stream;
1844 struct tstream_bsd *bsds = tstream_context_data(stream, struct tstream_bsd);
1850 ret = readv(bsds->fd, state->vector, state->count);
1852 /* propagate end of file */
1853 tevent_req_error(req, EPIPE);
1856 err = tsocket_bsd_error_from_errno(ret, errno, &retry);
1861 if (tevent_req_error(req, err)) {
1867 _count = state->count; /* tstream has size_t count, readv has int */
1868 ok = iov_advance(&state->vector, &_count, ret);
1869 state->count = _count;
1872 tevent_req_error(req, EINVAL);
1876 if (state->count > 0) {
1877 /* we have more to read */
1881 tevent_req_done(req);
1884 static int tstream_bsd_readv_recv(struct tevent_req *req,
1887 struct tstream_bsd_readv_state *state = tevent_req_data(req,
1888 struct tstream_bsd_readv_state);
1891 ret = tsocket_simple_int_recv(req, perrno);
1896 tevent_req_received(req);
1900 struct tstream_bsd_writev_state {
1901 struct tstream_context *stream;
1903 struct iovec *vector;
1909 static int tstream_bsd_writev_destructor(struct tstream_bsd_writev_state *state)
1911 struct tstream_bsd *bsds = tstream_context_data(state->stream,
1912 struct tstream_bsd);
1914 tstream_bsd_set_writeable_handler(bsds, NULL, NULL, NULL);
1919 static void tstream_bsd_writev_handler(void *private_data);
1921 static struct tevent_req *tstream_bsd_writev_send(TALLOC_CTX *mem_ctx,
1922 struct tevent_context *ev,
1923 struct tstream_context *stream,
1924 const struct iovec *vector,
1927 struct tevent_req *req;
1928 struct tstream_bsd_writev_state *state;
1929 struct tstream_bsd *bsds = tstream_context_data(stream, struct tstream_bsd);
1932 req = tevent_req_create(mem_ctx, &state,
1933 struct tstream_bsd_writev_state);
1938 state->stream = stream;
1939 /* we make a copy of the vector so that we can modify it */
1940 state->vector = talloc_array(state, struct iovec, count);
1941 if (tevent_req_nomem(state->vector, req)) {
1944 memcpy(state->vector, vector, sizeof(struct iovec)*count);
1945 state->count = count;
1948 talloc_set_destructor(state, tstream_bsd_writev_destructor);
1950 if (bsds->fd == -1) {
1951 tevent_req_error(req, ENOTCONN);
1956 * this is a fast path, not waiting for the
1957 * socket to become explicit writeable gains
1958 * about 10%-20% performance in benchmark tests.
1960 tstream_bsd_writev_handler(req);
1961 if (!tevent_req_is_in_progress(req)) {
1965 ret = tstream_bsd_set_writeable_handler(bsds, ev,
1966 tstream_bsd_writev_handler,
1969 tevent_req_error(req, errno);
1976 tevent_req_post(req, ev);
1980 static void tstream_bsd_writev_handler(void *private_data)
1982 struct tevent_req *req = talloc_get_type_abort(private_data,
1984 struct tstream_bsd_writev_state *state = tevent_req_data(req,
1985 struct tstream_bsd_writev_state);
1986 struct tstream_context *stream = state->stream;
1987 struct tstream_bsd *bsds = tstream_context_data(stream, struct tstream_bsd);
1995 msg.msg_name = NULL; /* optional address */
1996 msg.msg_namelen = 0; /* size of address */
1997 msg.msg_iov = state->vector; /* scatter/gather array */
1998 msg.msg_iovlen = state->count; /* # elements in msg_iov */
1999 msg.msg_control = NULL; /* ancillary data, see below */
2000 msg.msg_controllen = 0; /* ancillary data buffer len */
2001 msg.msg_flags = 0; /* flags on received message */
2004 flags |= MSG_NOSIGNAL;
2006 ret = sendmsg(bsds->fd, &msg, flags);
2008 /* propagate end of file */
2009 tevent_req_error(req, EPIPE);
2012 err = tsocket_bsd_error_from_errno(ret, errno, &retry);
2017 if (tevent_req_error(req, err)) {
2023 _count = state->count; /* tstream has size_t count, writev has int */
2024 ok = iov_advance(&state->vector, &_count, ret);
2025 state->count = _count;
2028 tevent_req_error(req, EINVAL);
2032 if (state->count > 0) {
2033 /* we have more to read */
2037 tevent_req_done(req);
2040 static int tstream_bsd_writev_recv(struct tevent_req *req, int *perrno)
2042 struct tstream_bsd_writev_state *state = tevent_req_data(req,
2043 struct tstream_bsd_writev_state);
2046 ret = tsocket_simple_int_recv(req, perrno);
2051 tevent_req_received(req);
2055 struct tstream_bsd_disconnect_state {
2059 static struct tevent_req *tstream_bsd_disconnect_send(TALLOC_CTX *mem_ctx,
2060 struct tevent_context *ev,
2061 struct tstream_context *stream)
2063 struct tstream_bsd *bsds = tstream_context_data(stream, struct tstream_bsd);
2064 struct tevent_req *req;
2065 struct tstream_bsd_disconnect_state *state;
2070 req = tevent_req_create(mem_ctx, &state,
2071 struct tstream_bsd_disconnect_state);
2076 if (bsds->fd == -1) {
2077 tevent_req_error(req, ENOTCONN);
2081 TALLOC_FREE(bsds->fde);
2082 ret = close(bsds->fd);
2084 err = tsocket_bsd_error_from_errno(ret, errno, &dummy);
2085 if (tevent_req_error(req, err)) {
2089 tevent_req_done(req);
2091 tevent_req_post(req, ev);
2095 static int tstream_bsd_disconnect_recv(struct tevent_req *req,
2100 ret = tsocket_simple_int_recv(req, perrno);
2102 tevent_req_received(req);
2106 static const struct tstream_context_ops tstream_bsd_ops = {
2109 .pending_bytes = tstream_bsd_pending_bytes,
2111 .readv_send = tstream_bsd_readv_send,
2112 .readv_recv = tstream_bsd_readv_recv,
2114 .writev_send = tstream_bsd_writev_send,
2115 .writev_recv = tstream_bsd_writev_recv,
2117 .disconnect_send = tstream_bsd_disconnect_send,
2118 .disconnect_recv = tstream_bsd_disconnect_recv,
2121 static int tstream_bsd_destructor(struct tstream_bsd *bsds)
2123 TALLOC_FREE(bsds->fde);
2124 if (bsds->fd != -1) {
2131 int _tstream_bsd_existing_socket(TALLOC_CTX *mem_ctx,
2133 struct tstream_context **_stream,
2134 const char *location)
2136 struct tstream_context *stream;
2137 struct tstream_bsd *bsds;
2139 stream = tstream_context_create(mem_ctx,
2149 talloc_set_destructor(bsds, tstream_bsd_destructor);
2155 struct tstream_bsd_connect_state {
2157 struct tevent_fd *fde;
2158 struct tstream_conext *stream;
2159 struct tsocket_address *local;
2162 static int tstream_bsd_connect_destructor(struct tstream_bsd_connect_state *state)
2164 TALLOC_FREE(state->fde);
2165 if (state->fd != -1) {
2173 static void tstream_bsd_connect_fde_handler(struct tevent_context *ev,
2174 struct tevent_fd *fde,
2176 void *private_data);
2178 static struct tevent_req *tstream_bsd_connect_send(TALLOC_CTX *mem_ctx,
2179 struct tevent_context *ev,
2181 const struct tsocket_address *local,
2182 const struct tsocket_address *remote)
2184 struct tevent_req *req;
2185 struct tstream_bsd_connect_state *state;
2186 struct tsocket_address_bsd *lbsda =
2187 talloc_get_type_abort(local->private_data,
2188 struct tsocket_address_bsd);
2189 struct tsocket_address_bsd *lrbsda = NULL;
2190 struct tsocket_address_bsd *rbsda =
2191 talloc_get_type_abort(remote->private_data,
2192 struct tsocket_address_bsd);
2194 bool do_bind = false;
2195 bool do_reuseaddr = false;
2196 bool do_ipv6only = false;
2197 bool is_inet = false;
2198 int sa_fam = lbsda->u.sa.sa_family;
2200 req = tevent_req_create(mem_ctx, &state,
2201 struct tstream_bsd_connect_state);
2208 talloc_set_destructor(state, tstream_bsd_connect_destructor);
2210 /* give the wrappers a chance to report an error */
2211 if (sys_errno != 0) {
2212 tevent_req_error(req, sys_errno);
2216 switch (lbsda->u.sa.sa_family) {
2218 if (lbsda->u.un.sun_path[0] != 0) {
2219 do_reuseaddr = true;
2224 if (lbsda->u.in.sin_port != 0) {
2225 do_reuseaddr = true;
2228 if (lbsda->u.in.sin_addr.s_addr != INADDR_ANY) {
2235 if (lbsda->u.in6.sin6_port != 0) {
2236 do_reuseaddr = true;
2239 if (memcmp(&in6addr_any,
2240 &lbsda->u.in6.sin6_addr,
2241 sizeof(in6addr_any)) != 0) {
2249 tevent_req_error(req, EINVAL);
2253 if (!do_bind && is_inet) {
2254 sa_fam = rbsda->u.sa.sa_family;
2257 do_ipv6only = false;
2268 state->local = tsocket_address_create(state,
2269 &tsocket_address_bsd_ops,
2271 struct tsocket_address_bsd,
2272 __location__ "bsd_connect");
2273 if (tevent_req_nomem(state->local, req)) {
2277 ZERO_STRUCTP(lrbsda);
2278 lrbsda->sa_socklen = sizeof(lrbsda->u.ss);
2279 #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
2280 lrbsda->u.sa.sa_len = lrbsda->sa_socklen;
2284 state->fd = socket(sa_fam, SOCK_STREAM, 0);
2285 if (state->fd == -1) {
2286 tevent_req_error(req, errno);
2290 state->fd = tsocket_bsd_common_prepare_fd(state->fd, true);
2291 if (state->fd == -1) {
2292 tevent_req_error(req, errno);
2300 ret = setsockopt(state->fd, IPPROTO_IPV6, IPV6_V6ONLY,
2301 (const void *)&val, sizeof(val));
2303 tevent_req_error(req, errno);
2312 ret = setsockopt(state->fd, SOL_SOCKET, SO_REUSEADDR,
2313 (const void *)&val, sizeof(val));
2315 tevent_req_error(req, errno);
2321 ret = bind(state->fd, &lbsda->u.sa, lbsda->sa_socklen);
2323 tevent_req_error(req, errno);
2328 if (rbsda->u.sa.sa_family != sa_fam) {
2329 tevent_req_error(req, EINVAL);
2333 ret = connect(state->fd, &rbsda->u.sa, rbsda->sa_socklen);
2335 if (errno == EINPROGRESS) {
2338 tevent_req_error(req, errno);
2342 if (!state->local) {
2343 tevent_req_done(req);
2347 if (lrbsda != NULL) {
2348 ret = getsockname(state->fd,
2350 &lrbsda->sa_socklen);
2352 tevent_req_error(req, errno);
2357 tevent_req_done(req);
2361 state->fde = tevent_add_fd(ev, state,
2363 TEVENT_FD_READ | TEVENT_FD_WRITE,
2364 tstream_bsd_connect_fde_handler,
2366 if (tevent_req_nomem(state->fde, req)) {
2373 tevent_req_post(req, ev);
2377 static void tstream_bsd_connect_fde_handler(struct tevent_context *ev,
2378 struct tevent_fd *fde,
2382 struct tevent_req *req = talloc_get_type_abort(private_data,
2384 struct tstream_bsd_connect_state *state = tevent_req_data(req,
2385 struct tstream_bsd_connect_state);
2386 struct tsocket_address_bsd *lrbsda = NULL;
2389 socklen_t len = sizeof(error);
2393 ret = getsockopt(state->fd, SOL_SOCKET, SO_ERROR, &error, &len);
2400 err = tsocket_bsd_error_from_errno(ret, errno, &retry);
2405 if (tevent_req_error(req, err)) {
2409 if (!state->local) {
2410 tevent_req_done(req);
2414 lrbsda = talloc_get_type_abort(state->local->private_data,
2415 struct tsocket_address_bsd);
2417 ret = getsockname(state->fd, &lrbsda->u.sa, &lrbsda->sa_socklen);
2419 tevent_req_error(req, errno);
2423 tevent_req_done(req);
2426 static int tstream_bsd_connect_recv(struct tevent_req *req,
2428 TALLOC_CTX *mem_ctx,
2429 struct tstream_context **stream,
2430 struct tsocket_address **local,
2431 const char *location)
2433 struct tstream_bsd_connect_state *state = tevent_req_data(req,
2434 struct tstream_bsd_connect_state);
2437 ret = tsocket_simple_int_recv(req, perrno);
2439 ret = _tstream_bsd_existing_socket(mem_ctx,
2447 TALLOC_FREE(state->fde);
2451 *local = talloc_move(mem_ctx, &state->local);
2456 tevent_req_received(req);
2460 struct tevent_req * tstream_inet_tcp_connect_send(TALLOC_CTX *mem_ctx,
2461 struct tevent_context *ev,
2462 const struct tsocket_address *local,
2463 const struct tsocket_address *remote)
2465 struct tsocket_address_bsd *lbsda =
2466 talloc_get_type_abort(local->private_data,
2467 struct tsocket_address_bsd);
2468 struct tevent_req *req;
2471 switch (lbsda->u.sa.sa_family) {
2483 req = tstream_bsd_connect_send(mem_ctx, ev, sys_errno, local, remote);
2488 int _tstream_inet_tcp_connect_recv(struct tevent_req *req,
2490 TALLOC_CTX *mem_ctx,
2491 struct tstream_context **stream,
2492 struct tsocket_address **local,
2493 const char *location)
2495 return tstream_bsd_connect_recv(req, perrno,
2496 mem_ctx, stream, local,
2500 struct tevent_req * tstream_unix_connect_send(TALLOC_CTX *mem_ctx,
2501 struct tevent_context *ev,
2502 const struct tsocket_address *local,
2503 const struct tsocket_address *remote)
2505 struct tsocket_address_bsd *lbsda =
2506 talloc_get_type_abort(local->private_data,
2507 struct tsocket_address_bsd);
2508 struct tevent_req *req;
2511 switch (lbsda->u.sa.sa_family) {
2519 req = tstream_bsd_connect_send(mem_ctx, ev, sys_errno, local, remote);
2524 int _tstream_unix_connect_recv(struct tevent_req *req,
2526 TALLOC_CTX *mem_ctx,
2527 struct tstream_context **stream,
2528 const char *location)
2530 return tstream_bsd_connect_recv(req, perrno,
2531 mem_ctx, stream, NULL,
2535 int _tstream_unix_socketpair(TALLOC_CTX *mem_ctx1,
2536 struct tstream_context **_stream1,
2537 TALLOC_CTX *mem_ctx2,
2538 struct tstream_context **_stream2,
2539 const char *location)
2545 struct tstream_context *stream1 = NULL;
2546 struct tstream_context *stream2 = NULL;
2548 ret = socketpair(AF_UNIX, SOCK_STREAM, 0, fds);
2555 fd1 = tsocket_bsd_common_prepare_fd(fd1, true);
2557 int sys_errno = errno;
2563 fd2 = tsocket_bsd_common_prepare_fd(fd2, true);
2565 int sys_errno = errno;
2571 ret = _tstream_bsd_existing_socket(mem_ctx1,
2576 int sys_errno = errno;
2583 ret = _tstream_bsd_existing_socket(mem_ctx2,
2588 int sys_errno = errno;
2589 talloc_free(stream1);
2595 *_stream1 = stream1;
2596 *_stream2 = stream2;