s3:libsmb: convert nb_trans_send/recv internals to tdgram
authorStefan Metzmacher <metze@samba.org>
Thu, 21 May 2015 02:43:27 +0000 (04:43 +0200)
committerStefan Metzmacher <metze@samba.org>
Fri, 12 Jun 2015 15:08:17 +0000 (17:08 +0200)
This simplifies/fixes the cleanup, because we need to remove any
tevent_fd object before closing the socket fd.

BUG: https://bugzilla.samba.org/show_bug.cgi?id=11316

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Volker Lendecke <vl@samba.org>
source3/libsmb/namequery.c

index d44b04376c0ed90e62b3dcc9b4d1bf1690c7659f..e900934cee7c8a13240a51d7caf1fcd0c329710d 100644 (file)
@@ -24,6 +24,7 @@
 #include "../lib/addns/dnsquery.h"
 #include "../libcli/netlogon/netlogon.h"
 #include "lib/async_req/async_sock.h"
+#include "lib/tsocket/tsocket.h"
 #include "libsmb/nmblib.h"
 #include "../libcli/nbt/libnbt.h"
 
@@ -294,11 +295,10 @@ struct sock_packet_read_state {
        struct nb_packet_reader *reader;
        struct tevent_req *reader_req;
 
-       int sock;
+       struct tdgram_context *sock;
        struct tevent_req *socket_req;
-       uint8_t buf[1024];
-       struct sockaddr_storage addr;
-       socklen_t addr_len;
+       uint8_t *buf;
+       struct tsocket_address *addr;
 
        bool (*validator)(struct packet_struct *p,
                          void *private_data);
@@ -314,7 +314,7 @@ static void sock_packet_read_got_socket(struct tevent_req *subreq);
 static struct tevent_req *sock_packet_read_send(
        TALLOC_CTX *mem_ctx,
        struct tevent_context *ev,
-       int sock, /* dgram socket */
+       struct tdgram_context *sock,
        struct nb_packet_reader *reader,
        enum packet_type type,
        int trn_id,
@@ -347,10 +347,7 @@ static struct tevent_req *sock_packet_read_send(
                        state->reader_req, sock_packet_read_got_packet, req);
        }
 
-       state->addr_len = sizeof(state->addr);
-       state->socket_req = recvfrom_send(state, ev, sock,
-                                         state->buf, sizeof(state->buf), 0,
-                                         &state->addr, &state->addr_len);
+       state->socket_req = tdgram_recvfrom_send(state, ev, state->sock);
        if (tevent_req_nomem(state->socket_req, req)) {
                return tevent_req_post(req, ev);
        }
@@ -422,11 +419,17 @@ static void sock_packet_read_got_socket(struct tevent_req *subreq)
                subreq, struct tevent_req);
        struct sock_packet_read_state *state = tevent_req_data(
                req, struct sock_packet_read_state);
-       struct sockaddr_in *in_addr;
+       union {
+               struct sockaddr sa;
+               struct sockaddr_in sin;
+       } addr;
+       ssize_t ret;
        ssize_t received;
        int err;
+       bool ok;
 
-       received = recvfrom_recv(subreq, &err);
+       received = tdgram_recvfrom_recv(subreq, &err, state,
+                                       &state->buf, &state->addr);
 
        TALLOC_FREE(state->socket_req);
 
@@ -443,13 +446,20 @@ static void sock_packet_read_got_socket(struct tevent_req *subreq)
                tevent_req_nterror(req, map_nt_error_from_unix(err));
                return;
        }
-       if (state->addr.ss_family != AF_INET) {
+       ok = tsocket_address_is_inet(state->addr, "ipv4");
+       if (!ok) {
                goto retry;
        }
-       in_addr = (struct sockaddr_in *)(void *)&state->addr;
+       ret = tsocket_address_bsd_sockaddr(state->addr,
+                                          &addr.sa,
+                                          sizeof(addr.sin));
+       if (ret == -1) {
+               tevent_req_nterror(req, map_nt_error_from_unix(errno));
+               return;
+       }
 
        state->packet = parse_packet((char *)state->buf, received, state->type,
-                                    in_addr->sin_addr, in_addr->sin_port);
+                                    addr.sin.sin_addr, addr.sin.sin_port);
        if (state->packet == NULL) {
                DEBUG(10, ("parse_packet failed\n"));
                goto retry;
@@ -475,9 +485,10 @@ retry:
                free_packet(state->packet);
                state->packet = NULL;
        }
-       state->socket_req = recvfrom_send(state, state->ev, state->sock,
-                                         state->buf, sizeof(state->buf), 0,
-                                         &state->addr, &state->addr_len);
+       TALLOC_FREE(state->buf);
+       TALLOC_FREE(state->addr);
+
+       state->socket_req = tdgram_recvfrom_send(state, state->ev, state->sock);
        if (tevent_req_nomem(state->socket_req, req)) {
                return;
        }
