async_sock: Map ASYNC_REQ_TIMEOUT to ETIMEDOUT instead of ETIME
[tprouty/samba.git] / lib / async_req / async_sock.c
1 /*
2    Unix SMB/CIFS implementation.
3    async socket syscalls
4    Copyright (C) Volker Lendecke 2008
5
6    This program is free software; you can redistribute it and/or modify
7    it under the terms of the GNU General Public License as published by
8    the Free Software Foundation; either version 3 of the License, or
9    (at your option) any later version.
10
11    This program is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14    GNU General Public License for more details.
15
16    You should have received a copy of the GNU General Public License
17    along with this program.  If not, see <http://www.gnu.org/licenses/>.
18 */
19
20 #include "includes.h"
21 #include "lib/talloc/talloc.h"
22 #include "lib/tevent/tevent.h"
23 #include "lib/async_req/async_req.h"
24 #include "lib/async_req/async_sock.h"
25 #include <fcntl.h>
26
27 #ifndef TALLOC_FREE
28 #define TALLOC_FREE(ctx) do { talloc_free(ctx); ctx=NULL; } while(0)
29 #endif
30
31 /**
32  * Discriminator for async_syscall_state
33  */
34 enum async_syscall_type {
35         ASYNC_SYSCALL_SEND,
36         ASYNC_SYSCALL_SENDALL,
37         ASYNC_SYSCALL_RECV,
38         ASYNC_SYSCALL_RECVALL,
39         ASYNC_SYSCALL_CONNECT
40 };
41
42 /**
43  * Holder for syscall arguments and the result
44  */
45
46 struct async_syscall_state {
47         enum async_syscall_type syscall_type;
48         struct tevent_fd *fde;
49
50         union {
51                 struct param_send {
52                         int fd;
53                         const void *buffer;
54                         size_t length;
55                         int flags;
56                 } param_send;
57                 struct param_sendall {
58                         int fd;
59                         const void *buffer;
60                         size_t length;
61                         int flags;
62                         size_t sent;
63                 } param_sendall;
64                 struct param_recv {
65                         int fd;
66                         void *buffer;
67                         size_t length;
68                         int flags;
69                 } param_recv;
70                 struct param_recvall {
71                         int fd;
72                         void *buffer;
73                         size_t length;
74                         int flags;
75                         size_t received;
76                 } param_recvall;
77                 struct param_connect {
78                         /**
79                          * connect needs to be done on a nonblocking
80                          * socket. Keep the old flags around
81                          */
82                         long old_sockflags;
83                         int fd;
84                         const struct sockaddr *address;
85                         socklen_t address_len;
86                 } param_connect;
87         } param;
88
89         union {
90                 ssize_t result_ssize_t;
91                 size_t result_size_t;
92                 int result_int;
93         } result;
94         int sys_errno;
95 };
96
97 /**
98  * @brief Map async_req states to unix-style errnos
99  * @param[in]  req      The async req to get the state from
100  * @param[out] err      Pointer to take the unix-style errno
101  *
102  * @return true if the async_req is in an error state, false otherwise
103  */
104
105 bool async_req_is_errno(struct async_req *req, int *err)
106 {
107         enum async_req_state state;
108         uint64_t error;
109
110         if (!async_req_is_error(req, &state, &error)) {
111                 return false;
112         }
113
114         switch (state) {
115         case ASYNC_REQ_USER_ERROR:
116                 *err = (int)error;
117                 break;
118         case ASYNC_REQ_TIMED_OUT:
119 #ifdef HAVE_ETIMEDOUT
120                 *err = ETIMEDOUT;
121 #else
122                 *err = EIO;
123 #endif
124                 break;
125         case ASYNC_REQ_NO_MEMORY:
126                 *err = ENOMEM;
127                 break;
128         default:
129                 *err = EIO;
130                 break;
131         }
132         return true;
133 }
134
135 int async_req_simple_recv_errno(struct async_req *req)
136 {
137         int err;
138
139         if (async_req_is_errno(req, &err)) {
140                 return err;
141         }
142
143         return 0;
144 }
145
146 /**
147  * @brief Create a new async syscall req
148  * @param[in] mem_ctx   The memory context to hang the result off
149  * @param[in] ev        The event context to work from
150  * @param[in] type      Which syscall will this be
151  * @param[in] pstate    Where to put the newly created private_data state
152  * @retval The new request
153  *
154  * This is a helper function to prepare a new struct async_req with an
155  * associated struct async_syscall_state. The async_syscall_state will be put
156  * into the async_req as private_data.
157  */
158
159 static struct async_req *async_syscall_new(TALLOC_CTX *mem_ctx,
160                                            struct tevent_context *ev,
161                                            enum async_syscall_type type,
162                                            struct async_syscall_state **pstate)
163 {
164         struct async_req *result;
165         struct async_syscall_state *state;
166
167         if (!async_req_setup(mem_ctx, &result, &state,
168                              struct async_syscall_state)) {
169                 return NULL;
170         }
171         state->syscall_type = type;
172
173         result->private_data = state;
174
175         *pstate = state;
176
177         return result;
178 }
179
180 /**
181  * @brief Create a new async syscall req based on a fd
182  * @param[in] mem_ctx   The memory context to hang the result off
183  * @param[in] ev        The event context to work from
184  * @param[in] type      Which syscall will this be
185  * @param[in] fd        The file descriptor we work on
186  * @param[in] fde_flags TEVENT_FD_READ/WRITE -- what are we interested in?
187  * @param[in] fde_cb    The callback function for the file descriptor event
188  * @param[in] pstate    Where to put the newly created private_data state
189  * @retval The new request
190  *
191  * This is a helper function to prepare a new struct async_req with an
192  * associated struct async_syscall_state and an associated file descriptor
193  * event.
194  */
195
196 static struct async_req *async_fde_syscall_new(
197         TALLOC_CTX *mem_ctx,
198         struct tevent_context *ev,
199         enum async_syscall_type type,
200         int fd,
201         uint16_t fde_flags,
202         void (*fde_cb)(struct tevent_context *ev,
203                        struct tevent_fd *fde, uint16_t flags,
204                        void *priv),
205         struct async_syscall_state **pstate)
206 {
207         struct async_req *result;
208         struct async_syscall_state *state;
209
210         result = async_syscall_new(mem_ctx, ev, type, &state);
211         if (result == NULL) {
212                 return NULL;
213         }
214
215         state->fde = tevent_add_fd(ev, state, fd, fde_flags, fde_cb, result);
216         if (state->fde == NULL) {
217                 TALLOC_FREE(result);
218                 return NULL;
219         }
220         *pstate = state;
221         return result;
222 }
223
224 /**
225  * Retrieve a ssize_t typed result from an async syscall
226  * @param[in] req       The syscall that has just finished
227  * @param[out] perrno   Where to put the syscall's errno
228  * @retval The return value from the asynchronously called syscall
229  */
230
231 ssize_t async_syscall_result_ssize_t(struct async_req *req, int *perrno)
232 {
233         struct async_syscall_state *state = talloc_get_type_abort(
234                 req->private_data, struct async_syscall_state);
235
236         *perrno = state->sys_errno;
237         return state->result.result_ssize_t;
238 }
239
240 /**
241  * Retrieve a size_t typed result from an async syscall
242  * @param[in] req       The syscall that has just finished
243  * @param[out] perrno   Where to put the syscall's errno
244  * @retval The return value from the asynchronously called syscall
245  */
246
247 size_t async_syscall_result_size_t(struct async_req *req, int *perrno)
248 {
249         struct async_syscall_state *state = talloc_get_type_abort(
250                 req->private_data, struct async_syscall_state);
251
252         *perrno = state->sys_errno;
253         return state->result.result_size_t;
254 }
255
256 /**
257  * Retrieve a int typed result from an async syscall
258  * @param[in] req       The syscall that has just finished
259  * @param[out] perrno   Where to put the syscall's errno
260  * @retval The return value from the asynchronously called syscall
261  */
262
263 int async_syscall_result_int(struct async_req *req, int *perrno)
264 {
265         struct async_syscall_state *state = talloc_get_type_abort(
266                 req->private_data, struct async_syscall_state);
267
268         *perrno = state->sys_errno;
269         return state->result.result_int;
270 }
271
272 /**
273  * fde event handler for the "send" syscall
274  * @param[in] ev        The event context that sent us here
275  * @param[in] fde       The file descriptor event associated with the send
276  * @param[in] flags     Can only be TEVENT_FD_WRITE here
277  * @param[in] priv      private data, "struct async_req *" in this case
278  */
279
280 static void async_send_callback(struct tevent_context *ev,
281                                 struct tevent_fd *fde, uint16_t flags,
282                                 void *priv)
283 {
284         struct async_req *req = talloc_get_type_abort(
285                 priv, struct async_req);
286         struct async_syscall_state *state = talloc_get_type_abort(
287                 req->private_data, struct async_syscall_state);
288         struct param_send *p = &state->param.param_send;
289
290         if (state->syscall_type != ASYNC_SYSCALL_SEND) {
291                 async_req_error(req, EIO);
292                 return;
293         }
294
295         state->result.result_ssize_t = send(p->fd, p->buffer, p->length,
296                                             p->flags);
297         state->sys_errno = errno;
298
299         TALLOC_FREE(state->fde);
300
301         async_req_done(req);
302 }
303
304 /**
305  * Async version of send(2)
306  * @param[in] mem_ctx   The memory context to hang the result off
307  * @param[in] ev        The event context to work from
308  * @param[in] fd        The socket to send to
309  * @param[in] buffer    The buffer to send
310  * @param[in] length    How many bytes to send
311  * @param[in] flags     flags passed to send(2)
312  *
313  * This function is a direct counterpart of send(2)
314  */
315
316 struct async_req *async_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev,
317                              int fd, const void *buffer, size_t length,
318                              int flags)
319 {
320         struct async_req *result;
321         struct async_syscall_state *state;
322
323         result = async_fde_syscall_new(
324                 mem_ctx, ev, ASYNC_SYSCALL_SEND,
325                 fd, TEVENT_FD_WRITE, async_send_callback,
326                 &state);
327         if (result == NULL) {
328                 return NULL;
329         }
330
331         state->param.param_send.fd = fd;
332         state->param.param_send.buffer = buffer;
333         state->param.param_send.length = length;
334         state->param.param_send.flags = flags;
335
336         return result;
337 }
338
339 /**
340  * fde event handler for the "sendall" syscall group
341  * @param[in] ev        The event context that sent us here
342  * @param[in] fde       The file descriptor event associated with the send
343  * @param[in] flags     Can only be TEVENT_FD_WRITE here
344  * @param[in] priv      private data, "struct async_req *" in this case
345  */
346
347 static void async_sendall_callback(struct tevent_context *ev,
348                                    struct tevent_fd *fde, uint16_t flags,
349                                    void *priv)
350 {
351         struct async_req *req = talloc_get_type_abort(
352                 priv, struct async_req);
353         struct async_syscall_state *state = talloc_get_type_abort(
354                 req->private_data, struct async_syscall_state);
355         struct param_sendall *p = &state->param.param_sendall;
356
357         if (state->syscall_type != ASYNC_SYSCALL_SENDALL) {
358                 async_req_error(req, EIO);
359                 return;
360         }
361
362         state->result.result_ssize_t = send(p->fd,
363                                             (const char *)p->buffer + p->sent,
364                                             p->length - p->sent, p->flags);
365         state->sys_errno = errno;
366
367         if (state->result.result_ssize_t == -1) {
368                 async_req_error(req, state->sys_errno);
369                 return;
370         }
371
372         if (state->result.result_ssize_t == 0) {
373                 async_req_error(req, EOF);
374                 return;
375         }
376
377         p->sent += state->result.result_ssize_t;
378         if (p->sent > p->length) {
379                 async_req_error(req, EIO);
380                 return;
381         }
382
383         if (p->sent == p->length) {
384                 TALLOC_FREE(state->fde);
385                 async_req_done(req);
386         }
387 }
388
389 /**
390  * @brief Send all bytes to a socket
391  * @param[in] mem_ctx   The memory context to hang the result off
392  * @param[in] ev        The event context to work from
393  * @param[in] fd        The socket to send to
394  * @param[in] buffer    The buffer to send
395  * @param[in] length    How many bytes to send
396  * @param[in] flags     flags passed to send(2)
397  *
398  * async_sendall calls send(2) as long as it is necessary to send all of the
399  * "length" bytes
400  */
401
402 struct async_req *sendall_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev,
403                                int fd, const void *buffer, size_t length,
404                                int flags)
405 {
406         struct async_req *result;
407         struct async_syscall_state *state;
408
409         result = async_fde_syscall_new(
410                 mem_ctx, ev, ASYNC_SYSCALL_SENDALL,
411                 fd, TEVENT_FD_WRITE, async_sendall_callback,
412                 &state);
413         if (result == NULL) {
414                 return NULL;
415         }
416
417         state->param.param_sendall.fd = fd;
418         state->param.param_sendall.buffer = buffer;
419         state->param.param_sendall.length = length;
420         state->param.param_sendall.flags = flags;
421         state->param.param_sendall.sent = 0;
422
423         return result;
424 }
425
426 ssize_t sendall_recv(struct async_req *req, int *perr)
427 {
428         struct async_syscall_state *state = talloc_get_type_abort(
429                 req->private_data, struct async_syscall_state);
430         int err;
431
432         err = async_req_simple_recv_errno(req);
433
434         if (err != 0) {
435                 *perr = err;
436                 return -1;
437         }
438
439         return state->result.result_ssize_t;
440 }
441
442 /**
443  * fde event handler for the "recv" syscall
444  * @param[in] ev        The event context that sent us here
445  * @param[in] fde       The file descriptor event associated with the recv
446  * @param[in] flags     Can only be TEVENT_FD_READ here
447  * @param[in] priv      private data, "struct async_req *" in this case
448  */
449
450 static void async_recv_callback(struct tevent_context *ev,
451                                 struct tevent_fd *fde, uint16_t flags,
452                                 void *priv)
453 {
454         struct async_req *req = talloc_get_type_abort(
455                 priv, struct async_req);
456         struct async_syscall_state *state = talloc_get_type_abort(
457                 req->private_data, struct async_syscall_state);
458         struct param_recv *p = &state->param.param_recv;
459
460         if (state->syscall_type != ASYNC_SYSCALL_RECV) {
461                 async_req_error(req, EIO);
462                 return;
463         }
464
465         state->result.result_ssize_t = recv(p->fd, p->buffer, p->length,
466                                             p->flags);
467         state->sys_errno = errno;
468
469         TALLOC_FREE(state->fde);
470
471         async_req_done(req);
472 }
473
474 /**
475  * Async version of recv(2)
476  * @param[in] mem_ctx   The memory context to hang the result off
477  * @param[in] ev        The event context to work from
478  * @param[in] fd        The socket to recv from
479  * @param[in] buffer    The buffer to recv into
480  * @param[in] length    How many bytes to recv
481  * @param[in] flags     flags passed to recv(2)
482  *
483  * This function is a direct counterpart of recv(2)
484  */
485
486 struct async_req *async_recv(TALLOC_CTX *mem_ctx, struct tevent_context *ev,
487                              int fd, void *buffer, size_t length,
488                              int flags)
489 {
490         struct async_req *result;
491         struct async_syscall_state *state;
492
493         result = async_fde_syscall_new(
494                 mem_ctx, ev, ASYNC_SYSCALL_RECV,
495                 fd, TEVENT_FD_READ, async_recv_callback,
496                 &state);
497
498         if (result == NULL) {
499                 return NULL;
500         }
501
502         state->param.param_recv.fd = fd;
503         state->param.param_recv.buffer = buffer;
504         state->param.param_recv.length = length;
505         state->param.param_recv.flags = flags;
506
507         return result;
508 }
509
510 /**
511  * fde event handler for the "recvall" syscall group
512  * @param[in] ev        The event context that sent us here
513  * @param[in] fde       The file descriptor event associated with the recv
514  * @param[in] flags     Can only be TEVENT_FD_READ here
515  * @param[in] priv      private data, "struct async_req *" in this case
516  */
517
518 static void async_recvall_callback(struct tevent_context *ev,
519                                    struct tevent_fd *fde, uint16_t flags,
520                                    void *priv)
521 {
522         struct async_req *req = talloc_get_type_abort(
523                 priv, struct async_req);
524         struct async_syscall_state *state = talloc_get_type_abort(
525                 req->private_data, struct async_syscall_state);
526         struct param_recvall *p = &state->param.param_recvall;
527
528         if (state->syscall_type != ASYNC_SYSCALL_RECVALL) {
529                 async_req_error(req, EIO);
530                 return;
531         }
532
533         state->result.result_ssize_t = recv(p->fd,
534                                             (char *)p->buffer + p->received,
535                                             p->length - p->received, p->flags);
536         state->sys_errno = errno;
537
538         if (state->result.result_ssize_t == -1) {
539                 async_req_error(req, state->sys_errno);
540                 return;
541         }
542
543         if (state->result.result_ssize_t == 0) {
544                 async_req_error(req, EIO);
545                 return;
546         }
547
548         p->received += state->result.result_ssize_t;
549         if (p->received > p->length) {
550                 async_req_error(req, EIO);
551                 return;
552         }
553
554         if (p->received == p->length) {
555                 TALLOC_FREE(state->fde);
556                 async_req_done(req);
557         }
558 }
559
560 /**
561  * Receive a specified number of bytes from a socket
562  * @param[in] mem_ctx   The memory context to hang the result off
563  * @param[in] ev        The event context to work from
564  * @param[in] fd        The socket to recv from
565  * @param[in] buffer    The buffer to recv into
566  * @param[in] length    How many bytes to recv
567  * @param[in] flags     flags passed to recv(2)
568  *
569  * async_recvall will call recv(2) until "length" bytes are received
570  */
571
572 struct async_req *recvall_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev,
573                                int fd, void *buffer, size_t length,
574                                int flags)
575 {
576         struct async_req *result;
577         struct async_syscall_state *state;
578
579         result = async_fde_syscall_new(
580                 mem_ctx, ev, ASYNC_SYSCALL_RECVALL,
581                 fd, TEVENT_FD_READ, async_recvall_callback,
582                 &state);
583         if (result == NULL) {
584                 return NULL;
585         }
586
587         state->param.param_recvall.fd = fd;
588         state->param.param_recvall.buffer = buffer;
589         state->param.param_recvall.length = length;
590         state->param.param_recvall.flags = flags;
591         state->param.param_recvall.received = 0;
592
593         return result;
594 }
595
596 ssize_t recvall_recv(struct async_req *req, int *perr)
597 {
598         struct async_syscall_state *state = talloc_get_type_abort(
599                 req->private_data, struct async_syscall_state);
600         int err;
601
602         err = async_req_simple_recv_errno(req);
603
604         if (err != 0) {
605                 *perr = err;
606                 return -1;
607         }
608
609         return state->result.result_ssize_t;
610 }
611
612 struct async_connect_state {
613         int fd;
614         int result;
615         int sys_errno;
616         long old_sockflags;
617 };
618
619 static void async_connect_connected(struct tevent_context *ev,
620                                     struct tevent_fd *fde, uint16_t flags,
621                                     void *priv);
622
623 /**
624  * @brief async version of connect(2)
625  * @param[in] mem_ctx   The memory context to hang the result off
626  * @param[in] ev        The event context to work from
627  * @param[in] fd        The socket to recv from
628  * @param[in] address   Where to connect?
629  * @param[in] address_len Length of *address
630  * @retval The async request
631  *
632  * This function sets the socket into non-blocking state to be able to call
633  * connect in an async state. This will be reset when the request is finished.
634  */
635
636 struct async_req *async_connect_send(TALLOC_CTX *mem_ctx,
637                                      struct tevent_context *ev,
638                                      int fd, const struct sockaddr *address,
639                                      socklen_t address_len)
640 {
641         struct async_req *result;
642         struct async_connect_state *state;
643         struct tevent_fd *fde;
644
645         if (!async_req_setup(mem_ctx, &result, &state,
646                              struct async_connect_state)) {
647                 return NULL;
648         }
649
650         /**
651          * We have to set the socket to nonblocking for async connect(2). Keep
652          * the old sockflags around.
653          */
654
655         state->fd = fd;
656         state->sys_errno = 0;
657
658         state->old_sockflags = fcntl(fd, F_GETFL, 0);
659         if (state->old_sockflags == -1) {
660                 goto post_errno;
661         }
662
663         set_blocking(fd, false);
664
665         state->result = connect(fd, address, address_len);
666         if (state->result == 0) {
667                 state->sys_errno = 0;
668                 goto post_status;
669         }
670
671         /**
672          * A number of error messages show that something good is progressing
673          * and that we have to wait for readability.
674          *
675          * If none of them are present, bail out.
676          */
677
678         if (!(errno == EINPROGRESS || errno == EALREADY ||
679 #ifdef EISCONN
680               errno == EISCONN ||
681 #endif
682               errno == EAGAIN || errno == EINTR)) {
683                 goto post_errno;
684         }
685
686         fde = tevent_add_fd(ev, state, fd, TEVENT_FD_READ | TEVENT_FD_WRITE,
687                            async_connect_connected, result);
688         if (fde == NULL) {
689                 state->sys_errno = ENOMEM;
690                 goto post_status;
691         }
692         return result;
693
694  post_errno:
695         state->sys_errno = errno;
696  post_status:
697         fcntl(fd, F_SETFL, state->old_sockflags);
698         if (!async_post_error(result, ev, state->sys_errno)) {
699                 goto fail;
700         }
701         return result;
702  fail:
703         TALLOC_FREE(result);
704         return NULL;
705 }
706
707 /**
708  * fde event handler for connect(2)
709  * @param[in] ev        The event context that sent us here
710  * @param[in] fde       The file descriptor event associated with the connect
711  * @param[in] flags     Indicate read/writeability of the socket
712  * @param[in] priv      private data, "struct async_req *" in this case
713  */
714
715 static void async_connect_connected(struct tevent_context *ev,
716                                     struct tevent_fd *fde, uint16_t flags,
717                                     void *priv)
718 {
719         struct async_req *req = talloc_get_type_abort(
720                 priv, struct async_req);
721         struct async_connect_state *state = talloc_get_type_abort(
722                 req->private_data, struct async_connect_state);
723
724         TALLOC_FREE(fde);
725
726         /*
727          * Stevens, Network Programming says that if there's a
728          * successful connect, the socket is only writable. Upon an
729          * error, it's both readable and writable.
730          */
731         if ((flags & (TEVENT_FD_READ|TEVENT_FD_WRITE))
732             == (TEVENT_FD_READ|TEVENT_FD_WRITE)) {
733                 int sockerr;
734                 socklen_t err_len = sizeof(sockerr);
735
736                 if (getsockopt(state->fd, SOL_SOCKET, SO_ERROR,
737                                (void *)&sockerr, &err_len) == 0) {
738                         errno = sockerr;
739                 }
740
741                 state->sys_errno = errno;
742
743                 DEBUG(10, ("connect returned %s\n", strerror(errno)));
744
745                 fcntl(state->fd, F_SETFL, state->old_sockflags);
746                 async_req_error(req, state->sys_errno);
747                 return;
748         }
749
750         state->sys_errno = 0;
751         async_req_done(req);
752 }
753
754 int async_connect_recv(struct async_req *req, int *perrno)
755 {
756         struct async_connect_state *state = talloc_get_type_abort(
757                 req->private_data, struct async_connect_state);
758         int err;
759
760         fcntl(state->fd, F_SETFL, state->old_sockflags);
761
762
763         if (async_req_is_errno(req, &err)) {
764                 *perrno = err;
765                 return -1;
766         }
767         if (state->sys_errno == 0) {
768                 return 0;
769         }
770
771         *perrno = state->sys_errno;
772         return -1;
773 }