summaryrefslogtreecommitdiff
path: root/source3/libsmb/unexpected.c
diff options
context:
space:
mode:
authorStefan Metzmacher <metze@samba.org>2015-05-21 01:53:44 +0200
committerStefan Metzmacher <metze@samba.org>2015-06-12 17:08:17 +0200
commit3ecf4ec6574de9bdd5a2d55529ed81b17c74d452 (patch)
treed9045b3599c796c5a12810c95f02bd8d20ebdf2e /source3/libsmb/unexpected.c
parent9ccf8e6d36618498c4952bb1d4b74152f75ab793 (diff)
downloadsamba-3ecf4ec6574de9bdd5a2d55529ed81b17c74d452.tar.gz
s3:libsmb: convert nb_packet_client to tstream_* functions
By using the tstream abstraction we don't need to take care error handling regarding dangling tevent_fd structures. 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>
Diffstat (limited to 'source3/libsmb/unexpected.c')
-rw-r--r--source3/libsmb/unexpected.c118
1 files changed, 67 insertions, 51 deletions
diff --git a/source3/libsmb/unexpected.c b/source3/libsmb/unexpected.c
index 40c09c38d75..5d494696bf4 100644
--- a/source3/libsmb/unexpected.c
+++ b/source3/libsmb/unexpected.c
@@ -20,6 +20,7 @@
#include "includes.h"
#include "../lib/util/tevent_ntstatus.h"
+#include "lib/tsocket/tsocket.h"
#include "lib/async_req/async_sock.h"
#include "libsmb/nmblib.h"
#include "lib/sys_rw.h"
@@ -55,8 +56,12 @@ struct nb_packet_client {
int trn_id;
char *mailslot_name;
- int sock;
- struct tevent_req *read_req;
+ struct {
+ uint8_t byte;
+ struct iovec iov[1];
+ } ack;
+
+ struct tstream_context *sock;
struct tevent_queue *out_queue;
};
@@ -128,6 +133,7 @@ static int nb_packet_client_destructor(struct nb_packet_client *c);
static ssize_t nb_packet_client_more(uint8_t *buf, size_t buflen,
void *private_data);
static void nb_packet_got_query(struct tevent_req *req);
+static void nb_packet_client_ack_done(struct tevent_req *req);
static void nb_packet_client_read_done(struct tevent_req *req);
static void nb_packet_server_listener(struct tevent_context *ev,
@@ -142,6 +148,7 @@ static void nb_packet_server_listener(struct tevent_context *ev,
struct sockaddr_un sunaddr;
socklen_t len;
int sock;
+ int ret;
len = sizeof(sunaddr);
@@ -158,7 +165,13 @@ static void nb_packet_server_listener(struct tevent_context *ev,
close(sock);
return;
}
- client->sock = sock;
+ ret = tstream_bsd_existing_socket(client, sock, &client->sock);
+ if (ret != 0) {
+ DEBUG(10, ("tstream_bsd_existing_socket failed\n"));
+ close(sock);
+ return;
+ }
+
client->server = server;
talloc_set_destructor(client, nb_packet_client_destructor);
@@ -170,11 +183,11 @@ static void nb_packet_server_listener(struct tevent_context *ev,
return;
}
- req = read_packet_send(client, ev, client->sock,
- sizeof(struct nb_packet_query),
- nb_packet_client_more, NULL);
+ req = tstream_read_packet_send(client, ev, client->sock,
+ sizeof(struct nb_packet_query),
+ nb_packet_client_more, NULL);
if (req == NULL) {
- DEBUG(10, ("read_packet_send failed\n"));
+ DEBUG(10, ("tstream_read_packet_send failed\n"));
TALLOC_FREE(client);
return;
}
@@ -212,10 +225,9 @@ static ssize_t nb_packet_client_more(uint8_t *buf, size_t buflen,
static int nb_packet_client_destructor(struct nb_packet_client *c)
{
- if (c->sock != -1) {
- close(c->sock);
- c->sock = -1;
- }
+ tevent_queue_stop(c->out_queue);
+ TALLOC_FREE(c->sock);
+
DLIST_REMOVE(c->server->clients, c);
c->server->num_clients -= 1;
return 0;
@@ -227,11 +239,10 @@ static void nb_packet_got_query(struct tevent_req *req)
req, struct nb_packet_client);
struct nb_packet_query q;
uint8_t *buf;
- ssize_t nread, nwritten;
+ ssize_t nread;
int err;
- char c;
- nread = read_packet_recv(req, talloc_tos(), &buf, &err);
+ nread = tstream_read_packet_recv(req, talloc_tos(), &buf, &err);
TALLOC_FREE(req);
if (nread < (ssize_t)sizeof(struct nb_packet_query)) {
DEBUG(10, ("read_packet_recv returned %d (%s)\n",
@@ -262,32 +273,51 @@ static void nb_packet_got_query(struct tevent_req *req)
}
}
- /*
- * Yes, this is a blocking write of 1 byte into a unix
- * domain socket that has never been written to. Highly
- * unlikely that this actually blocks.
- */
- c = 0;
- nwritten = sys_write(client->sock, &c, sizeof(c));
- if (nwritten != sizeof(c)) {
- DEBUG(10, ("Could not write success indicator to client: %s\n",
- strerror(errno)));
+ client->ack.byte = 0;
+ client->ack.iov[0].iov_base = &client->ack.byte;
+ client->ack.iov[0].iov_len = 1;
+ req = tstream_writev_queue_send(client, client->server->ev,
+ client->sock,
+ client->out_queue,
+ client->ack.iov, 1);
+ if (req == NULL) {
+ DEBUG(10, ("tstream_writev_queue_send failed\n"));
TALLOC_FREE(client);
return;
}
+ tevent_req_set_callback(req, nb_packet_client_ack_done, client);
- client->read_req = read_packet_send(client, client->server->ev,
- client->sock, 1, NULL, NULL);
- if (client->read_req == NULL) {
+ req = tstream_read_packet_send(client, client->server->ev,
+ client->sock, 1, NULL, NULL);
+ if (req == NULL) {
DEBUG(10, ("Could not activate reader for client exit "
"detection\n"));
TALLOC_FREE(client);
return;
}
- tevent_req_set_callback(client->read_req, nb_packet_client_read_done,
+ tevent_req_set_callback(req, nb_packet_client_read_done,
client);
}
+static void nb_packet_client_ack_done(struct tevent_req *req)
+{
+ struct nb_packet_client *client = tevent_req_callback_data(
+ req, struct nb_packet_client);
+ ssize_t nwritten;
+ int err;
+
+ nwritten = tstream_writev_queue_recv(req, &err);
+
+ TALLOC_FREE(req);
+
+ if (nwritten == -1) {
+ DEBUG(10, ("tstream_writev_queue_recv failed: %s\n",
+ strerror(err)));
+ TALLOC_FREE(client);
+ return;
+ }
+}
+
static void nb_packet_client_read_done(struct tevent_req *req)
{
struct nb_packet_client *client = tevent_req_callback_data(
@@ -296,7 +326,7 @@ static void nb_packet_client_read_done(struct tevent_req *req)
uint8_t *buf;
int err;
- nread = read_packet_recv(req, talloc_tos(), &buf, &err);
+ nread = tstream_read_packet_recv(req, talloc_tos(), &buf, &err);
TALLOC_FREE(req);
if (nread == 1) {
DEBUG(10, ("Protocol error, received data on write-only "
@@ -409,12 +439,12 @@ static void nb_packet_client_send(struct nb_packet_client *client,
state->iov[1].iov_base = state->buf;
state->iov[1].iov_len = state->hdr.len;
- TALLOC_FREE(client->read_req);
-
- req = writev_send(client, client->server->ev, client->out_queue,
- client->sock, true, state->iov, 2);
+ req = tstream_writev_queue_send(state, client->server->ev,
+ client->sock,
+ client->out_queue,
+ state->iov, 2);
if (req == NULL) {
- DEBUG(10, ("writev_send failed\n"));
+ DEBUG(10, ("tstream_writev_queue_send failed\n"));
return;
}
tevent_req_set_callback(req, nb_packet_client_send_done, state);
@@ -428,29 +458,15 @@ static void nb_packet_client_send_done(struct tevent_req *req)
ssize_t nwritten;
int err;
- nwritten = writev_recv(req, &err);
+ nwritten = tstream_writev_queue_recv(req, &err);
TALLOC_FREE(req);
TALLOC_FREE(state);
if (nwritten == -1) {
- DEBUG(10, ("writev failed: %s\n", strerror(err)));
+ DEBUG(10, ("tstream_writev_queue failed: %s\n", strerror(err)));
TALLOC_FREE(client);
- }
-
- if (tevent_queue_length(client->out_queue) == 0) {
- client->read_req = read_packet_send(client, client->server->ev,
- client->sock, 1,
- NULL, NULL);
- if (client->read_req == NULL) {
- DEBUG(10, ("Could not activate reader for client exit "
- "detection\n"));
- TALLOC_FREE(client);
- return;
- }
- tevent_req_set_callback(client->read_req,
- nb_packet_client_read_done,
- client);
+ return;
}
}