@@ -502,10 +513,11 @@ static NTSTATUS sock_packet_read_recv(struct tevent_req *req,
 
 struct nb_trans_state {
        struct tevent_context *ev;
-       int sock;
+       struct tdgram_context *sock;
        struct nb_packet_reader *reader;
 
-       const struct sockaddr_storage *dst_addr;
+       struct tsocket_address *src_addr;
+       struct tsocket_address *dst_addr;
        uint8_t *buf;
        size_t buflen;
        enum packet_type type;
@@ -527,8 +539,8 @@ static void nb_trans_send_next(struct tevent_req *subreq);
 static struct tevent_req *nb_trans_send(
        TALLOC_CTX *mem_ctx,
        struct tevent_context *ev,
-       const struct sockaddr_storage *my_addr,
-       const struct sockaddr_storage *dst_addr,
+       const struct sockaddr_storage *_my_addr,
+       const struct sockaddr_storage *_dst_addr,
        bool bcast,
        uint8_t *buf, size_t buflen,
        enum packet_type type, int trn_id,
@@ -536,8 +548,15 @@ static struct tevent_req *nb_trans_send(
                          void *private_data),
        void *private_data)
 {
+       const struct sockaddr *my_addr =
+               discard_const_p(const struct sockaddr, _my_addr);
+       size_t my_addr_len = sizeof(*_my_addr);
+       const struct sockaddr *dst_addr =
+               discard_const_p(const struct sockaddr, _dst_addr);
+       size_t dst_addr_len = sizeof(*_dst_addr);
        struct tevent_req *req, *subreq;
        struct nb_trans_state *state;
+       int ret;
 
        req = tevent_req_create(mem_ctx, &state, struct nb_trans_state);
        if (req == NULL) {
@@ -545,7 +564,6 @@ static struct tevent_req *nb_trans_send(
        }
        talloc_set_destructor(state, nb_trans_state_destructor);
        state->ev = ev;
-       state->dst_addr = dst_addr;
        state->buf = buf;
        state->buflen = buflen;
        state->type = type;
@@ -553,15 +571,27 @@ static struct tevent_req *nb_trans_send(
        state->validator = validator;
        state->private_data = private_data;
 
-       state->sock = open_socket_in(SOCK_DGRAM, 0, 3, my_addr, True);
-       if (state->sock == -1) {
+       ret = tsocket_address_bsd_from_sockaddr(state,
+                                               my_addr, my_addr_len,
+                                               &state->src_addr);
+       if (ret == -1) {
                tevent_req_nterror(req, map_nt_error_from_unix(errno));
-               DEBUG(10, ("open_socket_in failed: %s\n", strerror(errno)));
                return tevent_req_post(req, ev);
        }
 
-       if (bcast) {
-               set_socket_options(state->sock,"SO_BROADCAST");
+       ret = tsocket_address_bsd_from_sockaddr(state,
+                                               dst_addr, dst_addr_len,
+                                               &state->dst_addr);
+       if (ret == -1) {
+               tevent_req_nterror(req, map_nt_error_from_unix(errno));
+               return tevent_req_post(req, ev);
+       }
+
+       ret = tdgram_inet_udp_broadcast_socket(state->src_addr, state,
+                                              &state->sock);
+       if (ret == -1) {
+               tevent_req_nterror(req, map_nt_error_from_unix(errno));
+               return tevent_req_post(req, ev);
        }
 
        subreq = nb_packet_reader_send(state, ev, type, state->trn_id, NULL);
@@ -574,10 +604,6 @@ static struct tevent_req *nb_trans_send(
 
 static int nb_trans_state_destructor(struct nb_trans_state *s)
 {
-       if (s->sock != -1) {
-               close(s->sock);
-               s->sock = -1;
-       }
        if (s->packet != NULL) {
                free_packet(s->packet);
                s->packet = NULL;
@@ -610,8 +636,10 @@ static void nb_trans_got_reader(struct tevent_req *subreq)
        }
        tevent_req_set_callback(subreq, nb_trans_done, req);
 
-       subreq = sendto_send(state, state->ev, state->sock,
-                            state->buf, state->buflen, 0, state->dst_addr);
+       subreq = tdgram_sendto_send(state, state->ev,
+                                   state->sock,
+                                   state->buf, state->buflen,
+                                   state->dst_addr);
        if (tevent_req_nomem(subreq, req)) {
                return;
        }
@@ -627,7 +655,7 @@ static void nb_trans_sent(struct tevent_req *subreq)
        ssize_t sent;
        int err;
 
-       sent = sendto_recv(subreq, &err);
+       sent = tdgram_sendto_recv(subreq, &err);
        TALLOC_FREE(subreq);
        if (sent == -1) {
                DEBUG(10, ("sendto failed: %s\n", strerror(err)));
@@ -656,8 +684,10 @@ static void nb_trans_send_next(struct tevent_req *subreq)
                tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
                return;
        }
-       subreq = sendto_send(state, state->ev, state->sock,
-                            state->buf, state->buflen, 0, state->dst_addr);
+       subreq = tdgram_sendto_send(state, state->ev,
+                                   state->sock,
+                                   state->buf, state->buflen,
+                                   state->dst_addr);
        if (tevent_req_nomem(subreq, req)) {
                return;
        }