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"
30 #include "lib/util/iov_buf.h"
32 /* Note: lib/util/ is currently GPL */
33 #include "lib/util/tevent_unix.h"
34 #include "lib/util/samba_util.h"
37 #define TALLOC_FREE(ctx) do { talloc_free(ctx); ctx=NULL; } while(0)
45 const struct sockaddr_storage
*addr
;
50 static void sendto_handler(struct tevent_context
*ev
,
51 struct tevent_fd
*fde
,
52 uint16_t flags
, void *private_data
);
54 struct tevent_req
*sendto_send(TALLOC_CTX
*mem_ctx
, struct tevent_context
*ev
,
55 int fd
, const void *buf
, size_t len
, int flags
,
56 const struct sockaddr_storage
*addr
)
58 struct tevent_req
*result
;
59 struct sendto_state
*state
;
60 struct tevent_fd
*fde
;
62 result
= tevent_req_create(mem_ctx
, &state
, struct sendto_state
);
72 switch (addr
->ss_family
) {
74 state
->addr_len
= sizeof(struct sockaddr_in
);
76 #if defined(HAVE_IPV6)
78 state
->addr_len
= sizeof(struct sockaddr_in6
);
82 state
->addr_len
= sizeof(struct sockaddr_un
);
85 state
->addr_len
= sizeof(struct sockaddr_storage
);
89 fde
= tevent_add_fd(ev
, state
, fd
, TEVENT_FD_WRITE
, sendto_handler
,
98 static void sendto_handler(struct tevent_context
*ev
,
99 struct tevent_fd
*fde
,
100 uint16_t flags
, void *private_data
)
102 struct tevent_req
*req
= talloc_get_type_abort(
103 private_data
, struct tevent_req
);
104 struct sendto_state
*state
=
105 tevent_req_data(req
, struct sendto_state
);
107 state
->sent
= sendto(state
->fd
, state
->buf
, state
->len
, state
->flags
,
108 (const struct sockaddr
*)state
->addr
,
110 if ((state
->sent
== -1) && (errno
== EINTR
)) {
114 if (state
->sent
== -1) {
115 tevent_req_error(req
, errno
);
118 tevent_req_done(req
);
121 ssize_t
sendto_recv(struct tevent_req
*req
, int *perrno
)
123 struct sendto_state
*state
=
124 tevent_req_data(req
, struct sendto_state
);
126 if (tevent_req_is_unix_error(req
, perrno
)) {
132 struct recvfrom_state
{
137 struct sockaddr_storage
*addr
;
142 static void recvfrom_handler(struct tevent_context
*ev
,
143 struct tevent_fd
*fde
,
144 uint16_t flags
, void *private_data
);
146 struct tevent_req
*recvfrom_send(TALLOC_CTX
*mem_ctx
,
147 struct tevent_context
*ev
,
148 int fd
, void *buf
, size_t len
, int flags
,
149 struct sockaddr_storage
*addr
,
152 struct tevent_req
*result
;
153 struct recvfrom_state
*state
;
154 struct tevent_fd
*fde
;
156 result
= tevent_req_create(mem_ctx
, &state
, struct recvfrom_state
);
157 if (result
== NULL
) {
163 state
->flags
= flags
;
165 state
->addr_len
= addr_len
;
167 fde
= tevent_add_fd(ev
, state
, fd
, TEVENT_FD_READ
, recvfrom_handler
,
176 static void recvfrom_handler(struct tevent_context
*ev
,
177 struct tevent_fd
*fde
,
178 uint16_t flags
, void *private_data
)
180 struct tevent_req
*req
= talloc_get_type_abort(
181 private_data
, struct tevent_req
);
182 struct recvfrom_state
*state
=
183 tevent_req_data(req
, struct recvfrom_state
);
185 state
->received
= recvfrom(state
->fd
, state
->buf
, state
->len
,
186 state
->flags
, (struct sockaddr
*)state
->addr
,
188 if ((state
->received
== -1) && (errno
== EINTR
)) {
192 if (state
->received
== 0) {
193 tevent_req_error(req
, EPIPE
);
196 if (state
->received
== -1) {
197 tevent_req_error(req
, errno
);
200 tevent_req_done(req
);
203 ssize_t
recvfrom_recv(struct tevent_req
*req
, int *perrno
)
205 struct recvfrom_state
*state
=
206 tevent_req_data(req
, struct recvfrom_state
);
208 if (tevent_req_is_unix_error(req
, perrno
)) {
211 return state
->received
;
214 struct async_connect_state
{
219 socklen_t address_len
;
220 struct sockaddr_storage address
;
222 void (*before_connect
)(void *private_data
);
223 void (*after_connect
)(void *private_data
);
227 static void async_connect_connected(struct tevent_context
*ev
,
228 struct tevent_fd
*fde
, uint16_t flags
,
232 * @brief async version of connect(2)
233 * @param[in] mem_ctx The memory context to hang the result off
234 * @param[in] ev The event context to work from
235 * @param[in] fd The socket to recv from
236 * @param[in] address Where to connect?
237 * @param[in] address_len Length of *address
238 * @retval The async request
240 * This function sets the socket into non-blocking state to be able to call
241 * connect in an async state. This will be reset when the request is finished.
244 struct tevent_req
*async_connect_send(
245 TALLOC_CTX
*mem_ctx
, struct tevent_context
*ev
, int fd
,
246 const struct sockaddr
*address
, socklen_t address_len
,
247 void (*before_connect
)(void *private_data
),
248 void (*after_connect
)(void *private_data
),
251 struct tevent_req
*result
;
252 struct async_connect_state
*state
;
253 struct tevent_fd
*fde
;
255 result
= tevent_req_create(
256 mem_ctx
, &state
, struct async_connect_state
);
257 if (result
== NULL
) {
262 * We have to set the socket to nonblocking for async connect(2). Keep
263 * the old sockflags around.
267 state
->sys_errno
= 0;
268 state
->before_connect
= before_connect
;
269 state
->after_connect
= after_connect
;
270 state
->private_data
= private_data
;
272 state
->old_sockflags
= fcntl(fd
, F_GETFL
, 0);
273 if (state
->old_sockflags
== -1) {
277 state
->address_len
= address_len
;
278 if (address_len
> sizeof(state
->address
)) {
282 memcpy(&state
->address
, address
, address_len
);
284 set_blocking(fd
, false);
286 if (state
->before_connect
!= NULL
) {
287 state
->before_connect(state
->private_data
);
290 state
->result
= connect(fd
, address
, address_len
);
292 if (state
->after_connect
!= NULL
) {
293 state
->after_connect(state
->private_data
);
296 if (state
->result
== 0) {
297 tevent_req_done(result
);
302 * A number of error messages show that something good is progressing
303 * and that we have to wait for readability.
305 * If none of them are present, bail out.
308 if (!(errno
== EINPROGRESS
|| errno
== EALREADY
||
312 errno
== EAGAIN
|| errno
== EINTR
)) {
313 state
->sys_errno
= errno
;
317 fde
= tevent_add_fd(ev
, state
, fd
, TEVENT_FD_READ
| TEVENT_FD_WRITE
,
318 async_connect_connected
, result
);
320 state
->sys_errno
= ENOMEM
;
326 tevent_req_error(result
, state
->sys_errno
);
328 fcntl(fd
, F_SETFL
, state
->old_sockflags
);
329 return tevent_req_post(result
, ev
);
333 * fde event handler for connect(2)
334 * @param[in] ev The event context that sent us here
335 * @param[in] fde The file descriptor event associated with the connect
336 * @param[in] flags Indicate read/writeability of the socket
337 * @param[in] priv private data, "struct async_req *" in this case
340 static void async_connect_connected(struct tevent_context
*ev
,
341 struct tevent_fd
*fde
, uint16_t flags
,
344 struct tevent_req
*req
= talloc_get_type_abort(
345 priv
, struct tevent_req
);
346 struct async_connect_state
*state
=
347 tevent_req_data(req
, struct async_connect_state
);
350 if (state
->before_connect
!= NULL
) {
351 state
->before_connect(state
->private_data
);
354 ret
= connect(state
->fd
, (struct sockaddr
*)(void *)&state
->address
,
357 if (state
->after_connect
!= NULL
) {
358 state
->after_connect(state
->private_data
);
362 state
->sys_errno
= 0;
364 tevent_req_done(req
);
367 if (errno
== EINPROGRESS
) {
368 /* Try again later, leave the fde around */
371 state
->sys_errno
= errno
;
373 tevent_req_error(req
, errno
);
377 int async_connect_recv(struct tevent_req
*req
, int *perrno
)
379 struct async_connect_state
*state
=
380 tevent_req_data(req
, struct async_connect_state
);
383 fcntl(state
->fd
, F_SETFL
, state
->old_sockflags
);
385 if (tevent_req_is_unix_error(req
, &err
)) {
390 if (state
->sys_errno
== 0) {
394 *perrno
= state
->sys_errno
;
398 struct writev_state
{
399 struct tevent_context
*ev
;
405 bool err_on_readability
;
408 static void writev_trigger(struct tevent_req
*req
, void *private_data
);
409 static void writev_handler(struct tevent_context
*ev
, struct tevent_fd
*fde
,
410 uint16_t flags
, void *private_data
);
412 struct tevent_req
*writev_send(TALLOC_CTX
*mem_ctx
, struct tevent_context
*ev
,
413 struct tevent_queue
*queue
, int fd
,
414 bool err_on_readability
,
415 struct iovec
*iov
, int count
)
417 struct tevent_req
*req
;
418 struct writev_state
*state
;
420 req
= tevent_req_create(mem_ctx
, &state
, struct writev_state
);
426 state
->total_size
= 0;
427 state
->count
= count
;
428 state
->iov
= (struct iovec
*)talloc_memdup(
429 state
, iov
, sizeof(struct iovec
) * count
);
430 if (state
->iov
== NULL
) {
433 state
->flags
= TEVENT_FD_WRITE
|TEVENT_FD_READ
;
434 state
->err_on_readability
= err_on_readability
;
437 struct tevent_fd
*fde
;
438 fde
= tevent_add_fd(state
->ev
, state
, state
->fd
,
439 state
->flags
, writev_handler
, req
);
440 if (tevent_req_nomem(fde
, req
)) {
441 return tevent_req_post(req
, ev
);
446 if (!tevent_queue_add(queue
, ev
, req
, writev_trigger
, NULL
)) {
455 static void writev_trigger(struct tevent_req
*req
, void *private_data
)
457 struct writev_state
*state
= tevent_req_data(req
, struct writev_state
);
458 struct tevent_fd
*fde
;
460 fde
= tevent_add_fd(state
->ev
, state
, state
->fd
, state
->flags
,
461 writev_handler
, req
);
463 tevent_req_error(req
, ENOMEM
);
467 static void writev_handler(struct tevent_context
*ev
, struct tevent_fd
*fde
,
468 uint16_t flags
, void *private_data
)
470 struct tevent_req
*req
= talloc_get_type_abort(
471 private_data
, struct tevent_req
);
472 struct writev_state
*state
=
473 tevent_req_data(req
, struct writev_state
);
477 if ((state
->flags
& TEVENT_FD_READ
) && (flags
& TEVENT_FD_READ
)) {
480 if (state
->err_on_readability
) {
481 /* Readable and the caller wants an error on read. */
482 tevent_req_error(req
, EPIPE
);
486 /* Might be an error. Check if there are bytes to read */
487 ret
= ioctl(state
->fd
, FIONREAD
, &value
);
488 /* FIXME - should we also check
489 for ret == 0 and value == 0 here ? */
491 /* There's an error. */
492 tevent_req_error(req
, EPIPE
);
495 /* A request for TEVENT_FD_READ will succeed from now and
496 forevermore until the bytes are read so if there was
497 an error we'll wait until we do read, then get it in
498 the read callback function. Until then, remove TEVENT_FD_READ
499 from the flags we're waiting for. */
500 state
->flags
&= ~TEVENT_FD_READ
;
501 TEVENT_FD_NOT_READABLE(fde
);
503 /* If not writable, we're done. */
504 if (!(flags
& TEVENT_FD_WRITE
)) {
509 written
= writev(state
->fd
, state
->iov
, state
->count
);
510 if ((written
== -1) && (errno
== EINTR
)) {
515 tevent_req_error(req
, errno
);
519 tevent_req_error(req
, EPIPE
);
522 state
->total_size
+= written
;
524 ok
= iov_advance(&state
->iov
, &state
->count
, written
);
526 tevent_req_error(req
, EIO
);
530 if (state
->count
== 0) {
531 tevent_req_done(req
);
536 ssize_t
writev_recv(struct tevent_req
*req
, int *perrno
)
538 struct writev_state
*state
=
539 tevent_req_data(req
, struct writev_state
);
541 if (tevent_req_is_unix_error(req
, perrno
)) {
544 return state
->total_size
;
547 struct read_packet_state
{
551 ssize_t (*more
)(uint8_t *buf
, size_t buflen
, void *private_data
);
555 static void read_packet_handler(struct tevent_context
*ev
,
556 struct tevent_fd
*fde
,
557 uint16_t flags
, void *private_data
);
559 struct tevent_req
*read_packet_send(TALLOC_CTX
*mem_ctx
,
560 struct tevent_context
*ev
,
561 int fd
, size_t initial
,
562 ssize_t (*more
)(uint8_t *buf
,
567 struct tevent_req
*result
;
568 struct read_packet_state
*state
;
569 struct tevent_fd
*fde
;
571 result
= tevent_req_create(mem_ctx
, &state
, struct read_packet_state
);
572 if (result
== NULL
) {
578 state
->private_data
= private_data
;
580 state
->buf
= talloc_array(state
, uint8_t, initial
);
581 if (state
->buf
== NULL
) {
585 fde
= tevent_add_fd(ev
, state
, fd
, TEVENT_FD_READ
, read_packet_handler
,
596 static void read_packet_handler(struct tevent_context
*ev
,
597 struct tevent_fd
*fde
,
598 uint16_t flags
, void *private_data
)
600 struct tevent_req
*req
= talloc_get_type_abort(
601 private_data
, struct tevent_req
);
602 struct read_packet_state
*state
=
603 tevent_req_data(req
, struct read_packet_state
);
604 size_t total
= talloc_get_size(state
->buf
);
608 nread
= recv(state
->fd
, state
->buf
+state
->nread
, total
-state
->nread
,
610 if ((nread
== -1) && (errno
== ENOTSOCK
)) {
611 nread
= read(state
->fd
, state
->buf
+state
->nread
,
614 if ((nread
== -1) && (errno
== EINTR
)) {
619 tevent_req_error(req
, errno
);
623 tevent_req_error(req
, EPIPE
);
627 state
->nread
+= nread
;
628 if (state
->nread
< total
) {
629 /* Come back later */
634 * We got what was initially requested. See if "more" asks for -- more.
636 if (state
->more
== NULL
) {
637 /* Nobody to ask, this is a async read_data */
638 tevent_req_done(req
);
642 more
= state
->more(state
->buf
, total
, state
->private_data
);
644 /* We got an invalid packet, tell the caller */
645 tevent_req_error(req
, EIO
);
649 /* We're done, full packet received */
650 tevent_req_done(req
);
654 if (total
+ more
< total
) {
655 tevent_req_error(req
, EMSGSIZE
);
659 tmp
= talloc_realloc(state
, state
->buf
, uint8_t, total
+more
);
660 if (tevent_req_nomem(tmp
, req
)) {
666 ssize_t
read_packet_recv(struct tevent_req
*req
, TALLOC_CTX
*mem_ctx
,
667 uint8_t **pbuf
, int *perrno
)
669 struct read_packet_state
*state
=
670 tevent_req_data(req
, struct read_packet_state
);
672 if (tevent_req_is_unix_error(req
, perrno
)) {
675 *pbuf
= talloc_move(mem_ctx
, &state
->buf
);
676 return talloc_get_size(*pbuf
);
679 struct wait_for_read_state
{
680 struct tevent_req
*req
;
681 struct tevent_fd
*fde
;
684 static void wait_for_read_done(struct tevent_context
*ev
,
685 struct tevent_fd
*fde
,
689 struct tevent_req
*wait_for_read_send(TALLOC_CTX
*mem_ctx
,
690 struct tevent_context
*ev
,
693 struct tevent_req
*req
;
694 struct wait_for_read_state
*state
;
696 req
= tevent_req_create(mem_ctx
, &state
, struct wait_for_read_state
);
701 state
->fde
= tevent_add_fd(ev
, state
, fd
, TEVENT_FD_READ
,
702 wait_for_read_done
, state
);
703 if (tevent_req_nomem(state
->fde
, req
)) {
704 return tevent_req_post(req
, ev
);
709 static void wait_for_read_done(struct tevent_context
*ev
,
710 struct tevent_fd
*fde
,
714 struct wait_for_read_state
*state
= talloc_get_type_abort(
715 private_data
, struct wait_for_read_state
);
717 if (flags
& TEVENT_FD_READ
) {
718 TALLOC_FREE(state
->fde
);
719 tevent_req_done(state
->req
);
723 bool wait_for_read_recv(struct tevent_req
*req
, int *perr
)
727 if (tevent_req_is_unix_error(req
, &err
)) {