Overview
Comment: | Add support for UNIX socket addresses |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | unix-sockets |
Files: | files | file ages | folders |
SHA3-256: |
1db6618bb95b2b2f87dd9726669a6f7f |
User & Date: | js on 2021-04-05 16:30:36 |
Other Links: | branch diff | manifest | tags |
Context
2021-04-05
| ||
17:55 | socket.h: Add sa_family_t typedef on Windows check-in: 21a21f6a6b user: js tags: unix-sockets | |
16:30 | Add support for UNIX socket addresses check-in: 1db6618bb9 user: js tags: unix-sockets | |
2021-04-04
| ||
18:46 | Change -[contentsOfURLAtPath:] to return URLs check-in: 9135c5fcb8 user: js tags: trunk | |
Changes
Modified configure.ac from [bfb050aa3d] to [65cee2ac19].
︙ | ︙ | |||
1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 | AC_SUBST(USE_SRCS_SCTP, '${SRCS_SCTP}') ]) AC_CHECK_HEADERS([arpa/inet.h netdb.h]) AC_CHECK_HEADER(netipx/ipx.h, [ AC_DEFINE(OF_HAVE_NETIPX_IPX_H, 1, [Whether we have netipx/ipx.h]) ]) AC_CHECK_MEMBER([struct sockaddr_in6.sin6_addr], [ AC_EGREP_CPP(egrep_cpp_yes, [ #ifdef _WIN32 typedef int BOOL; #endif | > > > | 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 | AC_SUBST(USE_SRCS_SCTP, '${SRCS_SCTP}') ]) AC_CHECK_HEADERS([arpa/inet.h netdb.h]) AC_CHECK_HEADER(netipx/ipx.h, [ AC_DEFINE(OF_HAVE_NETIPX_IPX_H, 1, [Whether we have netipx/ipx.h]) ]) AC_CHECK_HEADERS(sys/un.h, [ AC_DEFINE(OF_HAVE_SYS_UN_H, 1, [Whether we have sys/un.h]) ]) AC_CHECK_MEMBER([struct sockaddr_in6.sin6_addr], [ AC_EGREP_CPP(egrep_cpp_yes, [ #ifdef _WIN32 typedef int BOOL; #endif |
︙ | ︙ | |||
1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 | egrep_cpp_yes #endif ], [ AC_DEFINE(OF_HAVE_IPX, 1, [Whether we have IPX/SPX]) AC_SUBST(USE_SRCS_IPX, '${SRCS_IPX}') ]) ]) AC_CHECK_FUNCS(paccept accept4, break) AC_CHECK_FUNCS(kqueue1 kqueue, [ AC_DEFINE(HAVE_KQUEUE, 1, [Whether we have kqueue]) AC_SUBST(OF_KQUEUE_KERNEL_EVENT_OBSERVER_M, "OFKqueueKernelEventObserver.m") | > > > > > > > > > | 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 | egrep_cpp_yes #endif ], [ AC_DEFINE(OF_HAVE_IPX, 1, [Whether we have IPX/SPX]) AC_SUBST(USE_SRCS_IPX, '${SRCS_IPX}') ]) ]) AC_CHECK_MEMBER(struct sockaddr_un.sun_path, [ AC_DEFINE(OF_HAVE_UNIX_SOCKETS, 1, [Whether we have UNIX sockets]) ], [], [ #ifdef OF_HAVE_SYS_UN_H # include <sys/un.h> #endif ]) AC_CHECK_FUNCS(paccept accept4, break) AC_CHECK_FUNCS(kqueue1 kqueue, [ AC_DEFINE(HAVE_KQUEUE, 1, [Whether we have kqueue]) AC_SUBST(OF_KQUEUE_KERNEL_EVENT_OBSERVER_M, "OFKqueueKernelEventObserver.m") |
︙ | ︙ |
Modified src/objfw-defs.h.in from [cb58f5fac1] to [fb41861118].
︙ | ︙ | |||
31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | #undef OF_HAVE_SCHED_YIELD #undef OF_HAVE_SOCKETS #undef OF_HAVE_STDNORETURN #undef OF_HAVE_SYMLINK #undef OF_HAVE_SYNC_BUILTINS #undef OF_HAVE_SYS_SOCKET_H #undef OF_HAVE_SYS_TYPES_H #undef OF_HAVE_THREADS #undef OF_HAVE_UNICODE_TABLES #undef OF_HAVE__THREAD_LOCAL #undef OF_HAVE___THREAD #undef OF_NINTENDO_3DS #undef OF_NINTENDO_DS #undef OF_NO_SHARED #undef OF_OBJFW_RUNTIME #undef OF_UNIVERSAL #undef OF_WII | > > | 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 | #undef OF_HAVE_SCHED_YIELD #undef OF_HAVE_SOCKETS #undef OF_HAVE_STDNORETURN #undef OF_HAVE_SYMLINK #undef OF_HAVE_SYNC_BUILTINS #undef OF_HAVE_SYS_SOCKET_H #undef OF_HAVE_SYS_TYPES_H #undef OF_HAVE_SYS_UN_H #undef OF_HAVE_THREADS #undef OF_HAVE_UNICODE_TABLES #undef OF_HAVE_UNIX_SOCKETS #undef OF_HAVE__THREAD_LOCAL #undef OF_HAVE___THREAD #undef OF_NINTENDO_3DS #undef OF_NINTENDO_DS #undef OF_NO_SHARED #undef OF_OBJFW_RUNTIME #undef OF_UNIVERSAL #undef OF_WII |
Modified src/socket.h from [07f169cd19] to [e6e5016044].
︙ | ︙ | |||
34 35 36 37 38 39 40 41 42 43 44 45 46 47 | #endif #ifdef OF_HAVE_NETINET_SCTP_H # include <netinet/sctp.h> #endif #ifdef OF_HAVE_NETIPX_IPX_H # include <netipx/ipx.h> #endif #include "platform.h" #ifdef OF_WINDOWS # include <windows.h> # include <ws2tcpip.h> # ifdef OF_HAVE_IPX | > > > | 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 | #endif #ifdef OF_HAVE_NETINET_SCTP_H # include <netinet/sctp.h> #endif #ifdef OF_HAVE_NETIPX_IPX_H # include <netipx/ipx.h> #endif #ifdef OF_HAVE_SYS_UN_H # include <sys/un.h> #endif #include "platform.h" #ifdef OF_WINDOWS # include <windows.h> # include <ws2tcpip.h> # ifdef OF_HAVE_IPX |
︙ | ︙ | |||
90 91 92 93 94 95 96 97 98 99 100 101 102 103 | OF_SOCKET_ADDRESS_FAMILY_UNKNOWN, /** IPv4 */ OF_SOCKET_ADDRESS_FAMILY_IPV4, /** IPv6 */ OF_SOCKET_ADDRESS_FAMILY_IPV6, /** IPX */ OF_SOCKET_ADDRESS_FAMILY_IPX, /** Any address family */ OF_SOCKET_ADDRESS_FAMILY_ANY = 255 } of_socket_address_family_t; #ifndef OF_HAVE_IPV6 struct sockaddr_in6 { sa_family_t sin6_family; | > > | 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 | OF_SOCKET_ADDRESS_FAMILY_UNKNOWN, /** IPv4 */ OF_SOCKET_ADDRESS_FAMILY_IPV4, /** IPv6 */ OF_SOCKET_ADDRESS_FAMILY_IPV6, /** IPX */ OF_SOCKET_ADDRESS_FAMILY_IPX, /** UNIX */ OF_SOCKET_ADDRESS_FAMILY_UNIX, /** Any address family */ OF_SOCKET_ADDRESS_FAMILY_ANY = 255 } of_socket_address_family_t; #ifndef OF_HAVE_IPV6 struct sockaddr_in6 { sa_family_t sin6_family; |
︙ | ︙ | |||
124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 | # define IPX_NODE_LEN 6 # define sipx_family sa_family # define sipx_network sa_netnum # define sipx_node sa_nodenum # define sipx_port sa_socket #endif /** * @struct of_socket_address_t socket.h ObjFW/socket.h * * @brief A struct which represents a host / port pair for a socket. */ struct OF_BOXABLE of_socket_address_t { /* * Even though struct sockaddr contains the family, we need to use our * own family, as we need to support storing an IPv6 address on systems * that don't support IPv6. These may not have AF_INET6 defined and we * can't just define it, as the value is system-dependent and might * clash with an existing value. */ of_socket_address_family_t family; union { struct sockaddr sockaddr; struct sockaddr_in in; struct sockaddr_in6 in6; struct sockaddr_ipx ipx; } sockaddr; socklen_t length; }; typedef struct of_socket_address_t of_socket_address_t; #ifdef __cplusplus extern "C" { | > > > > > > > > | 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 | # define IPX_NODE_LEN 6 # define sipx_family sa_family # define sipx_network sa_netnum # define sipx_node sa_nodenum # define sipx_port sa_socket #endif #ifndef OF_HAVE_UNIX_SOCKETS struct sockaddr_un { sa_family_t sun_family; char sun_path[108]; }; #endif /** * @struct of_socket_address_t socket.h ObjFW/socket.h * * @brief A struct which represents a host / port pair for a socket. */ struct OF_BOXABLE of_socket_address_t { /* * Even though struct sockaddr contains the family, we need to use our * own family, as we need to support storing an IPv6 address on systems * that don't support IPv6. These may not have AF_INET6 defined and we * can't just define it, as the value is system-dependent and might * clash with an existing value. */ of_socket_address_family_t family; union { struct sockaddr sockaddr; struct sockaddr_in in; struct sockaddr_in6 in6; struct sockaddr_ipx ipx; struct sockaddr_un un; } sockaddr; socklen_t length; }; typedef struct of_socket_address_t of_socket_address_t; #ifdef __cplusplus extern "C" { |
︙ | ︙ | |||
182 183 184 185 186 187 188 | * @param port The port to use * @return The parsed IPv6 and port as an of_socket_address_t */ extern of_socket_address_t of_socket_address_parse_ipv6( OFString *IP, uint16_t port); /** | | > > > > > > > > > | 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 | * @param port The port to use * @return The parsed IPv6 and port as an of_socket_address_t */ extern of_socket_address_t of_socket_address_parse_ipv6( OFString *IP, uint16_t port); /** * @brief Creates an IPX address for the specified node, network and port. * * @param node The node in the IPX network * @param network The IPX network * @param port The IPX port (sometimes called socket number) on the node * @return An IPX socket address with the specified node, network and port. */ extern of_socket_address_t of_socket_address_ipx( const unsigned char node[_Nonnull IPX_NODE_LEN], uint32_t network, uint16_t port); /** * @brief Creates a UNIX socket address from the specified path. * * @param path The path of the UNIX socket * @return A UNIX socket address with the specified path */ extern of_socket_address_t of_socket_address_unix(OFString *path); /** * @brief Compares two of_socket_address_t for equality. * * @param address1 The address to compare with the second address * @param address2 The second address * @return Whether the two addresses are equal */ |
︙ | ︙ | |||
281 282 283 284 285 286 287 288 289 290 291 292 293 294 | * @param address The address on which to get the IPX node * @param node A byte array to store the IPX node of the address */ extern void of_socket_address_get_ipx_node( const of_socket_address_t *_Nonnull address, unsigned char node[_Nonnull IPX_NODE_LEN]); extern bool of_socket_init(void); #if defined(OF_HAVE_THREADS) && defined(OF_AMIGAOS) && !defined(OF_MORPHOS) extern void of_socket_deinit(void); #endif extern int of_socket_errno(void); #if !defined(OF_WII) && !defined(OF_NINTENDO_3DS) extern int of_getsockname(of_socket_t sock, struct sockaddr *restrict addr, | > > > > > > > > > | 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 | * @param address The address on which to get the IPX node * @param node A byte array to store the IPX node of the address */ extern void of_socket_address_get_ipx_node( const of_socket_address_t *_Nonnull address, unsigned char node[_Nonnull IPX_NODE_LEN]); /** * @brief Gets the UNIX socket path of the specified of_socket_address_t. * * @param address The address on which to get the UNIX socket path * @return The UNIX socket path */ extern OFString *_Nullable of_socket_get_unix_path( const of_socket_address_t *_Nonnull address); extern bool of_socket_init(void); #if defined(OF_HAVE_THREADS) && defined(OF_AMIGAOS) && !defined(OF_MORPHOS) extern void of_socket_deinit(void); #endif extern int of_socket_errno(void); #if !defined(OF_WII) && !defined(OF_NINTENDO_3DS) extern int of_getsockname(of_socket_t sock, struct sockaddr *restrict addr, |
︙ | ︙ |
Modified src/socket.m from [21df00d3c4] to [70908a62f5].
︙ | ︙ | |||
35 36 37 38 39 40 41 42 43 44 45 46 47 48 | #import "OFString.h" #import "OFException.h" /* For some E* -> WSAE* defines */ #import "OFInitializationFailedException.h" #import "OFInvalidArgumentException.h" #import "OFInvalidFormatException.h" #import "OFLockFailedException.h" #import "OFUnlockFailedException.h" #import "socket.h" #import "socket_helpers.h" #ifdef OF_HAVE_THREADS # import "tlskey.h" #endif | > | 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 | #import "OFString.h" #import "OFException.h" /* For some E* -> WSAE* defines */ #import "OFInitializationFailedException.h" #import "OFInvalidArgumentException.h" #import "OFInvalidFormatException.h" #import "OFLockFailedException.h" #import "OFOutOfRangeException.h" #import "OFUnlockFailedException.h" #import "socket.h" #import "socket_helpers.h" #ifdef OF_HAVE_THREADS # import "tlskey.h" #endif |
︙ | ︙ | |||
534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 | network = OF_BSWAP32_IF_LE(network); memcpy(&ret.sockaddr.ipx.sipx_network, &network, sizeof(ret.sockaddr.ipx.sipx_network)); ret.sockaddr.ipx.sipx_port = OF_BSWAP16_IF_LE(port); return ret; } bool of_socket_address_equal(const of_socket_address_t *address1, const of_socket_address_t *address2) { const struct sockaddr_in *addrIn1, *addrIn2; const struct sockaddr_in6 *addrIn6_1, *addrIn6_2; const struct sockaddr_ipx *addrIPX1, *addrIPX2; if (address1->family != address2->family) return false; switch (address1->family) { case OF_SOCKET_ADDRESS_FAMILY_IPV4: #if defined(OF_WII) || defined(OF_NINTENDO_3DS) | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 | network = OF_BSWAP32_IF_LE(network); memcpy(&ret.sockaddr.ipx.sipx_network, &network, sizeof(ret.sockaddr.ipx.sipx_network)); ret.sockaddr.ipx.sipx_port = OF_BSWAP16_IF_LE(port); return ret; } of_socket_address_t of_socket_unix(OFString *path) { void *pool = objc_autoreleasePoolPush(); of_string_encoding_t encoding = [OFLocale encoding]; size_t length = [path cStringLengthWithEncoding: encoding]; of_socket_address_t ret; if (length > sizeof(ret.sockaddr.un.sun_path)) @throw [OFOutOfRangeException exception]; memset(&ret, '\0', sizeof(ret)); ret.family = OF_SOCKET_ADDRESS_FAMILY_UNIX; ret.length = (socklen_t)(sizeof(ret.sockaddr.un) - (sizeof(ret.sockaddr.un.sun_path) - length)); #ifdef AF_UNIX ret.sockaddr.un.sun_family = AF_UNIX; #else ret.sockaddr.un.sun_family = AF_UNSPEC; #endif memcpy(ret.sockaddr.un.sun_path, [path cStringWithEncoding: encoding], length); objc_autoreleasePoolPop(pool); return ret; } bool of_socket_address_equal(const of_socket_address_t *address1, const of_socket_address_t *address2) { const struct sockaddr_in *addrIn1, *addrIn2; const struct sockaddr_in6 *addrIn6_1, *addrIn6_2; const struct sockaddr_ipx *addrIPX1, *addrIPX2; void *pool; OFString *path1, *path2; bool ret; if (address1->family != address2->family) return false; switch (address1->family) { case OF_SOCKET_ADDRESS_FAMILY_IPV4: #if defined(OF_WII) || defined(OF_NINTENDO_3DS) |
︙ | ︙ | |||
565 566 567 568 569 570 571 | addrIn2 = &address2->sockaddr.in; if (addrIn1->sin_port != addrIn2->sin_port) return false; if (addrIn1->sin_addr.s_addr != addrIn2->sin_addr.s_addr) return false; | | | > > > > > > > | > > | > | > > | > > > > > > > > > > > > > | > > > | | 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 | addrIn2 = &address2->sockaddr.in; if (addrIn1->sin_port != addrIn2->sin_port) return false; if (addrIn1->sin_addr.s_addr != addrIn2->sin_addr.s_addr) return false; return true; case OF_SOCKET_ADDRESS_FAMILY_IPV6: if (address1->length < (socklen_t)sizeof(struct sockaddr_in6) || address2->length < (socklen_t)sizeof(struct sockaddr_in6)) @throw [OFInvalidArgumentException exception]; addrIn6_1 = &address1->sockaddr.in6; addrIn6_2 = &address2->sockaddr.in6; if (addrIn6_1->sin6_port != addrIn6_2->sin6_port) return false; if (memcmp(addrIn6_1->sin6_addr.s6_addr, addrIn6_2->sin6_addr.s6_addr, sizeof(addrIn6_1->sin6_addr.s6_addr)) != 0) return false; return true; case OF_SOCKET_ADDRESS_FAMILY_IPX: if (address1->length < (socklen_t)sizeof(struct sockaddr_ipx) || address2->length < (socklen_t)sizeof(struct sockaddr_ipx)) @throw [OFInvalidArgumentException exception]; addrIPX1 = &address1->sockaddr.ipx; addrIPX2 = &address2->sockaddr.ipx; if (addrIPX1->sipx_port != addrIPX2->sipx_port) return false; if (memcmp(&addrIPX1->sipx_network, &addrIPX2->sipx_network, 4) != 0) return false; if (memcmp(addrIPX1->sipx_node, addrIPX2->sipx_node, IPX_NODE_LEN) != 0) return false; return true; case OF_SOCKET_ADDRESS_FAMILY_UNIX: /* * This is a bit tricky. The only thing that is well-defined is * the path. So compare the path, and if both don't have a * path, compare bytes. */ if (address1->length != address2->length) return false; pool = objc_autoreleasePoolPush(); path1 = of_socket_get_unix_path(address1); path2 = of_socket_get_unix_path(address2); if (path1 == nil && path2 == nil) { objc_autoreleasePoolPop(pool); return (memcmp(&address1->sockaddr.un, &address2->sockaddr.un, address1->length) == 0); } if (path1 == nil || path2 == nil) ret = false; else ret = [path1 isEqual: path2]; objc_autoreleasePoolPop(pool); return ret; default: @throw [OFInvalidArgumentException exception]; } } unsigned long of_socket_address_hash(const of_socket_address_t *address) { unsigned long hash; OF_HASH_INIT(hash); OF_HASH_ADD(hash, address->family); switch (address->family) { case OF_SOCKET_ADDRESS_FAMILY_IPV4: #if defined(OF_WII) || defined(OF_NINTENDO_3DS) |
︙ | ︙ | |||
665 666 667 668 669 670 671 672 673 674 675 676 677 678 | for (size_t i = 0; i < sizeof(network); i++) OF_HASH_ADD(hash, network[i]); for (size_t i = 0; i < IPX_NODE_LEN; i++) OF_HASH_ADD(hash, address->sockaddr.ipx.sipx_node[i]); break; default: @throw [OFInvalidArgumentException exception]; } OF_HASH_FINALIZE(hash); | > > > > > > > > > > > > > > > > > > > > > > | 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 | for (size_t i = 0; i < sizeof(network); i++) OF_HASH_ADD(hash, network[i]); for (size_t i = 0; i < IPX_NODE_LEN; i++) OF_HASH_ADD(hash, address->sockaddr.ipx.sipx_node[i]); break; case OF_SOCKET_ADDRESS_FAMILY_UNIX:; /* * This is a bit tricky. The only thing that is well-defined is * the path. So hash the path if we have one, otherwise the * bytes. */ void *pool = objc_autoreleasePoolPush(); OFString *path = of_socket_get_unix_path(address); if (path != nil) { hash = [path hash]; objc_autoreleasePoolPop(pool); return hash; } objc_autoreleasePoolPop(pool); for (socklen_t i = 0; i < address->length; i++) OF_HASH_ADD(hash, ((const char *)&address->sockaddr.un)[i]); break; default: @throw [OFInvalidArgumentException exception]; } OF_HASH_FINALIZE(hash); |
︙ | ︙ | |||
852 853 854 855 856 857 858 | unsigned char node[IPX_NODE_LEN]) { if (address->family != OF_SOCKET_ADDRESS_FAMILY_IPX) @throw [OFInvalidArgumentException exception]; memcpy(node, address->sockaddr.ipx.sipx_node, IPX_NODE_LEN); } | > > > > > > > > > > > > > > > > > > > > > | 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 | unsigned char node[IPX_NODE_LEN]) { if (address->family != OF_SOCKET_ADDRESS_FAMILY_IPX) @throw [OFInvalidArgumentException exception]; memcpy(node, address->sockaddr.ipx.sipx_node, IPX_NODE_LEN); } OFString * of_socket_get_unix_path(const of_socket_address_t *_Nonnull address) { socklen_t maxLength = (socklen_t)sizeof(address->sockaddr.un); size_t length; if (address->family != OF_SOCKET_ADDRESS_FAMILY_UNIX || address->length > maxLength) @throw [OFInvalidArgumentException exception]; length = sizeof(address->sockaddr.un.sun_path) - (maxLength - address->length); if (length == 0) return nil; return [OFString stringWithCString: address->sockaddr.un.sun_path encoding: [OFLocale encoding] length: length]; } |