|
|
|
|
@ -271,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)
|
|
|
|
|
|
|
|
|
|
@ -1090,59 +1095,97 @@ typedef struct
|
|
|
|
|
} ZT_PeerList; |
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Types of stored objects that the core may wish to save or load |
|
|
|
|
* ZeroTier core state objects |
|
|
|
|
* |
|
|
|
|
* All of these objects can be persisted if desired. To preserve the |
|
|
|
|
* identity of a node and its address, the identity (public and secret) |
|
|
|
|
* must be saved at a minimum. |
|
|
|
|
* |
|
|
|
|
* The reference service implementation currently persists identity, |
|
|
|
|
* peer identities (for a period of time), planet, moons, and network |
|
|
|
|
* configurations. Other state is treated as ephemeral. |
|
|
|
|
* |
|
|
|
|
* All state objects should be replicated in cluster mode. The reference |
|
|
|
|
* clustering implementation uses a rumor mill algorithm in which state |
|
|
|
|
* updates that are accepted with RESULT_OK (but not RESULT_OK_IGNORED) |
|
|
|
|
* are flooded to all connected cluster peers. This results in updates |
|
|
|
|
* being flooded across the cluster until all cluster members have the |
|
|
|
|
* latest. |
|
|
|
|
*/ |
|
|
|
|
enum ZT_StoredObjectType |
|
|
|
|
enum ZT_StateObjectType |
|
|
|
|
{ |
|
|
|
|
/**
|
|
|
|
|
* Node status information (reserved, not currently used) |
|
|
|
|
*/ |
|
|
|
|
ZT_STORED_OBJECT_STATUS = 0, |
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* String serialized public identity |
|
|
|
|
* Null object -- ignored |
|
|
|
|
*/ |
|
|
|
|
ZT_STORED_OBJECT_IDENTITY_PUBLIC = 1, |
|
|
|
|
ZT_STATE_OBJECT_NULL = 0, |
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* String serialized secret identity |
|
|
|
|
* identity.public |
|
|
|
|
* |
|
|
|
|
* Object ID: this node's address if known, or 0 if unknown (first query) |
|
|
|
|
* Canonical path: <HOME>/identity.public |
|
|
|
|
* Persistence: required |
|
|
|
|
*/ |
|
|
|
|
ZT_STORED_OBJECT_IDENTITY_SECRET = 1, |
|
|
|
|
ZT_STATE_OBJECT_IDENTITY_PUBLIC = 1, |
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Binary serialized peer state |
|
|
|
|
* identity.secret |
|
|
|
|
* |
|
|
|
|
* Object ID: this node's address if known, or 0 if unknown (first query) |
|
|
|
|
* Canonical path: <HOME>/identity.public |
|
|
|
|
* Persistence: required, should be stored with restricted permissions e.g. mode 0600 on *nix |
|
|
|
|
*/ |
|
|
|
|
ZT_STORED_OBJECT_PEER = 3, |
|
|
|
|
ZT_STATE_OBJECT_IDENTITY_SECRET = 2, |
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Identity (other node, not this one) |
|
|
|
|
* A peer to which this node is communicating |
|
|
|
|
* |
|
|
|
|
* Object ID: peer address |
|
|
|
|
* Canonical path: <HOME>/peers.d/<ADDRESS> (10-digit hex address) |
|
|
|
|
* Persistence: optional, can be purged at any time |
|
|
|
|
*/ |
|
|
|
|
ZT_STORED_OBJECT_IDENTITY = 4, |
|
|
|
|
ZT_STATE_OBJECT_PEER = 3, |
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Network configuration object |
|
|
|
|
* The identity of a known peer |
|
|
|
|
* |
|
|
|
|
* Object ID: peer address |
|
|
|
|
* Canonical path: <HOME>/iddb.d/<ADDRESS> (10-digit hex address) |
|
|
|
|
* Persistence: optional, can be purged at any time, recommended ttl 30-60 days |
|
|
|
|
*/ |
|
|
|
|
ZT_STORED_OBJECT_NETWORK_CONFIG = 5, |
|
|
|
|
ZT_STATE_OBJECT_PEER_IDENTITY = 4, |
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Planet definition (object ID will be zero and should be ignored since there's only one) |
|
|
|
|
* 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_STORED_OBJECT_PLANET = 6, |
|
|
|
|
ZT_STATE_OBJECT_NETWORK_CONFIG = 5, |
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Moon definition |
|
|
|
|
* 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 |
|
|
|
|
*/ |
|
|
|
|
ZT_STORED_OBJECT_MOON = 7, |
|
|
|
|
ZT_STATE_OBJECT_PLANET = 6, |
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Multicast membership |
|
|
|
|
* 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 |
|
|
|
|
*/ |
|
|
|
|
ZT_STORED_OBJECT_MULTICAST_MEMBERSHIP = 8, |
|
|
|
|
ZT_STATE_OBJECT_MOON = 7, |
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* IDs above this are never used by the core and are available for implementation use |
|
|
|
|
* IDs above this value will not be used by the core (and could be used as implementation-specific IDs) |
|
|
|
|
*/ |
|
|
|
|
ZT_STORED_OBJECT__MAX_TYPE_ID = 255 |
|
|
|
|
ZT_STATE_OBJECT__MAX_ID = 255 |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
@ -1221,59 +1264,38 @@ 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. |
|
|
|
|
* |
|
|
|
|
* 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. |
|
|
|
|
* Callback for storing and/or publishing state information |
|
|
|
|
* |
|
|
|
|
* 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. |
|
|
|
|
* See ZT_StateObjectType docs for information about each state object type |
|
|
|
|
* and when and if it needs to be persisted. |
|
|
|
|
* |
|
|
|
|
* 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 */ |
|
|
|
|
uint64_t, /* 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 |
|
|
|
|
* Callback for retrieving stored state information |
|
|
|
|
* |
|
|
|
|
* Parameters: (1) node, (2) user ptr, (3) object name, (4) object data, |
|
|
|
|
* (5) object size, (6) secure? (bool). |
|
|
|
|
* |
|
|
|
|
* 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 */ |
|
|
|
|
uint64_t, /* 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 |
|
|
|
|
@ -1381,14 +1403,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 |
|
|
|
|
@ -1449,6 +1471,49 @@ enum ZT_ResultCode ZT_Node_new(ZT_Node **node,void *uptr,void *tptr,const struct
|
|
|
|
|
*/ |
|
|
|
|
void ZT_Node_delete(ZT_Node *node); |
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Notify node of an update to a state object |
|
|
|
|
* |
|
|
|
|
* This can be called after node startup to restore cached state objects such |
|
|
|
|
* as network configurations for joined networks, planet, moons, etc. See |
|
|
|
|
* the documentation of ZT_StateObjectType for more information. It's okay |
|
|
|
|
* to call this for everything in the object store, but note that the node |
|
|
|
|
* will automatically query for some core objects like identities so supplying |
|
|
|
|
* these via this function is not necessary. |
|
|
|
|
* |
|
|
|
|
* Unless clustering is being implemented this function doesn't need to be |
|
|
|
|
* used after startup. It could be called in response to filesystem changes |
|
|
|
|
* to allow some degree of live configurability by filesystem observation. |
|
|
|
|
* |
|
|
|
|
* The return value of this function indicates whether the update was accepted |
|
|
|
|
* as new. A return value of ZT_RESULT_OK indicates that the node gleaned new |
|
|
|
|
* information from this update and that therefore (in cluster rumor mill mode) |
|
|
|
|
* this update should be distributed to other members of a cluster. A return |
|
|
|
|
* value of ZT_RESULT_OK_IGNORED indicates that the object did not provide any |
|
|
|
|
* new information and therefore should not be propagated in a cluster. |
|
|
|
|
* |
|
|
|
|
* If clustering isn't being implemented the return value of this function can |
|
|
|
|
* generally be ignored. |
|
|
|
|
* |
|
|
|
|
* ZT_RESULT_ERROR_BAD_PARAMETER can be returned if the parameter was invalid |
|
|
|
|
* or not applicable. Object stores may delete the object in this case. |
|
|
|
|
* |
|
|
|
|
* @param node Node instance |
|
|
|
|
* @param tptr Thread pointer to pass to functions/callbacks resulting from this call |
|
|
|
|
* @param type State object type |
|
|
|
|
* @param id State object ID |
|
|
|
|
* @param data State object data |
|
|
|
|
* @param len Length of state object data in bytes |
|
|
|
|
* @return ZT_RESULT_OK if object was accepted or ZT_RESULT_OK_IGNORED if non-informative, error if object was invalid |
|
|
|
|
*/ |
|
|
|
|
enum ZT_ResultCode ZT_Node_processStateUpdate( |
|
|
|
|
ZT_Node *node, |
|
|
|
|
void *tptr, |
|
|
|
|
ZT_StateObjectType type, |
|
|
|
|
uint64_t id, |
|
|
|
|
const void *data, |
|
|
|
|
unsigned int len); |
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Process a packet received from the physical wire |
|
|
|
|
* |
|
|
|
|
|