X-Git-Url: http://git.meshlink.io/?a=blobdiff_plain;f=src%2Fmeshlink.h;h=b7c2fca6880a9fc507c4e26f79c817a6d816b181;hb=43d8f901c4bbb693643bb6f188c97dd28c1d0b0a;hp=26d0dfceda73af09b62bbb93565a928192823673;hpb=5c7be85686db219955e1af592b32d0d4108625cb;p=meshlink diff --git a/src/meshlink.h b/src/meshlink.h index 26d0dfce..b7c2fca6 100644 --- a/src/meshlink.h +++ b/src/meshlink.h @@ -3,7 +3,7 @@ /* meshlink.h -- MeshLink API - Copyright (C) 2014, 2017 Guus Sliepen + Copyright (C) 2014-2018 Guus Sliepen This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -51,18 +51,26 @@ typedef struct meshlink_node meshlink_node_t; /// A handle for a MeshLink channel. typedef struct meshlink_channel meshlink_channel_t; +/// A struct containing all parameters used for opening a mesh. +typedef struct meshlink_open_params meshlink_open_params_t; + +/// A handle for a MeshLink sub-mesh. +typedef struct meshlink_submesh meshlink_submesh_t; + /// Code of most recent error encountered. typedef enum { - MESHLINK_OK, ///< Everything is fine - MESHLINK_EINVAL, ///< Invalid parameter(s) to function call - MESHLINK_ENOMEM, ///< Out of memory - MESHLINK_ENOENT, ///< Node is not known - MESHLINK_EEXIST, ///< Node already exists + MESHLINK_OK, ///< Everything is fine + MESHLINK_EINVAL, ///< Invalid parameter(s) to function call + MESHLINK_ENOMEM, ///< Out of memory + MESHLINK_ENOENT, ///< Node is not known + MESHLINK_EEXIST, ///< Node already exists MESHLINK_EINTERNAL, ///< MeshLink internal error - MESHLINK_ERESOLV, ///< MeshLink could not resolve a hostname - MESHLINK_ESTORAGE, ///< MeshLink coud not load or write data from/to disk - MESHLINK_ENETWORK, ///< MeshLink encountered a network error - MESHLINK_EPEER, ///< A peer caused an error + MESHLINK_ERESOLV, ///< MeshLink could not resolve a hostname + MESHLINK_ESTORAGE, ///< MeshLink coud not load or write data from/to disk + MESHLINK_ENETWORK, ///< MeshLink encountered a network error + MESHLINK_EPEER, ///< A peer caused an error + MESHLINK_ENOTSUP, ///< The operation is not supported in the current configuration of MeshLink + MESHLINK_EBUSY ///< The MeshLink instance is already in use by another process } meshlink_errno_t; /// Device class @@ -74,6 +82,13 @@ typedef enum { _DEV_CLASS_MAX = 3 } dev_class_t; +/// Invitation flags +static const uint32_t MESHLINK_INVITE_LOCAL = 1; // Only use local addresses in the URL +static const uint32_t MESHLINK_INVITE_PUBLIC = 2; // Only use public or canonical addresses in the URL +static const uint32_t MESHLINK_INVITE_IPV4 = 4; // Only use IPv4 addresses in the URL +static const uint32_t MESHLINK_INVITE_IPV6 = 8; // Only use IPv6 addresses in the URL +static const uint32_t MESHLINK_INVITE_NUMERIC = 16; // Don't look up hostnames + /// Channel flags static const uint32_t MESHLINK_CHANNEL_RELIABLE = 1; // Data is retransmitted when packets are lost. static const uint32_t MESHLINK_CHANNEL_ORDERED = 2; // Data is delivered in-order to the application. @@ -102,11 +117,20 @@ struct meshlink_node { void *priv; ///< Private pointer which may be set freely by the application, and is never used or modified by MeshLink. }; +struct meshlink_submesh { + const char *const name; ///< Textual name of this Sub-Mesh. It is stored in a nul-terminated C string, which is allocated by MeshLink. + void *priv; ///< Private pointer which may be set freely by the application, and is never used or modified by MeshLink. +}; + struct meshlink_channel { struct meshlink_node *const node; ///< Pointer to the peer of this channel. void *priv; ///< Private pointer which may be set freely by the application, and is never used or modified by MeshLink. }; +struct meshlink_open_params { + /* This is an opaque struct, all parameters must be set using the corresponding meshlink_open_params_*() functions. */ +}; + #endif // MESHLINK_INTERNAL_H /// Get the text for the given MeshLink error code. @@ -120,6 +144,51 @@ struct meshlink_channel { */ extern const char *meshlink_strerror(meshlink_errno_t err); +/// Create a new meshlink_open_params_t struct. +/** This function allocates and initializes a new meshlink_open_params_t struct that can be passed to meshlink_open_ex(). + * The resulting struct may be reused for multiple calls to meshlink_open_ex(). + * After the last use, the application must free this struct using meshlink_open_params_free(). + * + * @param confbase The directory in which MeshLink will store its configuration files. + * After the function returns, the application is free to overwrite or free @a confbase @a. + * @param name The name which this instance of the application will use in the mesh. + * After the function returns, the application is free to overwrite or free @a name @a. + * @param appname The application name which will be used in the mesh. + * After the function returns, the application is free to overwrite or free @a name @a. + * @param devclass The device class which will be used in the mesh. + * + * @return A pointer to a meshlink_open_params_t which can be passed to meshlink_open_ex(), or NULL in case of an error. + * The pointer is valid until meshlink_open_params_free() is called. + */ +extern meshlink_open_params_t *meshlink_open_params_init(const char *confbase, const char *name, const char *appname, dev_class_t devclass); + +/// Free a meshlink_open_params_t struct. +/** This function frees a meshlink_open_params_t struct and all resources associated with it. + * + * @param params A pointer to a meshlink_open_params_t which must have been created earlier with meshlink_open_params_init(). + */ +extern void meshlink_open_params_free(meshlink_open_params_t *params); + +/// Open or create a MeshLink instance. +/** This function opens or creates a MeshLink instance. + * All parameters needed by MeshLink are passed via a meshlink_open_params_t struct, + * which must have been initialized earlier by the application. + * + * This function returns a pointer to a struct meshlink_handle that will be allocated by MeshLink. + * When the application does no longer need to use this handle, it must call meshlink_close() to + * free its resources. + * + * This function does not start any network I/O yet. The application should + * first set callbacks, and then call meshlink_start(). + * + * @param params A pointer to a meshlink_open_params_t which must be filled in by the application. + * After the function returns, the application is free to reuse or free @a params @a. + * + * @return A pointer to a meshlink_handle_t which represents this instance of MeshLink, or NULL in case of an error. + * The pointer is valid until meshlink_close() is called. + */ +extern meshlink_handle_t *meshlink_open_ex(const meshlink_open_params_t *params); + /// Open or create a MeshLink instance. /** This function opens or creates a MeshLink instance. * The state is stored in the configuration directory passed in the variable @a confbase @a. @@ -149,6 +218,21 @@ extern const char *meshlink_strerror(meshlink_errno_t err); */ extern meshlink_handle_t *meshlink_open(const char *confbase, const char *name, const char *appname, dev_class_t devclass); +/// Create Sub-Mesh. +/** This function causes MeshLink to open a new Sub-Mesh network + * create a new thread, which will handle all network I/O. + * + * It is allowed to call this function even if MeshLink is already started, in which case it will return true. + * + * @param mesh A handle which represents an instance of MeshLink. + * + * @param submesh Name of the new Sub-Mesh to create. + * + * @return A pointer to a meshlink_submesh_t which represents this instance of SubMesh, or NULL in case of an error. + * The pointer is valid until meshlink_close() is called. + */ +meshlink_submesh_t *meshlink_submesh_open(meshlink_handle_t *mesh, const char *submesh); + /// Start MeshLink. /** This function causes MeshLink to open network sockets, make outgoing connections, and * create a new thread, which will handle all network I/O. @@ -241,13 +325,33 @@ typedef void (*meshlink_node_status_cb_t)(meshlink_handle_t *mesh, meshlink_node */ extern void meshlink_set_node_status_cb(meshlink_handle_t *mesh, meshlink_node_status_cb_t cb); +/// A callback reporting duplicate node detection. +/** @param mesh A handle which represents an instance of MeshLink. + * @param node A pointer to a meshlink_node_t describing the node which is duplicate. + * This pointer is valid until meshlink_close() is called. + */ +typedef void (*meshlink_node_duplicate_cb_t)(meshlink_handle_t *mesh, meshlink_node_t *node); + +/// Set the node duplicate callback. +/** This functions sets the callback that is called whenever a duplicate node is detected. + * The callback is run in MeshLink's own thread. + * It is therefore important that the callback uses apprioriate methods (queues, pipes, locking, etc.) + * to hand the data over to the application's thread. + * The callback should also not block itself and return as quickly as possible. + * + * @param mesh A handle which represents an instance of MeshLink. + * @param cb A pointer to the function which will be called when a duplicate node is detected. + * If a NULL pointer is given, the callback will be disabled. + */ +extern void meshlink_set_node_duplicate_cb(meshlink_handle_t *mesh, meshlink_node_duplicate_cb_t cb); + /// Severity of log messages generated by MeshLink. typedef enum { MESHLINK_DEBUG, ///< Internal debugging messages. Only useful during application development. MESHLINK_INFO, ///< Informational messages. MESHLINK_WARNING, ///< Warnings which might indicate problems, but which are not real errors. MESHLINK_ERROR, ///< Errors which hamper correct functioning of MeshLink, without causing it to fail completely. - MESHLINK_CRITICAL, ///< Critical errors which cause MeshLink to fail completely. + MESHLINK_CRITICAL ///< Critical errors which cause MeshLink to fail completely. } meshlink_log_level_t; /// A callback for receiving log messages generated by MeshLink. @@ -388,6 +492,36 @@ extern meshlink_node_t **meshlink_get_all_nodes(meshlink_handle_t *mesh, meshlin */ extern bool meshlink_sign(meshlink_handle_t *mesh, const void *data, size_t len, void *signature, size_t *siglen); +/// Get the list of all nodes by device class. +/** This function returns a list with handles for all the nodes that matches with the given @a devclass @a . + * + * @param mesh A handle which represents an instance of MeshLink. + * @param devclass Device class of the nodes for which the list has to be obtained. + * @param nodes A pointer to a previously allocated array of pointers to meshlink_node_t, or NULL in which case MeshLink will allocate a new array. + * The application can supply an array it allocated itself with malloc, or the return value from the previous call to this function (which is the preferred way). + * The application is allowed to call free() on the array whenever it wishes. + * The pointers in the array are valid until meshlink_close() is called. + * @param nmemb A pointer to a variable holding the number of nodes with the same @a device class @a that are stored in the array. + * In case the @a nodes @a argument is not NULL, MeshLink might call realloc() on the array to change its size. + * The contents of this variable will be changed to reflect the new size of the array. + * + * @return A pointer to an array containing pointers to all known nodes of the given device class, or NULL in case of an error. + * If the @a nodes @a argument was not NULL, then the return value can either be the same value or a different value. + * If it is a new value, the old value of @a nodes @a should not be used anymore. + * If the new value is NULL, then the old array will have been freed by MeshLink. + */ +extern meshlink_node_t **meshlink_get_all_nodes_by_dev_class(meshlink_handle_t *mesh, dev_class_t devclass, meshlink_node_t **nodes, size_t *nmemb); + +/// Get the node's device class. +/** This function returns the device class of the given node. + * + * @param mesh A handle which represents an instance of MeshLink. + * @param node A pointer to a meshlink_node_t describing the node. + * + * @return This function returns the device class of the @a node @a , or -1 in case of an error. + */ +extern dev_class_t meshlink_get_node_dev_class(meshlink_handle_t *mesh, meshlink_node_t *node); + /// Verify the signature generated by another node of a piece of data. /** This function verifies the signature that another node generated for a piece of data. * @@ -476,10 +610,32 @@ extern char *meshlink_get_external_address(meshlink_handle_t *mesh); * * @return This function returns a pointer to a C string containing the discovered external address, * or NULL if there was an error looking up the address. - * After meshlink_get_external_address() returns, the application is free to overwrite or free this string. + * After meshlink_get_external_address_for_family() returns, the application is free to overwrite or free this string. */ extern char *meshlink_get_external_address_for_family(meshlink_handle_t *mesh, int address_family); +/// Try to discover the local address for the local node. +/** This function performs tries to discover the address of the local interface used for outgoing connection. + * + * Please note that this is function only returns a single address, + * even if the interface might have more than one address. + * In that case, there is no control over which address will be selected. + * Also note that if you have a dynamic IP address, + * there is no guarantee that the local address will be valid for an extended period of time. + * + * This function will fail if it couldn't find a local address for the given address family. + * If hostname resolving is requested, this function may block for a few seconds. + * + * @param mesh A handle which represents an instance of MeshLink. + * @param family The address family to check, for example AF_INET or AF_INET6. If AF_UNSPEC is given, + * this might return the local address for any working address family. + * + * @return This function returns a pointer to a C string containing the discovered local address, + * or NULL if there was an error looking up the address. + * After meshlink_get_local_address_for_family() returns, the application is free to overwrite or free this string. + */ +extern char *meshlink_get_local_address_for_family(meshlink_handle_t *mesh, int address_family); + /// Try to discover the external address for the local node, and add it to its list of addresses. /** This function is equivalent to: * @@ -520,6 +676,16 @@ extern int meshlink_get_port(meshlink_handle_t *mesh); extern bool meshlink_set_port(meshlink_handle_t *mesh, int port); +/// Set the timeout for invitations. +/** This function sets the timeout for invitations. + * Note that timeouts are only checked at the time a node tries to join using an invitation. + * The default timeout for invitations is 1 week. + * + * @param mesh A handle which represents an instance of MeshLink. + * @param timeout The timeout for invitations in seconds. + */ +extern void meshlink_set_invitation_timeout(meshlink_handle_t *mesh, int timeout); + /// Invite another node into the mesh. /** This function generates an invitation that can be used by another node to join the same mesh as the local node. * The generated invitation is a string containing a URL. @@ -527,13 +693,33 @@ extern bool meshlink_set_port(meshlink_handle_t *mesh, int port); * The URL can only be used once, after the user has joined the mesh the URL is no longer valid. * * @param mesh A handle which represents an instance of MeshLink. + * @param submesh A handle which represents an instance of SubMesh. * @param name A nul-terminated C string containing the name that the invitee will be allowed to use in the mesh. * After this function returns, the application is free to overwrite or free @a name @a. + * @param flags A bitwise-or'd combination of flags that controls how the URL is generated. * * @return This function returns a nul-terminated C string that contains the invitation URL, or NULL in case of an error. * The application should call free() after it has finished using the URL. */ -extern char *meshlink_invite(meshlink_handle_t *mesh, const char *name); +extern char *meshlink_invite_ex(meshlink_handle_t *mesh, meshlink_submesh_t *submesh, const char *name, uint32_t flags); + +/// Invite another node into the mesh. +/** This function generates an invitation that can be used by another node to join the same mesh as the local node. + * The generated invitation is a string containing a URL. + * This URL should be passed by the application to the invitee in a way that no eavesdroppers can see the URL. + * The URL can only be used once, after the user has joined the mesh the URL is no longer valid. + * + * Calling this function is equal to callen meshlink_invite_ex() with flags set to 0. + * + * @param mesh A handle which represents an instance of MeshLink. + * @param submesh A handle which represents an instance of SubMesh. + * @param name A nul-terminated C string containing the name that the invitee will be allowed to use in the mesh. + * After this function returns, the application is free to overwrite or free @a name @a. + * + * @return This function returns a nul-terminated C string that contains the invitation URL, or NULL in case of an error. + * The application should call free() after it has finished using the URL. + */ +extern char *meshlink_invite(meshlink_handle_t *mesh, meshlink_submesh_t *submesh, const char *name); /// Use an invitation to join a mesh. /** This function allows the local node to join an existing mesh using an invitation URL generated by another node. @@ -742,6 +928,9 @@ extern meshlink_channel_t *meshlink_channel_open_ex(meshlink_handle_t *mesh, mes * When the application does no longer need to use this channel, it must call meshlink_close() * to free its resources. * + * Calling this function is equivalent to calling meshlink_channel_open_ex() + * with the flags set to MESHLINK_CHANNEL_TCP. + * * @param mesh A handle which represents an instance of MeshLink. * @param node The node to which this channel is being initiated. * @param port The port number the peer wishes to connect to.