diff options
Diffstat (limited to 'include')
| -rw-r--r-- | include/ZeroTierOne.h | 428 |
1 files changed, 120 insertions, 308 deletions
diff --git a/include/ZeroTierOne.h b/include/ZeroTierOne.h index 318e7e76..1365a9a0 100644 --- a/include/ZeroTierOne.h +++ b/include/ZeroTierOne.h @@ -46,28 +46,28 @@ #include <sys/socket.h> #endif /* Windows or not */ -#if defined (_MSC_VER)
-#ifdef ZT_EXPORT
-#define ZT_SDK_API __declspec(dllexport)
-#else
-#define ZT_SDK_API __declspec(dllimport)
-#ifdef _DEBUG
-#ifdef _WIN64
-#pragma comment(lib, "ZeroTierOne_x64d.lib")
-#else
-#pragma comment(lib, "ZeroTierOne_x86d.lib")
-#endif
-#else
-#ifdef _WIN64
-#pragma comment(lib, "ZeroTierOne_x64.lib")
-#else
-#pragma comment(lib, "ZeroTierOne_x86.lib")
-#endif
-#endif
-#endif
-#else
-#define ZT_SDK_API
-#endif
+#if defined (_MSC_VER) +#ifdef ZT_EXPORT +#define ZT_SDK_API __declspec(dllexport) +#else +#define ZT_SDK_API __declspec(dllimport) +#ifdef _DEBUG +#ifdef _WIN64 +#pragma comment(lib, "ZeroTierOne_x64d.lib") +#else +#pragma comment(lib, "ZeroTierOne_x86d.lib") +#endif +#else +#ifdef _WIN64 +#pragma comment(lib, "ZeroTierOne_x64.lib") +#else +#pragma comment(lib, "ZeroTierOne_x86.lib") +#endif +#endif +#endif +#else +#define ZT_SDK_API +#endif #ifdef __cplusplus extern "C" { @@ -163,39 +163,6 @@ extern "C" { #define ZT_MAX_CAPABILITY_CUSTODY_CHAIN_LENGTH 7 /** - * Maximum number of hops in a ZeroTier circuit test - * - * This is more or less the max that can be fit in a given packet (with - * fragmentation) and only one address per hop. - */ -#define ZT_CIRCUIT_TEST_MAX_HOPS 256 - -/** - * Maximum number of addresses per hop in a circuit test - */ -#define ZT_CIRCUIT_TEST_MAX_HOP_BREADTH 8 - -/** - * Circuit test report flag: upstream peer authorized in path (e.g. by network COM) - */ -#define ZT_CIRCUIT_TEST_REPORT_FLAGS_UPSTREAM_AUTHORIZED_IN_PATH 0x0000000000000001ULL - -/** - * Maximum number of cluster members (and max member ID plus one) - */ -#define ZT_CLUSTER_MAX_MEMBERS 128 - -/** - * Maximum number of physical ZeroTier addresses a cluster member can report - */ -#define ZT_CLUSTER_MAX_ZT_PHYSICAL_ADDRESSES 16 - -/** - * Maximum allowed cluster message length in bytes - */ -#define ZT_CLUSTER_MAX_MESSAGE_LENGTH (1500 - 48) - -/** * Maximum value for link quality (min is 0) */ #define ZT_PATH_LINK_QUALITY_MAX 0xff @@ -285,11 +252,6 @@ extern "C" { */ #define ZT_RULE_PACKET_CHARACTERISTICS_TCP_FIN 0x0000000000000001ULL -/** - * A null/empty sockaddr (all zero) to signify an unspecified socket address - */ -extern const struct sockaddr_storage ZT_SOCKADDR_NULL; - /****************************************************************************/ /* Structures and other types */ /****************************************************************************/ @@ -309,22 +271,27 @@ enum ZT_ResultCode */ ZT_RESULT_OK = 0, - // Fatal errors (>0, <1000) + /** + * Call produced no error but no action was taken + */ + ZT_RESULT_OK_IGNORED = 1, + + // Fatal errors (>100, <1000) /** * Ran out of memory */ - ZT_RESULT_FATAL_ERROR_OUT_OF_MEMORY = 1, + ZT_RESULT_FATAL_ERROR_OUT_OF_MEMORY = 100, /** * Data store is not writable or has failed */ - ZT_RESULT_FATAL_ERROR_DATA_STORE_FAILED = 2, + ZT_RESULT_FATAL_ERROR_DATA_STORE_FAILED = 101, /** * Internal error (e.g. unexpected exception indicating bug or build problem) */ - ZT_RESULT_FATAL_ERROR_INTERNAL = 3, + ZT_RESULT_FATAL_ERROR_INTERNAL = 102, // Non-fatal errors (>1000) @@ -348,7 +315,7 @@ enum ZT_ResultCode * @param x Result code * @return True if result code indicates a fatal error */ -#define ZT_ResultCode_isFatal(x) ((((int)(x)) > 0)&&(((int)(x)) < 1000)) +#define ZT_ResultCode_isFatal(x) ((((int)(x)) >= 100)&&(((int)(x)) < 1000)) /** * Status codes sent to status update callback when things happen @@ -444,6 +411,13 @@ enum ZT_Event /** * User message used with ZT_EVENT_USER_MESSAGE + * + * These are direct VL1 P2P messages for application use. Encryption and + * authentication in the ZeroTier protocol will guarantee the origin + * address and message content, but you are responsible for any other + * levels of authentication or access control that are required. Any node + * in the world can send you a user message! (Unless your network is air + * gapped.) */ typedef struct { @@ -771,24 +745,6 @@ typedef struct } v; } ZT_VirtualNetworkRule; -typedef struct -{ - /** - * 128-bit ID (GUID) of this capability - */ - uint64_t id[2]; - - /** - * Expiration time (measured vs. network config timestamp issued by controller) - */ - uint64_t expiration; - - struct { - uint64_t from; - uint64_t to; - } custody[ZT_MAX_CAPABILITY_CUSTODY_CHAIN_LENGTH]; -} ZT_VirtualNetworkCapability; - /** * A route to be pushed on a virtual network */ @@ -1128,76 +1084,69 @@ typedef struct } ZT_PeerList; /** - * A cluster member's status + * ZeroTier core state objects */ -typedef struct { - /** - * This cluster member's ID (from 0 to 1-ZT_CLUSTER_MAX_MEMBERS) - */ - unsigned int id; - - /** - * Number of milliseconds since last 'alive' heartbeat message received via cluster backplane address - */ - unsigned int msSinceLastHeartbeat; - +enum ZT_StateObjectType +{ /** - * Non-zero if cluster member is alive + * Null object -- ignored */ - int alive; + ZT_STATE_OBJECT_NULL = 0, /** - * X, Y, and Z coordinates of this member (if specified, otherwise zero) + * Public address and public key * - * What these mean depends on the location scheme being used for - * location-aware clustering. At present this is GeoIP and these - * will be the X, Y, and Z coordinates of the location on a spherical - * approximation of Earth where Earth's core is the origin (in km). - * They don't have to be perfect and need only be comparable with others - * to find shortest path via the standard vector distance formula. - */ - int x,y,z; - - /** - * Cluster member's last reported load - */ - uint64_t load; - - /** - * Number of peers + * Object ID: this node's address if known, or 0 if unknown (first query) + * Canonical path: <HOME>/identity.public + * Persistence: required */ - uint64_t peers; + ZT_STATE_OBJECT_IDENTITY_PUBLIC = 1, /** - * Physical ZeroTier endpoints for this member (where peers are sent when directed here) + * Full identity with secret key + * + * Object ID: this node's address if known, or 0 if unknown (first query) + * Canonical path: <HOME>/identity.secret + * Persistence: required, should be stored with restricted permissions e.g. mode 0600 on *nix */ - struct sockaddr_storage zeroTierPhysicalEndpoints[ZT_CLUSTER_MAX_ZT_PHYSICAL_ADDRESSES]; + ZT_STATE_OBJECT_IDENTITY_SECRET = 2, /** - * Number of physical ZeroTier endpoints this member is announcing + * The planet (there is only one per... well... planet!) + * + * Object ID: world ID of planet, or 0 if unknown (first query) + * Canonical path: <HOME>/planet + * Persistence: recommended */ - unsigned int numZeroTierPhysicalEndpoints; -} ZT_ClusterMemberStatus; + ZT_STATE_OBJECT_PLANET = 3, -/** - * ZeroTier cluster status - */ -typedef struct { /** - * My cluster member ID (a record for 'self' is included in member[]) + * A moon (federated root set) + * + * Object ID: world ID of moon + * Canonical path: <HOME>/moons.d/<ID>.moon (16-digit hex ID) + * Persistence: required if moon memberships should persist */ - unsigned int myId; + ZT_STATE_OBJECT_MOON = 4, /** - * Number of cluster members + * Peer and related state + * + * Object ID: peer address + * Canonical path: <HOME>/peers.d/<ID> (10-digit address + * Persistence: optional, can be cleared at any time */ - unsigned int clusterSize; + ZT_STATE_OBJECT_PEER = 5, /** - * Cluster member statuses + * Network configuration + * + * Object ID: peer address + * Canonical path: <HOME>/networks.d/<NETWORKID>.conf (16-digit hex ID) + * Persistence: required if network memberships should persist */ - ZT_ClusterMemberStatus members[ZT_CLUSTER_MAX_MEMBERS]; -} ZT_ClusterStatus; + ZT_STATE_OBJECT_NETWORK_CONFIG = 6 +}; /** * An instance of a ZeroTier One node (opaque) @@ -1275,77 +1224,54 @@ typedef void (*ZT_EventCallback)( const void *); /* Event payload (if applicable) */ /** - * Function to get an object from the data store - * - * Parameters: (1) object name, (2) buffer to fill, (3) size of buffer, (4) - * index in object to start reading, (5) result parameter that must be set - * to the actual size of the object if it exists. + * Callback for storing and/or publishing state information * - * Object names can contain forward slash (/) path separators. They will - * never contain .. or backslash (\), so this is safe to map as a Unix-style - * path if the underlying storage permits. For security reasons we recommend - * returning errors if .. or \ are used. + * See ZT_StateObjectType docs for information about each state object type + * and when and if it needs to be persisted. * - * The function must return the actual number of bytes read. If the object - * doesn't exist, it should return -1. -2 should be returned on other errors - * such as errors accessing underlying storage. - * - * If the read doesn't fit in the buffer, the max number of bytes should be - * read. The caller may call the function multiple times to read the whole - * object. + * An object of length -1 is sent to indicate that an object should be + * deleted. */ -typedef long (*ZT_DataStoreGetFunction)( +typedef void (*ZT_StatePutFunction)( ZT_Node *, /* Node */ void *, /* User ptr */ void *, /* Thread ptr */ - const char *, - void *, - unsigned long, - unsigned long, - unsigned long *); + enum ZT_StateObjectType, /* State object type */ + const uint64_t [2], /* State object ID (if applicable) */ + const void *, /* State object data */ + int); /* Length of data or -1 to delete */ /** - * Function to store an object in the data store - * - * Parameters: (1) node, (2) user ptr, (3) object name, (4) object data, - * (5) object size, (6) secure? (bool). + * Callback for retrieving stored state information * - * If secure is true, the file should be set readable and writable only - * to the user running ZeroTier One. What this means is platform-specific. - * - * Name semantics are the same as the get function. This must return zero on - * success. You can return any OS-specific error code on failure, as these - * may be visible in logs or error messages and might aid in debugging. - * - * If the data pointer is null, this must be interpreted as a delete - * operation. + * This function should return the number of bytes actually stored to the + * buffer or -1 if the state object was not found or the buffer was too + * small to store it. */ -typedef int (*ZT_DataStorePutFunction)( - ZT_Node *, - void *, +typedef int (*ZT_StateGetFunction)( + ZT_Node *, /* Node */ + void *, /* User ptr */ void *, /* Thread ptr */ - const char *, - const void *, - unsigned long, - int); + enum ZT_StateObjectType, /* State object type */ + const uint64_t [2], /* State object ID (if applicable) */ + void *, /* Buffer to store state object data */ + unsigned int); /* Length of data buffer in bytes */ /** - * Function to send a ZeroTier packet out over the wire + * Function to send a ZeroTier packet out over the physical wire (L2/L3) * * Parameters: * (1) Node * (2) User pointer - * (3) Local interface address + * (3) Local socket or -1 for "all" or "any" * (4) Remote address * (5) Packet data * (6) Packet length * (7) Desired IP TTL or 0 to use default * - * If there is only one local interface it is safe to ignore the local - * interface address. Otherwise if running with multiple interfaces, the - * correct local interface should be chosen by address unless NULL. If - * the ss_family field is zero (NULL address), a random or preferred - * default interface should be used. + * If there is only one local socket, the local socket can be ignored. + * If the local socket is -1, the packet should be sent out from all + * bound local sockets or a random bound local socket. * * If TTL is nonzero, packets should have their IP TTL value set to this * value if possible. If this is not possible it is acceptable to ignore @@ -1359,7 +1285,7 @@ typedef int (*ZT_WirePacketSendFunction)( ZT_Node *, /* Node */ void *, /* User ptr */ void *, /* Thread ptr */ - const struct sockaddr_storage *, /* Local address */ + int64_t, /* Local socket */ const struct sockaddr_storage *, /* Remote address */ const void *, /* Packet data */ unsigned int, /* Packet length */ @@ -1372,7 +1298,7 @@ typedef int (*ZT_WirePacketSendFunction)( * (1) Node * (2) User pointer * (3) ZeroTier address or 0 for none/any - * (4) Local interface address + * (4) Local socket or -1 if unknown * (5) Remote address * * This function must return nonzero (true) if the path should be used. @@ -1385,16 +1311,13 @@ typedef int (*ZT_WirePacketSendFunction)( * all configured ZeroTier interfaces and check to ensure that the supplied * addresses will not result in ZeroTier traffic being sent over a ZeroTier * interface (recursion). - * - * Obviously this is not required in configurations where this can't happen, - * such as network containers or embedded. */ typedef int (*ZT_PathCheckFunction)( ZT_Node *, /* Node */ void *, /* User ptr */ void *, /* Thread ptr */ uint64_t, /* ZeroTier address */ - const struct sockaddr_storage *, /* Local address */ + int64_t, /* Local socket or -1 if unknown */ const struct sockaddr_storage *); /* Remote address */ /** @@ -1435,14 +1358,14 @@ struct ZT_Node_Callbacks long version; /** - * REQUIRED: Function to get objects from persistent storage + * REQUIRED: Function to store and/or replicate state objects */ - ZT_DataStoreGetFunction dataStoreGetFunction; + ZT_StatePutFunction statePutFunction; /** - * REQUIRED: Function to store objects in persistent storage + * REQUIRED: Function to retrieve state objects from an object store */ - ZT_DataStorePutFunction dataStorePutFunction; + ZT_StateGetFunction stateGetFunction; /** * REQUIRED: Function to send packets over the physical wire @@ -1476,13 +1399,12 @@ struct ZT_Node_Callbacks }; /** - * Create a new ZeroTier One node + * Create a new ZeroTier node * - * Note that this can take a few seconds the first time it's called, as it - * will generate an identity. - * - * TODO: should consolidate function pointers into versioned structure for - * better API stability. + * This will attempt to load its identity via the state get function in the + * callback struct. If that fails it will generate a new identity and store + * it. Identity generation can take anywhere from a few hundred milliseconds + * to a few seconds depending on your CPU speed. * * @param node Result: pointer is set to new node instance on success * @param uptr User pointer to pass to functions/callbacks @@ -1509,7 +1431,7 @@ ZT_SDK_API void ZT_Node_delete(ZT_Node *node); * @param node Node instance * @param tptr Thread pointer to pass to functions/callbacks resulting from this call * @param now Current clock in milliseconds - * @param localAddress Local address, or point to ZT_SOCKADDR_NULL if unspecified + * @param localSocket Local socket (you can use 0 if only one local socket is bound and ignore this) * @param remoteAddress Origin of packet * @param packetData Packet data * @param packetLength Packet length @@ -1520,7 +1442,7 @@ ZT_SDK_API enum ZT_ResultCode ZT_Node_processWirePacket( ZT_Node *node, void *tptr, uint64_t now, - const struct sockaddr_storage *localAddress, + int64_t localSocket, const struct sockaddr_storage *remoteAddress, const void *packetData, unsigned int packetLength, @@ -1789,116 +1711,6 @@ ZT_SDK_API int ZT_Node_sendUserMessage(ZT_Node *node,void *tptr,uint64_t dest,ui ZT_SDK_API void ZT_Node_setNetconfMaster(ZT_Node *node,void *networkConfigMasterInstance); /** - * Initialize cluster operation - * - * This initializes the internal structures and state for cluster operation. - * It takes two function pointers. The first is to a function that can be - * used to send data to cluster peers (mechanism is not defined by Node), - * and the second is to a function that can be used to get the location of - * a physical address in X,Y,Z coordinate space (e.g. as cartesian coordinates - * projected from the center of the Earth). - * - * Send function takes an arbitrary pointer followed by the cluster member ID - * to send data to, a pointer to the data, and the length of the data. The - * maximum message length is ZT_CLUSTER_MAX_MESSAGE_LENGTH (65535). Messages - * must be delivered whole and may be dropped or transposed, though high - * failure rates are undesirable and can cause problems. Validity checking or - * CRC is also not required since the Node validates the authenticity of - * cluster messages using cryptogrphic methods and will silently drop invalid - * messages. - * - * Address to location function is optional and if NULL geo-handoff is not - * enabled (in this case x, y, and z in clusterInit are also unused). It - * takes an arbitrary pointer followed by a physical address and three result - * parameters for x, y, and z. It returns zero on failure or nonzero if these - * three coordinates have been set. Coordinate space is arbitrary and can be - * e.g. coordinates on Earth relative to Earth's center. These can be obtained - * from latitutde and longitude with versions of the Haversine formula. - * - * See: http://stackoverflow.com/questions/1185408/converting-from-longitude-latitude-to-cartesian-coordinates - * - * Neither the send nor the address to location function should block. If the - * address to location function does not have a location for an address, it - * should return zero and then look up the address for future use since it - * will be called again in (typically) 1-3 minutes. - * - * Note that both functions can be called from any thread from which the - * various Node functions are called, and so must be thread safe if multiple - * threads are being used. - * - * @param node Node instance - * @param myId My cluster member ID (less than or equal to ZT_CLUSTER_MAX_MEMBERS) - * @param zeroTierPhysicalEndpoints Preferred physical address(es) for ZeroTier clients to contact this cluster member (for peer redirect) - * @param numZeroTierPhysicalEndpoints Number of physical endpoints in zeroTierPhysicalEndpoints[] (max allowed: 255) - * @param x My cluster member's X location - * @param y My cluster member's Y location - * @param z My cluster member's Z location - * @param sendFunction Function to be called to send data to other cluster members - * @param sendFunctionArg First argument to sendFunction() - * @param addressToLocationFunction Function to be called to get the location of a physical address or NULL to disable geo-handoff - * @param addressToLocationFunctionArg First argument to addressToLocationFunction() - * @return OK or UNSUPPORTED_OPERATION if this Node was not built with cluster support - */ -ZT_SDK_API enum ZT_ResultCode ZT_Node_clusterInit( - ZT_Node *node, - unsigned int myId, - const struct sockaddr_storage *zeroTierPhysicalEndpoints, - unsigned int numZeroTierPhysicalEndpoints, - int x, - int y, - int z, - void (*sendFunction)(void *,unsigned int,const void *,unsigned int), - void *sendFunctionArg, - int (*addressToLocationFunction)(void *,const struct sockaddr_storage *,int *,int *,int *), - void *addressToLocationFunctionArg); - -/** - * Add a member to this cluster - * - * Calling this without having called clusterInit() will do nothing. - * - * @param node Node instance - * @param memberId Member ID (must be less than or equal to ZT_CLUSTER_MAX_MEMBERS) - * @return OK or error if clustering is disabled, ID invalid, etc. - */ -ZT_SDK_API enum ZT_ResultCode ZT_Node_clusterAddMember(ZT_Node *node,unsigned int memberId); - -/** - * Remove a member from this cluster - * - * Calling this without having called clusterInit() will do nothing. - * - * @param node Node instance - * @param memberId Member ID to remove (nothing happens if not present) - */ -ZT_SDK_API void ZT_Node_clusterRemoveMember(ZT_Node *node,unsigned int memberId); - -/** - * Handle an incoming cluster state message - * - * The message itself contains cluster member IDs, and invalid or badly - * addressed messages will be silently discarded. - * - * Calling this without having called clusterInit() will do nothing. - * - * @param node Node instance - * @param msg Cluster message - * @param len Length of cluster message - */ -ZT_SDK_API void ZT_Node_clusterHandleIncomingMessage(ZT_Node *node,const void *msg,unsigned int len); - -/** - * Get the current status of the cluster from this node's point of view - * - * Calling this without clusterInit() or without cluster support will just - * zero out the structure and show a cluster size of zero. - * - * @param node Node instance - * @param cs Cluster status structure to fill with data - */ -ZT_SDK_API void ZT_Node_clusterStatus(ZT_Node *node,ZT_ClusterStatus *cs); - -/** * Set trusted paths * * A trusted path is a physical network (network/bits) over which both |
