1 /*
2 
3   Copyright (c) 2017 Martin Sustrik
4 
5   Permission is hereby granted, free of charge, to any person obtaining a copy
6   of this software and associated documentation files (the "Software"),
7   to deal in the Software without restriction, including without limitation
8   the rights to use, copy, modify, merge, publish, distribute, sublicense,
9   and/or sell copies of the Software, and to permit persons to whom
10   the Software is furnished to do so, subject to the following conditions:
11 
12   The above copyright notice and this permission notice shall be included
13   in all copies or substantial portions of the Software.
14 
15   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18   THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21   IN THE SOFTWARE.
22 
23 */
24 
25 #ifndef LIBDILL_H_INCLUDED
26 #define LIBDILL_H_INCLUDED
27 
28 #include <errno.h>
29 #include <setjmp.h>
30 #include <stddef.h>
31 #include <stdint.h>
32 #include <stdlib.h>
33 #include <unistd.h>
34 
35 #if defined __linux__
36 #include <alloca.h>
37 #endif
38 
39 /******************************************************************************/
40 /*  ABI versioning support                                                    */
41 /******************************************************************************/
42 
43 /*  Don't change this unless you know exactly what you're doing and have      */
44 /*  read and understood the following documents:                              */
45 /*  www.gnu.org/software/libtool/manual/html_node/Libtool-versioning.html     */
46 /*  www.gnu.org/software/libtool/manual/html_node/Updating-version-info.html  */
47 
48 /*  The current interface version. */
49 #define DILL_VERSION_CURRENT 25
50 
51 /*  The latest revision of the current interface. */
52 #define DILL_VERSION_REVISION 0
53 
54 /*  How many past interface versions are still supported. */
55 #define DILL_VERSION_AGE 5
56 
57 /******************************************************************************/
58 /*  Symbol visibility                                                         */
59 /******************************************************************************/
60 
61 #if !defined __GNUC__ && !defined __clang__
62 #error "Unsupported compiler!"
63 #endif
64 
65 #if DILL_NO_EXPORTS
66 #define DILL_EXPORT
67 #else
68 #define DILL_EXPORT __attribute__ ((visibility("default")))
69 #endif
70 
71 /* Old versions of GCC don't support visibility attribute. */
72 #if defined __GNUC__ && __GNUC__ < 4
73 #undef DILL_EXPORT
74 #define DILL_EXPORT
75 #endif
76 
77 #ifdef __cplusplus
78 extern "C" {
79 #endif
80 
81 /******************************************************************************/
82 /*  Helpers                                                                   */
83 /******************************************************************************/
84 
85 DILL_EXPORT int dill_fdclean(int fd);
86 DILL_EXPORT int dill_fdin(int fd, int64_t deadline);
87 DILL_EXPORT int dill_fdout(int fd, int64_t deadline);
88 DILL_EXPORT int64_t dill_now(void);
89 DILL_EXPORT int dill_msleep(int64_t deadline);
90 
91 #if !defined DILL_DISABLE_RAW_NAMES
92 #define fdclean dill_fdclean
93 #define fdin dill_fdin
94 #define fdout dill_fdout
95 #define now dill_now
96 #define msleep dill_msleep
97 #endif
98 
99 /******************************************************************************/
100 /*  Handles                                                                   */
101 /******************************************************************************/
102 
103 DILL_EXPORT int dill_hown(int h);
104 DILL_EXPORT int dill_hclose(int h);
105 
106 #if !defined DILL_DISABLE_RAW_NAMES
107 #define hown dill_hown
108 #define hclose dill_hclose
109 #endif
110 
111 /******************************************************************************/
112 /*  Coroutines                                                                */
113 /******************************************************************************/
114 
115 #define dill_coroutine __attribute__((noinline))
116 
117 DILL_EXPORT extern volatile void *dill_unoptimisable;
118 
119 DILL_EXPORT __attribute__((noinline)) int dill_prologue(sigjmp_buf **ctx,
120     void **ptr, size_t len, int bndl, const char *file, int line);
121 DILL_EXPORT __attribute__((noinline)) void dill_epilogue(void);
122 
123 /* The following macros use alloca(sizeof(size_t)) because clang
124    doesn't support alloca with size zero. */
125 
126 /* This assembly setjmp/longjmp mechanism is in the same order as glibc and
127    musl, but glibc implements pointer mangling, which is hard to support.
128    This should be binary-compatible with musl, though. */
129 
130 /* Stack-switching on X86-64. */
131 #if defined(__x86_64__) && !defined DILL_ARCH_FALLBACK
132 #define dill_setjmp(ctx) ({\
133     int ret;\
134     asm("lea     LJMPRET%=(%%rip), %%rcx\n\t"\
135         "xor     %%rax, %%rax\n\t"\
136         "mov     %%rbx, (%%rdx)\n\t"\
137         "mov     %%rbp, 8(%%rdx)\n\t"\
138         "mov     %%r12, 16(%%rdx)\n\t"\
139         "mov     %%r13, 24(%%rdx)\n\t"\
140         "mov     %%r14, 32(%%rdx)\n\t"\
141         "mov     %%r15, 40(%%rdx)\n\t"\
142         "mov     %%rsp, 48(%%rdx)\n\t"\
143         "mov     %%rcx, 56(%%rdx)\n\t"\
144         "LJMPRET%=:\n\t"\
145         : "=a" (ret)\
146         : "d" (ctx)\
147         : "memory", "rcx", "rsi", "rdi", "r8", "r9", "r10", "r11", "cc");\
148     ret;\
149 })
150 #define dill_longjmp(ctx) \
151     asm("movq   56(%%rdx), %%rcx\n\t"\
152         "movq   48(%%rdx), %%rsp\n\t"\
153         "movq   40(%%rdx), %%r15\n\t"\
154         "movq   32(%%rdx), %%r14\n\t"\
155         "movq   24(%%rdx), %%r13\n\t"\
156         "movq   16(%%rdx), %%r12\n\t"\
157         "movq   8(%%rdx), %%rbp\n\t"\
158         "movq   (%%rdx), %%rbx\n\t"\
159         ".cfi_def_cfa %%rdx, 0 \n\t"\
160         ".cfi_offset %%rbx, 0 \n\t"\
161         ".cfi_offset %%rbp, 8 \n\t"\
162         ".cfi_offset %%r12, 16 \n\t"\
163         ".cfi_offset %%r13, 24 \n\t"\
164         ".cfi_offset %%r14, 32 \n\t"\
165         ".cfi_offset %%r15, 40 \n\t"\
166         ".cfi_offset %%rsp, 48 \n\t"\
167         ".cfi_offset %%rip, 56 \n\t"\
168         "jmp    *%%rcx\n\t"\
169         : : "d" (ctx), "a" (1))
170 #define dill_setsp(x) \
171     asm(""::"r"(alloca(sizeof(size_t))));\
172     asm volatile("leaq (%%rax), %%rsp"::"rax"(x));
173 
174 /* Stack switching on X86. */
175 #elif defined(__i386__) && !defined DILL_ARCH_FALLBACK
176 #define dill_setjmp(ctx) ({\
177     int ret;\
178     asm("movl   $LJMPRET%=, %%ecx\n\t"\
179         "movl   %%ebx, (%%edx)\n\t"\
180         "movl   %%esi, 4(%%edx)\n\t"\
181         "movl   %%edi, 8(%%edx)\n\t"\
182         "movl   %%ebp, 12(%%edx)\n\t"\
183         "movl   %%esp, 16(%%edx)\n\t"\
184         "movl   %%ecx, 20(%%edx)\n\t"\
185         "xorl   %%eax, %%eax\n\t"\
186         "LJMPRET%=:\n\t"\
187         : "=a" (ret) : "d" (ctx) : "memory");\
188     ret;\
189 })
190 #define dill_longjmp(ctx) \
191     asm("movl   (%%edx), %%ebx\n\t"\
192         "movl   4(%%edx), %%esi\n\t"\
193         "movl   8(%%edx), %%edi\n\t"\
194         "movl   12(%%edx), %%ebp\n\t"\
195         "movl   16(%%edx), %%esp\n\t"\
196         "movl   20(%%edx), %%ecx\n\t"\
197         ".cfi_def_cfa %%edx, 0 \n\t"\
198         ".cfi_offset %%ebx, 0 \n\t"\
199         ".cfi_offset %%esi, 4 \n\t"\
200         ".cfi_offset %%edi, 8 \n\t"\
201         ".cfi_offset %%ebp, 12 \n\t"\
202         ".cfi_offset %%esp, 16 \n\t"\
203         ".cfi_offset %%eip, 20 \n\t"\
204         "jmp    *%%ecx\n\t"\
205         : : "d" (ctx), "a" (1))
206 #define dill_setsp(x) \
207     asm(""::"r"(alloca(sizeof(size_t))));\
208     asm volatile("leal (%%eax), %%esp"::"eax"(x));
209 
210 /* Stack-switching on other microarchitectures. */
211 #else
212 #define dill_setjmp(ctx) sigsetjmp(ctx, 0)
213 #define dill_longjmp(ctx) siglongjmp(ctx, 1)
214 /* For newer GCCs, -fstack-protector breaks on this; use -fno-stack-protector.
215    Alternatively, implement a custom dill_setsp for your microarchitecture. */
216 #define dill_setsp(x) \
217     dill_unoptimisable = alloca((char*)alloca(sizeof(size_t)) - (char*)(x));
218 #endif
219 
220 /* Statement expressions are a gcc-ism but they are also supported by clang.
221    Given that there's no other way to do this, screw other compilers for now.
222    See https://gcc.gnu.org/onlinedocs/gcc-3.2/gcc/Statement-Exprs.html */
223 
224 /* A bug in gcc have been observed where name clash between variable in the
225    outer scope and a local variable in this macro causes the variable to
226    get weird values. To avoid that, we use fancy names (dill_*__). */
227 
228 #define dill_go_(fn, ptr, len, bndl) \
229     ({\
230         sigjmp_buf *dill_ctx__;\
231         void *dill_stk__ = (ptr);\
232         int dill_handle__ = dill_prologue(&dill_ctx__, &dill_stk__, (len),\
233             (bndl), __FILE__, __LINE__);\
234         if(dill_handle__ >= 0) {\
235             if(!dill_setjmp(*dill_ctx__)) {\
236                 dill_setsp(dill_stk__);\
237                 fn;\
238                 dill_epilogue();\
239             }\
240         }\
241         dill_handle__;\
242     })
243 
244 #define dill_go(fn) dill_go_(fn, NULL, 0, -1)
245 #define dill_go_mem(fn, ptr, len) dill_go_(fn, ptr, len, -1)
246 
247 #define dill_bundle_go(bndl, fn) dill_go_(fn, NULL, 0, bndl)
248 #define dill_bundle_go_mem(bndl, fn, ptr, len) dill_go_(fn, ptr, len, bndl)
249 
250 struct dill_bundle_storage {char _[64];};
251 
252 DILL_EXPORT int dill_bundle(void);
253 DILL_EXPORT int dill_bundle_mem(struct dill_bundle_storage *mem);
254 DILL_EXPORT int dill_bundle_wait(int h, int64_t deadline);
255 DILL_EXPORT int dill_yield(void);
256 
257 #if !defined DILL_DISABLE_RAW_NAMES
258 #define coroutine dill_coroutine
259 #define go dill_go
260 #define go_mem dill_go_mem
261 #define bundle_go dill_bundle_go
262 #define bundle_go_mem dill_bundle_go_mem
263 #define bundle_storage dill_bundle_storage
264 #define bundle dill_bundle
265 #define bundle_mem dill_bundle_mem
266 #define bundle_wait dill_bundle_wait
267 #define yield dill_yield
268 #endif
269 
270 /******************************************************************************/
271 /*  Channels                                                                  */
272 /******************************************************************************/
273 
274 #define DILL_CHSEND 1
275 #define DILL_CHRECV 2
276 
277 struct dill_chclause {
278     int op;
279     int ch;
280     void *val;
281     size_t len;
282 };
283 
284 struct dill_chstorage {char _[144];};
285 
286 DILL_EXPORT int dill_chmake(
287     int chv[2]);
288 DILL_EXPORT int dill_chmake_mem(
289     struct dill_chstorage *mem,
290     int chv[2]);
291 DILL_EXPORT int dill_chsend(
292     int ch,
293     const void *val,
294     size_t len,
295     int64_t deadline);
296 DILL_EXPORT int dill_chrecv(
297     int ch,
298     void *val,
299     size_t len,
300     int64_t deadline);
301 DILL_EXPORT int dill_chdone(
302     int ch);
303 DILL_EXPORT int dill_choose(
304     struct dill_chclause *clauses,
305     int nclauses,
306     int64_t deadline);
307 
308 #if !defined DILL_DISABLE_RAW_NAMES
309 #define CHSEND DILL_CHSEND
310 #define CHRECV DILL_CHRECV
311 #define chclause dill_chclause
312 #define chstorage dill_chstorage
313 #define chmake dill_chmake
314 #define chmake_mem dill_chmake_mem
315 #define chsend dill_chsend
316 #define chrecv dill_chrecv
317 #define chdone dill_chdone
318 #define choose dill_choose
319 #endif
320 
321 #if !defined DILL_DISABLE_SOCKETS
322 
323 /******************************************************************************/
324 /*  Gather/scatter list.                                                      */
325 /******************************************************************************/
326 
327 struct dill_iolist {
328     void *iol_base;
329     size_t iol_len;
330     struct dill_iolist *iol_next;
331     int iol_rsvd;
332 };
333 
334 #if !defined DILL_DISABLE_RAW_NAMES
335 #define iolist dill_iolist
336 #endif
337 
338 /******************************************************************************/
339 /*  Bytestream sockets.                                                       */
340 /******************************************************************************/
341 
342 DILL_EXPORT int dill_bsend(
343     int s,
344     const void *buf,
345     size_t len,
346     int64_t deadline);
347 DILL_EXPORT int dill_brecv(
348     int s,
349     void *buf,
350     size_t len,
351     int64_t deadline);
352 DILL_EXPORT int dill_bsendl(
353     int s,
354     struct dill_iolist *first,
355     struct dill_iolist *last,
356     int64_t deadline);
357 DILL_EXPORT int dill_brecvl(
358     int s,
359     struct dill_iolist *first,
360     struct dill_iolist *last,
361     int64_t deadline);
362 
363 #if !defined DILL_DISABLE_RAW_NAMES
364 #define bsend dill_bsend
365 #define brecv dill_brecv
366 #define bsendl dill_bsendl
367 #define brecvl dill_brecvl
368 #endif
369 
370 /******************************************************************************/
371 /*  Message sockets.                                                          */
372 /******************************************************************************/
373 
374 DILL_EXPORT int dill_msend(
375     int s,
376     const void *buf,
377     size_t len,
378     int64_t deadline);
379 DILL_EXPORT ssize_t dill_mrecv(
380     int s,
381     void *buf,
382     size_t len,
383     int64_t deadline);
384 DILL_EXPORT int dill_msendl(
385     int s,
386     struct dill_iolist *first,
387     struct dill_iolist *last,
388     int64_t deadline);
389 DILL_EXPORT ssize_t dill_mrecvl(
390     int s,
391     struct dill_iolist *first,
392     struct dill_iolist *last,
393     int64_t deadline);
394 
395 #if !defined DILL_DISABLE_RAW_NAMES
396 #define msend dill_msend
397 #define mrecv dill_mrecv
398 #define msendl dill_msendl
399 #define mrecvl dill_mrecvl
400 #endif
401 
402 /******************************************************************************/
403 /*  IP address resolution.                                                    */
404 /******************************************************************************/
405 
406 struct sockaddr;
407 
408 #define DILL_IPADDR_IPV4 1
409 #define DILL_IPADDR_IPV6 2
410 #define DILL_IPADDR_PREF_IPV4 3
411 #define DILL_IPADDR_PREF_IPV6 4
412 #define DILL_IPADDR_MAXSTRLEN 46
413 
414 struct dill_ipaddr {char _[32];};
415 
416 DILL_EXPORT int dill_ipaddr_local(
417     struct dill_ipaddr *addr,
418     const char *name,
419     int port,
420     int mode);
421 DILL_EXPORT int dill_ipaddr_remote(
422     struct dill_ipaddr *addr,
423     const char *name,
424     int port,
425     int mode,
426     int64_t deadline);
427 DILL_EXPORT int dill_ipaddr_remotes(
428     struct dill_ipaddr *addrs,
429     int naddrs,
430     const char *name,
431     int port,
432     int mode,
433     int64_t deadline);
434 DILL_EXPORT const char *dill_ipaddr_str(
435     const struct dill_ipaddr *addr,
436     char *ipstr);
437 DILL_EXPORT int dill_ipaddr_family(
438     const struct dill_ipaddr *addr);
439 DILL_EXPORT const struct sockaddr *dill_ipaddr_sockaddr(
440     const struct dill_ipaddr *addr);
441 DILL_EXPORT int dill_ipaddr_len(
442     const struct dill_ipaddr *addr);
443 DILL_EXPORT int dill_ipaddr_port(
444     const struct dill_ipaddr *addr);
445 DILL_EXPORT void dill_ipaddr_setport(
446     struct dill_ipaddr *addr,
447     int port);
448 DILL_EXPORT int dill_ipaddr_equal(
449     const struct dill_ipaddr *addr1,
450     const struct dill_ipaddr *addr2,
451     int ignore_port);
452 
453 #if !defined DILL_DISABLE_RAW_NAMES
454 #define IPADDR_IPV4 DILL_IPADDR_IPV4
455 #define IPADDR_IPV6 DILL_IPADDR_IPV6
456 #define IPADDR_PREF_IPV4 DILL_IPADDR_PREF_IPV4
457 #define IPADDR_PREF_IPV6 DILL_IPADDR_PREF_IPV6
458 #define IPADDR_MAXSTRLEN DILL_IPADDR_MAXSTRLEN
459 #define ipaddr dill_ipaddr
460 #define ipaddr_local dill_ipaddr_local
461 #define ipaddr_remote dill_ipaddr_remote
462 #define ipaddr_remotes dill_ipaddr_remotes
463 #define ipaddr_str dill_ipaddr_str
464 #define ipaddr_family dill_ipaddr_family
465 #define ipaddr_sockaddr dill_ipaddr_sockaddr
466 #define ipaddr_len dill_ipaddr_len
467 #define ipaddr_port dill_ipaddr_port
468 #define ipaddr_setport dill_ipaddr_setport
469 #define ipaddr_equal dill_ipaddr_equal
470 #endif
471 
472 /******************************************************************************/
473 /*  TCP protocol.                                                             */
474 /******************************************************************************/
475 
476 struct dill_tcp_listener_storage {char _[56];};
477 
478 struct dill_tcp_storage {char _[72];};
479 
480 DILL_EXPORT int dill_tcp_listen(
481     struct dill_ipaddr *addr,
482     int backlog);
483 DILL_EXPORT int dill_tcp_listen_mem(
484     struct dill_ipaddr *addr,
485     int backlog,
486     struct dill_tcp_listener_storage *mem);
487 DILL_EXPORT int dill_tcp_accept(
488     int s,
489     struct dill_ipaddr *addr,
490     int64_t deadline);
491 DILL_EXPORT int dill_tcp_accept_mem(
492     int s,
493     struct dill_ipaddr *addr,
494     struct dill_tcp_storage *mem,
495     int64_t deadline);
496 DILL_EXPORT int dill_tcp_connect(
497     const struct dill_ipaddr *addr,
498     int64_t deadline);
499 DILL_EXPORT int dill_tcp_connect_mem(
500     const struct dill_ipaddr *addr,
501     struct dill_tcp_storage *mem,
502     int64_t deadline);
503 DILL_EXPORT int dill_tcp_done(
504     int s,
505     int64_t deadline);
506 DILL_EXPORT int dill_tcp_close(
507     int s,
508     int64_t deadline);
509 DILL_EXPORT int dill_tcp_listener_fromfd(
510     int fd);
511 DILL_EXPORT int dill_tcp_listener_fromfd_mem(
512     int fd,
513     struct dill_tcp_listener_storage *mem);
514 DILL_EXPORT int dill_tcp_fromfd(
515     int fd);
516 DILL_EXPORT int dill_tcp_fromfd_mem(
517     int fd,
518     struct dill_tcp_storage *mem);
519 
520 #if !defined DILL_DISABLE_RAW_NAMES
521 #define tcp_listener_storage dill_tcp_listener_storage
522 #define tcp_storage dill_tcp_storage
523 #define tcp_listen dill_tcp_listen
524 #define tcp_listen_mem dill_tcp_listen_mem
525 #define tcp_accept dill_tcp_accept
526 #define tcp_accept_mem dill_tcp_accept_mem
527 #define tcp_connect dill_tcp_connect
528 #define tcp_connect_mem dill_tcp_connect_mem
529 #define tcp_done dill_tcp_done
530 #define tcp_close dill_tcp_close
531 #define tcp_listener_fromfd dill_tcp_listener_fromfd
532 #define tcp_listener_fromfd_mem dill_tcp_listener_fromfd_mem
533 #define tcp_fromfd dill_tcp_fromfd
534 #define tcp_fromfd_mem dill_tcp_fromfd_mem
535 #endif
536 
537 /******************************************************************************/
538 /*  IPC protocol.                                                            */
539 /******************************************************************************/
540 
541 struct dill_ipc_listener_storage {char _[24];};
542 
543 struct dill_ipc_storage {char _[72];};
544 
545 struct dill_ipc_pair_storage {char _[144];};
546 
547 DILL_EXPORT int dill_ipc_listen(
548     const char *addr,
549     int backlog);
550 DILL_EXPORT int dill_ipc_listen_mem(
551     const char *addr,
552     int backlog,
553     struct dill_ipc_listener_storage *mem);
554 DILL_EXPORT int dill_ipc_accept(
555     int s,
556     int64_t deadline);
557 DILL_EXPORT int dill_ipc_accept_mem(
558     int s,
559     struct dill_ipc_storage *mem,
560     int64_t deadline);
561 DILL_EXPORT int dill_ipc_connect(
562     const char *addr,
563     int64_t deadline);
564 DILL_EXPORT int dill_ipc_connect_mem(
565     const char *addr,
566     struct dill_ipc_storage *mem,
567     int64_t deadline);
568 DILL_EXPORT int dill_ipc_sendfd(
569     int s,
570     int fd,
571     int64_t deadline);
572 DILL_EXPORT int dill_ipc_recvfd(
573     int s,
574     int64_t deadline);
575 DILL_EXPORT int dill_ipc_done(
576     int s,
577     int64_t deadline);
578 DILL_EXPORT int dill_ipc_close(
579     int s,
580     int64_t deadline);
581 DILL_EXPORT int dill_ipc_listener_fromfd(
582     int fd);
583 DILL_EXPORT int dill_ipc_listener_fromfd_mem(
584     int fd,
585     struct dill_ipc_listener_storage *mem);
586 DILL_EXPORT int dill_ipc_fromfd(
587     int fd);
588 DILL_EXPORT int dill_ipc_fromfd_mem(
589     int fd,
590     struct dill_ipc_storage *mem);
591 DILL_EXPORT int dill_ipc_pair(
592     int s[2]);
593 DILL_EXPORT int dill_ipc_pair_mem(
594     struct dill_ipc_pair_storage *mem,
595     int s[2]);
596 
597 #if !defined DILL_DISABLE_RAW_NAMES
598 #define ipc_listener_storage dill_ipc_listener_storage
599 #define ipc_storage dill_ipc_storage
600 #define ipc_pair_storage dill_ipc_pair_storage
601 #define ipc_listen dill_ipc_listen
602 #define ipc_listen_mem dill_ipc_listen_mem
603 #define ipc_accept dill_ipc_accept
604 #define ipc_accept_mem dill_ipc_accept_mem
605 #define ipc_connect dill_ipc_connect
606 #define ipc_connect_mem dill_ipc_connect_mem
607 #define ipc_sendfd dill_ipc_sendfd
608 #define ipc_recvfd dill_ipc_recvfd
609 #define ipc_done dill_ipc_done
610 #define ipc_close dill_ipc_close
611 #define ipc_listener_fromfd dill_ipc_listener_fromfd
612 #define ipc_listener_fromfd_mem dill_ipc_listener_fromfd_mem
613 #define ipc_fromfd dill_ipc_fromfd
614 #define ipc_fromfd_mem dill_ipc_fromfd_mem
615 #define ipc_pair dill_ipc_pair
616 #define ipc_pair_mem dill_ipc_pair_mem
617 #endif
618 
619 /******************************************************************************/
620 /*  PREFIX protocol.                                                          */
621 /*  Messages are prefixed by size.                                            */
622 /******************************************************************************/
623 
624 struct dill_prefix_storage {char _[56];};
625 
626 #define DILL_PREFIX_BIG_ENDIAN 0
627 #define DILL_PREFIX_LITTLE_ENDIAN 1
628 
629 DILL_EXPORT int dill_prefix_attach(
630     int s,
631     size_t hdrlen,
632     int flags);
633 DILL_EXPORT int dill_prefix_attach_mem(
634     int s,
635     size_t hdrlen,
636     int flags,
637     struct dill_prefix_storage *mem);
638 DILL_EXPORT int dill_prefix_detach(
639     int s);
640 
641 #if !defined DILL_DISABLE_RAW_NAMES
642 #define PREFIX_BIG_ENDIAN DILL_PREFIX_BIG_ENDIAN
643 #define PREFIX_LITTLE_ENDIAN DILL_PREFIX_LITTLE_ENDIAN
644 #define prefix_storage dill_prefix_storage
645 #define prefix_attach dill_prefix_attach
646 #define prefix_attach_mem dill_prefix_attach_mem
647 #define prefix_detach dill_prefix_detach
648 #endif
649 
650 /******************************************************************************/
651 /*  SUFFIX protocol.                                                          */
652 /*  Messages are suffixed by specified string of bytes.                       */
653 /******************************************************************************/
654 
655 struct dill_suffix_storage {char _[128];};
656 
657 DILL_EXPORT int dill_suffix_attach(
658     int s,
659     const void *suffix,
660     size_t suffixlen);
661 DILL_EXPORT int dill_suffix_attach_mem(
662     int s,
663     const void *suffix,
664     size_t suffixlen,
665     struct dill_suffix_storage *mem);
666 DILL_EXPORT int dill_suffix_detach(
667     int s,
668     int64_t deadline);
669 
670 #if !defined DILL_DISABLE_RAW_NAMES
671 #define suffix_storage dill_suffix_storage
672 #define suffix_attach dill_suffix_attach
673 #define suffix_attach_mem dill_suffix_attach_mem
674 #define suffix_detach dill_suffix_detach
675 #endif
676 
677 /******************************************************************************/
678 /*  UDP protocol.                                                             */
679 /*  Each UDP packet is treated as a separate message.                         */
680 /******************************************************************************/
681 
682 struct dill_udp_storage {char _[72];};
683 
684 DILL_EXPORT int dill_udp_open(
685     struct dill_ipaddr *local,
686     const struct dill_ipaddr *remote);
687 DILL_EXPORT int dill_udp_open_mem(
688     struct dill_ipaddr *local,
689     const struct dill_ipaddr *remote,
690     struct dill_udp_storage *mem);
691 DILL_EXPORT int dill_udp_send(
692     int s,
693     const struct dill_ipaddr *addr,
694     const void *buf,
695     size_t len);
696 DILL_EXPORT ssize_t dill_udp_recv(
697     int s,
698     struct dill_ipaddr *addr,
699     void *buf,
700     size_t len,
701     int64_t deadline);
702 DILL_EXPORT int dill_udp_sendl(
703     int s,
704     const struct dill_ipaddr *addr,
705     struct dill_iolist *first,
706     struct dill_iolist *last);
707 DILL_EXPORT ssize_t dill_udp_recvl(
708     int s,
709     struct dill_ipaddr *addr,
710     struct dill_iolist *first,
711     struct dill_iolist *last,
712     int64_t deadline);
713 
714 #if !defined DILL_DISABLE_RAW_NAMES
715 #define udp_storage dill_udp_storage
716 #define udp_open dill_udp_open
717 #define udp_open_mem dill_udp_open_mem
718 #define udp_send dill_udp_send
719 #define udp_recv dill_udp_recv
720 #define udp_sendl dill_udp_sendl
721 #define udp_recvl dill_udp_recvl
722 #endif
723 
724 /******************************************************************************/
725 /*  HTTP                                                                      */
726 /******************************************************************************/
727 
728 struct dill_http_storage {char _[1296];};
729 
730 DILL_EXPORT int dill_http_attach(
731     int s);
732 DILL_EXPORT int dill_http_attach_mem(
733     int s,
734     struct dill_http_storage *mem);
735 DILL_EXPORT int dill_http_done(
736     int s,
737     int64_t deadline);
738 DILL_EXPORT int dill_http_detach(
739     int s,
740     int64_t deadline);
741 DILL_EXPORT int dill_http_sendrequest(
742     int s,
743     const char *command,
744     const char *resource,
745     int64_t deadline);
746 DILL_EXPORT int dill_http_recvrequest(
747     int s,
748     char *command,
749     size_t commandlen,
750     char *resource,
751     size_t resourcelen,
752     int64_t deadline);
753 DILL_EXPORT int dill_http_sendstatus(
754     int s,
755     int status,
756     const char *reason,
757     int64_t deadline);
758 DILL_EXPORT int dill_http_recvstatus(
759     int s,
760     char *reason,
761     size_t reasonlen,
762     int64_t deadline);
763 DILL_EXPORT int dill_http_sendfield(
764     int s,
765     const char *name,
766     const char *value,
767     int64_t deadline);
768 DILL_EXPORT int dill_http_recvfield(
769     int s,
770     char *name,
771     size_t namelen,
772     char *value,
773     size_t valuelen,
774     int64_t deadline);
775 
776 #if !defined DILL_DISABLE_RAW_NAMES
777 #define http_storage dill_http_storage
778 #define http_attach dill_http_attach
779 #define http_attach_mem dill_http_attach_mem
780 #define http_done dill_http_done
781 #define http_detach dill_http_detach
782 #define http_sendrequest dill_http_sendrequest
783 #define http_recvrequest dill_http_recvrequest
784 #define http_sendstatus dill_http_sendstatus
785 #define http_recvstatus dill_http_recvstatus
786 #define http_sendfield dill_http_sendfield
787 #define http_recvfield dill_http_recvfield
788 #endif
789 
790 #if !defined DILL_DISABLE_TLS
791 
792 /******************************************************************************/
793 /*  TLS protocol.                                                             */
794 /******************************************************************************/
795 
796 struct dill_tls_storage {char _[72];};
797 
798 DILL_EXPORT int dill_tls_attach_server(
799     int s,
800     const char *cert,
801     const char *pkey,
802     int64_t deadline);
803 DILL_EXPORT int dill_tls_attach_server_mem(
804     int s,
805     const char *cert,
806     const char *pkey,
807     struct dill_tls_storage *mem,
808     int64_t deadline);
809 DILL_EXPORT int dill_tls_attach_client(
810     int s,
811     int64_t deadline);
812 DILL_EXPORT int dill_tls_attach_client_mem(
813     int s,
814     struct dill_tls_storage *mem,
815     int64_t deadline);
816 DILL_EXPORT int dill_tls_done(
817     int s,
818     int64_t deadline);
819 DILL_EXPORT int dill_tls_detach(
820     int s,
821     int64_t deadline);
822 
823 #if !defined DILL_DISABLE_RAW_NAMES
824 #define tls_storage dill_tls_storage
825 #define tls_attach_server dill_tls_attach_server
826 #define tls_attach_server_mem dill_tls_attach_server_mem
827 #define tls_attach_client dill_tls_attach_client
828 #define tls_attach_client_mem dill_tls_attach_client_mem
829 #define tls_done dill_tls_done
830 #define tls_detach dill_tls_detach
831 #endif
832 
833 /******************************************************************************/
834 /*  DTLS protocol.                                                            */
835 /******************************************************************************/
836 
837 struct dill_dtls_storage {char _[88];};
838 
839 DILL_EXPORT int dill_dtls_attach_server(
840     int s,
841     const char *cert,
842     const char *pkey,
843     int64_t deadline);
844 DILL_EXPORT int dill_dtls_attach_server_mem(
845     int s,
846     const char *cert,
847     const char *pkey,
848     struct dill_dtls_storage *mem,
849     int64_t deadline);
850 DILL_EXPORT int dill_dtls_attach_client(
851     int s,
852     int64_t deadline);
853 DILL_EXPORT int dill_dtls_attach_client_mem(
854     int s,
855     struct dill_dtls_storage *mem,
856     int64_t deadline);
857 DILL_EXPORT int dill_dtls_done(
858     int s,
859     int64_t deadline);
860 DILL_EXPORT int dill_dtls_detach(
861     int s,
862     int64_t deadline);
863 
864 #if !defined DILL_DISABLE_RAW_NAMES
865 #define dtls_storage dill_dtls_storage
866 #define dtls_attach_server dill_dtls_attach_server
867 #define dtls_attach_server_mem dill_dtls_attach_server_mem
868 #define dtls_attach_client dill_dtls_attach_client
869 #define dtls_attach_client_mem dill_dtls_attach_client_mem
870 #define dtls_done dill_dtls_done
871 #define dtls_detach dill_dtls_detach
872 #endif
873 
874 #endif
875 
876 /******************************************************************************/
877 /*  WebSockets protocol.                                                      */
878 /******************************************************************************/
879 
880 struct dill_ws_storage {char _[176];};
881 
882 #define DILL_WS_BINARY 0
883 #define DILL_WS_TEXT 1
884 #define DILL_WS_NOHTTP 2
885 
886 DILL_EXPORT int dill_ws_attach_client(
887     int s,
888     int flags,
889     const char *resource,
890     const char *host,
891     int64_t deadline);
892 DILL_EXPORT int dill_ws_attach_client_mem(
893     int s,
894     int flags,
895     const char *resource,
896     const char *host,
897     struct dill_ws_storage *mem,
898     int64_t deadline);
899 DILL_EXPORT int dill_ws_attach_server(
900     int s,
901     int flags,
902     char *resource,
903     size_t resourcelen,
904     char *host,
905     size_t hostlen,
906     int64_t deadline);
907 DILL_EXPORT int dill_ws_attach_server_mem(
908     int s,
909     int flags,
910     char *resource,
911     size_t resourcelen,
912     char *host,
913     size_t hostlen,
914     struct dill_ws_storage *mem,
915     int64_t deadline);
916 DILL_EXPORT int dill_ws_send(
917     int s,
918     int flags,
919     const void *buf,
920     size_t len,
921     int64_t deadline);
922 DILL_EXPORT ssize_t dill_ws_recv(
923     int s,
924     int *flags,
925     void *buf,
926     size_t len,
927     int64_t deadline);
928 DILL_EXPORT int dill_ws_sendl(
929     int s,
930     int flags,
931     struct dill_iolist *first,
932     struct dill_iolist *last,
933     int64_t deadline);
934 DILL_EXPORT ssize_t dill_ws_recvl(
935     int s,
936     int *flags,
937     struct dill_iolist *first,
938     struct dill_iolist *last,
939     int64_t deadline);
940 DILL_EXPORT int dill_ws_done(
941     int s,
942     int status,
943     const void *buf,
944     size_t len,
945     int64_t deadline);
946 DILL_EXPORT int dill_ws_detach(
947     int s,
948     int status,
949     const void *buf,
950     size_t len,
951     int64_t deadline);
952 DILL_EXPORT ssize_t dill_ws_status(
953     int s,
954     int *status,
955     void *buf,
956     size_t len);
957 
958 /* Helper functions for those who want to implement HTTP exchange by hand. */
959 
960 #define WS_KEY_SIZE 32
961 
962 DILL_EXPORT int dill_ws_request_key(
963     char *request_key);
964 DILL_EXPORT int dill_ws_response_key(
965     const char *request_key,
966     char *response_key);
967 
968 #if !defined DILL_DISABLE_RAW_NAMES
969 #define WS_BINARY DILL_WS_BINARY
970 #define WS_TEXT DILL_WS_TEXT
971 #define WS_NOHTTP DILL_WS_NOHTTP
972 #define ws_storage dill_ws_storage
973 #define ws_attach_server dill_ws_attach_server
974 #define ws_attach_server_mem dill_ws_attach_server_mem
975 #define ws_attach_client dill_ws_attach_client
976 #define ws_attach_client_mem dill_ws_attach_client_mem
977 #define ws_send dill_ws_send
978 #define ws_recv dill_ws_recv
979 #define ws_sendl dill_ws_sendl
980 #define ws_recvl dill_ws_recvl
981 #define ws_done dill_ws_done
982 #define ws_detach dill_ws_detach
983 #define ws_status dill_ws_status
984 #define ws_request_key dill_ws_request_key
985 #define ws_response_key dill_ws_response_key
986 #endif
987 
988 /******************************************************************************/
989 /*  SOCKS5                                                                    */
990 /******************************************************************************/
991 
992 // SOCKS5 client commands
993 #define DILL_SOCKS5_CONNECT (0x01)
994 #define DILL_SOCKS5_BIND (0x02)
995 #define DILL_SOCKS5_UDP_ASSOCIATE (0x03)
996 
997 // SOCKS5 server reply codes
998 #define DILL_SOCKS5_SUCCESS (0x00)
999 #define DILL_SOCKS5_GENERAL_FAILURE (0x01)
1000 #define DILL_SOCKS5_CONNECTION_NOT_ALLOWED (0x02)
1001 #define DILL_SOCKS5_NETWORK_UNREACHABLE (0x03)
1002 #define DILL_SOCKS5_HOST_UNREACHABLE (0x04)
1003 #define DILL_SOCKS5_CONNECTION_REFUSED (0x05)
1004 #define DILL_SOCKS5_TTL_EXPIRED (0x06)
1005 #define DILL_SOCKS5_COMMAND_NOT_SUPPORTED (0x07)
1006 #define DILL_SOCKS5_ADDRESS_TYPE_NOT_SUPPORTED (0x08)
1007 
1008 
1009 typedef int dill_socks5_auth_function(const char *username,
1010     const char *password);
1011 
1012 DILL_EXPORT int dill_socks5_client_connect(
1013     int s, const char *username, const char *password,
1014     struct dill_ipaddr *addr, int64_t deadline);
1015 
1016 DILL_EXPORT int dill_socks5_client_connectbyname(
1017     int s, const char *username, const char *password, const char *hostname,
1018     int port, int64_t deadline);
1019 
1020 DILL_EXPORT int dill_socks5_proxy_auth(
1021     int s, dill_socks5_auth_function *auth_fn, int64_t deadline);
1022 
1023 DILL_EXPORT int dill_socks5_proxy_recvcommand(
1024     int s, struct dill_ipaddr *ipaddr, int64_t deadline);
1025 
1026 DILL_EXPORT int dill_socks5_proxy_recvcommandbyname(
1027     int s, char *host, int *port, int64_t deadline);
1028 
1029 DILL_EXPORT int dill_socks5_proxy_sendreply(
1030     int s, int reply, struct dill_ipaddr *ipaddr, int64_t deadline);
1031 
1032 #if !defined DILL_DISABLE_RAW_NAMES
1033 
1034 #define socks5_client_connect dill_socks5_client_connect
1035 #define socks5_client_connectbyname dill_socks5_client_connectbyname
1036 #define socks5_proxy_auth dill_socks5_proxy_auth
1037 #define socks5_proxy_recvcommand dill_socks5_proxy_recvcommand
1038 #define socks5_proxy_recvcommandbyname dill_socks5_proxy_recvcommandbyname
1039 #define socks5_proxy_sendreply dill_socks5_proxy_sendreply
1040 
1041 #define SOCKS5_CONNECT DILL_SOCKS5_CONNECT
1042 #define SOCKS5_BIND DILL_SOCKS5_BIND
1043 #define SOCKS5_UDP_ASSOCIATE DILL_SOCKS5_UDP_ASSOCIATE
1044 
1045 #define SOCKS5_SUCCESS DILL_SOCKS5_SUCCESS
1046 #define SOCKS5_GENERAL_FAILURE DILL_SOCKS5_GENERAL_FAILURE
1047 #define SOCKS5_CONNECTION_NOT_ALLOWED DILL_SOCKS5_CONNECTION_NOT_ALLOWED
1048 #define SOCKS5_NETWORK_UNREACHABLE DILL_SOCKS5_NETWORK_UNREACHABLE
1049 #define SOCKS5_HOST_UNREACHABLE DILL_SOCKS5_HOST_UNREACHABLE
1050 #define SOCKS5_CONNECTION_REFUSED DILL_SOCKS5_CONNECTION_REFUSED
1051 #define SOCKS5_TTL_EXPIRED DILL_SOCKS5_TTL_EXPIRED
1052 #define SOCKS5_COMMAND_NOT_SUPPORTED DILL_SOCKS5_COMMAND_NOT_SUPPORTED
1053 #define SOCKS5_ADDRESS_TYPE_NOT_SUPPORTED DILL_SOCKS5_ADDRESS_TYPE_NOT_SUPPORTED
1054 
1055 #endif /* !defined DILL_DISABLE_RAW_NAMES */
1056 
1057 /******************************************************************************/
1058 /*  TERM protocol.                                                            */
1059 /*  Implementes terminal handshake on the top of any message-based protocol.  */
1060 /******************************************************************************/
1061 
1062 struct dill_term_storage {char _[88];};
1063 
1064 DILL_EXPORT int dill_term_attach(
1065     int s,
1066     const void *buf,
1067     size_t len);
1068 DILL_EXPORT int dill_term_attach_mem(
1069     int s,
1070     const void *buf,
1071     size_t len,
1072     struct dill_term_storage *mem);
1073 DILL_EXPORT int dill_term_done(
1074     int s,
1075     int64_t deadline);
1076 DILL_EXPORT int dill_term_detach(
1077     int s,
1078     int64_t deadline);
1079 
1080 #if !defined DILL_DISABLE_RAW_NAMES
1081 #define term_storage dill_term_storage
1082 #define term_attach dill_term_attach
1083 #define term_attach_mem dill_term_attach_mem
1084 #define term_done dill_term_done
1085 #define term_detach dill_term_detach
1086 #endif
1087 
1088 /******************************************************************************/
1089 /* Happy Eyeballs (RFC 8305).                                                 */
1090 /* Implements concurrent TCP connecting to the remote endpoint.               */
1091 /******************************************************************************/
1092 
1093 int dill_happyeyeballs_connect(const char *name, int port, int64_t deadline);
1094 
1095 #if !defined DILL_DISABLE_RAW_NAMES
1096 #define happyeyeballs_connect dill_happyeyeballs_connect
1097 #endif
1098 
1099 #endif
1100 
1101 #ifdef __cplusplus
1102 }
1103 #endif
1104 
1105 #endif
1106 
1107