diff options
author | Stefan Metzmacher <metze@samba.org> | 2015-05-21 04:43:27 +0200 |
---|---|---|
committer | Stefan Metzmacher <metze@samba.org> | 2015-06-12 17:08:17 +0200 |
commit | a3282911f6ceb76b2ada567e569a55af8c7ef160 (patch) | |
tree | b4de920bc75d7b0e821736d7a580ab2aee46ef62 | |
parent | ecb4d041de89441941a112ab3a724887e568117e (diff) | |
download | samba-a3282911f6ceb76b2ada567e569a55af8c7ef160.tar.gz |
s3:libsmb: convert nb_trans_send/recv internals to tdgram
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>
-rw-r--r-- | source3/libsmb/namequery.c | 102 |
1 files changed, 66 insertions, 36 deletions
diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index d44b04376c0..e900934cee7 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -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; } |