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
|TEVENT_FD_READ
;
433 state
->err_on_readability
= err_on_readability
;
436 struct tevent_fd
*fde
;
437 fde
= tevent_add_fd(state
->ev
, state
, state
->fd
,
438 state
->flags
, writev_handler
, req
);
439 if (tevent_req_nomem(fde
, req
)) {
440 return tevent_req_post(req
, ev
);
445 if (!tevent_queue_add(queue
, ev
, req
, writev_trigger
, NULL
)) {
454 static void writev_trigger(struct tevent_req
*req
, void *private_data
)
456 struct writev_state
*state
= tevent_req_data(req
, struct writev_state
);
457 struct tevent_fd
*fde
;
459 fde
= tevent_add_fd(state
->ev
, state
, state
->fd
, state
->flags
,
460 writev_handler
, req
);
462 tevent_req_error(req
, ENOMEM
);
466 static void writev_handler(struct tevent_context
*ev
, struct tevent_fd
*fde
,
467 uint16_t flags
, void *private_data
)
469 struct tevent_req
*req
= talloc_get_type_abort(
470 private_data
, struct tevent_req
);
471 struct writev_state
*state
=
472 tevent_req_data(req
, struct writev_state
);
473 size_t to_write
, written
;
478 if ((state
->flags
& TEVENT_FD_READ
) && (flags
& TEVENT_FD_READ
)) {
481 if (state
->err_on_readability
) {
482 /* Readable and the caller wants an error on read. */
483 tevent_req_error(req
, EPIPE
);
487 /* Might be an error. Check if there are bytes to read */
488 ret
= ioctl(state
->fd
, FIONREAD
, &value
);
489 /* FIXME - should we also check
490 for ret == 0 and value == 0 here ? */
492 /* There's an error. */
493 tevent_req_error(req
, EPIPE
);
496 /* A request for TEVENT_FD_READ will succeed from now and
497 forevermore until the bytes are read so if there was
498 an error we'll wait until we do read, then get it in
499 the read callback function. Until then, remove TEVENT_FD_READ
500 from the flags we're waiting for. */
501 state
->flags
&= ~TEVENT_FD_READ
;
502 TEVENT_FD_NOT_READABLE(fde
);
504 /* If not writable, we're done. */
505 if (!(flags
& TEVENT_FD_WRITE
)) {
510 for (i
=0; i
<state
->count
; i
++) {
511 to_write
+= state
->iov
[i
].iov_len
;
514 written
= writev(state
->fd
, state
->iov
, state
->count
);
515 if ((written
== -1) && (errno
== EINTR
)) {
520 tevent_req_error(req
, errno
);
524 tevent_req_error(req
, EPIPE
);
527 state
->total_size
+= written
;
529 if (written
== to_write
) {
530 tevent_req_done(req
);
535 * We've written less than we were asked to, drop stuff from
539 while (written
> 0) {
540 if (written
< state
->iov
[0].iov_len
) {
541 state
->iov
[0].iov_base
=
542 (char *)state
->iov
[0].iov_base
+ written
;
543 state
->iov
[0].iov_len
-= written
;
546 written
-= state
->iov
[0].iov_len
;
552 ssize_t
writev_recv(struct tevent_req
*req
, int *perrno
)
554 struct writev_state
*state
=
555 tevent_req_data(req
, struct writev_state
);
557 if (tevent_req_is_unix_error(req
, perrno
)) {
560 return state
->total_size
;
563 struct read_packet_state
{
567 ssize_t (*more
)(uint8_t *buf
, size_t buflen
, void *private_data
);
571 static void read_packet_handler(struct tevent_context
*ev
,
572 struct tevent_fd
*fde
,
573 uint16_t flags
, void *private_data
);
575 struct tevent_req
*read_packet_send(TALLOC_CTX
*mem_ctx
,
576 struct tevent_context
*ev
,
577 int fd
, size_t initial
,
578 ssize_t (*more
)(uint8_t *buf
,
583 struct tevent_req
*result
;
584 struct read_packet_state
*state
;
585 struct tevent_fd
*fde
;
587 result
= tevent_req_create(mem_ctx
, &state
, struct read_packet_state
);
588 if (result
== NULL
) {
594 state
->private_data
= private_data
;
596 state
->buf
= talloc_array(state
, uint8_t, initial
);
597 if (state
->buf
== NULL
) {
601 fde
= tevent_add_fd(ev
, state
, fd
, TEVENT_FD_READ
, read_packet_handler
,
612 static void read_packet_handler(struct tevent_context
*ev
,
613 struct tevent_fd
*fde
,
614 uint16_t flags
, void *private_data
)
616 struct tevent_req
*req
= talloc_get_type_abort(
617 private_data
, struct tevent_req
);
618 struct read_packet_state
*state
=
619 tevent_req_data(req
, struct read_packet_state
);
620 size_t total
= talloc_get_size(state
->buf
);
624 nread
= recv(state
->fd
, state
->buf
+state
->nread
, total
-state
->nread
,
626 if ((nread
== -1) && (errno
== ENOTSOCK
)) {
627 nread
= read(state
->fd
, state
->buf
+state
->nread
,
630 if ((nread
== -1) && (errno
== EINTR
)) {
635 tevent_req_error(req
, errno
);
639 tevent_req_error(req
, EPIPE
);
643 state
->nread
+= nread
;
644 if (state
->nread
< total
) {
645 /* Come back later */
650 * We got what was initially requested. See if "more" asks for -- more.
652 if (state
->more
== NULL
) {
653 /* Nobody to ask, this is a async read_data */
654 tevent_req_done(req
);
658 more
= state
->more(state
->buf
, total
, state
->private_data
);
660 /* We got an invalid packet, tell the caller */
661 tevent_req_error(req
, EIO
);
665 /* We're done, full packet received */
666 tevent_req_done(req
);
670 tmp
= talloc_realloc(state
, state
->buf
, uint8_t, total
+more
);
671 if (tevent_req_nomem(tmp
, req
)) {
677 ssize_t
read_packet_recv(struct tevent_req
*req
, TALLOC_CTX
*mem_ctx
,
678 uint8_t **pbuf
, int *perrno
)
680 struct read_packet_state
*state
=
681 tevent_req_data(req
, struct read_packet_state
);
683 if (tevent_req_is_unix_error(req
, perrno
)) {
686 *pbuf
= talloc_move(mem_ctx
, &state
->buf
);
687 return talloc_get_size(*pbuf
);
690 struct wait_for_read_state
{
691 struct tevent_req
*req
;
692 struct tevent_fd
*fde
;
695 static void wait_for_read_done(struct tevent_context
*ev
,
696 struct tevent_fd
*fde
,
700 struct tevent_req
*wait_for_read_send(TALLOC_CTX
*mem_ctx
,
701 struct tevent_context
*ev
,
704 struct tevent_req
*req
;
705 struct wait_for_read_state
*state
;
707 req
= tevent_req_create(mem_ctx
, &state
, struct wait_for_read_state
);
712 state
->fde
= tevent_add_fd(ev
, state
, fd
, TEVENT_FD_READ
,
713 wait_for_read_done
, state
);
714 if (tevent_req_nomem(state
->fde
, req
)) {
715 return tevent_req_post(req
, ev
);
720 static void wait_for_read_done(struct tevent_context
*ev
,
721 struct tevent_fd
*fde
,
725 struct wait_for_read_state
*state
= talloc_get_type_abort(
726 private_data
, struct wait_for_read_state
);
728 if (flags
& TEVENT_FD_READ
) {
729 TALLOC_FREE(state
->fde
);
730 tevent_req_done(state
->req
);
734 bool wait_for_read_recv(struct tevent_req
*req
, int *perr
)
738 if (tevent_req_is_unix_error(req
, &err
)) {