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