diff options
Diffstat (limited to 'include')
| -rw-r--r-- | include/README.md | 4 | ||||
| -rw-r--r-- | include/Xcode-Bridging-Header.h | 69 | ||||
| -rw-r--r-- | include/ZeroTier.h | 1277 | ||||
| -rw-r--r-- | include/ZeroTierConstants.h | 251 | ||||
| -rw-r--r-- | include/ZeroTierSockets.h | 1688 |
5 files changed, 1692 insertions, 1597 deletions
diff --git a/include/README.md b/include/README.md new file mode 100644 index 0000000..f2318b7 --- /dev/null +++ b/include/README.md @@ -0,0 +1,4 @@ +ZeroTier Socket API +====== + +This is the externally facing plain C API. It provides a platform-agnostic ZeroTier-based socket interface. diff --git a/include/Xcode-Bridging-Header.h b/include/Xcode-Bridging-Header.h deleted file mode 100644 index 1317ec1..0000000 --- a/include/Xcode-Bridging-Header.h +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright (c)2013-2020 ZeroTier, Inc. - * - * Use of this software is governed by the Business Source License included - * in the LICENSE.TXT file in the project's root directory. - * - * Change Date: 2024-01-01 - * - * On the date above, in accordance with the Business Source License, use - * of this software will be governed by version 2.0 of the Apache License. - */ -/****/ - -/** - * @file - * - * ZeroTier socket API - */ - -#ifndef LIBZT_BRIDGING_HEADER_H -#define LIBZT_BRIDGING_HEADER_H - -#include <sys/socket.h> -#include "ZeroTier.h" - -////////////////////////////////////////////////////////////////////////////// -// Service Controls // -////////////////////////////////////////////////////////////////////////////// - -int zts_start(const char *path, void *callbackFunc, int port); -void zts_stop(); -int zts_join(uint64_t nwid); -int zts_leave(uint64_t nwid); -uint64_t zts_get_node_id(); -uint64_t zts_get_node_status(); -int get_peer_status(uint64_t peerId); - -////////////////////////////////////////////////////////////////////////////// -// Socket API // -////////////////////////////////////////////////////////////////////////////// - -int zts_socket(int socket_family, int socket_type, int protocol); -int zts_connect(int fd, const struct sockaddr *addr, socklen_t addrlen); -int zts_bind(int fd, const struct sockaddr *addr, socklen_t addrlen); -int zts_listen(int fd, int backlog); -int zts_accept(int fd, struct sockaddr *addr, socklen_t *addrlen); -int zts_setsockopt(int fd, int level, int optname, const void *optval, socklen_t optlen); -int zts_getsockopt(int fd, int level, int optname, void *optval, socklen_t *optlen); -int zts_read(int fd, void *buf, size_t len); -int zts_write(int fd, const void *buf, size_t len); -ssize_t zts_send(int fd, const void *buf, size_t len, int flags); -ssize_t zts_sendto(int fd, const void *buf, size_t len, int flags, const struct sockaddr *addr, socklen_t addrlen); -ssize_t zts_sendmsg(int fd, const struct msghdr *msg, int flags); -ssize_t zts_recv(int fd, void *buf, size_t len, int flags); -ssize_t zts_recvfrom(int fd, void *buf, size_t len, int flags, struct sockaddr *addr, socklen_t *addrlen); -ssize_t zts_recvmsg(int fd, struct msghdr *msg,int flags); -int zts_shutdown(int fd, int how); -int zts_close(int fd); -int zts_getsockname(int fd, struct sockaddr *addr, socklen_t *addrlen); -int zts_getpeername(int fd, struct sockaddr *addr, socklen_t *addrlen); -int zts_select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout); -int zts_fcntl(int fd, int cmd, int flags); -int zts_ioctl(int fd, unsigned long request, void *argp); - -#endif // _H - - - - diff --git a/include/ZeroTier.h b/include/ZeroTier.h deleted file mode 100644 index 464d56c..0000000 --- a/include/ZeroTier.h +++ /dev/null @@ -1,1277 +0,0 @@ -/* - * Copyright (c)2013-2020 ZeroTier, Inc. - * - * Use of this software is governed by the Business Source License included - * in the LICENSE.TXT file in the project's root directory. - * - * Change Date: 2024-01-01 - * - * On the date above, in accordance with the Business Source License, use - * of this software will be governed by version 2.0 of the Apache License. - */ -/****/ - -/** - * @file - * - * ZeroTier socket API - */ - -#ifndef ZEROTIER_H -#define ZEROTIER_H - -#include "ZeroTierConstants.h" - -#if defined(_MSC_VER) -#include <BaseTsd.h> -typedef int ssize_t; -#endif - -#ifdef _WIN32 - #ifdef ADD_EXPORTS - #define ZT_SOCKET_API __declspec(dllexport) - #else - #define ZT_SOCKET_API __declspec(dllimport) - #endif - #define ZTCALL __cdecl -#else - #define ZT_SOCKET_API - #define ZTCALL -#endif - -#if !defined(_WIN32) && !defined(__ANDROID__) -typedef unsigned int socklen_t; -#else -//typedef int socklen_t; -//#include <sys/socket.h> -#endif - -#if defined(__APPLE__) - #include "TargetConditionals.h" - //#if TARGET_OS_IPHONE - //#ifndef sockaddr_storage - #include <sys/socket.h> - //#endif - //#endif - // TARGET_OS_MAC -#endif - -#if defined(_WIN32) -#include <WinSock2.h> -#include <stdint.h> -#include <WS2tcpip.h> -#include <Windows.h> -#endif - -//namespace ZeroTier { - -#ifdef __cplusplus -extern "C" { -#endif - -typedef uint32_t zts_in_addr_t; -typedef uint16_t zts_in_port_t; -typedef uint8_t zts_sa_family_t; - -struct zts_in_addr { -#if defined(_WIN32) - zts_in_addr_t S_addr; -#else - zts_in_addr_t s_addr; -#endif -}; - -struct zts_in6_addr { - union un { - uint32_t u32_addr[4]; - uint8_t u8_addr[16]; - } un; -//#define s6_addr un.u8_addr -}; - -struct zts_sockaddr_in { - uint8_t sin_len; - zts_sa_family_t sin_family; - zts_in_port_t sin_port; - struct zts_in_addr sin_addr; -#define SIN_ZERO_LEN 8 - char sin_zero[SIN_ZERO_LEN]; -}; - -struct zts_sockaddr_in6 { - uint8_t sin6_len; // length of this structure - zts_sa_family_t sin6_family; // AF_INET6 - zts_in_port_t sin6_port; // Transport layer port # - uint32_t sin6_flowinfo; // IPv6 flow information - struct zts_in6_addr sin6_addr; // IPv6 address - uint32_t sin6_scope_id; // Set of interfaces for scope -}; - -struct zts_sockaddr { - uint8_t sa_len; - zts_sa_family_t sa_family; - char sa_data[14]; -}; - -struct zts_sockaddr_storage { - uint8_t s2_len; - zts_sa_family_t ss_family; - char s2_data1[2]; - uint32_t s2_data2[3]; - uint32_t s2_data3[3]; -}; - -#if !defined(zts_iovec) -struct zts_iovec { - void *iov_base; - size_t iov_len; -}; -#endif - -struct zts_msghdr { - void *msg_name; - socklen_t msg_namelen; - struct iovec *msg_iov; - int msg_iovlen; - void *msg_control; - socklen_t msg_controllen; - int msg_flags; -}; - -/* - * Structure used for manipulating linger option. - */ -struct zts_linger { - int l_onoff; // option on/off - int l_linger; // linger time in seconds -}; - -typedef struct zts_fd_set -{ - unsigned char fd_bits [(FD_SETSIZE+7)/8]; -} zts_fd_set; - -#ifdef __cplusplus -} -#endif - -////////////////////////////////////////////////////////////////////////////// -// Subset of: ZeroTierOne.h // -// We redefine a few ZT structures here so that we don't need to drag the // -// entire ZeroTierOne.h file into the user application // -////////////////////////////////////////////////////////////////////////////// - -/** - * Maximum address assignments per network - */ -#define ZTS_MAX_ASSIGNED_ADDRESSES 16 - -/** - * Maximum routes per network - */ -#define ZTS_MAX_NETWORK_ROUTES 32 - -/** - * Maximum number of direct network paths to a given peer - */ -#define ZT_MAX_PEER_NETWORK_PATHS 16 - -/** - * What trust hierarchy role does this peer have? - */ -enum zts_peer_role -{ - ZTS_PEER_ROLE_LEAF = 0, // ordinary node - ZTS_PEER_ROLE_MOON = 1, // moon root - ZTS_PEER_ROLE_PLANET = 2 // planetary root -}; - -/** - * A structure used to convey details about the current node - * to the user application - */ -struct zts_node_details -{ - /** - * The node ID - */ - uint64_t address; - - /** - * The current clock value accord to the node - */ - uint64_t clock; - - /** - * Whether or not this node is online - */ - bool online; - - /** - * Whether port mapping is enabled - */ - bool portMappingEnabled; - - /** - * Whether multipath support is enabled. If true, this node will - * be capable of utilizing multiple physical links simultaneously - * to create higher quality or more robust aggregate links. - * - * See: https://www.zerotier.com/manual.shtml#2_1_5 - */ - bool multipathEnabled; - - /** - * The port used by the service to send and receive - * all encapsulated traffic - */ - uint16_t primaryPort; - - /** - * Planet ID - */ - uint64_t planetWorldId; - uint64_t planetWorldTimestamp; - uint8_t versionMajor; - uint8_t versionMinor; - uint8_t versionRev; -}; - -/** - * A structure used to convey information to a user application via - * a callback function. - */ -struct zts_callback_msg -{ - /** - * Event identifier - */ - int eventCode; - - struct zts_node_details *node; - struct zts_network_details *network; - struct zts_netif_details *netif; - struct zts_virtual_network_route *route; - struct zts_physical_path *path; - struct zts_peer_details *peer; - struct zts_addr_details *addr; -}; - -struct zts_addr_details -{ - uint64_t nwid; - struct sockaddr_storage addr; -}; - -/** - * A structure used to convey information about a virtual network - * interface (netif) to a user application. - */ -struct zts_netif_details -{ - /** - * The virtual network that this interface was commissioned for. - */ - uint64_t nwid; - - /** - * The hardware address assigned to this interface - */ - uint64_t mac; - - /** - * The MTU for this interface - */ - int mtu; - - /** - * The IPv4 address assigned to this interface. - */ - //struct sockaddr_in ip4_addr; - - /** - * The IPv6 addresses assigned to this interface. - */ - //struct sockaddr_in6 ip6_addr[LWIP_IPV6_NUM_ADDRESSES]; - - /** - * Number of IPv4 addresses assigned to this interface - */ - //int num_ip4_addr; - - /** - * Number of IPv6 addresses assigned to this interface - */ - //int num_ip6_addr; -}; - -/** - * A structure used to represent a virtual network route - */ -struct zts_virtual_network_route -{ - /** - * Target network / netmask bits (in port field) or NULL or 0.0.0.0/0 for default - */ - struct sockaddr_storage target; - - /** - * Gateway IP address (port ignored) or NULL (family == 0) for LAN-local (no gateway) - */ - struct sockaddr_storage via; - - /** - * Route flags - */ - uint16_t flags; - - /** - * Route metric (not currently used) - */ - uint16_t metric; -}; - -/** - * A structure used to convey network-specific details to the user application - */ -struct zts_network_details -{ - /** - * Network ID - */ - uint64_t nwid; - - /** - * Maximum Transmission Unit size for this network - */ - int mtu; - - /** - * Number of addresses (actually) assigned to the node on this network - */ - short num_addresses; - - /** - * Array of IPv4 and IPv6 addresses assigned to the node on this network - */ - struct sockaddr_storage addr[ZTS_MAX_ASSIGNED_ADDRESSES]; - - /** - * Number of routes - */ - unsigned int num_routes; - - /** - * Array of IPv4 and IPv6 addresses assigned to the node on this network - */ - struct zts_virtual_network_route routes[ZTS_MAX_NETWORK_ROUTES]; -}; - -/** - * Physical network path to a peer - */ -struct zts_physical_path -{ - /** - * Address of endpoint - */ - struct sockaddr_storage address; - - /** - * Time of last send in milliseconds or 0 for never - */ - uint64_t lastSend; - - /** - * Time of last receive in milliseconds or 0 for never - */ - uint64_t lastReceive; - - /** - * Is this a trusted path? If so this will be its nonzero ID. - */ - uint64_t trustedPathId; - - /** - * Is path expired? - */ - int expired; - - /** - * Is path preferred? - */ - int preferred; -}; - -/** - * Peer status result buffer - */ -struct zts_peer_details -{ - /** - * ZeroTier address (40 bits) - */ - uint64_t address; - - /** - * Remote major version or -1 if not known - */ - int versionMajor; - - /** - * Remote minor version or -1 if not known - */ - int versionMinor; - - /** - * Remote revision or -1 if not known - */ - int versionRev; - - /** - * Last measured latency in milliseconds or -1 if unknown - */ - int latency; - - /** - * What trust hierarchy role does this device have? - */ - enum zts_peer_role role; - - /** - * Number of paths (size of paths[]) - */ - unsigned int pathCount; - - /** - * Known network paths to peer - */ - struct zts_physical_path paths[ZT_MAX_PEER_NETWORK_PATHS]; -}; - -/** - * List of peers - */ -struct zts_peer_list -{ - struct zts_peer_details *peers; - unsigned long peerCount; -}; - -////////////////////////////////////////////////////////////////////////////// -// ZeroTier Service Controls // -////////////////////////////////////////////////////////////////////////////// - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * @brief Enable or disable whether the service will cache network details (enabled by default) - * - * This can potentially shorten (startup) times. This allows the service to nearly instantly - * inform the network stack of an address to use for this peer so that it can - * create an interface. This can be disabled for cases where one may not want network - * config details to be written to storage. This is especially useful for situations where - * address assignments do not change often. - * - * @usage Should be called before zts_start() if you intend on changing its state. - * - * @param enabled Whether or not this feature is enabled - */ -ZT_SOCKET_API void ZTCALL zts_set_network_caching(bool enabled); - -/** - * @brief Enable or disable whether the service will cache peer details (enabled by default) - * - * This can potentially shorten (connection) times. This allows the service to - * re-use previously discovered paths to a peer, this prevents the service from having - * to go through the entire transport-triggered link provisioning process. This is especially - * useful for situations where paths to peers do not change often. This is enabled by default - * and can be disabled for cases where one may not want peer details to be written to storage. - * - * @usage Should be called before zts_start() if you intend on changing its state. - * - * @param enabled Whether or not this feature is enabled - */ -ZT_SOCKET_API void ZTCALL zts_set_peer_caching(bool enabled); - -/** - * @brief Starts the ZeroTier service and notifies user application of events via callback - * - * @usage Should be called at the beginning of your application. Will blocks until all of the following conditions are met: - * - ZeroTier core service has been initialized - * - Cryptographic identity has been generated or loaded from directory specified by `path` - * - Virtual network is successfully joined - * - IP address is assigned by network controller service - * @param path path directory where cryptographic identities and network configuration files are stored and retrieved - * (`identity.public`, `identity.secret`) - * @param userCallbackFunc User-specified callback for ZeroTier events - * @return 0 if successful; or 1 if failed - */ -ZT_SOCKET_API int ZTCALL zts_start(const char *path, void (*userCallbackFunc)(struct zts_callback_msg*), int port); - -/** - * @brief Stops the ZeroTier service, brings down all virtual interfaces in order to stop all traffic processing. - * - * @usage This should be called when the application anticipates not needing any sort of traffic processing for a - * prolonged period of time. The stack driver (with associated timers) will remain active in case future traffic - * processing is required. Note that the application must tolerate a multi-second startup time if zts_start() - * zts_startjoin() is called again. To stop this background thread and free all resources use zts_free() instead. - * @return Returns 0 on success, -1 on failure - */ -ZT_SOCKET_API int ZTCALL zts_stop(); - -/** - * @brief Stops and re-starts the ZeroTier service. - * - * @usage This call will block until the service has been brought offline. Then - * it will return and the user application can then watch for the appropriate - * startup callback events. - * @return Returns ZTS_ERR_OK on success, -1 on failure - */ -ZT_SOCKET_API int ZTCALL zts_restart(); - -/** - * @brief Stops all background services, brings down all interfaces, frees all resources. After calling this function - * an application restart will be required before the library can be used again. This is a blocking call. - * - * @usage This should be called at the end of your program or when you do not anticipate communicating over ZeroTier - * @return Returns 0 on success, -1 on failure - */ -ZT_SOCKET_API int ZTCALL zts_free(); - -/** - * @brief Return whether the ZeroTier service is currently running - * - * @usage Call this after zts_start() - * @return 1 if running, 0 if not running - */ -ZT_SOCKET_API int ZTCALL zts_core_running(); - -/** - * @brief Return the number of networks currently joined by this node - * - * @usage Call this after zts_start(), zts_startjoin() and/or zts_join() - * @return Number of networks joined by this node - */ -ZT_SOCKET_API size_t ZTCALL zts_get_num_joined_networks(); - -/** - * @brief Populates a structure with details for a given network - * - * @usage Call this from the application thread any time after the node has joined a network - * @param nwid A 16-digit hexidecimal virtual network ID - * @param nd Pointer to a zts_network_details structure to populate - * @return ZTS_ERR_SERVICE if failed, 0 if otherwise - */ -ZT_SOCKET_API int ZTCALL zts_get_network_details(uint64_t nwid, struct zts_network_details *nd); - -/** - * @brief Populates an array of structures with details for any given number of networks - * - * @usage Call this from the application thread any time after the node has joined a network - * @param nds Pointer to an array of zts_network_details structures to populate - * @param num Number of zts_network_details structures available to copy data into, will be updated - * to reflect number of structures that were actually populated - * @return ZTS_ERR_SERVICE if failed, 0 if otherwise - */ -ZT_SOCKET_API int ZTCALL zts_get_all_network_details(struct zts_network_details *nds, int *num); - -/** - * @brief Join a network - * - * @usage Call this from application thread. Only after zts_start() has succeeded - * @param nwid A 16-digit hexidecimal virtual network ID - * @return 0 if successful, -1 for any failure - */ -ZT_SOCKET_API int ZTCALL zts_join(const uint64_t nwid); - -/** - * @brief Leave a network - * - * @usage Call this from application thread. Only after zts_start() has succeeded - * @param nwid A 16-digit hexidecimal virtual network ID - * @return 0 if successful, -1 for any failure - */ -ZT_SOCKET_API int ZTCALL zts_leave(const uint64_t nwid); - -/** - * @brief Leaves all networks - * - * @usage Call this from application thread. Only after zts_start() has succeeded - * @return 0 if successful, -1 for any failure - */ -ZT_SOCKET_API int ZTCALL zts_leave_all(); - -/** - * @brief Orbits a given moon (user-defined root server) - * - * @usage Call this from application thread. Only after zts_start() has succeeded - * @param moonWorldId A 16-digit hexidecimal world ID - * @param moonSeed A 16-digit hexidecimal seed ID - * @return ZTS_ERR_OK if successful, ZTS_ERR_SERVICE, ZTS_ERR_INVALID_ARG, ZTS_ERR_INVALID_OP if otherwise - */ -ZT_SOCKET_API int ZTCALL zts_orbit(uint64_t moonWorldId, uint64_t moonSeed); - -/** - * @brief De-orbits a given moon (user-defined root server) - * - * @usage Call this from application thread. Only after zts_start() has succeeded - * @param moonWorldId A 16-digit hexidecimal world ID - * @return ZTS_ERR_OK if successful, ZTS_ERR_SERVICE, ZTS_ERR_INVALID_ARG, ZTS_ERR_INVALID_OP if otherwise - */ -ZT_SOCKET_API int ZTCALL zts_deorbit(uint64_t moonWorldId); - -/** - * @brief Copies the configuration path used by ZeroTier into the provided buffer - * - * @usage Use this to determine where ZeroTier is storing identity files - * @param homePath Path to ZeroTier configuration files - * @param len Length of destination buffer - * @return 0 if no error, -1 if invalid argument was supplied - */ -ZT_SOCKET_API int ZTCALL zts_get_path(char *homePath, size_t *len); - -/** - * @brief Returns the node ID of this instance - * - * @usage Call this after zts_start() and/or when zts_running() returns true - * @return - */ -ZT_SOCKET_API uint64_t ZTCALL zts_get_node_id(); - -/** - * @brief Returns whether any address has been assigned to the SockTap for this network - * - * @usage This is used as an indicator of readiness for service for the ZeroTier core and stack - * @param nwid Network ID - * @return - */ -ZT_SOCKET_API int ZTCALL zts_has_address(const uint64_t nwid); - - -/** - * @brief Returns the number of addresses assigned to this node for the given nwid - * - * @param nwid Network ID - * @return The number of addresses assigned - */ -ZT_SOCKET_API int ZTCALL zts_get_num_assigned_addresses(const uint64_t nwid); - -/** - * @brief Returns the assigned address located at the given index - * - * @usage The indices of each assigned address are not guaranteed and should only - * be used for iterative purposes. - * @param nwid Network ID - * @param index location of assigned address - * @return The number of addresses assigned - */ -ZT_SOCKET_API int ZTCALL zts_get_address_at_index( - const uint64_t nwid, const int index, struct sockaddr *addr, socklen_t *addrlen); - -/** - * @brief Get IP address for this device on a given network - * - * @usage FIXME: Only returns first address found, good enough for most cases - * @param nwid Network ID - * @param addr Destination structure for address - * @param addrlen size of destination address buffer, will be changed to size of returned address - * @return 0 if an address was successfully found, -1 if failure - */ -ZT_SOCKET_API int ZTCALL zts_get_address( - const uint64_t nwid, struct sockaddr_storage *addr, const int address_family); - -/** - * @brief Computes a 6PLANE IPv6 address for the given Network ID and Node ID - * - * @usage Can call any time - * @param addr Destination structure for address - * @param nwid Network ID - * @param nodeId Node ID - * @return - */ -ZT_SOCKET_API int ZTCALL zts_get_6plane_addr( - struct sockaddr_storage *addr, const uint64_t nwid, const uint64_t nodeId); - -/** - * @brief Computes a RFC4193 IPv6 address for the given Network ID and Node ID - * - * @usage Can call any time - * @param addr Destination structure for address - * @param nwid Network ID - * @param nodeId Node ID - * @return - */ -ZT_SOCKET_API int ZTCALL zts_get_rfc4193_addr( - struct sockaddr_storage *addr, const uint64_t nwid, const uint64_t nodeId); - -/** - * Ad-hoc Network: - * - * ffSSSSEEEE000000 - * | | | | - * | | | Reserved for future use, must be 0 - * | | End of port range (hex) - * | Start of port range (hex) - * Reserved ZeroTier address prefix indicating a controller-less network. - * - * Ad-hoc networks are public (no access control) networks that have no network controller. Instead - * their configuration and other credentials are generated locally. Ad-hoc networks permit only IPv6 - * UDP and TCP unicast traffic (no multicast or broadcast) using 6plane format NDP-emulated IPv6 - * addresses. In addition an ad-hoc network ID encodes an IP port range. UDP packets and TCP SYN - * (connection open) packets are only allowed to destination ports within the encoded range. - * - * For example ff00160016000000 is an ad-hoc network allowing only SSH, while ff0000ffff000000 is an - * ad-hoc network allowing any UDP or TCP port. - * - * Keep in mind that these networks are public and anyone in the entire world can join them. Care must - * be taken to avoid exposing vulnerable services or sharing unwanted files or other resources. - * - */ -uint64_t zts_generate_adhoc_nwid_from_range(uint16_t startPortOfRange, uint16_t endPortOfRange); - -/** - * @brief Return the number of peers - * - * @usage Call this after zts_start() has succeeded - * @return - */ -ZT_SOCKET_API int zts_get_peer_count(); - -/** - * @brief Return details of all peers - * - * @param pds Pointer to array of zts_peer_details structs to be filled out - * @param num Length of destination array, will be filled out with actual number - * of peers that details were available for. - * @usage Call this after zts_start() has succeeded - * @return - */ -ZT_SOCKET_API int zts_get_peers(struct zts_peer_details *pds, unsigned int *num); - -/** - * @brief Return details of a given peer. - * - * @param pds Pointer to zts_peer_details struct to be filled out - * @param peerId ID of peer that the caller wants details of - * @usage Call this after zts_start() has succeeded - * @return - */ -ZT_SOCKET_API int zts_get_peer(struct zts_peer_details *pds, uint64_t peerId); - -/** - * @brief Starts a ZeroTier service in the background - * - * @usage For internal use only. - * @param - * @return - */ -#if defined(_WIN32) -DWORD WINAPI _zts_start_service(LPVOID thread_id); -#else -void *_zts_start_service(void *thread_id); -#endif - -/** - * @brief [Should not be called from user application] This function must be surrounded by - * ZT service locks. It will determine if it is currently safe and allowed to operate on - * the service. - * @usage Can be called at any time - * @return 1 or 0 - */ -int _zts_can_perform_service_operation(); - -////////////////////////////////////////////////////////////////////////////// -// Statistics // -////////////////////////////////////////////////////////////////////////////// - -#ifndef LWIP_STATS - -/** Protocol related stats */ -struct zts_stats_proto { - uint32_t xmit; /* Transmitted packets. */ - uint32_t recv; /* Received packets. */ - uint32_t fw; /* Forwarded packets. */ - uint32_t drop; /* Dropped packets. */ - uint32_t chkerr; /* Checksum error. */ - uint32_t lenerr; /* Invalid length error. */ - uint32_t memerr; /* Out of memory error. */ - uint32_t rterr; /* Routing error. */ - uint32_t proterr; /* Protocol error. */ - uint32_t opterr; /* Error in options. */ - uint32_t err; /* Misc error. */ - uint32_t cachehit; -}; - -/** IGMP stats */ -struct zts_stats_igmp { - uint32_t xmit; /* Transmitted packets. */ - uint32_t recv; /* Received packets. */ - uint32_t drop; /* Dropped packets. */ - uint32_t chkerr; /* Checksum error. */ - uint32_t lenerr; /* Invalid length error. */ - uint32_t memerr; /* Out of memory error. */ - uint32_t proterr; /* Protocol error. */ - uint32_t rx_v1; /* Received v1 frames. */ - uint32_t rx_group; /* Received group-specific queries. */ - uint32_t rx_general; /* Received general queries. */ - uint32_t rx_report; /* Received reports. */ - uint32_t tx_join; /* Sent joins. */ - uint32_t tx_leave; /* Sent leaves. */ - uint32_t tx_report; /* Sent reports. */ -}; - -/** System element stats */ -struct zts_stats_syselem { - uint32_t used; - uint32_t max; - uint32_t err; -}; - -/** System stats */ -struct zts_stats_sys { - struct zts_stats_syselem sem; - struct zts_stats_syselem mutex; - struct zts_stats_syselem mbox; -}; - -/** lwIP stats container */ -struct zts_stats { - /** Link level */ - struct zts_stats_proto link; - /** ARP */ - struct zts_stats_proto etharp; - /** Fragmentation */ - struct zts_stats_proto ip_frag; - /** IP */ - struct zts_stats_proto ip; - /** ICMP */ - struct zts_stats_proto icmp; - /** IGMP */ - struct zts_stats_igmp igmp; - /** UDP */ - struct zts_stats_proto udp; - /** TCP */ - struct zts_stats_proto tcp; - /** System */ - struct zts_stats_sys sys; - /** IPv6 */ - struct zts_stats_proto ip6; - /** ICMP6 */ - struct zts_stats_proto icmp6; - /** IPv6 fragmentation */ - struct zts_stats_proto ip6_frag; - /** Multicast listener discovery */ - struct zts_stats_igmp mld6; - /** Neighbor discovery */ - struct zts_stats_proto nd6; -}; - -#endif - -/** - * @brief Returns all statistical counters for all protocols (inefficient) - * - * @usage This function can only be used in debug builds. It can be called at - * any time after the node has come online - * @return ZTS_ERR_OK if successful, ZTS_ERR_* otherwise - */ -int zts_get_all_stats(struct zts_stats *statsDest); - - -/** - * @brief Populates the given structure with the requested protocol's - * statistical counters (from lwIP) - * - * @usage This function can only be used in debug builds. It can be called at - * any time after the node has come online - * @return ZTS_ERR_OK if successful, ZTS_ERR_* otherwise - */ -int zts_get_protocol_stats(int protocolType, void *protoStatsDest); - -////////////////////////////////////////////////////////////////////////////// -// Status getters // -////////////////////////////////////////////////////////////////////////////// - -/** - * @brief Queries a the status of the core node/service - * - * @usage Can be called at any time - * @return ZTS_EVENT_NODE_ONLINE, ZTS_EVENT_NODE_OFFLINE, or standard ZTS_ errors - */ -ZT_SOCKET_API int zts_get_node_status(); - -/** - * @brief Queries a the status of a network - * - * @usage Can be called at any time - * @return ZTS_NETWORK_ values, or standard ZTS_ errors - */ -ZT_SOCKET_API int zts_get_network_status(uint64_t nwid); - -/** - * @brief Determines whether a peer is reachable via a P2P connection - * or is being relayed via roots. - * - * @usage - * @param peerId The ID of the peer to check - * @return ZTS_PEER_ values, or standard ZTS_ errors - */ -ZT_SOCKET_API int zts_get_peer_status(uint64_t peerId); - -////////////////////////////////////////////////////////////////////////////// -// Socket API // -////////////////////////////////////////////////////////////////////////////// - -/** - * @brief Create a socket - * - * This function will return an integer which can be used in much the same way as a - * typical file descriptor, however it is only valid for use with libzt library calls - * as this is merely a facade which is associated with the internal socket representation - * of both the network stacks and drivers. - * - * @usage Call this after zts_start() has succeeded - * @param socket_family Address family (AF_INET, AF_INET6) - * @param socket_type Type of socket (SOCK_STREAM, SOCK_DGRAM, SOCK_RAW) - * @param protocol Protocols supported on this socket - * @return - */ -ZT_SOCKET_API int ZTCALL zts_socket(int socket_family, int socket_type, int protocol); - -/** - * @brief Connect a socket to a remote host - * - * @usage Call this after zts_start() has succeeded - * @param fd File descriptor (only valid for use with libzt calls) - * @param addr Remote host address to connect to - * @param addrlen Length of address - * @return - */ -ZT_SOCKET_API int ZTCALL zts_connect(int fd, const struct sockaddr *addr, socklen_t addrlen); - -/** - * @brief Bind a socket to a virtual interface - * - * @usage Call this after zts_start() has succeeded - * @param fd File descriptor (only valid for use with libzt calls) - * @param addr Local interface address to bind to - * @param addrlen Length of address - * @return - */ -ZT_SOCKET_API int ZTCALL zts_bind(int fd, const struct sockaddr *addr, socklen_t addrlen); - -/** - * @brief Listen for incoming connections - * - * @usage Call this after zts_start() has succeeded - * @param fd File descriptor (only valid for use with libzt calls) - * @param backlog Number of backlogged connection allowed - * @return - */ -ZT_SOCKET_API int ZTCALL zts_listen(int fd, int backlog); - -/** - * @brief Accept an incoming connection - * - * @usage Call this after zts_start() has succeeded - * @param fd File descriptor (only valid for use with libzt calls) - * @param addr Address of remote host for accepted connection - * @param addrlen Length of address - * @return - */ -ZT_SOCKET_API int ZTCALL zts_accept(int fd, struct sockaddr *addr, socklen_t *addrlen); - -/** - * @brief Accept an incoming connection - * - * @usage Call this after zts_start() has succeeded - * @param fd File descriptor (only valid for use with libzt calls) - * @param addr Address of remote host for accepted connection - * @param addrlen Length of address - * @param flags - * @return - */ -#if defined(__linux__) - int zts_accept4(int fd, struct sockaddr *addr, socklen_t *addrlen, int flags); -#endif - -/** - * @brief Set socket options - * - * @usage Call this after zts_start() has succeeded - * @param fd File descriptor (only valid for use with libzt calls) - * @param level Protocol level to which option name should apply - * @param optname Option name to set - * @param optval Source of option value to set - * @param optlen Length of option value - * @return - */ -ZT_SOCKET_API int ZTCALL zts_setsockopt( - int fd, int level, int optname, const void *optval, socklen_t optlen); - -/** - * @brief Get socket options - * - * @usage Call this after zts_start() has succeeded - * @param fd File descriptor (only valid for use with libzt calls) - * @param level Protocol level to which option name should apply - * @param optname Option name to get - * @param optval Where option value will be stored - * @param optlen Length of value - * @return - */ -ZT_SOCKET_API int ZTCALL zts_getsockopt( - int fd, int level, int optname, void *optval, socklen_t *optlen); - -/** - * @brief Get socket name - * - * @usage Call this after zts_start() has succeeded - * @param fd File descriptor (only valid for use with libzt calls) - * @param addr Name associated with this socket - * @param addrlen Length of name - * @return - */ -ZT_SOCKET_API int ZTCALL zts_getsockname(int fd, struct sockaddr *addr, socklen_t *addrlen); - -/** - * @brief Get the peer name for the remote end of a connected socket - * - * @usage Call this after zts_start() has succeeded - * @param fd File descriptor (only valid for use with libzt calls) - * @param addr Name associated with remote end of this socket - * @param addrlen Length of name - * @return - */ -ZT_SOCKET_API int ZTCALL zts_getpeername(int fd, struct sockaddr *addr, socklen_t *addrlen); - -/** - * @brief Gets current hostname - * - * @usage Call this after zts_start() has succeeded - * @param name - * @param len - * @return - */ -ZT_SOCKET_API int ZTCALL zts_gethostname(char *name, size_t len); - -/** - * @brief Sets current hostname - * - * @usage Call this after zts_start() has succeeded - * @param name - * @param len - * @return - */ -ZT_SOCKET_API int ZTCALL zts_sethostname(const char *name, size_t len); - -/** - * @brief Return a pointer to an object with the following structure describing an internet host referenced by name - * - * @usage Call this after zts_start() has succeeded - * @param name - * @return Returns pointer to hostent structure otherwise NULL if failure - */ -ZT_SOCKET_API struct hostent *zts_gethostbyname(const char *name); - -/** - * @brief Close a socket - * - * @usage Call this after zts_start() has succeeded - * @param fd File descriptor (only valid for use with libzt calls) - * @return - */ -ZT_SOCKET_API int ZTCALL zts_close(int fd); - -/** - * @brief Waits for one of a set of file descriptors to become ready to perform I/O. - * - * @usage Call this after zts_start() has succeeded - * @param fds - * @param nfds - * @param timeout - * @return - */ -#if defined(__linux__) -/* -typedef unsigned int nfds_t; -int zts_poll(struct pollfd *fds, nfds_t nfds, int timeout); -*/ -#endif - -/** - * @brief Monitor multiple file descriptors, waiting until one or more of the file descriptors become "ready" - * - * @usage Call this after zts_start() has succeeded - * @param nfds - * @param readfds - * @param writefds - * @param exceptfds - * @param timeout - * @return - */ -ZT_SOCKET_API int ZTCALL zts_select( - int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout); - -/** - * @brief Issue file control commands on a socket - * - * @usage Call this after zts_start() has succeeded - * @param fd File descriptor (only valid for use with libzt calls) - * @param cmd - * @param flags - * @return - */ -#if defined(_WIN32) -#define F_SETFL 0 -#define O_NONBLOCK 0 -#endif -ZT_SOCKET_API int ZTCALL zts_fcntl(int fd, int cmd, int flags); - -/** - * @brief Control a device - * - * @usage Call this after zts_start() has succeeded - * @param fd File descriptor (only valid for use with libzt calls) - * @param request - * @param argp - * @return - */ -ZT_SOCKET_API int ZTCALL zts_ioctl(int fd, unsigned long request, void *argp); - -/** - * @brief Send data to remote host - * - * @usage Call this after zts_start() has succeeded - * @param fd File descriptor (only valid for use with libzt calls) - * @param buf Pointer to data buffer - * @param len Length of data to write - * @param flags - * @return - */ -ZT_SOCKET_API ssize_t ZTCALL zts_send(int fd, const void *buf, size_t len, int flags); - -/** - * @brief Send data to remote host - * - * @usage Call this after zts_start() has succeeded - * @param fd File descriptor (only valid for use with libzt calls) - * @param buf Pointer to data buffer - * @param len Length of data to write - * @param flags - * @param addr Destination address - * @param addrlen Length of destination address - * @return - */ -ZT_SOCKET_API ssize_t ZTCALL zts_sendto( - int fd, const void *buf, size_t len, int flags, const struct sockaddr *addr, socklen_t addrlen); - -/** - * @brief Send message to remote host - * - * @usage Call this after zts_start() has succeeded - * @param fd File descriptor (only valid for use with libzt calls) - * @param msg - * @param flags - * @return - */ -ZT_SOCKET_API ssize_t ZTCALL zts_sendmsg(int fd, const struct msghdr *msg, int flags); - -/** - * @brief Receive data from remote host - * - * @usage Call this after zts_start() has succeeded - * @param fd File descriptor (only valid for use with libzt calls) - * @param buf Pointer to data buffer - * @param len Length of data buffer - * @param flags - * @return - */ -ZT_SOCKET_API ssize_t ZTCALL zts_recv(int fd, void *buf, size_t len, int flags); - -/** - * @brief Receive data from remote host - * - * @usage Call this after zts_start() has succeeded - * @param fd File descriptor (only valid for use with libzt calls) - * @param buf Pointer to data buffer - * @param len Length of data buffer - * @param flags - * @param addr - * @param addrlen - * @return - */ -ZT_SOCKET_API ssize_t ZTCALL zts_recvfrom( - int fd, void *buf, size_t len, int flags, struct sockaddr *addr, socklen_t *addrlen); - -/** - * @brief Receive a message from remote host - * - * @usage Call this after zts_start() has succeeded - * @param fd File descriptor (only valid for use with libzt calls) - * @param msg - * @param flags - * @return - */ -ZT_SOCKET_API ssize_t ZTCALL zts_recvmsg(int fd, struct msghdr *msg,int flags); - -/** - * @brief Read bytes from socket onto buffer - * - * @usage Call this after zts_start() has succeeded - * @param fd File descriptor (only valid for use with libzt calls) - * @param buf Pointer to data buffer - * @param len Length of data buffer to receive data - * @return - */ -ZT_SOCKET_API int ZTCALL zts_read(int fd, void *buf, size_t len); - -/** - * @brief Write bytes from buffer to socket - * - * @usage Call this after zts_start() has succeeded - * @param fd File descriptor (only valid for use with libzt calls) - * @param buf Pointer to data buffer - * @param len Length of buffer to write - * @return - */ -ZT_SOCKET_API int ZTCALL zts_write(int fd, const void *buf, size_t len); - -/** - * @brief Shut down some aspect of a socket (read, write, or both) - * - * @usage Call this after zts_start() has succeeded - * @param fd File descriptor (only valid for use with libzt calls) - * @param how Which aspects of the socket should be shut down - * @return - */ -ZT_SOCKET_API int ZTCALL zts_shutdown(int fd, int how); - -/** - * @brief Adds a DNS nameserver for the network stack to use - * - * @usage Call this after zts_start() has succeeded - * @param addr Address for DNS nameserver - * @return - */ -ZT_SOCKET_API int ZTCALL zts_add_dns_nameserver(struct sockaddr *addr); - -/** - * @brief Removes a DNS nameserver - * - * @usage Call this after zts_start() has succeeded - * @param addr Address for DNS nameserver - * @return - */ -ZT_SOCKET_API int ZTCALL zts_del_dns_nameserver(struct sockaddr *addr); - -#ifdef __cplusplus -} // extern "C" -#endif - -//} // namespace ZeroTier - -#endif // _H diff --git a/include/ZeroTierConstants.h b/include/ZeroTierConstants.h deleted file mode 100644 index 89d1fb2..0000000 --- a/include/ZeroTierConstants.h +++ /dev/null @@ -1,251 +0,0 @@ -/* - * Copyright (c)2013-2020 ZeroTier, Inc. - * - * Use of this software is governed by the Business Source License included - * in the LICENSE.TXT file in the project's root directory. - * - * Change Date: 2024-01-01 - * - * On the date above, in accordance with the Business Source License, use - * of this software will be governed by version 2.0 of the Apache License. - */ -/****/ - -/** - * @file - * - * Common constants used throughout the SDK - */ - -#ifndef ZEROTIER_CONSTANTS_H -#define ZEROTIER_CONSTANTS_H - -#ifdef __cplusplus -extern "C" { -#endif - -// Custom errno to prevent conflicts with platform's own errno -extern int zts_errno; - -#ifdef __cplusplus -} -#endif - -////////////////////////////////////////////////////////////////////////////// -// Control API error codes // -////////////////////////////////////////////////////////////////////////////// - -// No error. -#define ZTS_ERR_OK 0 -// Error (see zts_errno for more info) -#define ZTS_ERR -1 -// A argument provided is invalid (e.g. out of range, NULL, etc) -#define ZTS_ERR_INVALID_ARG -2 -// The service isn't initialized or is currently unavailable. Try again. -#define ZTS_ERR_SERVICE -3 -// This API operation is not permitted or doesn't make sense at this time. -#define ZTS_ERR_INVALID_OP -4 -// The call succeeded, but no object or relevant result was available. -#define ZTS_ERR_NO_RESULT -5 -// General internal failure. Consider filing a bug report. -#define ZTS_ERR_GENERAL -6 - -/** - * The system port upon which ZT traffic is sent and received - */ -#define ZTS_DEFAULT_PORT 9994 - -////////////////////////////////////////////////////////////////////////////// -// Control API event codes // -////////////////////////////////////////////////////////////////////////////// - -#define ZTS_EVENT_NONE -1 -#define ZTS_EVENT_NODE_UP 0 -// Standard node events -#define ZTS_EVENT_NODE_OFFLINE 1 -#define ZTS_EVENT_NODE_ONLINE 2 -#define ZTS_EVENT_NODE_DOWN 3 -#define ZTS_EVENT_NODE_IDENTITY_COLLISION 4 -#define ZTS_EVENT_NODE_UNRECOVERABLE_ERROR 16 -#define ZTS_EVENT_NODE_NORMAL_TERMINATION 17 -// Network events -#define ZTS_EVENT_NETWORK_NOT_FOUND 32 -#define ZTS_EVENT_NETWORK_CLIENT_TOO_OLD 33 -#define ZTS_EVENT_NETWORK_REQUESTING_CONFIG 34 -#define ZTS_EVENT_NETWORK_OK 35 -#define ZTS_EVENT_NETWORK_ACCESS_DENIED 36 -#define ZTS_EVENT_NETWORK_READY_IP4 37 -#define ZTS_EVENT_NETWORK_READY_IP6 38 -#define ZTS_EVENT_NETWORK_READY_IP4_IP6 39 -#define ZTS_EVENT_NETWORK_DOWN 40 -// Network Stack events -#define ZTS_EVENT_STACK_UP 48 -#define ZTS_EVENT_STACK_DOWN 49 -// lwIP netif events -#define ZTS_EVENT_NETIF_UP 64 -#define ZTS_EVENT_NETIF_DOWN 65 -#define ZTS_EVENT_NETIF_REMOVED 66 -#define ZTS_EVENT_NETIF_LINK_UP 67 -#define ZTS_EVENT_NETIF_LINK_DOWN 68 -// Peer events -#define ZTS_EVENT_PEER_P2P 96 -#define ZTS_EVENT_PEER_RELAY 97 -#define ZTS_EVENT_PEER_UNREACHABLE 98 -// Path events -#define ZTS_EVENT_PATH_DISCOVERED 112 -#define ZTS_EVENT_PATH_ALIVE 113 -#define ZTS_EVENT_PATH_DEAD 114 -// Route events -#define ZTS_EVENT_ROUTE_ADDED 128 -#define ZTS_EVENT_ROUTE_REMOVED 129 -// Address events -#define ZTS_EVENT_ADDR_ADDED_IP4 144 -#define ZTS_EVENT_ADDR_REMOVED_IP4 145 -#define ZTS_EVENT_ADDR_ADDED_IP6 146 -#define ZTS_EVENT_ADDR_REMOVED_IP6 147 - -// Macros for legacy behaviour -#define NODE_EVENT_TYPE(code) code >= ZTS_EVENT_NODE_UP && code <= ZTS_EVENT_NODE_NORMAL_TERMINATION -#define NETWORK_EVENT_TYPE(code) code >= ZTS_EVENT_NETWORK_NOT_FOUND && code <= ZTS_EVENT_NETWORK_DOWN -#define STACK_EVENT_TYPE(code) code >= ZTS_EVENT_STACK_UP && code <= ZTS_EVENT_STACK_DOWN -#define NETIF_EVENT_TYPE(code) code >= ZTS_EVENT_NETIF_UP && code <= ZTS_EVENT_NETIF_LINK_DOWN -#define PEER_EVENT_TYPE(code) code >= ZTS_EVENT_PEER_P2P && code <= ZTS_EVENT_PEER_UNREACHABLE -#define PATH_EVENT_TYPE(code) code >= ZTS_EVENT_PATH_DISCOVERED && code <= ZTS_EVENT_PATH_DEAD -#define ROUTE_EVENT_TYPE(code) code >= ZTS_EVENT_ROUTE_ADDED && code <= ZTS_EVENT_ROUTE_REMOVED -#define ADDR_EVENT_TYPE(code) code >= ZTS_EVENT_ADDR_ADDED_IP4 && code <= ZTS_EVENT_ADDR_REMOVED_IP6 - -////////////////////////////////////////////////////////////////////////////// -// Common definitions and structures for interacting with the ZT socket API // -// This is a subset of lwip/sockets.h, lwip/arch.h, and lwip/inet.h // -// // -// These re-definitions exist here so that the user application's usage // -// of the API is internally consistent with the underlying network stack. // -// They have an attached prefix so that they can co-exist with the native // -// platform's own definitions and structures. // -////////////////////////////////////////////////////////////////////////////// - -// Socket protocol types -#define ZTS_SOCK_STREAM 0x0001 -#define ZTS_SOCK_DGRAM 0x0002 -#define ZTS_SOCK_RAW 0x0003 -// Socket family types -#define ZTS_AF_UNSPEC 0x0000 -#define ZTS_AF_INET 0x0002 -#define ZTS_AF_INET6 0x000a -#define ZTS_PF_INET ZTS_AF_INET -#define ZTS_PF_INET6 ZTS_AF_INET6 -#define ZTS_PF_UNSPEC ZTS_AF_UNSPEC -// Protocol command types -#define ZTS_IPPROTO_IP 0x0000 -#define ZTS_IPPROTO_ICMP 0x0001 -#define ZTS_IPPROTO_TCP 0x0006 -#define ZTS_IPPROTO_UDP 0x0011 -#define ZTS_IPPROTO_IPV6 0x0029 -#define ZTS_IPPROTO_ICMPV6 0x003a -#define ZTS_IPPROTO_UDPLITE 0x0088 -#define ZTS_IPPROTO_RAW 0x00ff -// send() and recv() flags -#define ZTS_MSG_PEEK 0x0001 -#define ZTS_MSG_WAITALL 0x0002 // NOT YET SUPPORTED -#define ZTS_MSG_OOB 0x0004 // NOT YET SUPPORTED -#define ZTS_MSG_DONTWAIT 0x0008 -#define ZTS_MSG_MORE 0x0010 -// fnctl() commands -#define ZTS_F_GETFL 0x0003 -#define ZTS_F_SETFL 0x0004 -// fnctl() flags -#define ZTS_O_NONBLOCK 0x0001 -#define ZTS_O_NDELAY 0x0001 -// Shutdown commands -#define ZTS_SHUT_RD 0x0000 -#define ZTS_SHUT_WR 0x0001 -#define ZTS_SHUT_RDWR 0x0002 -// Socket level option number -#define ZTS_SOL_SOCKET 0x0fff -// Socket options -#define ZTS_SO_DEBUG 0x0001 // NOT YET SUPPORTED -#define ZTS_SO_ACCEPTCONN 0x0002 -#define ZTS_SO_REUSEADDR 0x0004 -#define ZTS_SO_KEEPALIVE 0x0008 -#define ZTS_SO_DONTROUTE 0x0010 // NOT YET SUPPORTED -#define ZTS_SO_BROADCAST 0x0020 -#define ZTS_SO_USELOOPBACK 0x0040 // NOT YET SUPPORTED -#define ZTS_SO_LINGER 0x0080 -#define ZTS_SO_DONTLINGER ((int)(~ZTS_SO_LINGER)) -#define ZTS_SO_OOBINLINE 0x0100 // NOT YET SUPPORTED -#define ZTS_SO_REUSEPORT 0x0200 // NOT YET SUPPORTED -#define ZTS_SO_SNDBUF 0x1001 // NOT YET SUPPORTED -#define ZTS_SO_RCVBUF 0x1002 -#define ZTS_SO_SNDLOWAT 0x1003 // NOT YET SUPPORTED -#define ZTS_SO_RCVLOWAT 0x1004 // NOT YET SUPPORTED -#define ZTS_SO_SNDTIMEO 0x1005 -#define ZTS_SO_RCVTIMEO 0x1006 -#define ZTS_SO_ERROR 0x1007 -#define ZTS_SO_TYPE 0x1008 -#define ZTS_SO_CONTIMEO 0x1009 -#define ZTS_SO_NO_CHECK 0x100a -// IPPROTO_IP options -#define ZTS_IP_TOS 0x0001 -#define ZTS_IP_TTL 0x0002 -// IPPROTO_TCP options -#define ZTS_TCP_NODELAY 0x0001 -#define ZTS_TCP_KEEPALIVE 0x0002 -#define ZTS_TCP_KEEPIDLE 0x0003 -#define ZTS_TCP_KEEPINTVL 0x0004 -#define ZTS_TCP_KEEPCNT 0x0005 -// IPPROTO_IPV6 options -#define ZTS_IPV6_CHECKSUM 0x0007 // RFC3542 -#define ZTS_IPV6_V6ONLY 0x001b // RFC3493 -// Macro's for defining ioctl() command values -#define ZTS_IOCPARM_MASK 0x7fU -#define ZTS_IOC_VOID 0x20000000UL -#define ZTS_IOC_OUT 0x40000000UL -#define ZTS_IOC_IN 0x80000000UL -#define ZTS_IOC_INOUT (ZTS_IOC_IN | ZTS_IOC_OUT) -#define ZTS_IO(x,y) (ZTS_IOC_VOID | ((x)<<8)|(y)) -#define ZTS_IOR(x,y,t) (ZTS_IOC_OUT | (((long)sizeof(t) & ZTS_IOCPARM_MASK)<<16) | ((x)<<8) | (y)) -#define ZTS_IOW(x,y,t) (ZTS_IOC_IN | (((long)sizeof(t) & ZTS_IOCPARM_MASK)<<16) | ((x)<<8) | (y)) -// ioctl() commands -#define ZTS_FIONREAD ZTS_IOR('f', 127, unsigned long) -#define ZTS_FIONBIO ZTS_IOW('f', 126, unsigned long) - -/* FD_SET used for lwip_select */ - -#ifndef ZTS_FD_SET -#undef ZTS_FD_SETSIZE -// Make FD_SETSIZE match NUM_SOCKETS in socket.c -#define ZTS_FD_SETSIZE MEMP_NUM_NETCONN -#define ZTS_FDSETSAFESET(n, code) do { \ - if (((n) - LWIP_SOCKET_OFFSET < MEMP_NUM_NETCONN) && (((int)(n) - LWIP_SOCKET_OFFSET) >= 0)) { \ - code; }} while(0) -#define ZTS_FDSETSAFEGET(n, code) (((n) - LWIP_SOCKET_OFFSET < MEMP_NUM_NETCONN) && (((int)(n) - LWIP_SOCKET_OFFSET) >= 0) ?\ - (code) : 0) -#define ZTS_FD_SET(n, p) ZTS_FDSETSAFESET(n, (p)->fd_bits[((n)-LWIP_SOCKET_OFFSET)/8] |= (1 << (((n)-LWIP_SOCKET_OFFSET) & 7))) -#define ZTS_FD_CLR(n, p) ZTS_FDSETSAFESET(n, (p)->fd_bits[((n)-LWIP_SOCKET_OFFSET)/8] &= ~(1 << (((n)-LWIP_SOCKET_OFFSET) & 7))) -#define ZTS_FD_ISSET(n,p) ZTS_FDSETSAFEGET(n, (p)->fd_bits[((n)-LWIP_SOCKET_OFFSET)/8] & (1 << (((n)-LWIP_SOCKET_OFFSET) & 7))) -#define ZTS_FD_ZERO(p) memset((void*)(p), 0, sizeof(*(p))) - -#elif LWIP_SOCKET_OFFSET -#error LWIP_SOCKET_OFFSET does not work with external FD_SET! -#elif ZTS_FD_SETSIZE < MEMP_NUM_NETCONN -#error "external ZTS_FD_SETSIZE too small for number of sockets" -#endif // FD_SET - -////////////////////////////////////////////////////////////////////////////// -// Statistics // -////////////////////////////////////////////////////////////////////////////// - -#define ZTS_STATS_PROTOCOL_LINK 0 -#define ZTS_STATS_PROTOCOL_ETHARP 1 -#define ZTS_STATS_PROTOCOL_IP 2 -#define ZTS_STATS_PROTOCOL_UDP 3 -#define ZTS_STATS_PROTOCOL_TCP 4 -#define ZTS_STATS_PROTOCOL_ICMP 5 -#define ZTS_STATS_PROTOCOL_IP_FRAG 6 -#define ZTS_STATS_PROTOCOL_IP6 7 -#define ZTS_STATS_PROTOCOL_ICMP6 8 -#define ZTS_STATS_PROTOCOL_IP6_FRAG 9 - -//#if defined(_USING_LWIP_DEFINITIONS_) - -#endif // ZEROTIER_CONSTANTS_H
\ No newline at end of file diff --git a/include/ZeroTierSockets.h b/include/ZeroTierSockets.h new file mode 100644 index 0000000..9c870ad --- /dev/null +++ b/include/ZeroTierSockets.h @@ -0,0 +1,1688 @@ +/* + * Copyright (c)2013-2020 ZeroTier, Inc. + * + * Use of this software is governed by the Business Source License included + * in the LICENSE.TXT file in the project's root directory. + * + * Change Date: 2024-01-01 + * + * On the date above, in accordance with the Business Source License, use + * of this software will be governed by version 2.0 of the Apache License. + */ +/****/ + +/** + * @file + * + * This defines the external C API for ZeroTier Sockets + */ + +#ifndef ZT_SOCKETS_H +#define ZT_SOCKETS_H + +#include <inttypes.h> + +#if defined(_MSC_VER) + #ifndef ssize_t + // TODO: Should be SSIZE_T, would require lwIP patch + // #include <BaseTsd.h> + // typedef SSIZE_T ssize_t; + typedef int ssize_t; + #endif +#else + #include <unistd.h> +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +////////////////////////////////////////////////////////////////////////////// +// Event codes // +////////////////////////////////////////////////////////////////////////////// + +// Node events +#define ZTS_EVENT_NODE_UP 200 +#define ZTS_EVENT_NODE_ONLINE 201 +#define ZTS_EVENT_NODE_OFFLINE 202 +#define ZTS_EVENT_NODE_DOWN 203 +#define ZTS_EVENT_NODE_IDENTITY_COLLISION 204 +#define ZTS_EVENT_NODE_UNRECOVERABLE_ERROR 205 +#define ZTS_EVENT_NODE_NORMAL_TERMINATION 206 +// Network events +#define ZTS_EVENT_NETWORK_NOT_FOUND 210 +#define ZTS_EVENT_NETWORK_CLIENT_TOO_OLD 211 +#define ZTS_EVENT_NETWORK_REQ_CONFIG 212 +#define ZTS_EVENT_NETWORK_OK 213 +#define ZTS_EVENT_NETWORK_ACCESS_DENIED 214 +#define ZTS_EVENT_NETWORK_READY_IP4 215 +#define ZTS_EVENT_NETWORK_READY_IP6 216 +#define ZTS_EVENT_NETWORK_READY_IP4_IP6 217 +#define ZTS_EVENT_NETWORK_DOWN 218 +// Network Stack events +#define ZTS_EVENT_STACK_UP 220 +#define ZTS_EVENT_STACK_DOWN 221 +// lwIP netif events +#define ZTS_EVENT_NETIF_UP 230 +#define ZTS_EVENT_NETIF_DOWN 231 +#define ZTS_EVENT_NETIF_REMOVED 232 +#define ZTS_EVENT_NETIF_LINK_UP 233 +#define ZTS_EVENT_NETIF_LINK_DOWN 234 +// Peer events +#define ZTS_EVENT_PEER_DIRECT 240 +#define ZTS_EVENT_PEER_RELAY 241 +#define ZTS_EVENT_PEER_UNREACHABLE 242 +// Path events +#define ZTS_EVENT_PATH_DISCOVERED 250 +#define ZTS_EVENT_PATH_ALIVE 251 +#define ZTS_EVENT_PATH_DEAD 252 +// Route events +#define ZTS_EVENT_ROUTE_ADDED 260 +#define ZTS_EVENT_ROUTE_REMOVED 261 +// Address events +#define ZTS_EVENT_ADDR_ADDED_IP4 270 +#define ZTS_EVENT_ADDR_REMOVED_IP4 271 +#define ZTS_EVENT_ADDR_ADDED_IP6 272 +#define ZTS_EVENT_ADDR_REMOVED_IP6 273 + +////////////////////////////////////////////////////////////////////////////// +// Return Error codes // +////////////////////////////////////////////////////////////////////////////// + +#define ZTS_ERR_OK 0 // No error +#define ZTS_ERR_SOCKET -1 // Socket error, see zts_errno +#define ZTS_ERR_SERVICE -2 // You probably did something at the wrong time +#define ZTS_ERR_ARG -3 // Invalid argument +#define ZTS_ERR_NO_RESULT -4 // No result (not necessarily an error) +#define ZTS_ERR_GENERAL -5 // Consider filing a bug report + +////////////////////////////////////////////////////////////////////////////// +// zts_errno Error codes // +////////////////////////////////////////////////////////////////////////////// + +// Error variable set after each zts_* call to provide additional information. +extern int zts_errno; + +#define ZTS_EPERM 1 /* Operation not permitted */ +#define ZTS_ENOENT 2 /* No such file or directory */ +#define ZTS_ESRCH 3 /* No such process */ +#define ZTS_EINTR 4 /* Interrupted system call */ +#define ZTS_EIO 5 /* I/O error */ +#define ZTS_ENXIO 6 /* No such device or address */ +#define ZTS_E2BIG 7 /* Arg list too long */ +#define ZTS_ENOEXEC 8 /* Exec format error */ +#define ZTS_EBADF 9 /* Bad file number */ +#define ZTS_ECHILD 10 /* No child processes */ +#define ZTS_EAGAIN 11 /* Try again */ +#define ZTS_ENOMEM 12 /* Out of memory */ +#define ZTS_EACCES 13 /* Permission denied */ +#define ZTS_EFAULT 14 /* Bad address */ +#define ZTS_ENOTBLK 15 /* Block device required */ +#define ZTS_EBUSY 16 /* Device or resource busy */ +#define ZTS_EEXIST 17 /* File exists */ +#define ZTS_EXDEV 18 /* Cross-device link */ +#define ZTS_ENODEV 19 /* No such device */ +#define ZTS_ENOTDIR 20 /* Not a directory */ +#define ZTS_EISDIR 21 /* Is a directory */ +#define ZTS_EINVAL 22 /* Invalid argument */ +#define ZTS_ENFILE 23 /* File table overflow */ +#define ZTS_EMFILE 24 /* Too many open files */ +#define ZTS_ENOTTY 25 /* Not a typewriter */ +#define ZTS_ETXTBSY 26 /* Text file busy */ +#define ZTS_EFBIG 27 /* File too large */ +#define ZTS_ENOSPC 28 /* No space left on device */ +#define ZTS_ESPIPE 29 /* Illegal seek */ +#define ZTS_EROFS 30 /* Read-only file system */ +#define ZTS_EMLINK 31 /* Too many links */ +#define ZTS_EPIPE 32 /* Broken pipe */ +#define ZTS_EDOM 33 /* Math argument out of domain of func */ +#define ZTS_ERANGE 34 /* Math result not representable */ +#define ZTS_EDEADLK 35 /* Resource deadlock would occur */ +#define ZTS_ENAMETOOLONG 36 /* File name too long */ +#define ZTS_ENOLCK 37 /* No record locks available */ +#define ZTS_ENOSYS 38 /* Function not implemented */ +#define ZTS_ENOTEMPTY 39 /* Directory not empty */ +#define ZTS_ELOOP 40 /* Too many symbolic links encountered */ +#define ZTS_EWOULDBLOCK ZTS_EAGAIN /* Operation would block */ +#define ZTS_ENOMSG 42 /* No message of desired type */ +#define ZTS_EIDRM 43 /* Identifier removed */ +#define ZTS_ECHRNG 44 /* Channel number out of range */ +#define ZTS_EL2NSYNC 45 /* Level 2 not synchronized */ +#define ZTS_EL3HLT 46 /* Level 3 halted */ +#define ZTS_EL3RST 47 /* Level 3 reset */ +#define ZTS_ELNRNG 48 /* Link number out of range */ +#define ZTS_EUNATCH 49 /* Protocol driver not attached */ +#define ZTS_ENOCSI 50 /* No CSI structure available */ +#define ZTS_EL2HLT 51 /* Level 2 halted */ +#define ZTS_EBADE 52 /* Invalid exchange */ +#define ZTS_EBADR 53 /* Invalid request descriptor */ +#define ZTS_EXFULL 54 /* Exchange full */ +#define ZTS_ENOANO 55 /* No anode */ +#define ZTS_EBADRQC 56 /* Invalid request code */ +#define ZTS_EBADSLT 57 /* Invalid slot */ + +#define ZTS_EDEADLOCK ZTS_EDEADLK + +#define ZTS_EBFONT 59 /* Bad font file format */ +#define ZTS_ENOSTR 60 /* Device not a stream */ +#define ZTS_ENODATA 61 /* No data available */ +#define ZTS_ETIME 62 /* Timer expired */ +#define ZTS_ENOSR 63 /* Out of streams resources */ +#define ZTS_ENONET 64 /* Machine is not on the network */ +#define ZTS_ENOPKG 65 /* Package not installed */ +#define ZTS_EREMOTE 66 /* Object is remote */ +#define ZTS_ENOLINK 67 /* Link has been severed */ +#define ZTS_EADV 68 /* Advertise error */ +#define ZTS_ESRMNT 69 /* Srmount error */ +#define ZTS_ECOMM 70 /* Communication error on send */ +#define ZTS_EPROTO 71 /* Protocol error */ +#define ZTS_EMULTIHOP 72 /* Multihop attempted */ +#define ZTS_EDOTDOT 73 /* RFS specific error */ +#define ZTS_EBADMSG 74 /* Not a data message */ +#define ZTS_EOVERFLOW 75 /* Value too large for defined data type */ +#define ZTS_ENOTUNIQ 76 /* Name not unique on network */ +#define ZTS_EBADFD 77 /* File descriptor in bad state */ +#define ZTS_EREMCHG 78 /* Remote address changed */ +#define ZTS_ELIBACC 79 /* Can not access a needed shared library */ +#define ZTS_ELIBBAD 80 /* Accessing a corrupted shared library */ +#define ZTS_ELIBSCN 81 /* .lib section in a.out corrupted */ +#define ZTS_ELIBMAX 82 /* Attempting to link in too many shared libraries */ +#define ZTS_ELIBEXEC 83 /* Cannot exec a shared library directly */ +#define ZTS_EILSEQ 84 /* Illegal byte sequence */ +#define ZTS_ERESTART 85 /* Interrupted system call should be restarted */ +#define ZTS_ESTRPIPE 86 /* Streams pipe error */ +#define ZTS_EUSERS 87 /* Too many users */ +#define ZTS_ENOTSOCK 88 /* Socket operation on non-socket */ +#define ZTS_EDESTADDRREQ 89 /* Destination address required */ +#define ZTS_EMSGSIZE 90 /* Message too long */ +#define ZTS_EPROTOTYPE 91 /* Protocol wrong type for socket */ +#define ZTS_ENOPROTOOPT 92 /* Protocol not available */ +#define ZTS_EPROTONOSUPPORT 93 /* Protocol not supported */ +#define ZTS_ESOCKTNOSUPPORT 94 /* Socket type not supported */ +#define ZTS_EOPNOTSUPP 95 /* Operation not supported on transport endpoint */ +#define ZTS_EPFNOSUPPORT 96 /* Protocol family not supported */ +#define ZTS_EAFNOSUPPORT 97 /* Address family not supported by protocol */ +#define ZTS_EADDRINUSE 98 /* Address already in use */ +#define ZTS_EADDRNOTAVAIL 99 /* Cannot assign requested address */ +#define ZTS_ENETDOWN 100 /* Network is down */ +#define ZTS_ENETUNREACH 101 /* Network is unreachable */ +#define ZTS_ENETRESET 102 /* Network dropped connection because of reset */ +#define ZTS_ECONNABORTED 103 /* Software caused connection abort */ +#define ZTS_ECONNRESET 104 /* Connection reset by peer */ +#define ZTS_ENOBUFS 105 /* No buffer space available */ +#define ZTS_EISCONN 106 /* Transport endpoint is already connected */ +#define ZTS_ENOTCONN 107 /* Transport endpoint is not connected */ +#define ZTS_ESHUTDOWN 108 /* Cannot send after transport endpoint shutdown */ +#define ZTS_ETOOMANYREFS 109 /* Too many references: cannot splice */ +#define ZTS_ETIMEDOUT 110 /* Connection timed out */ +#define ZTS_ECONNREFUSED 111 /* Connection refused */ +#define ZTS_EHOSTDOWN 112 /* Host is down */ +#define ZTS_EHOSTUNREACH 113 /* No route to host */ +#define ZTS_EALREADY 114 /* Operation already in progress */ +#define ZTS_EINPROGRESS 115 /* Operation now in progress */ +#define ZTS_ESTALE 116 /* Stale NFS file handle */ +#define ZTS_EUCLEAN 117 /* Structure needs cleaning */ +#define ZTS_ENOTNAM 118 /* Not a XENIX named type file */ +#define ZTS_ENAVAIL 119 /* No XENIX semaphores available */ +#define ZTS_EISNAM 120 /* Is a named type file */ +#define ZTS_EREMOTEIO 121 /* Remote I/O error */ +#define ZTS_EDQUOT 122 /* Quota exceeded */ + +#define ZTS_ENOMEDIUM 123 /* No medium found */ +#define ZTS_EMEDIUMTYPE 124 /* Wrong medium type */ + +////////////////////////////////////////////////////////////////////////////// +// Common definitions and structures for interoperability between zts_* and // +// lwIP functions. Some of the code in the following section is a borrowed // +// from the lwIP codebase so that the user doesn't need to include headers // +// from that project in addition to the ZeroTier SDK headers. The license // +// applying to this code borrowed from lwIP is produced below and only // +// applies to the portions of code which are merely renamed versions of // +// their lwIP counterparts. The rest of the code in this C API file is // +// governed by the license text provided at the beginning of this file. // +////////////////////////////////////////////////////////////////////////////// + +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels <[email protected]> + * + */ + +#define ZTS_INET_ADDRSTRLEN 16 +#define ZTS_INET6_ADDRSTRLEN 46 + +/** 255.255.255.255 */ +#define ZTS_IPADDR_NONE ((uint32_t)0xffffffffUL) +/** 127.0.0.1 */ +#define ZTS_IPADDR_LOOPBACK ((uint32_t)0x7f000001UL) +/** 0.0.0.0 */ +#define ZTS_IPADDR_ANY ((uint32_t)0x00000000UL) +/** 255.255.255.255 */ +#define ZTS_IPADDR_BROADCAST ((uint32_t)0xffffffffUL) + +/** 255.255.255.255 */ +#define ZTS_INADDR_NONE ZTS_IPADDR_NONE +/** 127.0.0.1 */ +#define ZTS_INADDR_LOOPBACK ZTS_IPADDR_LOOPBACK +/** 0.0.0.0 */ +#define ZTS_INADDR_ANY ZTS_IPADDR_ANY +/** 255.255.255.255 */ +#define ZTS_INADDR_BROADCAST ZTS_IPADDR_BROADCAST + +// Socket protocol types +#define ZTS_SOCK_STREAM 0x0001 +#define ZTS_SOCK_DGRAM 0x0002 +#define ZTS_SOCK_RAW 0x0003 +// Socket family types +#define ZTS_AF_UNSPEC 0x0000 +#define ZTS_AF_INET 0x0002 +#define ZTS_AF_INET6 0x000a +#define ZTS_PF_INET ZTS_AF_INET +#define ZTS_PF_INET6 ZTS_AF_INET6 +#define ZTS_PF_UNSPEC ZTS_AF_UNSPEC +// Protocol command types +#define ZTS_IPPROTO_IP 0x0000 +#define ZTS_IPPROTO_ICMP 0x0001 +#define ZTS_IPPROTO_TCP 0x0006 +#define ZTS_IPPROTO_UDP 0x0011 +#define ZTS_IPPROTO_IPV6 0x0029 +#define ZTS_IPPROTO_ICMPV6 0x003a +#define ZTS_IPPROTO_UDPLITE 0x0088 +#define ZTS_IPPROTO_RAW 0x00ff +// send() and recv() flags +#define ZTS_MSG_PEEK 0x0001 +#define ZTS_MSG_WAITALL 0x0002 // NOT YET SUPPORTED +#define ZTS_MSG_OOB 0x0004 // NOT YET SUPPORTED +#define ZTS_MSG_DONTWAIT 0x0008 +#define ZTS_MSG_MORE 0x0010 + +// Macro's for defining ioctl() command values +#define ZTS_IOCPARM_MASK 0x7fU +#define ZTS_IOC_VOID 0x20000000UL +#define ZTS_IOC_OUT 0x40000000UL +#define ZTS_IOC_IN 0x80000000UL +#define ZTS_IOC_INOUT (ZTS_IOC_IN | ZTS_IOC_OUT) +#define ZTS_IO(x,y) (ZTS_IOC_VOID | ((x)<<8)|(y)) +#define ZTS_IOR(x,y,t) (ZTS_IOC_OUT | (((long)sizeof(t) & ZTS_IOCPARM_MASK)<<16) | ((x)<<8) | (y)) +#define ZTS_IOW(x,y,t) (ZTS_IOC_IN | (((long)sizeof(t) & ZTS_IOCPARM_MASK)<<16) | ((x)<<8) | (y)) +// ioctl() commands +#define ZTS_FIONREAD ZTS_IOR('f', 127, unsigned long) +#define ZTS_FIONBIO ZTS_IOW('f', 126, unsigned long) + +////////////////////////////////////////////////////////////////////////////// +// Custom but still mostly standard socket interface structures // +////////////////////////////////////////////////////////////////////////////// + +typedef uint32_t zts_socklen_t; +typedef uint32_t zts_in_addr_t; +typedef uint16_t zts_in_port_t; +typedef uint8_t zts_sa_family_t; + +struct zts_in_addr { +#if defined(__WINDOWS__) + zts_in_addr_t S_addr; +#else + // A definition in winsock may conflict with s_addr + zts_in_addr_t s_addr; +#endif +}; + +struct zts_in6_addr { + union un { + uint32_t u32_addr[4]; + uint8_t u8_addr[16]; + } un; +//#define s6_addr un.u8_addr +}; + +struct zts_sockaddr_in { + uint8_t sin_len; + zts_sa_family_t sin_family; + zts_in_port_t sin_port; + struct zts_in_addr sin_addr; +#define SIN_ZERO_LEN 8 + char sin_zero[SIN_ZERO_LEN]; +}; + +struct zts_sockaddr_in6 { + uint8_t sin6_len; // length of this structure + zts_sa_family_t sin6_family; // ZTS_AF_INET6 + zts_in_port_t sin6_port; // Transport layer port # + uint32_t sin6_flowinfo; // IPv6 flow information + struct zts_in6_addr sin6_addr; // IPv6 address + uint32_t sin6_scope_id; // Set of interfaces for scope +}; + +struct zts_sockaddr { + uint8_t sa_len; + zts_sa_family_t sa_family; + char sa_data[14]; +}; + +struct zts_sockaddr_storage { + uint8_t s2_len; + zts_sa_family_t ss_family; + char s2_data1[2]; + uint32_t s2_data2[3]; + uint32_t s2_data3[3]; +}; + +////////////////////////////////////////////////////////////////////////////// +// Subset of: ZeroTierOne.h // +// We redefine a few ZT structures here so that we don't need to drag the // +// entire ZeroTierOne.h file into the user application // +////////////////////////////////////////////////////////////////////////////// + +/** + * Maximum address assignments per network + */ +#define ZTS_MAX_ASSIGNED_ADDRESSES 16 + +/** + * Maximum routes per network + */ +#define ZTS_MAX_NETWORK_ROUTES 32 + +/** + * Maximum number of direct network paths to a given peer + */ +#define ZT_MAX_PEER_NETWORK_PATHS 16 + +/** + * What trust hierarchy role does this peer have? + */ +enum zts_peer_role +{ + ZTS_PEER_ROLE_LEAF = 0, // ordinary node + ZTS_PEER_ROLE_MOON = 1, // moon root + ZTS_PEER_ROLE_PLANET = 2 // planetary root +}; + +////////////////////////////////////////////////////////////////////////////// +// Structures used to convey details during various callback events // +////////////////////////////////////////////////////////////////////////////// + +/** + * A structure used to convey details about the current node + * to the user application + */ +struct zts_node_details +{ + /** + * The node ID + */ + uint64_t address; + + /** + * The current clock value accord to the node + */ + uint64_t clock; + + /** + * Whether or not this node is online + */ + uint8_t online; + + /** + * Whether port mapping is enabled + */ + uint8_t portMappingEnabled; + + /** + * Whether multipath support is enabled. If true, this node will + * be capable of utilizing multiple physical links simultaneously + * to create higher quality or more robust aggregate links. + * + * See: https://www.zerotier.com/manual.shtml#2_1_5 + */ + uint8_t multipathEnabled; + + /** + * The port used by the service to send and receive + * all encapsulated traffic + */ + uint16_t primaryPort; + + /** + * Planet ID + */ + uint64_t planetWorldId; + uint64_t planetWorldTimestamp; + uint8_t versionMajor; + uint8_t versionMinor; + uint8_t versionRev; +}; + +/** + * A structure used to convey information to a user application via + * a callback function. + */ +struct zts_callback_msg +{ + /** + * Event identifier + */ + int16_t eventCode; + + struct zts_node_details *node; + struct zts_network_details *network; + struct zts_netif_details *netif; + struct zts_virtual_network_route *route; + struct zts_physical_path *path; + struct zts_peer_details *peer; + struct zts_addr_details *addr; +}; + +struct zts_addr_details +{ + uint64_t nwid; + struct zts_sockaddr_storage addr; +}; + +/** + * A structure used to convey information about a virtual network + * interface (netif) to a user application. + */ +struct zts_netif_details +{ + /** + * The virtual network that this interface was commissioned for. + */ + uint64_t nwid; + + /** + * The hardware address assigned to this interface + */ + uint64_t mac; + + /** + * The MTU for this interface + */ + int mtu; + + /** + * The IPv4 address assigned to this interface. + */ + //struct sockaddr_in ip4_addr; + + /** + * The IPv6 addresses assigned to this interface. + */ + //struct sockaddr_in6 ip6_addr[LWIP_IPV6_NUM_ADDRESSES]; + + /** + * Number of IPv4 addresses assigned to this interface + */ + //int num_ip4_addr; + + /** + * Number of IPv6 addresses assigned to this interface + */ + //int num_ip6_addr; +}; + +/** + * A structure used to represent a virtual network route + */ +struct zts_virtual_network_route +{ + /** + * Target network / netmask bits (in port field) or NULL or 0.0.0.0/0 for default + */ + struct zts_sockaddr_storage target; + + /** + * Gateway IP address (port ignored) or NULL (family == 0) for LAN-local (no gateway) + */ + struct zts_sockaddr_storage via; + + /** + * Route flags + */ + uint16_t flags; + + /** + * Route metric (not currently used) + */ + uint16_t metric; +}; + +/** + * A structure used to convey network-specific details to the user application + */ +struct zts_network_details +{ + /** + * Network ID + */ + uint64_t nwid; + + /** + * Maximum Transmission Unit size for this network + */ + int mtu; + + /** + * Number of addresses (actually) assigned to the node on this network + */ + short num_addresses; + + /** + * Array of IPv4 and IPv6 addresses assigned to the node on this network + */ + struct zts_sockaddr_storage addr[ZTS_MAX_ASSIGNED_ADDRESSES]; + + /** + * Number of routes + */ + unsigned int num_routes; + + /** + * Array of IPv4 and IPv6 addresses assigned to the node on this network + */ + struct zts_virtual_network_route routes[ZTS_MAX_NETWORK_ROUTES]; +}; + +/** + * Physical network path to a peer + */ +struct zts_physical_path +{ + /** + * Address of endpoint + */ + struct zts_sockaddr_storage address; + + /** + * Time of last send in milliseconds or 0 for never + */ + uint64_t lastSend; + + /** + * Time of last receive in milliseconds or 0 for never + */ + uint64_t lastReceive; + + /** + * Is this a trusted path? If so this will be its nonzero ID. + */ + uint64_t trustedPathId; + + /** + * Is path expired? + */ + int expired; + + /** + * Is path preferred? + */ + int preferred; +}; + +/** + * Peer status result buffer + */ +struct zts_peer_details +{ + /** + * ZeroTier address (40 bits) + */ + uint64_t address; + + /** + * Remote major version or -1 if not known + */ + int versionMajor; + + /** + * Remote minor version or -1 if not known + */ + int versionMinor; + + /** + * Remote revision or -1 if not known + */ + int versionRev; + + /** + * Last measured latency in milliseconds or -1 if unknown + */ + int latency; + + /** + * What trust hierarchy role does this device have? + */ + enum zts_peer_role role; + + /** + * Number of paths (size of paths[]) + */ + unsigned int pathCount; + + /** + * Known network paths to peer + */ + struct zts_physical_path paths[ZT_MAX_PEER_NETWORK_PATHS]; +}; + +/** + * List of peers + */ +struct zts_peer_list +{ + struct zts_peer_details *peers; + unsigned long peerCount; +}; + +////////////////////////////////////////////////////////////////////////////// +// ZeroTier Service Controls // +////////////////////////////////////////////////////////////////////////////// + +#if defined(__WINDOWS__) + #ifdef ADD_EXPORTS + #define ZT_SOCKET_API __declspec(dllexport) + #else + #define ZT_SOCKET_API __declspec(dllimport) + #endif + #define ZTCALL __cdecl +#else + #define ZT_SOCKET_API + #define ZTCALL +#endif + +/** + * @brief Enable or disable whether the service will cache network details (enabled by default) + * + * This can potentially shorten (startup) times. This allows the service to nearly instantly + * inform the network stack of an address to use for this peer so that it can + * create an interface. This can be disabled for cases where one may not want network + * config details to be written to storage. This is especially useful for situations where + * address assignments do not change often. + * + * @usage Should be called before zts_start() if you intend on changing its state. + * + * @param enabled Whether or not this feature is enabled + * @return ZTS_ERR_OK on success. ZTS_ERR_SERVICE on failure. + */ +ZT_SOCKET_API int ZTCALL zts_allow_network_caching(uint8_t allowed); + +/** + * @brief Enable or disable whether the service will cache peer details (enabled by default) + * + * This can potentially shorten (connection) times. This allows the service to + * re-use previously discovered paths to a peer, this prevents the service from having + * to go through the entire transport-triggered link provisioning process. This is especially + * useful for situations where paths to peers do not change often. This is enabled by default + * and can be disabled for cases where one may not want peer details to be written to storage. + * + * @usage Should be called before zts_start() if you intend on changing its state. + * + * @param enabled Whether or not this feature is enabled + * @return ZTS_ERR_OK on success. ZTS_ERR_SERVICE on failure. + */ +ZT_SOCKET_API int ZTCALL zts_allow_peer_caching(uint8_t allowed); + +/** + * @brief Enable or disable whether the service will read from a local.conf + * + * @usage Should be called before zts_start() if you intend on changing its state. + * + * @param enabled Whether or not this feature is enabled + * @return ZTS_ERR_OK on success. ZTS_ERR_SERVICE on failure. + */ +ZT_SOCKET_API int ZTCALL zts_allow_local_conf(uint8_t allowed); + +/** + * @brief Starts the ZeroTier service and notifies user application of events via callback + * + * @param path path directory where configuration files are stored + * @param callback User-specified callback for ZTS_EVENT_* events + * @return ZTS_ERR_OK on success. ZTS_ERR_SERVICE or ZTS_ERR_ARG on failure + */ +ZT_SOCKET_API int ZTCALL zts_start(const char *path, void (*callback)(void *), uint16_t port); + +/** + * @brief Stops the ZeroTier service and brings down all virtual network interfaces + * + * @usage While the ZeroTier service will stop, the stack driver (with associated timers) + * will remain active in case future traffic processing is required. To stop all activity + * and free all resources use zts_free() instead. + * @return ZTS_ERR_OK on success. ZTS_ERR_SERVICE on failure. + */ +ZT_SOCKET_API int ZTCALL zts_stop(); + +/** + * @brief Restart the ZeroTier service. + * + * @usage This call will block until the service has been brought offline. Then + * it will return and the user application can then watch for the appropriate + * startup callback events. + * @return ZTS_ERR_OK on success. ZTS_ERR_SERVICE on failure. + */ +ZT_SOCKET_API int ZTCALL zts_restart(); + +/** + * @brief Stop all background services, bring down all interfaces, free all resources. After + * calling this function an application restart will be required before the library can be + * used again. + * + * @usage This should be called at the end of your program or when you do not anticipate + * communicating over ZeroTier + * @return ZTS_ERR_OK on success. ZTS_ERR_SERVICE on failure. + */ +ZT_SOCKET_API int ZTCALL zts_free(); + +/** + * @brief Populate a structure with details for a given network + * + * @param nwid A 16-digit hexadecimal virtual network ID + * @param nd Pointer to a zts_network_details structure to populate + * @return ZTS_ERR_OK on success. ZTS_ERR_SERVICE or ZTS_ERR_ARG on failure. + */ +ZT_SOCKET_API int ZTCALL zts_get_network_details(uint64_t nwid, struct zts_network_details *nd); + +/** + * @brief Populate an array of structures with details for any given number of networks + * + * @param nds Pointer to an array of zts_network_details structures to populate + * @param num Number of zts_network_details structures available to copy data into, will be updated + * to reflect number of structures that were actually populated + * @return ZTS_ERR_OK on success. ZTS_ERR_SERVICE or ZTS_ERR_ARG on failure. + */ +ZT_SOCKET_API int ZTCALL zts_get_all_network_details(struct zts_network_details *nds, int *num); + +/** + * @brief Join a network + * + * @param nwid A 16-digit hexadecimal virtual network ID + * @return ZTS_ERR_OK on success. ZTS_ERR_SERVICE or ZTS_ERR_ARG on failure. + */ +ZT_SOCKET_API int ZTCALL zts_join(const uint64_t nwid); + +/** + * @brief Leave a network + * + * @param nwid A 16-digit hexadecimal virtual network ID + * @return ZTS_ERR_OK on success. ZTS_ERR_SERVICE or ZTS_ERR_ARG on failure. + */ +ZT_SOCKET_API int ZTCALL zts_leave(const uint64_t nwid); + +/** + * @brief Leave all networks + * + * @return ZTS_ERR_OK on success. ZTS_ERR_SERVICE or ZTS_ERR_ARG on failure. + */ +ZT_SOCKET_API int ZTCALL zts_leave_all(); + +/** + * @brief Orbit a given moon (user-defined root server) + * + * @param moonWorldId A 16-digit hexadecimal world ID + * @param moonSeed A 16-digit hexadecimal seed ID + * @return ZTS_ERR_OK on success. ZTS_ERR_SERVICE or ZTS_ERR_ARG on failure. + */ +ZT_SOCKET_API int ZTCALL zts_orbit(uint64_t moonWorldId, uint64_t moonSeed); + +/** + * @brief De-orbit a given moon (user-defined root server) + * + * @param moonWorldId A 16-digit world ID + * @return ZTS_ERR_OK on success. ZTS_ERR_SERVICE or ZTS_ERR_ARG on failure. + */ +ZT_SOCKET_API int ZTCALL zts_deorbit(uint64_t moonWorldId); + +/** + * @brief Return the node ID of this instance + * + * @return 64-bit node ID + */ +ZT_SOCKET_API uint64_t ZTCALL zts_get_node_id(); + +/** + * @brief Compute a 6PLANE IPv6 address for the given Network ID and Node ID + * + * @param addr Destination structure for address + * @param nwid Network ID + * @param nodeId Node ID + * @return ZTS_ERR_OK on success. ZTS_ERR_ARG on failure. + */ +ZT_SOCKET_API int ZTCALL zts_get_6plane_addr( + struct zts_sockaddr_storage *addr, const uint64_t nwid, const uint64_t nodeId); + +/** + * @brief Compute a RFC4193 IPv6 address for the given Network ID and Node ID + * + * @param addr Destination structure for address + * @param nwid Network ID + * @param nodeId Node ID + * @return ZTS_ERR_OK on success. ZTS_ERR_ARG on failure. + */ +ZT_SOCKET_API int ZTCALL zts_get_rfc4193_addr( + struct zts_sockaddr_storage *addr, const uint64_t nwid, const uint64_t nodeId); + +/** + * @brief Compute a RFC4193 IPv6 address for the given Network ID and Node ID + * + * Ad-hoc Network: + * + * ffSSSSEEEE000000 + * | | | | + * | | | Reserved for future use, must be 0 + * | | End of port range (hex) + * | Start of port range (hex) + * Reserved ZeroTier address prefix indicating a controller-less network. + * + * Ad-hoc networks are public (no access control) networks that have no network controller. Instead + * their configuration and other credentials are generated locally. Ad-hoc networks permit only IPv6 + * UDP and TCP unicast traffic (no multicast or broadcast) using 6plane format NDP-emulated IPv6 + * addresses. In addition an ad-hoc network ID encodes an IP port range. UDP packets and TCP SYN + * (connection open) packets are only allowed to destination ports within the encoded range. + * + * For example ff00160016000000 is an ad-hoc network allowing only SSH, while ff0000ffff000000 is an + * ad-hoc network allowing any UDP or TCP port. + * + * Keep in mind that these networks are public and anyone in the entire world can join them. Care must + * be taken to avoid exposing vulnerable services or sharing unwanted files or other resources. + * + * + * @param startPortOfRange Start of port allowed port range + * @param endPortOfRange End of allowed port range + * @return An Ad-hoc network ID + */ +ZT_SOCKET_API uint64_t ZTCALL zts_generate_adhoc_nwid_from_range( + uint16_t startPortOfRange, uint16_t endPortOfRange); + +/** + * @brief Return details of all peers + * + * @param pds Pointer to array of zts_peer_details structs to be filled out + * @param num Length of destination array, will be filled out with actual number + * of peers that details were available for. + * @return ZTS_ERR_OK on success. ZTS_ERR_SERVICE or ZTS_ERR_ARG on failure. + */ +ZT_SOCKET_API int ZTCALL zts_get_peers(struct zts_peer_details *pds, uint32_t *num); + +/** + * @brief Return details of a given peer. + * + * @param pds Pointer to zts_peer_details struct to be filled out + * @param peerId ID of peer that the caller wants details of + * @return ZTS_ERR_OK on success. ZTS_ERR_SERVICE or ZTS_ERR_ARG on failure. + */ +ZT_SOCKET_API int ZTCALL zts_get_peer(struct zts_peer_details *pds, uint64_t peerId); + +#define ZTS_STATE_NODE_OFFLINE ZTS_EVENT_NODE_OFFLINE +#define ZTS_STATE_NODE_ONLINE ZTS_EVENT_NODE_ONLINE + +/** + * @brief Return the state of this node + * + * @return ZTS_STATE_NODE_ONLINE, ZTS_STATE_NODE_OFFLINE + */ +ZT_SOCKET_API int ZTCALL zts_get_node_status(); + +#define ZTS_STATE_NETWORK_NOT_FOUND ZTS_EVENT_NETWORK_NOT_FOUND +#define ZTS_STATE_NETWORK_CLIENT_TOO_OLD ZTS_EVENT_NETWORK_CLIENT_TOO_OLD +#define ZTS_STATE_NETWORK_REQUESTING_CONFIG ZTS_EVENT_NETWORK_REQUESTING_CONFIG +#define ZTS_STATE_NETWORK_OK ZTS_EVENT_NETWORK_OK +#define ZTS_STATE_NETWORK_ACCESS_DENIED ZTS_EVENT_NETWORK_ACCESS_DENIED +#define ZTS_STATE_NETWORK_DOWN ZTS_EVENT_NETWORK_DOWN + +/** + * @brief Return the state of a given network + * + * @param nwid Network ID + * @return ZTS_STATE_NETWORK_OK, ZTS_STATE_NETWORK_REQUESTING_CONFIG, etc + */ +ZT_SOCKET_API int ZTCALL zts_get_network_status(uint64_t nwid); + +#define ZTS_STATE_PEER_DIRECT ZTS_EVENT_PEER_DIRECT +#define ZTS_STATE_PEER_RELAY ZTS_EVENT_PEER_RELAY +#define ZTS_STATE_PEER_UNREACHABLE ZTS_EVENT_PEER_UNREACHABLE + +/** + * @brief Return the reachability state of a given remote peer + * + * @param peerId Remote peer ID + * @return ZTS_STATE_PEER_DIRECT, ZTS_STATE_PEER_RELAY, or ZTS_STATE_PEER_UNREACHABLE + */ +ZT_SOCKET_API int ZTCALL zts_get_peer_status(uint64_t peerId); + +/** + * @brief Platform-agnostic delay (provided for convenience) + * + * @param interval_ms Number of milliseconds to delay + */ +ZT_SOCKET_API void ZTCALL zts_delay_ms(long interval_ms); + +////////////////////////////////////////////////////////////////////////////// +// Statistics // +////////////////////////////////////////////////////////////////////////////// + +#define ZTS_STATS_PROTOCOL_LINK 0 +#define ZTS_STATS_PROTOCOL_ETHARP 1 +#define ZTS_STATS_PROTOCOL_IP 2 +#define ZTS_STATS_PROTOCOL_UDP 3 +#define ZTS_STATS_PROTOCOL_TCP 4 +#define ZTS_STATS_PROTOCOL_ICMP 5 +#define ZTS_STATS_PROTOCOL_IP_FRAG 6 +#define ZTS_STATS_PROTOCOL_IP6 7 +#define ZTS_STATS_PROTOCOL_ICMP6 8 +#define ZTS_STATS_PROTOCOL_IP6_FRAG 9 + +/** Protocol related stats */ +struct zts_stats_proto { + uint32_t xmit; /* Transmitted packets. */ + uint32_t recv; /* Received packets. */ + uint32_t fw; /* Forwarded packets. */ + uint32_t drop; /* Dropped packets. */ + uint32_t chkerr; /* Checksum error. */ + uint32_t lenerr; /* Invalid length error. */ + uint32_t memerr; /* Out of memory error. */ + uint32_t rterr; /* Routing error. */ + uint32_t proterr; /* Protocol error. */ + uint32_t opterr; /* Error in options. */ + uint32_t err; /* Misc error. */ + uint32_t cachehit; +}; + +/** IGMP stats */ +struct zts_stats_igmp { + uint32_t xmit; /* Transmitted packets. */ + uint32_t recv; /* Received packets. */ + uint32_t drop; /* Dropped packets. */ + uint32_t chkerr; /* Checksum error. */ + uint32_t lenerr; /* Invalid length error. */ + uint32_t memerr; /* Out of memory error. */ + uint32_t proterr; /* Protocol error. */ + uint32_t rx_v1; /* Received v1 frames. */ + uint32_t rx_group; /* Received group-specific queries. */ + uint32_t rx_general; /* Received general queries. */ + uint32_t rx_report; /* Received reports. */ + uint32_t tx_join; /* Sent joins. */ + uint32_t tx_leave; /* Sent leaves. */ + uint32_t tx_report; /* Sent reports. */ +}; + +/** System element stats */ +struct zts_stats_syselem { + uint32_t used; + uint32_t max; + uint32_t err; +}; + +/** System stats */ +struct zts_stats_sys { + struct zts_stats_syselem sem; + struct zts_stats_syselem mutex; + struct zts_stats_syselem mbox; +}; + +/** lwIP stats container */ +struct zts_stats { + /** Link level */ + struct zts_stats_proto link; + /** ARP */ + struct zts_stats_proto etharp; + /** Fragmentation */ + struct zts_stats_proto ip_frag; + /** IP */ + struct zts_stats_proto ip; + /** ICMP */ + struct zts_stats_proto icmp; + /** IGMP */ + struct zts_stats_igmp igmp; + /** UDP */ + struct zts_stats_proto udp; + /** TCP */ + struct zts_stats_proto tcp; + /** System */ + struct zts_stats_sys sys; + /** IPv6 */ + struct zts_stats_proto ip6; + /** ICMP6 */ + struct zts_stats_proto icmp6; + /** IPv6 fragmentation */ + struct zts_stats_proto ip6_frag; + /** Multicast listener discovery */ + struct zts_stats_igmp mld6; + /** Neighbor discovery */ + struct zts_stats_proto nd6; +}; + +/** + * @brief Return all statistical counters for all protocols (inefficient) + * + * @usage This function can only be used in debug builds. + * @return ZTS_ERR_OK on success. ZTS_ERR_ARG or ZTS_ERR_NO_RESULT on failure. + */ +ZT_SOCKET_API int ZTCALL zts_get_all_stats(struct zts_stats *statsDest); + +/** + * @brief Populate the given structure with the requested protocol's + * statistical counters (from network stack) + * + * @usage This function can only be used in debug builds. + * @return ZTS_ERR_OK on success. ZTS_ERR_ARG or ZTS_ERR_NO_RESULT on failure. + */ +ZT_SOCKET_API int ZTCALL zts_get_protocol_stats(int protocolType, void *protoStatsDest); + +////////////////////////////////////////////////////////////////////////////// +// Socket API // +////////////////////////////////////////////////////////////////////////////// + +/** + * @brief Create a socket (sets zts_errno) + * + * @param socket_family Address family (ZTS_AF_INET, ZTS_AF_INET6) + * @param socket_type Type of socket (ZTS_SOCK_STREAM, ZTS_SOCK_DGRAM, ZTS_SOCK_RAW) + * @param protocol Protocols supported on this socket + * @return Numbered file descriptor on success. ZTS_ERR_SERVICE or ZTS_ERR_SOCKET on failure. + */ +ZT_SOCKET_API int ZTCALL zts_socket( + const int socket_family, const int socket_type, const int protocol); + +/** + * @brief Connect a socket to a remote host (sets zts_errno) + * + * @param fd Socket file descriptor + * @param addr Remote host address to connect to + * @param addrlen Length of address + * @return ZTS_ERR_OK on success. ZTS_ERR_SOCKET, ZTS_ERR_SERVICE, ZTS_ERR_ARG on failure. + */ +ZT_SOCKET_API int ZTCALL zts_connect( + int fd, const struct zts_sockaddr *addr, zts_socklen_t addrlen); + +/** + * @brief Bind a socket to a virtual interface (sets zts_errno) + * + * @param fd Socket file descriptor + * @param addr Local interface address to bind to + * @param addrlen Length of address + * @return ZTS_ERR_OK on success. ZTS_ERR_SOCKET, ZTS_ERR_SERVICE, ZTS_ERR_ARG on failure. + */ +ZT_SOCKET_API int ZTCALL zts_bind( + int fd, const struct zts_sockaddr *addr, zts_socklen_t addrlen); + +/** + * @brief Listen for incoming connections on socket (sets zts_errno) + * + * @param fd Socket file descriptor + * @param backlog Number of backlogged connections allowed + * @return ZTS_ERR_OK on success. ZTS_ERR_SOCKET, ZTS_ERR_SERVICE, ZTS_ERR_ARG on failure. + */ +ZT_SOCKET_API int ZTCALL zts_listen(int fd, int backlog); + +/** + * @brief Accept an incoming connection (sets zts_errno) + * + * @param fd Socket file descriptor + * @param addr Address of remote host for accepted connection + * @param addrlen Length of address + * @return New socket file descriptor on success. ZTS_ERR_SOCKET, ZTS_ERR_SERVICE, ZTS_ERR_ARG on failure. + */ +ZT_SOCKET_API int ZTCALL zts_accept(int fd, struct zts_sockaddr *addr, zts_socklen_t *addrlen); + +/** + * @brief Accept an incoming connection (sets zts_errno) + * + * @param fd Socket file descriptor + * @param addr Address of remote host for accepted connection + * @param addrlen Length of address + * @param flags + * @return New socket file descriptor on success. ZTS_ERR_SOCKET, ZTS_ERR_SERVICE, ZTS_ERR_ARG on failure. + */ +#if defined(__linux__) + int zts_accept4(int fd, struct zts_sockaddr *addr, zts_socklen_t *addrlen, int flags); +#endif + +// Socket level option number +#define ZTS_SOL_SOCKET 0x0fff +// Socket options +#define ZTS_SO_DEBUG 0x0001 // NOT YET SUPPORTED +#define ZTS_SO_ACCEPTCONN 0x0002 +#define ZTS_SO_REUSEADDR 0x0004 +#define ZTS_SO_KEEPALIVE 0x0008 +#define ZTS_SO_DONTROUTE 0x0010 // NOT YET SUPPORTED +#define ZTS_SO_BROADCAST 0x0020 +#define ZTS_SO_USELOOPBACK 0x0040 // NOT YET SUPPORTED +#define ZTS_SO_LINGER 0x0080 + +/* + * Structure used for manipulating linger option. + */ +struct zts_linger { + int l_onoff; // option on/off + int l_linger; // linger time in seconds +}; + +#define ZTS_SO_DONTLINGER ((int)(~ZTS_SO_LINGER)) +#define ZTS_SO_OOBINLINE 0x0100 // NOT YET SUPPORTED +#define ZTS_SO_REUSEPORT 0x0200 // NOT YET SUPPORTED +#define ZTS_SO_SNDBUF 0x1001 // NOT YET SUPPORTED +#define ZTS_SO_RCVBUF 0x1002 +#define ZTS_SO_SNDLOWAT 0x1003 // NOT YET SUPPORTED +#define ZTS_SO_RCVLOWAT 0x1004 // NOT YET SUPPORTED +#define ZTS_SO_SNDTIMEO 0x1005 +#define ZTS_SO_RCVTIMEO 0x1006 +#define ZTS_SO_ERROR 0x1007 +#define ZTS_SO_TYPE 0x1008 +#define ZTS_SO_CONTIMEO 0x1009 +#define ZTS_SO_NO_CHECK 0x100a +#define ZTS_SO_BINDTODEVICE 0x100b +// IPPROTO_IP options +#define ZTS_IP_TOS 0x0001 +#define ZTS_IP_TTL 0x0002 +#define ZTS_IP_PKTINFO 0x0008 +// IPPROTO_TCP options +#define ZTS_TCP_NODELAY 0x0001 +#define ZTS_TCP_KEEPALIVE 0x0002 +#define ZTS_TCP_KEEPIDLE 0x0003 +#define ZTS_TCP_KEEPINTVL 0x0004 +#define ZTS_TCP_KEEPCNT 0x0005 +// IPPROTO_IPV6 options +#define ZTS_IPV6_CHECKSUM 0x0007 /* RFC3542: calculate and insert the ICMPv6 checksum for raw sockets. */ +#define ZTS_IPV6_V6ONLY 0x001b /* RFC3493: boolean control to restrict ZTS_AF_INET6 sockets to IPv6 communications only. */ +// UDPLITE options +#define ZTS_UDPLITE_SEND_CSCOV 0x01 /* sender checksum coverage */ +#define ZTS_UDPLITE_RECV_CSCOV 0x02 /* minimal receiver checksum coverage */ +// UDPLITE options +#define ZTS_IP_MULTICAST_TTL 5 +#define ZTS_IP_MULTICAST_IF 6 +#define ZTS_IP_MULTICAST_LOOP 7 + +// Multicast options +#define ZTS_IP_ADD_MEMBERSHIP 3 +#define ZTS_IP_DROP_MEMBERSHIP 4 + +typedef struct zts_ip_mreq { + struct zts_in_addr imr_multiaddr; /* IP multicast address of group */ + struct zts_in_addr imr_interface; /* local IP address of interface */ +} zts_ip_mreq; + +struct zts_in_pktinfo { + unsigned int ipi_ifindex; /* Interface index */ + struct zts_in_addr ipi_addr; /* Destination (from header) address */ +}; + +#define ZTS_IPV6_JOIN_GROUP 12 +#define ZTS_IPV6_ADD_MEMBERSHIP ZTS_IPV6_JOIN_GROUP +#define ZTS_IPV6_LEAVE_GROUP 13 +#define ZTS_IPV6_DROP_MEMBERSHIP ZTS_IPV6_LEAVE_GROUP + +typedef struct zts_ipv6_mreq { + struct zts_in6_addr ipv6mr_multiaddr; /* IPv6 multicast addr */ + unsigned int ipv6mr_interface; /* interface index, or 0 */ +} zts_ipv6_mreq; + +/* + * The Type of Service provides an indication of the abstract + * parameters of the quality of service desired. These parameters are + * to be used to guide the selection of the actual service parameters + * when transmitting a datagram through a particular network. Several + * networks offer service precedence, which somehow treats high + * precedence traffic as more important than other traffic (generally + * by accepting only traffic above a certain precedence at time of high + * load). The major choice is a three way tradeoff between low-delay, + * high-reliability, and high-throughput. + * The use of the Delay, Throughput, and Reliability indications may + * increase the cost (in some sense) of the service. In many networks + * better performance for one of these parameters is coupled with worse + * performance on another. Except for very unusual cases at most two + * of these three indications should be set. + */ +#define ZTS_IPTOS_TOS_MASK 0x1E +#define ZTS_IPTOS_TOS(tos) ((tos) & ZTS_IPTOS_TOS_MASK) +#define ZTS_IPTOS_LOWDELAY 0x10 +#define ZTS_IPTOS_THROUGHPUT 0x08 +#define ZTS_IPTOS_RELIABILITY 0x04 +#define ZTS_IPTOS_LOWCOST 0x02 +#define ZTS_IPTOS_MINCOST ZTS_IPTOS_LOWCOST + +/* + * The Network Control precedence designation is intended to be used + * within a network only. The actual use and control of that + * designation is up to each network. The Internetwork Control + * designation is intended for use by gateway control originators only. + * If the actual use of these precedence designations is of concern to + * a particular network, it is the responsibility of that network to + * control the access to, and use of, those precedence designations. + */ +#define ZTS_IPTOS_PREC_MASK 0xe0 +#define ZTS_IPTOS_PREC(tos) ((tos) & ZTS_IPTOS_PREC_MASK) +#define ZTS_IPTOS_PREC_NETCONTROL 0xe0 +#define ZTS_IPTOS_PREC_INTERNETCONTROL 0xc0 +#define ZTS_IPTOS_PREC_CRITIC_ECP 0xa0 +#define ZTS_IPTOS_PREC_FLASHOVERRIDE 0x80 +#define ZTS_IPTOS_PREC_FLASH 0x60 +#define ZTS_IPTOS_PREC_IMMEDIATE 0x40 +#define ZTS_IPTOS_PREC_PRIORITY 0x20 +#define ZTS_IPTOS_PREC_ROUTINE 0x00 + +/** + * @brief Set socket options (sets zts_errno) + * + * @param fd Socket file descriptor + * @param level Protocol level to which option name should apply + * @param optname Option name to set + * @param optval Source of option value to set + * @param optlen Length of option value + * @return ZTS_ERR_OK on success. ZTS_ERR_SOCKET, ZTS_ERR_SERVICE, ZTS_ERR_ARG on failure. + */ +ZT_SOCKET_API int ZTCALL zts_setsockopt( + int fd, int level, int optname, const void *optval, zts_socklen_t optlen); + +/** + * @brief Get socket options (sets zts_errno) + * + * @param fd Socket file descriptor + * @param level Protocol level to which option name should apply + * @param optname Option name to get + * @param optval Where option value will be stored + * @param optlen Length of value + * @return ZTS_ERR_OK on success. ZTS_ERR_SOCKET, ZTS_ERR_SERVICE, ZTS_ERR_ARG on failure. + */ +ZT_SOCKET_API int ZTCALL zts_getsockopt( + int fd, int level, int optname, void *optval, zts_socklen_t *optlen); + +/** + * @brief Get socket name (sets zts_errno) + * + * @param fd Socket file descriptor + * @param addr Name associated with this socket + * @param addrlen Length of name + * @return ZTS_ERR_OK on success. ZTS_ERR_SOCKET, ZTS_ERR_SERVICE, ZTS_ERR_ARG on failure. + */ +ZT_SOCKET_API int ZTCALL zts_getsockname(int fd, struct zts_sockaddr *addr, zts_socklen_t *addrlen); + +/** + * @brief Get the peer name for the remote end of a connected socket + * + * @param fd Socket file descriptor + * @param addr Name associated with remote end of this socket + * @param addrlen Length of name + * @return ZTS_ERR_OK on success. ZTS_ERR_SOCKET, ZTS_ERR_SERVICE, ZTS_ERR_ARG on failure. + */ +ZT_SOCKET_API int ZTCALL zts_getpeername(int fd, struct zts_sockaddr *addr, zts_socklen_t *addrlen); + +/** + * @brief Close a socket (sets zts_errno) + * + * @param fd Socket file descriptor + * @return ZTS_ERR_OK on success. ZTS_ERR_SOCKET, ZTS_ERR_SERVICE on failure. + */ +ZT_SOCKET_API int ZTCALL zts_close(int fd); + +/* FD_SET used for lwip_select */ + +#define MEMP_NUM_NETCONN 1024 + +#ifndef ZTS_FD_SET +#undef ZTS_FD_SETSIZE +// Make FD_SETSIZE match NUM_SOCKETS in socket.c +#define ZTS_FD_SETSIZE MEMP_NUM_NETCONN +#define ZTS_FDSETSAFESET(n, code) do { \ + if (((n) - LWIP_SOCKET_OFFSET < MEMP_NUM_NETCONN) && (((int)(n) - LWIP_SOCKET_OFFSET) >= 0)) { \ + code; }} while(0) +#define ZTS_FDSETSAFEGET(n, code) \ + (((n) - LWIP_SOCKET_OFFSET < MEMP_NUM_NETCONN) && (((int)(n) - LWIP_SOCKET_OFFSET) >= 0) ? \ + (code) : 0) +#define ZTS_FD_SET(n, p) \ + ZTS_FDSETSAFESET(n, (p)->fd_bits[((n)-LWIP_SOCKET_OFFSET)/8] |= (1 << (((n)-LWIP_SOCKET_OFFSET) & 7))) +#define ZTS_FD_CLR(n, p) \ + ZTS_FDSETSAFESET(n, (p)->fd_bits[((n)-LWIP_SOCKET_OFFSET)/8] &= ~(1 << (((n)-LWIP_SOCKET_OFFSET) & 7))) +#define ZTS_FD_ISSET(n,p) \ + ZTS_FDSETSAFEGET(n, (p)->fd_bits[((n)-LWIP_SOCKET_OFFSET)/8] & (1 << (((n)-LWIP_SOCKET_OFFSET) & 7))) +#define ZTS_FD_ZERO(p) memset((void*)(p), 0, sizeof(*(p))) + +#elif LWIP_SOCKET_OFFSET +#error LWIP_SOCKET_OFFSET does not work with external FD_SET! +#elif ZTS_FD_SETSIZE < MEMP_NUM_NETCONN +#error "external ZTS_FD_SETSIZE too small for number of sockets" +#endif // FD_SET + +typedef struct zts_fd_set +{ + unsigned char fd_bits [(ZTS_FD_SETSIZE+7)/8]; +} zts_fd_set; + +struct zts_timeval { + long tv_sec; /* seconds */ + long tv_usec; /* and microseconds */ +}; + +/** + * @brief Monitor multiple file descriptors for "readiness" (sets zts_errno) + * + * @param nfds Set to the highest numbered file descriptor in any of the given sets + * @param readfds Set of file descriptors to monitor for READ readiness + * @param writefds Set of file descriptors to monitor for WRITE readiness + * @param exceptfds Set of file descriptors to monitor for exceptional conditions + * @param timeout How long this call should block + * @return Number of ready file descriptors on success. ZTS_ERR_SOCKET, ZTS_ERR_SERVICE on failure. + */ +ZT_SOCKET_API int ZTCALL zts_select( + int nfds, zts_fd_set *readfds, zts_fd_set *writefds, zts_fd_set *exceptfds, struct zts_timeval *timeout); + +// fnctl() commands +#define ZTS_F_GETFL 0x0003 +#define ZTS_F_SETFL 0x0004 +/* File status flags and file access modes for fnctl, + these are bits in an int. */ +#define ZTS_O_NONBLOCK 1 +#define ZTS_O_NDELAY ZTS_O_NONBLOCK +#define ZTS_O_RDONLY 2 +#define ZTS_O_WRONLY 4 +#define ZTS_O_RDWR (ZTS_O_RDONLY|ZTS_O_WRONLY) + +/** + * @brief Issue file control commands on a socket + * + * @param fd File descriptor + * @param cmd + * @param flags + * @return + */ +ZT_SOCKET_API int ZTCALL zts_fcntl(int fd, int cmd, int flags); + +#define ZTS_POLLIN 0x001 +#define ZTS_POLLOUT 0x002 +#define ZTS_POLLERR 0x004 +#define ZTS_POLLNVAL 0x008 +/* Below values are unimplemented */ +#define ZTS_POLLRDNORM 0x010 +#define ZTS_POLLRDBAND 0x020 +#define ZTS_POLLPRI 0x040 +#define ZTS_POLLWRNORM 0x080 +#define ZTS_POLLWRBAND 0x100 +#define ZTS_POLLHUP 0x200 + +typedef unsigned int zts_nfds_t; + +struct zts_pollfd +{ + int fd; + short events; + short revents; +}; + +/** + * @brief Wait for some event on a file descriptor. (sets zts_errno) + * + * @param fds Set of file descriptors to monitor + * @param nfds Number of elements in the fds array + * @param timeout How long this call should block + * @return Number of ready file descriptors on success. ZTS_ERR_SOCKET, ZTS_ERR_SERVICE on failure. + */ +ZT_SOCKET_API int ZTCALL zts_poll(struct zts_pollfd *fds, zts_nfds_t nfds, int timeout); + +/** + * @brief Control a device (sets zts_errno) + * + * @param fd Socket file descriptor + * @param request + * @param argp + * @return ZTS_ERR_OK on success, ZTS_ERR_SERVICE on failure. + */ +ZT_SOCKET_API int ZTCALL zts_ioctl(int fd, unsigned long request, void *argp); + +/** + * @brief Send data to remote host (sets zts_errno) + * + * @param fd Socket file descriptor + * @param buf Pointer to data buffer + * @param len Length of data to write + * @param flags + * @return Byte count sent on success. ZTS_ERR_SOCKET, ZTS_ERR_SERVICE, ZTS_ERR_ARG on failure. + */ +ZT_SOCKET_API ssize_t ZTCALL zts_send(int fd, const void *buf, size_t len, int flags); + +/** + * @brief Send data to remote host (sets zts_errno) + * + * @param fd Socket file descriptor + * @param buf Pointer to data buffer + * @param len Length of data to write + * @param flags + * @param addr Destination address + * @param addrlen Length of destination address + * @return Byte count sent on success. ZTS_ERR_SOCKET, ZTS_ERR_SERVICE, ZTS_ERR_ARG on failure. + */ +ZT_SOCKET_API ssize_t ZTCALL zts_sendto( + int fd, const void *buf, size_t len, int flags, const struct zts_sockaddr *addr, zts_socklen_t addrlen); + +struct zts_iovec { + void *iov_base; + size_t iov_len; +}; + +/* */ +struct zts_msghdr { + void *msg_name; + zts_socklen_t msg_namelen; + struct zts_iovec *msg_iov; + int msg_iovlen; + void *msg_control; + zts_socklen_t msg_controllen; + int msg_flags; +}; + +/* struct msghdr->msg_flags bit field values */ +#define ZTS_MSG_TRUNC 0x04 +#define ZTS_MSG_CTRUNC 0x08 + +/** + * @brief Send message to remote host (sets zts_errno) + * + * @param fd Socket file descriptor + * @param msg + * @param flags + * @return Byte count sent on success. ZTS_ERR_SOCKET, ZTS_ERR_SERVICE, ZTS_ERR_ARG on failure. + */ +ZT_SOCKET_API ssize_t ZTCALL zts_sendmsg(int fd, const struct msghdr *msg, int flags); + +/** + * @brief Receive data from remote host (sets zts_errno) + * + * @param fd Socket file descriptor + * @param buf Pointer to data buffer + * @param len Length of data buffer + * @param flags + * @return Byte count received on success. ZTS_ERR_SOCKET, ZTS_ERR_SERVICE, ZTS_ERR_ARG on failure. + */ +ZT_SOCKET_API ssize_t ZTCALL zts_recv(int fd, void *buf, size_t len, int flags); + +/** + * @brief Receive data from remote host (sets zts_errno) + * + * @param fd Socket file descriptor + * @param buf Pointer to data buffer + * @param len Length of data buffer + * @param flags + * @param addr + * @param addrlen + * @return Byte count received on success. ZTS_ERR_SOCKET, ZTS_ERR_SERVICE, ZTS_ERR_ARG on failure. + */ +ZT_SOCKET_API ssize_t ZTCALL zts_recvfrom( + int fd, void *buf, size_t len, int flags, struct zts_sockaddr *addr, zts_socklen_t *addrlen); + +/** + * @brief Receive a message from remote host (sets zts_errno) + * + * @param fd Socket file descriptor + * @param msg + * @param flags + * @return Byte count received on success. ZTS_ERR_SOCKET, ZTS_ERR_SERVICE, ZTS_ERR_ARG on failure. + */ +ZT_SOCKET_API ssize_t ZTCALL zts_recvmsg(int fd, struct msghdr *msg,int flags); + +/** + * @brief Read bytes from socket onto buffer (sets zts_errno) + * + * @param fd Socket file descriptor + * @param buf Pointer to data buffer + * @param len Length of data buffer to receive data + * @return Byte count received on success. ZTS_ERR_SOCKET, ZTS_ERR_SERVICE, ZTS_ERR_ARG on failure. + */ +ZT_SOCKET_API ssize_t ZTCALL zts_read(int fd, void *buf, size_t len); + +/** + * @brief Read bytes from socket into multiple buffers (sets zts_errno) + * + * @param fd Socket file descriptor + * @param iov Array of destination buffers + * @param iovcnt Number of buffers to read into + * @return Byte count received on success. ZTS_ERR_SOCKET, ZTS_ERR_SERVICE, ZTS_ERR_ARG on failure. + */ +ZT_SOCKET_API ssize_t ZTCALL zts_readv(int fd, const struct zts_iovec *iov, int iovcnt); + +/** + * @brief Write bytes from buffer to socket (sets zts_errno) + * + * @param fd Socket file descriptor + * @param buf Pointer to data buffer + * @param len Length of buffer to write + * @return Byte count sent on success. ZTS_ERR_SOCKET, ZTS_ERR_SERVICE, ZTS_ERR_ARG on failure. + */ +ZT_SOCKET_API ssize_t ZTCALL zts_write(int fd, const void *buf, size_t len); + +/** + * @brief Write data from multiple buffers to socket. (sets zts_errno) + * + * @param fd Socket file descriptor + * @param iov Array of source buffers + * @param iovcnt Number of buffers to read from + * @return Byte count sent on success. ZTS_ERR_SOCKET, ZTS_ERR_SERVICE, ZTS_ERR_ARG on failure. + */ +ZT_SOCKET_API ssize_t ZTCALL zts_writev(int fd, const struct zts_iovec *iov, int iovcnt); + +#define ZTS_SHUT_RD 0x0 +#define ZTS_SHUT_WR 0x1 +#define ZTS_SHUT_RDWR 0x2 + +/** + * @brief Shut down some aspect of a socket (sets zts_errno) + * + * @param fd Socket file descriptor + * @param how Which aspects of the socket should be shut down + * @return ZTS_ERR_OK on success. ZTS_ERR_SOCKET, ZTS_ERR_SERVICE, ZTS_ERR_ARG on failure. + */ +ZT_SOCKET_API int ZTCALL zts_shutdown(int fd, int how); + +/** + * @brief Add a DNS nameserver for the network stack to use + * + * @param addr Address for DNS nameserver + * @return ZTS_ERR_SERVICE + */ +ZT_SOCKET_API int ZTCALL zts_add_dns_nameserver(struct zts_sockaddr *addr); + +/** + * @brief Remove a DNS nameserver + * + * @param addr Address for DNS nameserver + * @return ZTS_ERR_SERVICE + */ +ZT_SOCKET_API int ZTCALL zts_del_dns_nameserver(struct zts_sockaddr *addr); + +/** + * Convert an uint16_t from host to network byte order. + * + * @param n uint16_t in host byte order + * @return n in network byte order + */ +ZT_SOCKET_API uint16_t ZTCALL zts_htons(uint16_t n); + +/** + * Convert an uint32_t from host to network byte order. + * + * @param n uint32_t in host byte order + * @return n in network byte order + */ +ZT_SOCKET_API uint32_t ZTCALL zts_htonl(uint32_t n); + +/** + * Length of human-readable MAC address string + */ +#define ZTS_MAC_ADDRSTRLEN 18 + +#ifndef htonll +#define htonll(x) ((1==htonl(1)) ? (x) : ((uint64_t)htonl((x) & 0xFFFFFFFF) << 32) | htonl((x) >> 32)) +#endif + +/** + * Convert an uint16_t from network to host byte order. + * + * @param n uint16_t in network byte order + * @return n in host byte order + */ +ZT_SOCKET_API uint16_t ZTCALL zts_ntohs(uint16_t n); + +/** + * Convert an uint32_t from network to host byte order. + * + * @param n uint32_t in network byte order + * @return n in host byte order + */ +ZT_SOCKET_API uint32_t ZTCALL zts_ntohl(uint32_t n); + +/** + * Convert IPv4 and IPv6 address structures to human-readable text form. + * + * @param af Address family (ZTS_AF_INET, ZTS_AF_INET6) + * @param src Pointer to source address structure + * @param dst Pointer to destination character array + * @param size Size of the destination buffer + * @return On success, returns a non-null pointer to the destination character array + */ +ZT_SOCKET_API const char * ZTCALL zts_inet_ntop(int af, const void *src, char *dst, zts_socklen_t size); + +/** + * Convert C-string IPv4 and IPv6 addresses to binary form. + * + * @param af Address family (ZTS_AF_INET, ZTS_AF_INET6) + * @param src Pointer to source character array + * @param dst Pointer to destination address structure + * @return return 1 on success. 0 or -1 on failure. (Does not follow zts_* conventions) + */ +ZT_SOCKET_API int ZTCALL zts_inet_pton(int af, const char *src, void *dst); + +/** + * Convert a C-string IPv4 address to integer representation. + * + * @param cp Human-readable IPv4 string + * @return 32-bit integer representation of address + */ +ZT_SOCKET_API uint32_t ZTCALL zts_inet_addr(const char *cp); + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // _H |
