2 Unix SMB/CIFS implementation.
4 Copyright (C) Volker Lendecke 2008
6 ** NOTE! The following LGPL license applies to the async_sock
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 Library General Public License for more details.
20 You should have received a copy of the GNU Lesser General Public License
21 along with this program. If not, see <http://www.gnu.org/licenses/>.
25 #include "system/network.h"
26 #include "system/filesys.h"
29 #include "lib/async_req/async_sock.h"
31 /* Note: lib/util/ is currently GPL */
32 #include "lib/util/tevent_unix.h"
33 #include "lib/util/samba_util.h"
36 #define TALLOC_FREE(ctx) do { talloc_free(ctx); ctx=NULL; } while(0)
44 const struct sockaddr_storage *addr;
49 static void sendto_handler(struct tevent_context *ev,
50 struct tevent_fd *fde,
51 uint16_t flags, void *private_data);
53 struct tevent_req *sendto_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev,
54 int fd, const void *buf, size_t len, int flags,
55 const struct sockaddr_storage *addr)
57 struct tevent_req *result;
58 struct sendto_state *state;
59 struct tevent_fd *fde;
61 result = tevent_req_create(mem_ctx, &state, struct sendto_state);
71 switch (addr->ss_family) {
73 state->addr_len = sizeof(struct sockaddr_in);
75 #if defined(HAVE_IPV6)
77 state->addr_len = sizeof(struct sockaddr_in6);
81 state->addr_len = sizeof(struct sockaddr_un);
84 state->addr_len = sizeof(struct sockaddr_storage);
88 fde = tevent_add_fd(ev, state, fd, TEVENT_FD_WRITE, sendto_handler,
97 static void sendto_handler(struct tevent_context *ev,
98 struct tevent_fd *fde,
99 uint16_t flags, void *private_data)
101 struct tevent_req *req = talloc_get_type_abort(
102 private_data, struct tevent_req);
103 struct sendto_state *state =
104 tevent_req_data(req, struct sendto_state);
106 state->sent = sendto(state->fd, state->buf, state->len, state->flags,
107 (const struct sockaddr *)state->addr,
109 if ((state->sent == -1) && (errno == EINTR)) {
113 if (state->sent == -1) {
114 tevent_req_error(req, errno);
117 tevent_req_done(req);
120 ssize_t sendto_recv(struct tevent_req *req, int *perrno)
122 struct sendto_state *state =
123 tevent_req_data(req, struct sendto_state);
125 if (tevent_req_is_unix_error(req, perrno)) {
131 struct recvfrom_state {
136 struct sockaddr_storage *addr;
141 static void recvfrom_handler(struct tevent_context *ev,
142 struct tevent_fd *fde,
143 uint16_t flags, void *private_data);
145 struct tevent_req *recvfrom_send(TALLOC_CTX *mem_ctx,
146 struct tevent_context *ev,
147 int fd, void *buf, size_t len, int flags,
148 struct sockaddr_storage *addr,
151 struct tevent_req *result;
152 struct recvfrom_state *state;
153 struct tevent_fd *fde;
155 result = tevent_req_create(mem_ctx, &state, struct recvfrom_state);
156 if (result == NULL) {
162 state->flags = flags;
164 state->addr_len = addr_len;
166 fde = tevent_add_fd(ev, state, fd, TEVENT_FD_READ, recvfrom_handler,
175 static void recvfrom_handler(struct tevent_context *ev,
176 struct tevent_fd *fde,
177 uint16_t flags, void *private_data)
179 struct tevent_req *req = talloc_get_type_abort(
180 private_data, struct tevent_req);
181 struct recvfrom_state *state =
182 tevent_req_data(req, struct recvfrom_state);
184 state->received = recvfrom(state->fd, state->buf, state->len,
185 state->flags, (struct sockaddr *)state->addr,
187 if ((state->received == -1) && (errno == EINTR)) {
191 if (state->received == 0) {
192 tevent_req_error(req, EPIPE);
195 if (state->received == -1) {
196 tevent_req_error(req, errno);
199 tevent_req_done(req);
202 ssize_t recvfrom_recv(struct tevent_req *req, int *perrno)
204 struct recvfrom_state *state =
205 tevent_req_data(req, struct recvfrom_state);
207 if (tevent_req_is_unix_error(req, perrno)) {
210 return state->received;
213 struct async_connect_state {
218 socklen_t address_len;
219 struct sockaddr_storage address;
221 void (*before_connect)(void *private_data);
222 void (*after_connect)(void *private_data);
226 static void async_connect_connected(struct tevent_context *ev,
227 struct tevent_fd *fde, uint16_t flags,
231 * @brief async version of connect(2)
232 * @param[in] mem_ctx The memory context to hang the result off
233 * @param[in] ev The event context to work from
234 * @param[in] fd The socket to recv from
235 * @param[in] address Where to connect?
236 * @param[in] address_len Length of *address
237 * @retval The async request
239 * This function sets the socket into non-blocking state to be able to call
240 * connect in an async state. This will be reset when the request is finished.
243 struct tevent_req *async_connect_send(
244 TALLOC_CTX *mem_ctx, struct tevent_context *ev, int fd,
245 const struct sockaddr *address, socklen_t address_len,
246 void (*before_connect)(void *private_data),
247 void (*after_connect)(void *private_data),
250 struct tevent_req *result;
251 struct async_connect_state *state;
252 struct tevent_fd *fde;
254 result = tevent_req_create(
255 mem_ctx, &state, struct async_connect_state);
256 if (result == NULL) {
261 * We have to set the socket to nonblocking for async connect(2). Keep
262 * the old sockflags around.
266 state->sys_errno = 0;
267 state->before_connect = before_connect;
268 state->after_connect = after_connect;
269 state->private_data = private_data;
271 state->old_sockflags = fcntl(fd, F_GETFL, 0);
272 if (state->old_sockflags == -1) {
276 state->address_len = address_len;
277 if (address_len > sizeof(state->address)) {
281 memcpy(&state->address, address, address_len);
283 set_blocking(fd, false);
285 if (state->before_connect != NULL) {
286 state->before_connect(state->private_data);
289 state->result = connect(fd, address, address_len);
291 if (state->after_connect != NULL) {
292 state->after_connect(state->private_data);
295 if (state->result == 0) {
296 tevent_req_done(result);
301 * A number of error messages show that something good is progressing
302 * and that we have to wait for readability.
304 * If none of them are present, bail out.
307 if (!(errno == EINPROGRESS || errno == EALREADY ||
311 errno == EAGAIN || errno == EINTR)) {
312 state->sys_errno = errno;
316 fde = tevent_add_fd(ev, state, fd, TEVENT_FD_READ | TEVENT_FD_WRITE,
317 async_connect_connected, result);
319 state->sys_errno = ENOMEM;
325 tevent_req_error(result, state->sys_errno);
327 fcntl(fd, F_SETFL, state->old_sockflags);
328 return tevent_req_post(result, ev);
332 * fde event handler for connect(2)
333 * @param[in] ev The event context that sent us here
334 * @param[in] fde The file descriptor event associated with the connect
335 * @param[in] flags Indicate read/writeability of the socket
336 * @param[in] priv private data, "struct async_req *" in this case
339 static void async_connect_connected(struct tevent_context *ev,
340 struct tevent_fd *fde, uint16_t flags,
343 struct tevent_req *req = talloc_get_type_abort(
344 priv, struct tevent_req);
345 struct async_connect_state *state =
346 tevent_req_data(req, struct async_connect_state);
349 if (state->before_connect != NULL) {
350 state->before_connect(state->private_data);
353 ret = connect(state->fd, (struct sockaddr *)(void *)&state->address,
356 if (state->after_connect != NULL) {
357 state->after_connect(state->private_data);
361 state->sys_errno = 0;
363 tevent_req_done(req);
366 if (errno == EINPROGRESS) {
367 /* Try again later, leave the fde around */
370 state->sys_errno = errno;
372 tevent_req_error(req, errno);
376 int async_connect_recv(struct tevent_req *req, int *perrno)
378 struct async_connect_state *state =
379 tevent_req_data(req, struct async_connect_state);
382 fcntl(state->fd, F_SETFL, state->old_sockflags);
384 if (tevent_req_is_unix_error(req, &err)) {
389 if (state->sys_errno == 0) {
393 *perrno = state->sys_errno;
397 struct writev_state {
398 struct tevent_context *ev;
404 bool err_on_readability;
407 static void writev_trigger(struct tevent_req *req, void *private_data);
408 static void writev_handler(struct tevent_context *ev, struct tevent_fd *fde,
409 uint16_t flags, void *private_data);
411 struct tevent_req *writev_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev,
412 struct tevent_queue *queue, int fd,
413 bool err_on_readability,
414 struct iovec *iov, int count)
416 struct tevent_req *req;
417 struct writev_state *state;
419 req = tevent_req_create(mem_ctx, &state, struct writev_state);
425 state->total_size = 0;
426 state->count = count;
427 state->iov = (struct iovec *)talloc_memdup(
428 state, iov, sizeof(struct iovec) * count);
429 if (state->iov == NULL) {
432 state->flags = TEVENT_FD_WRITE;
433 state->err_on_readability = err_on_readability;
434 if (state->err_on_readability) {
435 state->flags |= TEVENT_FD_READ;
439 struct tevent_fd *fde;
440 fde = tevent_add_fd(state->ev, state, state->fd,
441 state->flags, writev_handler, req);
442 if (tevent_req_nomem(fde, req)) {
443 return tevent_req_post(req, ev);
448 if (!tevent_queue_add(queue, ev, req, writev_trigger, NULL)) {
457 static void writev_trigger(struct tevent_req *req, void *private_data)
459 struct writev_state *state = tevent_req_data(req, struct writev_state);
460 struct tevent_fd *fde;
462 fde = tevent_add_fd(state->ev, state, state->fd, state->flags,
463 writev_handler, req);
465 tevent_req_error(req, ENOMEM);
469 static void writev_handler(struct tevent_context *ev, struct tevent_fd *fde,
470 uint16_t flags, void *private_data)
472 struct tevent_req *req = talloc_get_type_abort(
473 private_data, struct tevent_req);
474 struct writev_state *state =
475 tevent_req_data(req, struct writev_state);
476 size_t to_write, written;
481 if ((state->flags & TEVENT_FD_READ) && (flags & TEVENT_FD_READ)) {
484 if (state->err_on_readability) {
485 /* Readable and the caller wants an error on read. */
486 tevent_req_error(req, EPIPE);
490 /* Might be an error. Check if there are bytes to read */
491 ret = ioctl(state->fd, FIONREAD, &value);
492 /* FIXME - should we also check
493 for ret == 0 and value == 0 here ? */
495 /* There's an error. */
496 tevent_req_error(req, EPIPE);
499 /* A request for TEVENT_FD_READ will succeed from now and
500 forevermore until the bytes are read so if there was
501 an error we'll wait until we do read, then get it in
502 the read callback function. Until then, remove TEVENT_FD_READ
503 from the flags we're waiting for. */
504 state->flags &= ~TEVENT_FD_READ;
505 TEVENT_FD_NOT_READABLE(fde);
507 /* If not writable, we're done. */
508 if (!(flags & TEVENT_FD_WRITE)) {
513 for (i=0; i<state->count; i++) {
514 to_write += state->iov[i].iov_len;
517 written = writev(state->fd, state->iov, state->count);
518 if ((written == -1) && (errno == EINTR)) {
523 tevent_req_error(req, errno);
527 tevent_req_error(req, EPIPE);
530 state->total_size += written;
532 if (written == to_write) {
533 tevent_req_done(req);
538 * We've written less than we were asked to, drop stuff from
542 while (written > 0) {
543 if (written < state->iov[0].iov_len) {
544 state->iov[0].iov_base =
545 (char *)state->iov[0].iov_base + written;
546 state->iov[0].iov_len -= written;
549 written -= state->iov[0].iov_len;
555 ssize_t writev_recv(struct tevent_req *req, int *perrno)
557 struct writev_state *state =
558 tevent_req_data(req, struct writev_state);
560 if (tevent_req_is_unix_error(req, perrno)) {
563 return state->total_size;
566 struct read_packet_state {
570 ssize_t (*more)(uint8_t *buf, size_t buflen, void *private_data);
574 static void read_packet_handler(struct tevent_context *ev,
575 struct tevent_fd *fde,
576 uint16_t flags, void *private_data);
578 struct tevent_req *read_packet_send(TALLOC_CTX *mem_ctx,
579 struct tevent_context *ev,
580 int fd, size_t initial,
581 ssize_t (*more)(uint8_t *buf,
586 struct tevent_req *result;
587 struct read_packet_state *state;
588 struct tevent_fd *fde;
590 result = tevent_req_create(mem_ctx, &state, struct read_packet_state);
591 if (result == NULL) {
597 state->private_data = private_data;
599 state->buf = talloc_array(state, uint8_t, initial);
600 if (state->buf == NULL) {
604 fde = tevent_add_fd(ev, state, fd, TEVENT_FD_READ, read_packet_handler,
615 static void read_packet_handler(struct tevent_context *ev,
616 struct tevent_fd *fde,
617 uint16_t flags, void *private_data)
619 struct tevent_req *req = talloc_get_type_abort(
620 private_data, struct tevent_req);
621 struct read_packet_state *state =
622 tevent_req_data(req, struct read_packet_state);
623 size_t total = talloc_get_size(state->buf);
627 nread = recv(state->fd, state->buf+state->nread, total-state->nread,
629 if ((nread == -1) && (errno == ENOTSOCK)) {
630 nread = read(state->fd, state->buf+state->nread,
633 if ((nread == -1) && (errno == EINTR)) {
638 tevent_req_error(req, errno);
642 tevent_req_error(req, EPIPE);
646 state->nread += nread;
647 if (state->nread < total) {
648 /* Come back later */
653 * We got what was initially requested. See if "more" asks for -- more.
655 if (state->more == NULL) {
656 /* Nobody to ask, this is a async read_data */
657 tevent_req_done(req);
661 more = state->more(state->buf, total, state->private_data);
663 /* We got an invalid packet, tell the caller */
664 tevent_req_error(req, EIO);
668 /* We're done, full packet received */
669 tevent_req_done(req);
673 if (total + more < total) {
674 tevent_req_error(req, EMSGSIZE);
678 tmp = talloc_realloc(state, state->buf, uint8_t, total+more);
679 if (tevent_req_nomem(tmp, req)) {
685 ssize_t read_packet_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
686 uint8_t **pbuf, int *perrno)
688 struct read_packet_state *state =
689 tevent_req_data(req, struct read_packet_state);
691 if (tevent_req_is_unix_error(req, perrno)) {
694 *pbuf = talloc_move(mem_ctx, &state->buf);
695 return talloc_get_size(*pbuf);
698 struct wait_for_read_state {
699 struct tevent_req *req;
700 struct tevent_fd *fde;
703 static void wait_for_read_done(struct tevent_context *ev,
704 struct tevent_fd *fde,
708 struct tevent_req *wait_for_read_send(TALLOC_CTX *mem_ctx,
709 struct tevent_context *ev,
712 struct tevent_req *req;
713 struct wait_for_read_state *state;
715 req = tevent_req_create(mem_ctx, &state, struct wait_for_read_state);
720 state->fde = tevent_add_fd(ev, state, fd, TEVENT_FD_READ,
721 wait_for_read_done, state);
722 if (tevent_req_nomem(state->fde, req)) {
723 return tevent_req_post(req, ev);
728 static void wait_for_read_done(struct tevent_context *ev,
729 struct tevent_fd *fde,
733 struct wait_for_read_state *state = talloc_get_type_abort(
734 private_data, struct wait_for_read_state);
736 if (flags & TEVENT_FD_READ) {
737 TALLOC_FREE(state->fde);
738 tevent_req_done(state->req);
742 bool wait_for_read_recv(struct tevent_req *req, int *perr)
746 if (tevent_req_is_unix_error(req, &err)) {