Adjust nomenclature. Add more C API extension functions
This commit is contained in:
@@ -100,6 +100,7 @@ int main(int argc, char** argv)
|
||||
|
||||
// Close
|
||||
|
||||
printf("Closing sockets\n");
|
||||
zts_close(fd);
|
||||
return zts_node_stop();
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
void print_peer_details(const char* msg, zts_peer_info_t* d)
|
||||
{
|
||||
printf(" %s\n", msg);
|
||||
printf("\t- peer : %llx\n", d->address);
|
||||
printf("\t- peer : %llx\n", d->peer_id);
|
||||
printf("\t- role : %d\n", d->role);
|
||||
printf("\t- latency : %d\n", d->latency);
|
||||
printf("\t- version : %d.%d.%d\n", d->ver_major, d->ver_minor, d->ver_rev);
|
||||
@@ -61,49 +61,58 @@ int main()
|
||||
{
|
||||
// World generation
|
||||
|
||||
// Buffers that will be filled after generating the world
|
||||
char world_data_out[4096] = { 0 }; // (binary) Your new world definition
|
||||
unsigned int world_len = 0;
|
||||
// Buffers that will be filled after generating the roots
|
||||
char roots_data_out[4096] = { 0 }; // (binary) Your new custom roots definition
|
||||
unsigned int roots_len = 0;
|
||||
unsigned int prev_key_len = 0;
|
||||
unsigned int curr_key_len = 0;
|
||||
char prev_key[4096] = { 0 }; // (binary) (optional) For updating a world
|
||||
char prev_key[4096] = { 0 }; // (binary) (optional) For updating roots
|
||||
char curr_key[4096] = { 0 }; // (binary) You should save this
|
||||
|
||||
// Arbitrary World ID
|
||||
uint64_t id = 149604618;
|
||||
|
||||
// Timestamp indicating when this world was generated
|
||||
// Timestamp indicating when this signed root blob was generated
|
||||
uint64_t ts = 1567191349589ULL;
|
||||
|
||||
// struct containing public keys and stable IP endpoints for roots
|
||||
zts_world_t world = { 0 };
|
||||
zts_root_set_t roots = { 0 };
|
||||
|
||||
world.public_id_str[0] =
|
||||
roots.public_id_str[0] =
|
||||
"992fcf1db7:0:"
|
||||
"206ed59350b31916f749a1f85dffb3a8787dcbf83b8c6e9448d4e3ea0e3369301be716c3609344a9d1533850fb4460c5"
|
||||
"0af43322bcfc8e13d3301a1f1003ceb6";
|
||||
world.endpoint_ip_str[0][0] = "195.181.173.159/9993";
|
||||
world.endpoint_ip_str[0][1] = "2a02:6ea0:c024::/9993";
|
||||
roots.endpoint_ip_str[0][0] = "195.181.173.159/9993";
|
||||
roots.endpoint_ip_str[0][1] = "2a02:6ea0:c024::/9993";
|
||||
|
||||
// Generate world
|
||||
// Generate roots
|
||||
|
||||
zts_util_world_new(&world_data_out, &world_len, &prev_key, &prev_key_len, &curr_key, &curr_key_len, id, ts, &world);
|
||||
zts_util_sign_root_set(
|
||||
&roots_data_out,
|
||||
&roots_len,
|
||||
&prev_key,
|
||||
&prev_key_len,
|
||||
&curr_key,
|
||||
&curr_key_len,
|
||||
id,
|
||||
ts,
|
||||
&roots);
|
||||
|
||||
printf("world_data_out= ");
|
||||
for (int i = 0; i < world_len; i++) {
|
||||
printf("roots_data_out= ");
|
||||
for (int i = 0; i < roots_len; i++) {
|
||||
if (i > 0) {
|
||||
printf(",");
|
||||
}
|
||||
printf("0x%.2x", (unsigned char)world_data_out[i]);
|
||||
printf("0x%.2x", (unsigned char)roots_data_out[i]);
|
||||
}
|
||||
printf("\n");
|
||||
printf("world_len = %d\n", world_len);
|
||||
printf("roots_len = %d\n", roots_len);
|
||||
printf("prev_key_len = %d\n", prev_key_len);
|
||||
printf("curr_key_len = %d\n", curr_key_len);
|
||||
|
||||
// Now, initialize node and use newly-generated world definition
|
||||
// Now, initialize node and use newly-generated roots definition
|
||||
|
||||
zts_init_set_world(&world_data_out, world_len);
|
||||
zts_init_set_roots(&roots_data_out, roots_len);
|
||||
zts_init_set_event_handler(&on_zts_event);
|
||||
zts_init_from_storage(".");
|
||||
|
||||
|
||||
@@ -103,7 +103,7 @@ int main(int argc, char** argv)
|
||||
|
||||
// Close
|
||||
|
||||
printf("Closing connection socket\n");
|
||||
printf("Closing sockets\n");
|
||||
err = zts_close(accfd);
|
||||
err = zts_close(fd);
|
||||
return zts_node_stop();
|
||||
|
||||
@@ -344,11 +344,13 @@ typedef enum {
|
||||
*/
|
||||
#define ZTS_MAX_MULTICAST_SUBSCRIPTIONS 1024
|
||||
|
||||
#define ZTS_MAX_ENDPOINT_STR_LEN ZTS_INET6_ADDRSTRLEN + 6
|
||||
|
||||
//----------------------------------------------------------------------------//
|
||||
// Misc //
|
||||
//----------------------------------------------------------------------------//
|
||||
|
||||
#if ! defined(ZTS_ENABLE_PYTHON) && ! defined(ZTS_ENABLE_PINVOKE)
|
||||
#if ! defined(ZTS_ENABLE_PYTHON) && ! defined(ZTS_ENABLE_PINVOKE) && ! defined(ZTS_ENABLE_JAVA)
|
||||
#define ZTS_C_API_ONLY 1
|
||||
#endif
|
||||
|
||||
@@ -877,7 +879,7 @@ typedef struct {
|
||||
/**
|
||||
* ZeroTier address (40 bits)
|
||||
*/
|
||||
uint64_t address;
|
||||
uint64_t peer_id;
|
||||
|
||||
/**
|
||||
* Remote major version or -1 if not known
|
||||
@@ -929,7 +931,7 @@ typedef struct {
|
||||
typedef struct {
|
||||
char* public_id_str[ZTS_MAX_NUM_ROOTS];
|
||||
char* endpoint_ip_str[ZTS_MAX_NUM_ROOTS][ZTS_MAX_ENDPOINTS_PER_ROOT];
|
||||
} zts_world_t;
|
||||
} zts_root_set_t;
|
||||
|
||||
/**
|
||||
* Structure used to convey information about a virtual network
|
||||
@@ -1285,6 +1287,10 @@ ZTS_API int ZTCALL zts_init_set_event_handler(PythonDirectorCallbackClass* callb
|
||||
#ifdef ZTS_ENABLE_PINVOKE
|
||||
ZTS_API int ZTCALL zts_init_set_event_handler(CppCallback callback);
|
||||
#endif
|
||||
#ifdef ZTS_ENABLE_JAVA
|
||||
#include <jni.h>
|
||||
int zts_init_set_event_handler(jobject obj_ref, jmethodID id);
|
||||
#endif
|
||||
#ifdef ZTS_C_API_ONLY
|
||||
ZTS_API int ZTCALL zts_init_set_event_handler(void (*callback)(void*));
|
||||
#endif
|
||||
@@ -1302,15 +1308,15 @@ ZTS_API int ZTCALL zts_init_set_event_handler(void (*callback)(void*));
|
||||
ZTS_API int ZTCALL zts_init_blacklist_if(const char* prefix, unsigned int len);
|
||||
|
||||
/**
|
||||
* @brief Present a world definition for ZeroTier to use instead of the default.
|
||||
* @brief Present a root set definition for ZeroTier to use instead of the default.
|
||||
* This is an initialization function that can only be called before `zts_node_start()`.
|
||||
*
|
||||
* @param world_data Array of world definition data (binary)
|
||||
* @param roots_data Array of roots definition data (binary)
|
||||
* @param len Length of binary data
|
||||
* @return `ZTS_ERR_OK` if successful, `ZTS_ERR_SERVICE` if the node
|
||||
* experiences a problem, `ZTS_ERR_ARG` if invalid argument.
|
||||
*/
|
||||
ZTS_API int ZTCALL zts_init_set_world(const void* world_data, unsigned int len);
|
||||
ZTS_API int ZTCALL zts_init_set_roots(const void* roots_data, unsigned int len);
|
||||
|
||||
/**
|
||||
* @brief Set the port to which the node should bind. This is an initialization function that can
|
||||
@@ -1362,14 +1368,14 @@ ZTS_API int ZTCALL zts_init_allow_net_cache(unsigned int allowed);
|
||||
ZTS_API int ZTCALL zts_init_allow_peer_cache(unsigned int allowed);
|
||||
|
||||
/**
|
||||
* @brief Enable or disable whether the node will cache world definitions (enabled
|
||||
* @brief Enable or disable whether the node will cache root definitions (enabled
|
||||
* by default when `zts_init_from_storage()` is used.) Must be called before `zts_node_start()`.
|
||||
*
|
||||
* @param enabled Whether or not this feature is enabled
|
||||
* @return `ZTS_ERR_OK` if successful, `ZTS_ERR_SERVICE` if the node
|
||||
* experiences a problem, `ZTS_ERR_ARG` if invalid argument.
|
||||
*/
|
||||
ZTS_API int ZTCALL zts_init_allow_world_cache(unsigned int allowed);
|
||||
ZTS_API int ZTCALL zts_init_allow_roots_cache(unsigned int allowed);
|
||||
|
||||
/**
|
||||
* @brief Enable or disable whether the node will cache identities (enabled
|
||||
@@ -1647,12 +1653,12 @@ ZTS_API uint64_t ZTCALL zts_node_get_id();
|
||||
* `WARNING`: This function exports your secret key and should be used carefully.
|
||||
*
|
||||
* @param key User-provided destination buffer
|
||||
* @param key_buf_len Length of user-provided destination buffer. Will be set to
|
||||
* @param key_dst_len Length of user-provided destination buffer. Will be set to
|
||||
* number of bytes copied.
|
||||
* @return `ZTS_ERR_OK` if successful, `ZTS_ERR_SERVICE` if the node
|
||||
* experiences a problem, `ZTS_ERR_ARG` if invalid argument.
|
||||
*/
|
||||
ZTS_API int ZTCALL zts_node_get_id_pair(char* key, unsigned int* key_buf_len);
|
||||
ZTS_API int ZTCALL zts_node_get_id_pair(char* key, unsigned int* key_dst_len);
|
||||
|
||||
/**
|
||||
* @brief Get the primary port to which the node is bound. Callable only after the node has been
|
||||
@@ -1692,21 +1698,21 @@ ZTS_API int ZTCALL zts_node_free();
|
||||
/**
|
||||
* @brief Orbit a given moon (user-defined root server)
|
||||
*
|
||||
* @param moon_world_id World ID
|
||||
* @param moon_roots_id World ID
|
||||
* @param moon_seed Seed ID
|
||||
* @return `ZTS_ERR_OK` if successful, `ZTS_ERR_SERVICE` if the node
|
||||
* experiences a problem, `ZTS_ERR_ARG` if invalid argument.
|
||||
*/
|
||||
ZTS_API int ZTCALL zts_moon_orbit(uint64_t moon_world_id, uint64_t moon_seed);
|
||||
ZTS_API int ZTCALL zts_moon_orbit(uint64_t moon_roots_id, uint64_t moon_seed);
|
||||
|
||||
/**
|
||||
* @brief De-orbit a given moon (user-defined root server)
|
||||
*
|
||||
* @param moon_world_id World ID
|
||||
* @param moon_roots_id World ID
|
||||
* @return `ZTS_ERR_OK` if successful, `ZTS_ERR_SERVICE` if the node
|
||||
* experiences a problem, `ZTS_ERR_ARG` if invalid argument.
|
||||
*/
|
||||
ZTS_API int ZTCALL zts_moon_deorbit(uint64_t moon_world_id);
|
||||
ZTS_API int ZTCALL zts_moon_deorbit(uint64_t moon_roots_id);
|
||||
|
||||
//----------------------------------------------------------------------------//
|
||||
// Statistics //
|
||||
@@ -1837,31 +1843,6 @@ ZTS_API int ZTCALL zts_socket(int family, int type, int protocol);
|
||||
*/
|
||||
ZTS_API int ZTCALL zts_connect(int fd, const struct zts_sockaddr* addr, zts_socklen_t addrlen);
|
||||
|
||||
/**
|
||||
* @brief Connect a socket to a remote host
|
||||
*
|
||||
* This convenience function exists because ZeroTier uses transport-triggered
|
||||
* links. This means that links between peers do not exist until peers try to
|
||||
* talk to each other. This can be a problem during connection procedures since
|
||||
* some of the initial packets are lost. To alleviate the need to try
|
||||
* `zts_connect` many times, this function will keep re-trying for you, even if
|
||||
* no known routes exist. However, if the socket is set to `non-blocking` mode
|
||||
* it will behave identically to `zts_connect` and return immediately upon
|
||||
* failure.
|
||||
*
|
||||
* @param fd Socket file descriptor
|
||||
* @param ipstr Human-readable IP string
|
||||
* @param port Port
|
||||
* @param timeout_ms (Approximate) amount of time in milliseconds before
|
||||
* connection attempt is aborted. Will block for `30 seconds` if timeout is
|
||||
* set to `0`.
|
||||
*
|
||||
* @return `ZTS_ERR_OK` if successful, `ZTS_ERR_SOCKET` if the function times
|
||||
* out with no connection made, `ZTS_ERR_SERVICE` if the node experiences a
|
||||
* problem, `ZTS_ERR_ARG` if invalid argument. Sets `zts_errno`
|
||||
*/
|
||||
ZTS_API int ZTCALL zts_simple_connect(int fd, const char* ipstr, int port, int timeout_ms);
|
||||
|
||||
/**
|
||||
* @brief Bind a socket to a local address
|
||||
*
|
||||
@@ -1873,17 +1854,6 @@ ZTS_API int ZTCALL zts_simple_connect(int fd, const char* ipstr, int port, int t
|
||||
*/
|
||||
ZTS_API int ZTCALL zts_bind(int fd, const struct zts_sockaddr* addr, zts_socklen_t addrlen);
|
||||
|
||||
/**
|
||||
* @brief Bind a socket to a local address
|
||||
*
|
||||
* @param fd Socket file descriptor
|
||||
* @param ipstr Human-readable IP string
|
||||
* @param port Port
|
||||
* @return `ZTS_ERR_OK` if successful, `ZTS_ERR_SERVICE` if the node
|
||||
* experiences a problem, `ZTS_ERR_ARG` if invalid argument. Sets `zts_errno`
|
||||
*/
|
||||
ZTS_API int ZTCALL zts_simple_bind(int fd, const char* ipstr, int port);
|
||||
|
||||
/**
|
||||
* @brief Listen for incoming connections on socket
|
||||
*
|
||||
@@ -1905,71 +1875,6 @@ ZTS_API int ZTCALL zts_listen(int fd, int backlog);
|
||||
*/
|
||||
ZTS_API int ZTCALL zts_accept(int fd, struct zts_sockaddr* addr, zts_socklen_t* addrlen);
|
||||
|
||||
/**
|
||||
* @brief Accept an incoming connection
|
||||
*
|
||||
* @param fd Socket file descriptor
|
||||
* @param remote_addr Buffer that will receive remote host IP string
|
||||
* @param len Size of buffer that will receive remote host IP string
|
||||
* (must be exactly `ZTS_IP_MAX_STR_LEN`)
|
||||
* @param port Port number of the newly connected remote host (value-result)
|
||||
* @return New file descriptor if successful, `ZTS_ERR_SERVICE` if the node
|
||||
* experiences a problem, `ZTS_ERR_ARG` if invalid argument. Sets `zts_errno`
|
||||
*/
|
||||
ZTS_API int ZTCALL zts_simple_accept(int fd, char* remote_addr, int len, int* port);
|
||||
|
||||
/**
|
||||
* @brief A convenience function that takes a remote address IP string and creates
|
||||
* the appropriate type of socket, and uses it to connect to a remote host.
|
||||
*
|
||||
* @param remote_ipstr Remote address string. IPv4 or IPv6
|
||||
* @param remote_port Port to
|
||||
*
|
||||
* @return New file descriptor if successful, `ZTS_ERR_SERVICE` if the node
|
||||
* experiences a problem, `ZTS_ERR_ARG` if invalid argument. Sets `zts_errno`
|
||||
*/
|
||||
ZTS_API int ZTCALL zts_simple_tcp_client(const char* remote_ipstr, int remote_port);
|
||||
|
||||
/**
|
||||
* @brief A convenience function that takes a remote address IP string and creates
|
||||
* the appropriate type of socket, binds, listens, and then accepts on it.
|
||||
*
|
||||
* @param local_ipstr Local address to bind
|
||||
* @param local_port Local port to bind
|
||||
* @param remote_ipstr String-format IP address of newly connected remote host
|
||||
* @param len Length of `remote_ipstr`
|
||||
* @param remote_port Port of remote host
|
||||
*
|
||||
* @return New file descriptor if successful, `ZTS_ERR_SERVICE` if the node
|
||||
* experiences a problem, `ZTS_ERR_ARG` if invalid argument. Sets `zts_errno`
|
||||
*/
|
||||
ZTS_API int ZTCALL
|
||||
zts_simple_tcp_server(const char* local_ipstr, int local_port, char* remote_ipstr, int len, int* remote_port);
|
||||
|
||||
/**
|
||||
* @brief A convenience function that takes a remote address IP string and creates
|
||||
* the appropriate type of socket, and binds to it.
|
||||
*
|
||||
* @param local_ipstr Local address to bind
|
||||
* @param local_port Local port to bind
|
||||
*
|
||||
* @return New file descriptor if successful, `ZTS_ERR_SERVICE` if the node
|
||||
* experiences a problem, `ZTS_ERR_ARG` if invalid argument. Sets `zts_errno`
|
||||
*/
|
||||
ZTS_API int ZTCALL zts_simple_udp_server(const char* local_ipstr, int local_port);
|
||||
|
||||
/**
|
||||
* @brief This function doesn't really do anything other than be a namespace
|
||||
* counterpart to `zts_simple_udp_server`. All this function does is create a
|
||||
* `ZTS_SOCK_DGRAM` socket and return its file descriptor.
|
||||
*
|
||||
* @param remote_ipstr Remote address string. IPv4 or IPv6
|
||||
*
|
||||
* @return New file descriptor if successful, `ZTS_ERR_SERVICE` if the node
|
||||
* experiences a problem, `ZTS_ERR_ARG` if invalid argument. Sets `zts_errno`
|
||||
*/
|
||||
ZTS_API int ZTCALL zts_simple_udp_client(const char* remote_ipstr);
|
||||
|
||||
// Socket level option number
|
||||
#define ZTS_SOL_SOCKET 0x0fff
|
||||
// Socket options
|
||||
@@ -2124,7 +2029,7 @@ ZTS_API int ZTCALL zts_setsockopt(int fd, int level, int optname, const void* op
|
||||
ZTS_API int ZTCALL zts_getsockopt(int fd, int level, int optname, void* optval, zts_socklen_t* optlen);
|
||||
|
||||
/**
|
||||
* @brief Get socket name.
|
||||
* @brief Get the name (address) of the local end of the socket
|
||||
*
|
||||
* @param fd Socket file descriptor
|
||||
* @param addr Name associated with this socket
|
||||
@@ -2135,7 +2040,7 @@ ZTS_API int ZTCALL zts_getsockopt(int fd, int level, int optname, void* optval,
|
||||
ZTS_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.
|
||||
* @brief Get the name (address) of the remote end of the socket
|
||||
*
|
||||
* @param fd Socket file descriptor
|
||||
* @param addr Name associated with remote end of this socket
|
||||
@@ -2433,6 +2338,141 @@ ZTS_API int ZTCALL zts_shutdown(int fd, int how);
|
||||
// Convenience functions //
|
||||
//----------------------------------------------------------------------------//
|
||||
|
||||
/**
|
||||
* Helper functions that simplify API wrapper generation and usage in other
|
||||
* non-C-like languages. Use simple integer types instead of bit flags,
|
||||
* limit the number of operations each function performs, prevent the user
|
||||
* from needing to manipulate the contents of structures in a non-native
|
||||
* language.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Connect a socket to a remote host
|
||||
*
|
||||
* This convenience function exists because ZeroTier uses transport-triggered
|
||||
* links. This means that links between peers do not exist until peers try to
|
||||
* talk to each other. This can be a problem during connection procedures since
|
||||
* some of the initial packets are lost. To alleviate the need to try
|
||||
* `zts_connect` many times, this function will keep re-trying for you, even if
|
||||
* no known routes exist. However, if the socket is set to `non-blocking` mode
|
||||
* it will behave identically to `zts_connect` and return immediately upon
|
||||
* failure.
|
||||
*
|
||||
* @param fd Socket file descriptor
|
||||
* @param ipstr Human-readable IP string
|
||||
* @param port Port
|
||||
* @param timeout_ms (Approximate) amount of time in milliseconds before
|
||||
* connection attempt is aborted. Will block for `30 seconds` if timeout is
|
||||
* set to `0`.
|
||||
*
|
||||
* @return `ZTS_ERR_OK` if successful, `ZTS_ERR_SOCKET` if the function times
|
||||
* out with no connection made, `ZTS_ERR_SERVICE` if the node experiences a
|
||||
* problem, `ZTS_ERR_ARG` if invalid argument. Sets `zts_errno`
|
||||
*/
|
||||
ZTS_API int ZTCALL zts_simple_connect(int fd, const char* ipstr, unsigned short port, int timeout_ms);
|
||||
|
||||
/**
|
||||
* @brief Bind a socket to a local address
|
||||
*
|
||||
* @param fd Socket file descriptor
|
||||
* @param ipstr Human-readable IP string
|
||||
* @param port Port
|
||||
* @return `ZTS_ERR_OK` if successful, `ZTS_ERR_SERVICE` if the node
|
||||
* experiences a problem, `ZTS_ERR_ARG` if invalid argument. Sets `zts_errno`
|
||||
*/
|
||||
ZTS_API int ZTCALL zts_simple_bind(int fd, const char* ipstr, unsigned short port);
|
||||
|
||||
/**
|
||||
* @brief Accept an incoming connection
|
||||
*
|
||||
* @param fd Socket file descriptor
|
||||
* @param remote_addr Buffer that will receive remote host IP string
|
||||
* @param len Size of buffer that will receive remote host IP string
|
||||
* (must be exactly `ZTS_IP_MAX_STR_LEN`)
|
||||
* @param port Port number of the newly connected remote host (value-result)
|
||||
* @return New file descriptor if successful, `ZTS_ERR_SERVICE` if the node
|
||||
* experiences a problem, `ZTS_ERR_ARG` if invalid argument. Sets `zts_errno`
|
||||
*/
|
||||
ZTS_API int ZTCALL zts_simple_accept(int fd, char* remote_addr, int len, unsigned short* port);
|
||||
|
||||
/**
|
||||
* @brief Get the name (address) of the remote end of the socket
|
||||
*
|
||||
* @param fd Socket file descriptor
|
||||
* @param remote_addr_str Destination buffer to contain name (address) of the remote end of the socket
|
||||
* @param len Length of destination buffer
|
||||
* @param port Value-result parameter that will contain resultant port number
|
||||
* @return `ZTS_ERR_OK` if successful, `ZTS_ERR_ARG` if invalid argument. Sets `zts_errno`
|
||||
*/
|
||||
ZTS_API int ZTCALL zts_simple_getpeername(int fd, char* remote_addr_str, int len, unsigned short* port);
|
||||
|
||||
/**
|
||||
* @brief Get the name (address) of the local end of the socket
|
||||
*
|
||||
* @param fd Socket file descriptor
|
||||
* @param local_addr_str Destination buffer to contain name (address) of the local end of the socket
|
||||
* @param len Length of destination buffer
|
||||
* @param port Value-result parameter that will contain resultant port number
|
||||
* @return `ZTS_ERR_OK` if successful, `ZTS_ERR_ARG` if invalid argument. Sets `zts_errno`
|
||||
*/
|
||||
ZTS_API int ZTCALL zts_simple_getsockname(int fd, char* local_addr_str, int len, unsigned short* port);
|
||||
|
||||
/**
|
||||
* @brief A convenience function that takes a remote address IP string and creates
|
||||
* the appropriate type of socket, and uses it to connect to a remote host.
|
||||
*
|
||||
* @param remote_ipstr Remote address string. IPv4 or IPv6
|
||||
* @param remote_port Port to
|
||||
*
|
||||
* @return New file descriptor if successful, `ZTS_ERR_SERVICE` if the node
|
||||
* experiences a problem, `ZTS_ERR_ARG` if invalid argument. Sets `zts_errno`
|
||||
*/
|
||||
ZTS_API int ZTCALL zts_simple_tcp_client(const char* remote_ipstr, unsigned short remote_port);
|
||||
|
||||
/**
|
||||
* @brief A convenience function that takes a remote address IP string and creates
|
||||
* the appropriate type of socket, binds, listens, and then accepts on it.
|
||||
*
|
||||
* @param local_ipstr Local address to bind
|
||||
* @param local_port Local port to bind
|
||||
* @param remote_ipstr String-format IP address of newly connected remote host
|
||||
* @param len Length of `remote_ipstr`
|
||||
* @param remote_port Port of remote host
|
||||
*
|
||||
* @return New file descriptor if successful, `ZTS_ERR_SERVICE` if the node
|
||||
* experiences a problem, `ZTS_ERR_ARG` if invalid argument. Sets `zts_errno`
|
||||
*/
|
||||
ZTS_API int ZTCALL zts_simple_tcp_server(
|
||||
const char* local_ipstr,
|
||||
unsigned short local_port,
|
||||
char* remote_ipstr,
|
||||
int len,
|
||||
unsigned short* remote_port);
|
||||
|
||||
/**
|
||||
* @brief A convenience function that takes a remote address IP string and creates
|
||||
* the appropriate type of socket, and binds to it.
|
||||
*
|
||||
* @param local_ipstr Local address to bind
|
||||
* @param local_port Local port to bind
|
||||
*
|
||||
* @return New file descriptor if successful, `ZTS_ERR_SERVICE` if the node
|
||||
* experiences a problem, `ZTS_ERR_ARG` if invalid argument. Sets `zts_errno`
|
||||
*/
|
||||
ZTS_API int ZTCALL zts_simple_udp_server(const char* local_ipstr, unsigned short local_port);
|
||||
|
||||
/**
|
||||
* @brief This function doesn't really do anything other than be a namespace
|
||||
* counterpart to `zts_simple_udp_server`. All this function does is create a
|
||||
* `ZTS_SOCK_DGRAM` socket and return its file descriptor.
|
||||
*
|
||||
* @param remote_ipstr Remote address string. IPv4 or IPv6
|
||||
*
|
||||
* @return New file descriptor if successful, `ZTS_ERR_SERVICE` if the node
|
||||
* experiences a problem, `ZTS_ERR_ARG` if invalid argument. Sets `zts_errno`
|
||||
*/
|
||||
ZTS_API int ZTCALL zts_simple_udp_client(const char* remote_ipstr);
|
||||
|
||||
/**
|
||||
* @brief Enable or disable `TCP_NODELAY`. Enabling this is equivalent to
|
||||
* turning off Nagle's algorithm
|
||||
@@ -2482,6 +2522,15 @@ ZTS_API int ZTCALL zts_simple_get_linger_enabled(int fd);
|
||||
*/
|
||||
ZTS_API int ZTCALL zts_simple_get_linger_value(int fd);
|
||||
|
||||
/**
|
||||
* @brief Return the number of bytes available to read from the network buffer
|
||||
*
|
||||
* @param fd Socket file descriptor
|
||||
* @return Number of bytes to read if successful, `ZTS_ERR_SERVICE` if the node
|
||||
* experiences a problem, `ZTS_ERR_ARG` if invalid argument. Sets `zts_errno`
|
||||
*/
|
||||
ZTS_API int ZTCALL zts_simple_get_pending_data_size(int fd);
|
||||
|
||||
/**
|
||||
* @brief Enable or disable `SO_REUSEADDR`
|
||||
*
|
||||
@@ -2837,21 +2886,21 @@ ZTS_API int ZTCALL zts_core_query_mc(uint64_t net_id, unsigned int idx, uint64_t
|
||||
//----------------------------------------------------------------------------//
|
||||
|
||||
/**
|
||||
* @brief Generates a new world definition
|
||||
* @brief Generates a new root set definition
|
||||
*
|
||||
* @param world_id The desired World ID (arbitrary)
|
||||
* @param roots_id The desired World ID (arbitrary)
|
||||
* @param ts Timestamp indicating when this generation took place
|
||||
*/
|
||||
ZTS_API int ZTCALL zts_util_world_new(
|
||||
char* world_out,
|
||||
unsigned int* world_len,
|
||||
ZTS_API int ZTCALL zts_util_sign_root_set(
|
||||
char* roots_out,
|
||||
unsigned int* roots_len,
|
||||
char* prev_key,
|
||||
unsigned int* prev_key_len,
|
||||
char* curr_key,
|
||||
unsigned int* curr_key_len,
|
||||
uint64_t id,
|
||||
uint64_t ts,
|
||||
zts_world_t* world_spec);
|
||||
zts_root_set_t* roots_spec);
|
||||
|
||||
/**
|
||||
* @brief Platform-agnostic delay
|
||||
@@ -2881,10 +2930,25 @@ ZTS_API int ZTCALL zts_util_get_ip_family(const char* ipstr);
|
||||
*/
|
||||
int zts_util_ipstr_to_saddr(
|
||||
const char* src_ipstr,
|
||||
unsigned int port,
|
||||
unsigned short port,
|
||||
struct zts_sockaddr* dstaddr,
|
||||
zts_socklen_t* addrlen);
|
||||
|
||||
/**
|
||||
* @brief Similar to `inet_ntop` but determines family automatically and returns
|
||||
* port as a value result parameter.
|
||||
*
|
||||
* @param addr Pointer to address structure
|
||||
* @param addrlen Length of address structure
|
||||
* @param dst_str Destination buffer
|
||||
* @param len Length of destination buffer
|
||||
* @param port Value-result parameter that will contain resultant port number
|
||||
*
|
||||
* @return return `ZTS_ERR_OK` on success, `ZTS_ERR_ARG` if invalid argument
|
||||
*/
|
||||
ZTS_API int ZTCALL
|
||||
zts_util_ntop(struct zts_sockaddr* addr, zts_socklen_t addrlen, char* dst_str, int len, unsigned short* port);
|
||||
|
||||
//----------------------------------------------------------------------------//
|
||||
// Convenience functions pulled from lwIP //
|
||||
//----------------------------------------------------------------------------//
|
||||
|
||||
@@ -18,11 +18,9 @@
|
||||
#include "OSUtils.hpp"
|
||||
#include "ZeroTierSockets.h"
|
||||
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
#include <curl/curl.h>
|
||||
#include <iomanip>
|
||||
#include <iostream>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#define REQ_LEN 64
|
||||
|
||||
@@ -98,7 +96,7 @@ int zts_central_init(const char* url_str, const char* token_str, char* resp_buf,
|
||||
// Initialize all curl internal submodules
|
||||
curl_global_init(CURL_GLOBAL_ALL);
|
||||
|
||||
int url_len = strlen(url_str);
|
||||
int url_len = strnlen(url_str, ZTS_CENRTAL_MAX_URL_LEN);
|
||||
if (url_len < 3 || url_len > ZTS_CENRTAL_MAX_URL_LEN) {
|
||||
return ZTS_ERR_ARG;
|
||||
}
|
||||
@@ -106,7 +104,7 @@ int zts_central_init(const char* url_str, const char* token_str, char* resp_buf,
|
||||
memset(api_url, 0, ZTS_CENRTAL_MAX_URL_LEN);
|
||||
strncpy(api_url, url_str, url_len);
|
||||
}
|
||||
int token_len = strlen(token_str);
|
||||
int token_len = strnlen(token_str, ZTS_CENTRAL_TOKEN_LEN);
|
||||
if (token_len != ZTS_CENTRAL_TOKEN_LEN) {
|
||||
return ZTS_ERR_ARG;
|
||||
}
|
||||
@@ -147,9 +145,9 @@ int central_req(
|
||||
return ZTS_ERR_SERVICE;
|
||||
}
|
||||
zts_central_clear_resp_buf();
|
||||
int central_strlen = strlen(central_str);
|
||||
int api_route_strlen = strlen(api_route_str);
|
||||
int token_strlen = strlen(token_str);
|
||||
int central_strlen = strnlen(central_str, ZTS_CENRTAL_MAX_URL_LEN);
|
||||
int api_route_strlen = strnlen(api_route_str, ZTS_CENRTAL_MAX_URL_LEN);
|
||||
int token_strlen = strnlen(token_str, ZTS_CENTRAL_TOKEN_LEN);
|
||||
int url_len = central_strlen + api_route_strlen;
|
||||
if (token_strlen > ZTS_CENTRAL_TOKEN_LEN) {
|
||||
return ZTS_ERR_ARG;
|
||||
|
||||
@@ -17,21 +17,11 @@
|
||||
* Node / Network control interface
|
||||
*/
|
||||
|
||||
#include "Constants.hpp"
|
||||
#include "Events.hpp"
|
||||
#include "Mutex.hpp"
|
||||
#include "Node.hpp"
|
||||
#include "NodeService.hpp"
|
||||
#include "OSUtils.hpp"
|
||||
#include "Signals.hpp"
|
||||
#include "Thread.hpp"
|
||||
#include "VirtualTap.hpp"
|
||||
#include "ZeroTierSockets.h"
|
||||
#include "lwip/stats.h"
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <sys/types.h>
|
||||
#include <thread>
|
||||
#include <string.h>
|
||||
|
||||
using namespace ZeroTier;
|
||||
|
||||
@@ -63,12 +53,11 @@ Events* zts_events;
|
||||
extern Mutex events_m;
|
||||
Mutex service_m;
|
||||
|
||||
/** Set up service and callback threads and tell them about one another.
|
||||
* A separate thread is used for callbacks so that if the user fails to return
|
||||
* control it won't affect the core service's operations.
|
||||
*/
|
||||
int init_subsystems()
|
||||
{
|
||||
/** Set up service and callback threads and tell them about one another.
|
||||
* A separate thread is used for callbacks so that if the user fails to
|
||||
* return control it won't affect the core service's operations. */
|
||||
if (! zts_events) {
|
||||
zts_events = new Events();
|
||||
}
|
||||
@@ -108,15 +97,22 @@ int zts_init_set_event_handler(PythonDirectorCallbackClass* callback)
|
||||
#ifdef ZTS_ENABLE_PINVOKE
|
||||
int zts_init_set_event_handler(CppCallback callback)
|
||||
#endif
|
||||
#ifdef ZTS_ENABLE_JAVA
|
||||
int zts_init_set_event_handler(jobject obj_ref, jmethodID id)
|
||||
#endif
|
||||
#ifdef ZTS_C_API_ONLY
|
||||
int zts_init_set_event_handler(void (*callback)(void*))
|
||||
int zts_init_set_event_handler(void (*callback)(void*))
|
||||
#endif
|
||||
{
|
||||
ACQUIRE_SERVICE_OFFLINE();
|
||||
#ifdef ZTS_ENABLE_JAVA
|
||||
zts_events->setJavaCallback(obj_ref, id);
|
||||
#else
|
||||
if (! callback) {
|
||||
return ZTS_ERR_ARG;
|
||||
}
|
||||
_userEventCallback = callback;
|
||||
#endif
|
||||
zts_service->enableEvents();
|
||||
return ZTS_ERR_OK;
|
||||
}
|
||||
@@ -127,10 +123,10 @@ int zts_init_blacklist_if(const char* prefix, unsigned int len)
|
||||
return zts_service->addInterfacePrefixToBlacklist(prefix, len);
|
||||
}
|
||||
|
||||
int zts_init_set_world(const void* world_data, unsigned int len)
|
||||
int zts_init_set_roots(const void* roots_data, unsigned int len)
|
||||
{
|
||||
ACQUIRE_SERVICE_OFFLINE();
|
||||
return zts_service->setWorld(world_data, len);
|
||||
return zts_service->setWorld(roots_data, len);
|
||||
}
|
||||
|
||||
int zts_init_set_port(unsigned short port)
|
||||
@@ -152,7 +148,7 @@ int zts_init_allow_net_cache(unsigned int allowed)
|
||||
return zts_service->allowNetworkCaching(allowed);
|
||||
}
|
||||
|
||||
int zts_init_allow_world_cache(unsigned int allowed)
|
||||
int zts_init_allow_roots_cache(unsigned int allowed)
|
||||
{
|
||||
ACQUIRE_SERVICE_OFFLINE();
|
||||
return zts_service->allowWorldCaching(allowed);
|
||||
@@ -216,7 +212,7 @@ int zts_addr_compute_6plane_str(uint64_t net_id, uint64_t node_id, char* dst, un
|
||||
return ZTS_ERR_OK;
|
||||
}
|
||||
|
||||
uint64_t zts_net_compute_adhoc_id(uint16_t start_port, uint16_t end_port)
|
||||
uint64_t zts_net_compute_adhoc_id(unsigned short start_port, unsigned short end_port)
|
||||
{
|
||||
char net_id_str[ZTS_INET6_ADDRSTRLEN] = { 0 };
|
||||
OSUtils::ztsnprintf(net_id_str, ZTS_INET6_ADDRSTRLEN, "ff%04x%04x000000", start_port, end_port);
|
||||
@@ -247,7 +243,7 @@ int zts_id_pair_is_valid(const char* key, unsigned int len)
|
||||
return false;
|
||||
}
|
||||
Identity id;
|
||||
if ((strlen(key) > 32) && (key[10] == ':')) {
|
||||
if ((strnlen(key, len) > 32) && (key[10] == ':')) {
|
||||
if (id.fromString(key)) {
|
||||
return id.locallyValidate();
|
||||
}
|
||||
@@ -255,11 +251,14 @@ int zts_id_pair_is_valid(const char* key, unsigned int len)
|
||||
return false;
|
||||
}
|
||||
|
||||
int zts_node_get_id_pair(char* key, unsigned int* dst_len)
|
||||
int zts_node_get_id_pair(char* key, unsigned int* key_dst_len)
|
||||
{
|
||||
ACQUIRE_SERVICE(ZTS_ERR_SERVICE);
|
||||
zts_service->getIdentity(key, dst_len);
|
||||
return *dst_len > 0 ? ZTS_ERR_OK : ZTS_ERR_GENERAL;
|
||||
int err = ZTS_ERR_OK;
|
||||
if ((err = zts_service->getIdentity(key, key_dst_len)) != ZTS_ERR_OK) {
|
||||
return err;
|
||||
}
|
||||
return *key_dst_len > 0 ? ZTS_ERR_OK : ZTS_ERR_GENERAL;
|
||||
}
|
||||
|
||||
#if defined(__WINDOWS__)
|
||||
@@ -272,10 +271,10 @@ void* cbRun(void* arg)
|
||||
pthread_setname_np(ZTS_EVENT_CALLBACK_THREAD_NAME);
|
||||
#endif
|
||||
zts_events->run();
|
||||
#if ZTS_ENABLE_JAVA
|
||||
_java_detach_from_thread();
|
||||
//#if ZTS_ENABLE_JAVA
|
||||
// _java_detach_from_thread();
|
||||
// pthread_exit(0);
|
||||
#endif
|
||||
//#endif
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -497,8 +496,6 @@ void* _runNodeService(void* arg)
|
||||
zts_util_delay(ZTS_CALLBACK_PROCESSING_INTERVAL * 2);
|
||||
if (zts_events) {
|
||||
zts_events->disable();
|
||||
delete zts_events;
|
||||
zts_events = (Events*)0;
|
||||
}
|
||||
events_m.unlock();
|
||||
}
|
||||
@@ -514,7 +511,7 @@ int zts_node_start()
|
||||
{
|
||||
ACQUIRE_SERVICE_OFFLINE();
|
||||
// Start TCP/IP stack
|
||||
_lwip_driver_init();
|
||||
zts_lwip_driver_init();
|
||||
// Start callback thread
|
||||
int res = ZTS_ERR_OK;
|
||||
if (zts_events->hasCallback()) {
|
||||
@@ -591,21 +588,23 @@ int zts_node_free()
|
||||
#if defined(__WINDOWS__)
|
||||
WSACleanup();
|
||||
#endif
|
||||
_lwip_driver_shutdown();
|
||||
zts_lwip_driver_shutdown();
|
||||
delete zts_events;
|
||||
zts_events = (Events*)0;
|
||||
return ZTS_ERR_OK;
|
||||
}
|
||||
|
||||
int zts_moon_orbit(uint64_t moon_world_id, uint64_t moon_seed)
|
||||
int zts_moon_orbit(uint64_t moon_roots_id, uint64_t moon_seed)
|
||||
{
|
||||
ACQUIRE_SERVICE(ZTS_ERR_SERVICE);
|
||||
zts_service->orbit(NULL, moon_world_id, moon_seed);
|
||||
zts_service->orbit(NULL, moon_roots_id, moon_seed);
|
||||
return ZTS_ERR_OK;
|
||||
}
|
||||
|
||||
int zts_moon_deorbit(uint64_t moon_world_id)
|
||||
int zts_moon_deorbit(uint64_t moon_roots_id)
|
||||
{
|
||||
ACQUIRE_SERVICE(ZTS_ERR_SERVICE);
|
||||
zts_service->deorbit(NULL, moon_world_id);
|
||||
zts_service->deorbit(NULL, moon_roots_id);
|
||||
return ZTS_ERR_OK;
|
||||
}
|
||||
|
||||
@@ -623,7 +622,7 @@ int zts_stats_get_all(zts_stats_counter_t* dst)
|
||||
|
||||
#define lws lwip_stats
|
||||
|
||||
/* Here we summarize lwIP's statistics for simplicity at the expense of specificity */
|
||||
/* Summarize lwIP's statistics for simplicity at the expense of specificity */
|
||||
|
||||
// link
|
||||
dst->link_tx = lws.link.xmit;
|
||||
|
||||
@@ -20,9 +20,6 @@
|
||||
#ifndef ZTS_DEBUG_HPP
|
||||
#define ZTS_DEBUG_HPP
|
||||
|
||||
#if defined(__linux__) || defined(__APPLE__)
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#include <string.h>
|
||||
|
||||
#define ZT_COLOR true
|
||||
|
||||
@@ -19,11 +19,8 @@
|
||||
|
||||
#include "Events.hpp"
|
||||
|
||||
#include "Constants.hpp"
|
||||
#include "Node.hpp"
|
||||
#include "Mutex.hpp"
|
||||
#include "NodeService.hpp"
|
||||
#include "OSUtils.hpp"
|
||||
#include "ZeroTierSockets.h"
|
||||
#include "concurrentqueue.h"
|
||||
|
||||
#ifdef ZTS_ENABLE_JAVA
|
||||
@@ -49,6 +46,13 @@ void PythonDirectorCallbackClass::on_zerotier_event(zts_event_msg_t* msg)
|
||||
|
||||
namespace ZeroTier {
|
||||
|
||||
#ifdef ZTS_ENABLE_JAVA
|
||||
// References to JNI objects and VM kept for future callbacks
|
||||
JavaVM* jvm;
|
||||
jobject javaCbObjRef = NULL;
|
||||
jmethodID javaCbMethodId = NULL;
|
||||
#endif
|
||||
|
||||
extern NodeService* zts_service;
|
||||
|
||||
// Global state variable shared between Socket, Control, Event and
|
||||
@@ -175,7 +179,7 @@ void Events::sendToUser(zts_event_msg_t* msg)
|
||||
PyGILState_Release(state);
|
||||
#endif
|
||||
#ifdef ZTS_ENABLE_JAVA
|
||||
if (_userCallbackMethodRef) {
|
||||
if (javaCbMethodId) {
|
||||
JNIEnv* env;
|
||||
#if defined(__ANDROID__)
|
||||
jint rs = jvm->AttachCurrentThread(&env, NULL);
|
||||
@@ -185,15 +189,15 @@ void Events::sendToUser(zts_event_msg_t* msg)
|
||||
uint64_t arg = 0;
|
||||
uint64_t id = 0;
|
||||
if (ZTS_NODE_EVENT(msg->event_code)) {
|
||||
id = msg->node ? msg->node->address : 0;
|
||||
id = msg->node ? msg->node->node_id : 0;
|
||||
}
|
||||
if (ZTS_NETWORK_EVENT(msg->event_code)) {
|
||||
id = msg->network ? msg->network->nwid : 0;
|
||||
id = msg->network ? msg->network->net_id : 0;
|
||||
}
|
||||
if (ZTS_PEER_EVENT(msg->event_code)) {
|
||||
id = msg->peer ? msg->peer->address : 0;
|
||||
id = msg->peer ? msg->peer->peer_id : 0;
|
||||
}
|
||||
env->CallVoidMethod(objRef, _userCallbackMethodRef, id, msg->event_code);
|
||||
env->CallVoidMethod(javaCbObjRef, javaCbMethodId, id, msg->event_code);
|
||||
}
|
||||
#endif // ZTS_ENABLE_JAVA
|
||||
#ifdef ZTS_ENABLE_PINVOKE
|
||||
@@ -214,12 +218,19 @@ void Events::sendToUser(zts_event_msg_t* msg)
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef ZTS_ENABLE_JAVA
|
||||
void Events::setJavaCallback(jobject objRef, jmethodID methodId)
|
||||
{
|
||||
javaCbObjRef = objRef;
|
||||
javaCbMethodId = methodId;
|
||||
}
|
||||
#endif
|
||||
bool Events::hasCallback()
|
||||
{
|
||||
events_m.lock();
|
||||
bool retval = false;
|
||||
#ifdef ZTS_ENABLE_JAVA
|
||||
retval = (jvm && objRef && _userCallbackMethodRef);
|
||||
retval = (jvm && javaCbObjRef && javaCbMethodId);
|
||||
#else
|
||||
retval = _userEventCallback;
|
||||
#endif
|
||||
@@ -231,8 +242,8 @@ void Events::clrCallback()
|
||||
{
|
||||
events_m.lock();
|
||||
#ifdef ZTS_ENABLE_JAVA
|
||||
objRef = NULL;
|
||||
_userCallbackMethodRef = NULL;
|
||||
javaCbObjRef = NULL;
|
||||
javaCbMethodId = NULL;
|
||||
#else
|
||||
_userEventCallback = NULL;
|
||||
#endif
|
||||
|
||||
@@ -22,8 +22,6 @@
|
||||
|
||||
#include "ZeroTierSockets.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
#ifdef __WINDOWS__
|
||||
#include <BaseTsd.h>
|
||||
#endif
|
||||
@@ -130,6 +128,10 @@ class Events {
|
||||
*/
|
||||
void destroy(zts_event_msg_t* msg);
|
||||
|
||||
#ifdef ZTS_ENABLE_JAVA
|
||||
void setJavaCallback(jobject objRef, jmethodID methodId);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Return whether a callback method has been set
|
||||
*/
|
||||
|
||||
@@ -20,19 +20,12 @@
|
||||
#include "NodeService.hpp"
|
||||
|
||||
#include "../version.h"
|
||||
#include "BlockingQueue.hpp"
|
||||
#include "Constants.hpp"
|
||||
#include "Events.hpp"
|
||||
#include "InetAddress.hpp"
|
||||
#include "MAC.hpp"
|
||||
#include "Mutex.hpp"
|
||||
#include "Node.hpp"
|
||||
#include "OSUtils.hpp"
|
||||
#include "Phy.hpp"
|
||||
#include "Utilities.hpp"
|
||||
#include "Utils.hpp"
|
||||
#include "ZeroTierSockets.h"
|
||||
|
||||
#include <arpa/inet.h>
|
||||
#include <iostream>
|
||||
#include "VirtualTap.hpp"
|
||||
|
||||
#if defined(__WINDOWS__)
|
||||
#include <ShlObj.h>
|
||||
@@ -629,7 +622,7 @@ void NodeService::generateEventMsgs()
|
||||
{
|
||||
// Force the ordering of callback messages, these messages are
|
||||
// only useful if the node and stack are both up and running
|
||||
if (! _node->online() || ! _lwip_is_up()) {
|
||||
if (! _node->online() || ! zts_lwip_is_up()) {
|
||||
return;
|
||||
}
|
||||
// Generate messages to be dequeued by the callback message thread
|
||||
@@ -653,10 +646,10 @@ void NodeService::generateEventMsgs()
|
||||
sendEventToUser(ZTS_EVENT_NETWORK_REQ_CONFIG, (void*)prepare_network_details_msg(netState));
|
||||
break;
|
||||
case ZT_NETWORK_STATUS_OK:
|
||||
if (tap->hasIpv4Addr() && _lwip_is_netif_up(tap->netif4)) {
|
||||
if (tap->hasIpv4Addr() && zts_lwip_is_netif_up(tap->netif4)) {
|
||||
sendEventToUser(ZTS_EVENT_NETWORK_READY_IP4, (void*)prepare_network_details_msg(netState));
|
||||
}
|
||||
if (tap->hasIpv6Addr() && _lwip_is_netif_up(tap->netif6)) {
|
||||
if (tap->hasIpv6Addr() && zts_lwip_is_netif_up(tap->netif6)) {
|
||||
sendEventToUser(ZTS_EVENT_NETWORK_READY_IP6, (void*)prepare_network_details_msg(netState));
|
||||
}
|
||||
// In addition to the READY messages, send one OK message
|
||||
@@ -971,28 +964,28 @@ int NodeService::networkHasRoute(uint64_t net_id, unsigned int family)
|
||||
return false;
|
||||
}
|
||||
|
||||
int NodeService::orbit(void* tptr, uint64_t moon_world_id, uint64_t moon_seed)
|
||||
int NodeService::orbit(void* tptr, uint64_t moon_roots_id, uint64_t moon_seed)
|
||||
{
|
||||
if (! moon_world_id || ! moon_seed) {
|
||||
if (! moon_roots_id || ! moon_seed) {
|
||||
return ZTS_ERR_ARG;
|
||||
}
|
||||
Mutex::Lock _lr(_run_m);
|
||||
if (! _run) {
|
||||
return ZTS_ERR_SERVICE;
|
||||
}
|
||||
return _node->orbit(NULL, moon_world_id, moon_seed);
|
||||
return _node->orbit(NULL, moon_roots_id, moon_seed);
|
||||
}
|
||||
|
||||
int NodeService::deorbit(void* tptr, uint64_t moon_world_id)
|
||||
int NodeService::deorbit(void* tptr, uint64_t moon_roots_id)
|
||||
{
|
||||
if (! moon_world_id) {
|
||||
if (! moon_roots_id) {
|
||||
return ZTS_ERR_ARG;
|
||||
}
|
||||
Mutex::Lock _lr(_run_m);
|
||||
if (! _run) {
|
||||
return ZTS_ERR_SERVICE;
|
||||
}
|
||||
return _node->deorbit(NULL, moon_world_id);
|
||||
return _node->deorbit(NULL, moon_roots_id);
|
||||
}
|
||||
|
||||
uint64_t NodeService::getNodeId()
|
||||
@@ -1033,6 +1026,10 @@ int NodeService::getIdentity(char* keypair, unsigned int* len)
|
||||
if (_node) {
|
||||
_node->identity().toString(true, keypair);
|
||||
}
|
||||
else {
|
||||
return ZTS_ERR_GENERAL;
|
||||
}
|
||||
*len = strnlen(keypair, ZT_IDENTITY_STRING_BUFFER_LENGTH);
|
||||
return ZTS_ERR_OK;
|
||||
}
|
||||
|
||||
@@ -1082,9 +1079,9 @@ void NodeService::nodeStatePutFunction(
|
||||
break;
|
||||
case ZT_STATE_OBJECT_PLANET:
|
||||
sendEventToUser(ZTS_EVENT_STORE_PLANET, data, len);
|
||||
memcpy(_worldData, data, len);
|
||||
memcpy(_rootsData, data, len);
|
||||
if (_homePath.length() > 0 && _allowWorldCaching) {
|
||||
OSUtils::ztsnprintf(p, sizeof(p), "%s" ZT_PATH_SEPARATOR_S "world", _homePath.c_str());
|
||||
OSUtils::ztsnprintf(p, sizeof(p), "%s" ZT_PATH_SEPARATOR_S "roots", _homePath.c_str());
|
||||
}
|
||||
else {
|
||||
return;
|
||||
@@ -1198,10 +1195,10 @@ int NodeService::nodeStateGetFunction(
|
||||
break;
|
||||
case ZT_STATE_OBJECT_PLANET:
|
||||
if (_userDefinedWorld) {
|
||||
memcpy(data, _worldData, _worldDataLen);
|
||||
return _worldDataLen;
|
||||
memcpy(data, _rootsData, _rootsDataLen);
|
||||
return _rootsDataLen;
|
||||
}
|
||||
OSUtils::ztsnprintf(p, sizeof(p), "%s" ZT_PATH_SEPARATOR_S "world", _homePath.c_str());
|
||||
OSUtils::ztsnprintf(p, sizeof(p), "%s" ZT_PATH_SEPARATOR_S "roots", _homePath.c_str());
|
||||
break;
|
||||
case ZT_STATE_OBJECT_NETWORK_CONFIG:
|
||||
OSUtils::ztsnprintf(
|
||||
@@ -1545,9 +1542,9 @@ void NodeService::enableEvents()
|
||||
_events->enable();
|
||||
}
|
||||
|
||||
int NodeService::setWorld(const void* worldData, unsigned int len)
|
||||
int NodeService::setWorld(const void* rootsData, unsigned int len)
|
||||
{
|
||||
if (! worldData || len <= 0 || len > ZTS_STORE_DATA_LEN) {
|
||||
if (! rootsData || len <= 0 || len > ZTS_STORE_DATA_LEN) {
|
||||
return ZTS_ERR_ARG;
|
||||
}
|
||||
Mutex::Lock _lr(_run_m);
|
||||
@@ -1555,8 +1552,8 @@ int NodeService::setWorld(const void* worldData, unsigned int len)
|
||||
return ZTS_ERR_SERVICE;
|
||||
}
|
||||
Mutex::Lock _ls(_store_m);
|
||||
memcpy(_worldData, worldData, len);
|
||||
_worldDataLen = len;
|
||||
memcpy(_rootsData, rootsData, len);
|
||||
_rootsDataLen = len;
|
||||
_userDefinedWorld = true;
|
||||
return ZTS_ERR_OK;
|
||||
}
|
||||
@@ -1610,7 +1607,7 @@ int NodeService::getNetworkName(uint64_t net_id, char* dst, unsigned int len) co
|
||||
return ZTS_ERR_NO_RESULT;
|
||||
}
|
||||
auto netState = n->second;
|
||||
memcpy(dst, netState.config.name, sizeof(netState.config.name));
|
||||
strncpy(dst, netState.config.name, ZTS_MAX_NETWORK_SHORT_NAME_LENGTH);
|
||||
return ZTS_ERR_OK;
|
||||
}
|
||||
|
||||
|
||||
@@ -21,13 +21,10 @@
|
||||
#define ZTS_NODE_SERVICE_HPP
|
||||
|
||||
#include "Binder.hpp"
|
||||
#include "Constants.hpp"
|
||||
#include "Events.hpp"
|
||||
#include "InetAddress.hpp"
|
||||
#include "Mutex.hpp"
|
||||
#include "Node.hpp"
|
||||
#include "Phy.hpp"
|
||||
#include "PortMapper.hpp"
|
||||
#include "VirtualTap.hpp"
|
||||
#include "ZeroTierSockets.h"
|
||||
|
||||
#include <string>
|
||||
@@ -50,6 +47,11 @@
|
||||
|
||||
namespace ZeroTier {
|
||||
|
||||
class InetAddress;
|
||||
class VirtualTap;
|
||||
class MAC;
|
||||
class Events;
|
||||
|
||||
/**
|
||||
* ZeroTier node service
|
||||
*/
|
||||
@@ -205,8 +207,8 @@ class NodeService {
|
||||
char _secretIdStr[ZT_IDENTITY_STRING_BUFFER_LENGTH] = { 0 };
|
||||
|
||||
bool _userDefinedWorld;
|
||||
char _worldData[ZTS_STORE_DATA_LEN] = { 0 };
|
||||
int _worldDataLen = 0;
|
||||
char _rootsData[ZTS_STORE_DATA_LEN] = { 0 };
|
||||
int _rootsDataLen = 0;
|
||||
|
||||
/** Whether the node has successfully come online */
|
||||
bool _nodeIsOnline;
|
||||
@@ -373,7 +375,7 @@ class NodeService {
|
||||
|
||||
void enableEvents();
|
||||
|
||||
/** Set the world definition */
|
||||
/** Set the roots definition */
|
||||
int setWorld(const void* data, unsigned int len);
|
||||
|
||||
/** Add Interface prefix to blacklist (prevents ZeroTier from using that interface) */
|
||||
@@ -394,7 +396,7 @@ class NodeService {
|
||||
/** Allow ZeroTier to write identities to storage */
|
||||
int allowIdentityCaching(unsigned int allowed);
|
||||
|
||||
/** Allow ZeroTier to cache world definitions to storage */
|
||||
/** Allow ZeroTier to cache root definitions to storage */
|
||||
int allowWorldCaching(unsigned int allowed);
|
||||
|
||||
/** Return whether broadcast is enabled on the given network */
|
||||
|
||||
@@ -26,14 +26,8 @@
|
||||
|
||||
#ifdef ZTS_ENABLE_CUSTOM_SIGNAL_HANDLERS
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
void _signal_handler(int signal);
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
void _install_signal_handlers();
|
||||
|
||||
#endif // ZTS_ENABLE_CUSTOM_SIGNAL_HANDLERS
|
||||
|
||||
128
src/Sockets.cpp
128
src/Sockets.cpp
@@ -20,17 +20,11 @@
|
||||
#include "lwip/sockets.h"
|
||||
|
||||
#include "Events.hpp"
|
||||
#include "Utilities.hpp"
|
||||
#include "ZeroTierSockets.h"
|
||||
#include "lwip/def.h"
|
||||
#include "lwip/dns.h"
|
||||
#include "lwip/inet.h"
|
||||
#include "lwip/ip_addr.h"
|
||||
#include "lwip/netdb.h"
|
||||
|
||||
// errno-like reporting variable
|
||||
int zts_errno;
|
||||
extern int last_state_check;
|
||||
|
||||
namespace ZeroTier {
|
||||
|
||||
@@ -61,7 +55,7 @@ int zts_connect(int fd, const struct zts_sockaddr* addr, zts_socklen_t addrlen)
|
||||
return lwip_connect(fd, (sockaddr*)addr, addrlen);
|
||||
}
|
||||
|
||||
int zts_simple_connect(int fd, const char* ipstr, int port, int timeout_ms)
|
||||
int zts_simple_connect(int fd, const char* ipstr, unsigned short port, int timeout_ms)
|
||||
{
|
||||
if (! transport_ok()) {
|
||||
return ZTS_ERR_SERVICE;
|
||||
@@ -114,20 +108,22 @@ int zts_bind(int fd, const struct zts_sockaddr* addr, zts_socklen_t addrlen)
|
||||
return lwip_bind(fd, (sockaddr*)addr, addrlen);
|
||||
}
|
||||
|
||||
int zts_simple_bind(int fd, const char* ipstr, int port)
|
||||
int zts_simple_bind(int fd, const char* ipstr, unsigned short port)
|
||||
{
|
||||
if (! transport_ok()) {
|
||||
return ZTS_ERR_SERVICE;
|
||||
}
|
||||
|
||||
zts_socklen_t addrlen = 0;
|
||||
struct zts_sockaddr_storage ss;
|
||||
struct zts_sockaddr* sa = NULL;
|
||||
|
||||
addrlen = sizeof(ss);
|
||||
zts_util_ipstr_to_saddr(ipstr, port, (struct zts_sockaddr*)&ss, &addrlen);
|
||||
int err = ZTS_ERR_OK;
|
||||
if ((err = zts_util_ipstr_to_saddr(ipstr, port, (struct zts_sockaddr*)&ss, &addrlen)) != ZTS_ERR_OK) {
|
||||
printf("ERRRRRRR=%d\n", err);
|
||||
return err;
|
||||
}
|
||||
sa = (struct zts_sockaddr*)&ss;
|
||||
|
||||
return zts_bind(fd, sa, addrlen);
|
||||
}
|
||||
|
||||
@@ -147,7 +143,7 @@ int zts_accept(int fd, struct zts_sockaddr* addr, zts_socklen_t* addrlen)
|
||||
return lwip_accept(fd, (sockaddr*)addr, (socklen_t*)addrlen);
|
||||
}
|
||||
|
||||
int zts_simple_accept(int fd, char* remote_addr, int len, int* port)
|
||||
int zts_simple_accept(int fd, char* remote_addr, int len, unsigned short* port)
|
||||
{
|
||||
if (! transport_ok()) {
|
||||
return ZTS_ERR_SERVICE;
|
||||
@@ -159,21 +155,50 @@ int zts_simple_accept(int fd, char* remote_addr, int len, int* port)
|
||||
zts_socklen_t addrlen = sizeof(ss);
|
||||
|
||||
int acc_fd = zts_accept(fd, (zts_sockaddr*)&ss, (zts_socklen_t*)&addrlen);
|
||||
struct zts_sockaddr* sa = (struct zts_sockaddr*)&ss;
|
||||
if (sa->sa_family == ZTS_AF_INET) {
|
||||
struct zts_sockaddr_in* in4 = (struct zts_sockaddr_in*)sa;
|
||||
zts_inet_ntop(ZTS_AF_INET, &(in4->sin_addr), remote_addr, ZTS_INET_ADDRSTRLEN);
|
||||
*port = ntohs(in4->sin_port);
|
||||
}
|
||||
if (sa->sa_family == ZTS_AF_INET6) {
|
||||
struct zts_sockaddr_in6* in6 = (struct zts_sockaddr_in6*)sa;
|
||||
zts_inet_ntop(ZTS_AF_INET6, &(in6->sin6_addr), remote_addr, ZTS_INET6_ADDRSTRLEN);
|
||||
*port = ntohs(in6->sin6_port);
|
||||
int err = ZTS_ERR_OK;
|
||||
if ((err = zts_util_ntop((struct zts_sockaddr*)&ss, addrlen, remote_addr, len, port)) < ZTS_ERR_OK) {
|
||||
return err;
|
||||
}
|
||||
return acc_fd;
|
||||
}
|
||||
|
||||
int zts_simple_tcp_client(const char* remote_ipstr, int remote_port)
|
||||
int zts_simple_getpeername(int fd, char* remote_addr_str, int len, unsigned short* port)
|
||||
{
|
||||
if (! transport_ok()) {
|
||||
return ZTS_ERR_SERVICE;
|
||||
}
|
||||
if (len != ZTS_INET6_ADDRSTRLEN) {
|
||||
return ZTS_ERR_ARG;
|
||||
}
|
||||
struct zts_sockaddr_storage ss;
|
||||
struct zts_sockaddr* sa = (struct zts_sockaddr*)&ss;
|
||||
int err = ZTS_ERR_OK;
|
||||
zts_socklen_t addrlen = sizeof(ss);
|
||||
if ((err = zts_getpeername(fd, sa, &addrlen)) < 0) {
|
||||
return err;
|
||||
}
|
||||
return zts_util_ntop(sa, addrlen, remote_addr_str, len, port);
|
||||
}
|
||||
|
||||
int zts_simple_getsockname(int fd, char* local_addr_str, int len, unsigned short* port)
|
||||
{
|
||||
if (! transport_ok()) {
|
||||
return ZTS_ERR_SERVICE;
|
||||
}
|
||||
if (len != ZTS_INET6_ADDRSTRLEN) {
|
||||
return ZTS_ERR_ARG;
|
||||
}
|
||||
struct zts_sockaddr_storage ss;
|
||||
struct zts_sockaddr* sa = (struct zts_sockaddr*)&ss;
|
||||
int err = ZTS_ERR_OK;
|
||||
zts_socklen_t addrlen = sizeof(ss);
|
||||
if ((err = zts_getsockname(fd, sa, &addrlen)) < 0) {
|
||||
return err;
|
||||
}
|
||||
return zts_util_ntop(sa, addrlen, local_addr_str, len, port);
|
||||
}
|
||||
|
||||
int zts_simple_tcp_client(const char* remote_ipstr, unsigned short remote_port)
|
||||
{
|
||||
int fd, family = zts_util_get_ip_family(remote_ipstr);
|
||||
if ((fd = zts_socket(family, ZTS_SOCK_STREAM, 0)) < 0) {
|
||||
@@ -187,7 +212,12 @@ int zts_simple_tcp_client(const char* remote_ipstr, int remote_port)
|
||||
return fd;
|
||||
}
|
||||
|
||||
int zts_simple_tcp_server(const char* local_ipstr, int local_port, char* remote_ipstr, int len, int* remote_port)
|
||||
int zts_simple_tcp_server(
|
||||
const char* local_ipstr,
|
||||
unsigned short local_port,
|
||||
char* remote_ipstr,
|
||||
int len,
|
||||
unsigned short* remote_port)
|
||||
{
|
||||
int listen_fd, family = zts_util_get_ip_family(local_ipstr);
|
||||
if ((listen_fd = zts_socket(family, ZTS_SOCK_STREAM, 0)) < 0) {
|
||||
@@ -208,7 +238,7 @@ int zts_simple_tcp_server(const char* local_ipstr, int local_port, char* remote_
|
||||
return acc_fd;
|
||||
}
|
||||
|
||||
int zts_simple_udp_server(const char* local_ipstr, int local_port)
|
||||
int zts_simple_udp_server(const char* local_ipstr, unsigned short local_port)
|
||||
{
|
||||
int fd, family = zts_util_get_ip_family(local_ipstr);
|
||||
if ((fd = zts_socket(family, ZTS_SOCK_DGRAM, 0)) < 0) {
|
||||
@@ -489,7 +519,7 @@ int zts_inet_pton(int family, const char* src, void* dst)
|
||||
|
||||
int zts_util_ipstr_to_saddr(
|
||||
const char* src_ipstr,
|
||||
unsigned int port,
|
||||
unsigned short port,
|
||||
struct zts_sockaddr* dest_addr,
|
||||
zts_socklen_t* addrlen)
|
||||
{
|
||||
@@ -524,18 +554,6 @@ int zts_util_ipstr_to_saddr(
|
||||
return ZTS_ERR_ARG;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------//
|
||||
// Convenience functions //
|
||||
//----------------------------------------------------------------------------//
|
||||
|
||||
/**
|
||||
* Helper functions that simplify API wrapper generation and usage in other
|
||||
* non-C-like languages. Use simple integer types instead of bit flags,
|
||||
* limit the number of operations each function performs, prevent the user
|
||||
* from needing to manipulate the content of structures in a non-native
|
||||
* language.
|
||||
*/
|
||||
|
||||
int zts_simple_set_no_delay(int fd, int enabled)
|
||||
{
|
||||
if (! transport_ok()) {
|
||||
@@ -605,6 +623,19 @@ int zts_simple_get_linger_value(int fd)
|
||||
return linger.l_linger;
|
||||
}
|
||||
|
||||
int zts_simple_get_pending_data_size(int fd)
|
||||
{
|
||||
if (! transport_ok()) {
|
||||
return ZTS_ERR_SERVICE;
|
||||
}
|
||||
int bytes_available = 0;
|
||||
int err = ZTS_ERR_OK;
|
||||
if ((err = zts_ioctl(fd, ZTS_FIONREAD, &bytes_available)) < 0) {
|
||||
return err;
|
||||
}
|
||||
return bytes_available;
|
||||
}
|
||||
|
||||
int zts_simple_set_reuse_addr(int fd, int enabled)
|
||||
{
|
||||
if (! transport_ok()) {
|
||||
@@ -812,6 +843,27 @@ int zts_simple_get_keepalive(int fd)
|
||||
return optval != 0;
|
||||
}
|
||||
|
||||
int zts_util_ntop(struct zts_sockaddr* addr, zts_socklen_t addrlen, char* dst_str, int len, unsigned short* port)
|
||||
{
|
||||
if (! addr || addrlen < sizeof(struct zts_sockaddr_in) || addrlen > sizeof(struct zts_sockaddr_storage) || ! dst_str
|
||||
|| len != ZTS_INET6_ADDRSTRLEN) {
|
||||
return ZTS_ERR_ARG;
|
||||
}
|
||||
if (addr->sa_family == ZTS_AF_INET) {
|
||||
struct zts_sockaddr_in* in4 = (struct zts_sockaddr_in*)addr;
|
||||
zts_inet_ntop(ZTS_AF_INET, &(in4->sin_addr), dst_str, len);
|
||||
*port = ntohs(in4->sin_port);
|
||||
return ZTS_ERR_OK;
|
||||
}
|
||||
if (addr->sa_family == ZTS_AF_INET6) {
|
||||
struct zts_sockaddr_in6* in6 = (struct zts_sockaddr_in6*)addr;
|
||||
zts_inet_ntop(ZTS_AF_INET6, &(in6->sin6_addr), dst_str, len);
|
||||
*port = ntohs(in6->sin6_port);
|
||||
return ZTS_ERR_OK;
|
||||
}
|
||||
return ZTS_ERR_ARG;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -15,20 +15,9 @@
|
||||
|
||||
#include "ZeroTierSockets.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <netinet/in.h>
|
||||
#include <node/C25519.hpp>
|
||||
#include <node/Constants.hpp>
|
||||
#include <node/Identity.hpp>
|
||||
#include <node/InetAddress.hpp>
|
||||
#include <node/World.hpp>
|
||||
#include <osdep/OSUtils.hpp>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#ifdef __WINDOWS__
|
||||
#include <windows.h>
|
||||
@@ -75,18 +64,18 @@ void zts_util_delay(unsigned long milliseconds)
|
||||
#endif
|
||||
}
|
||||
|
||||
int zts_util_world_new(
|
||||
char* world_out,
|
||||
unsigned int* world_len,
|
||||
int zts_util_sign_root_set(
|
||||
char* roots_out,
|
||||
unsigned int* roots_len,
|
||||
char* prev_key,
|
||||
unsigned int* prev_key_len,
|
||||
char* curr_key,
|
||||
unsigned int* curr_key_len,
|
||||
uint64_t id,
|
||||
uint64_t ts,
|
||||
zts_world_t* world_spec)
|
||||
zts_root_set_t* roots_spec)
|
||||
{
|
||||
if (! world_spec || ! prev_key || ! curr_key || ! prev_key_len || ! curr_key_len) {
|
||||
if (! roots_spec || ! prev_key || ! curr_key || ! prev_key_len || ! curr_key_len) {
|
||||
return ZTS_ERR_ARG;
|
||||
}
|
||||
// Generate signing keys
|
||||
@@ -110,23 +99,23 @@ int zts_util_world_new(
|
||||
memcpy(currentKP.pub.data, current.data(), ZT_C25519_PUBLIC_KEY_LEN);
|
||||
memcpy(currentKP.priv.data, current.data() + ZT_C25519_PUBLIC_KEY_LEN, ZT_C25519_PRIVATE_KEY_LEN);
|
||||
|
||||
// Set up world definition
|
||||
// Set up roots definition
|
||||
std::vector<World::Root> roots;
|
||||
for (int i = 0; i < ZTS_MAX_NUM_ROOTS; i++) {
|
||||
if (! world_spec->public_id_str[i]) {
|
||||
if (! roots_spec->public_id_str[i]) {
|
||||
break;
|
||||
}
|
||||
if (strlen(world_spec->public_id_str[i])) {
|
||||
// printf("id = %s\n", world_spec->public_id_str[i]);
|
||||
if (strnlen(roots_spec->public_id_str[i], ZT_IDENTITY_STRING_BUFFER_LENGTH)) {
|
||||
// printf("id = %s\n", roots_spec->public_id_str[i]);
|
||||
roots.push_back(World::Root());
|
||||
roots.back().identity = Identity(world_spec->public_id_str[i]);
|
||||
roots.back().identity = Identity(roots_spec->public_id_str[i]);
|
||||
for (int j = 0; j < ZTS_MAX_ENDPOINTS_PER_ROOT; j++) {
|
||||
if (! world_spec->endpoint_ip_str[i][j]) {
|
||||
if (! roots_spec->endpoint_ip_str[i][j]) {
|
||||
break;
|
||||
}
|
||||
if (strlen(world_spec->endpoint_ip_str[i][j])) {
|
||||
roots.back().stableEndpoints.push_back(InetAddress(world_spec->endpoint_ip_str[i][j]));
|
||||
// printf(" ep = %s\n", world_spec->endpoint_ip_str[i][j]);
|
||||
if (strnlen(roots_spec->endpoint_ip_str[i][j], ZTS_MAX_ENDPOINT_STR_LEN)) {
|
||||
roots.back().stableEndpoints.push_back(InetAddress(roots_spec->endpoint_ip_str[i][j]));
|
||||
// printf(" ep = %s\n", roots_spec->endpoint_ip_str[i][j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -144,8 +133,8 @@ int zts_util_world_new(
|
||||
return ZTS_ERR_GENERAL;
|
||||
}
|
||||
// Write output
|
||||
memcpy(world_out, (char*)outtmp.data(), outtmp.size());
|
||||
*world_len = outtmp.size();
|
||||
memcpy(roots_out, (char*)outtmp.data(), outtmp.size());
|
||||
*roots_len = outtmp.size();
|
||||
memcpy(prev_key, previous.data(), previous.length());
|
||||
*prev_key_len = ZT_C25519_PRIVATE_KEY_LEN + ZT_C25519_PUBLIC_KEY_LEN;
|
||||
memcpy(curr_key, current.data(), current.length());
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
#ifndef ZTS_UTILITIES_HPP
|
||||
#define ZTS_UTILITIES_HPP
|
||||
|
||||
#include "ZeroTierSockets.h"
|
||||
struct zts_sockaddr_storage;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
||||
@@ -17,7 +17,6 @@
|
||||
* Virtual Ethernet tap device and combined network stack driver
|
||||
*/
|
||||
|
||||
#include "Constants.hpp"
|
||||
#include "InetAddress.hpp"
|
||||
#include "MAC.hpp"
|
||||
#include "MulticastGroup.hpp"
|
||||
@@ -36,7 +35,6 @@
|
||||
|
||||
#include "Events.hpp"
|
||||
#include "VirtualTap.hpp"
|
||||
#include "ZeroTierSockets.h"
|
||||
|
||||
#if defined(__WINDOWS__)
|
||||
#include "Synchapi.h"
|
||||
@@ -45,7 +43,7 @@
|
||||
#endif
|
||||
|
||||
#define ZTS_TAP_THREAD_POLLING_INTERVAL 50
|
||||
#define LWIP_DRIVER_LOOP_INTERVAL 250
|
||||
#define LWIP_DRIVER_LOOP_INTERVAL 100
|
||||
|
||||
namespace ZeroTier {
|
||||
|
||||
@@ -81,7 +79,6 @@ VirtualTap::VirtualTap(
|
||||
, _mac(mac)
|
||||
, _mtu(mtu)
|
||||
, _net_id(net_id)
|
||||
, _unixListenSocket((PhySocket*)0)
|
||||
, _phy(this, false, true)
|
||||
{
|
||||
OSUtils::ztsnprintf(vtap_full_name, VTAP_NAME_LEN, "libzt-vtap-%llx", _net_id);
|
||||
@@ -99,9 +96,9 @@ VirtualTap::~VirtualTap()
|
||||
::write(_shutdownSignalPipe[1], "\0", 1);
|
||||
#endif
|
||||
_phy.whack();
|
||||
_lwip_remove_netif(netif4);
|
||||
zts_lwip_remove_netif(netif4);
|
||||
netif4 = NULL;
|
||||
_lwip_remove_netif(netif6);
|
||||
zts_lwip_remove_netif(netif6);
|
||||
netif6 = NULL;
|
||||
Thread::join(_thread);
|
||||
#ifndef __WINDOWS__
|
||||
@@ -181,7 +178,7 @@ bool VirtualTap::addIp(const InetAddress& ip)
|
||||
return false;
|
||||
}
|
||||
if (std::find(_ips.begin(), _ips.end(), ip) == _ips.end()) {
|
||||
_lwip_init_interface((void*)this, ip);
|
||||
zts_lwip_init_interface((void*)this, ip);
|
||||
_ips.push_back(ip);
|
||||
std::sort(_ips.begin(), _ips.end());
|
||||
}
|
||||
@@ -193,7 +190,7 @@ bool VirtualTap::removeIp(const InetAddress& ip)
|
||||
Mutex::Lock _l(_ips_m);
|
||||
if (std::find(_ips.begin(), _ips.end(), ip) != _ips.end()) {
|
||||
std::vector<InetAddress>::iterator i(std::find(_ips.begin(), _ips.end(), ip));
|
||||
_lwip_remove_address_from_netif((void*)this, ip);
|
||||
zts_lwip_remove_address_from_netif((void*)this, ip);
|
||||
_ips.erase(i);
|
||||
}
|
||||
return true;
|
||||
@@ -208,7 +205,7 @@ std::vector<InetAddress> VirtualTap::ips() const
|
||||
void VirtualTap::put(const MAC& from, const MAC& to, unsigned int etherType, const void* data, unsigned int len)
|
||||
{
|
||||
if (len && _enabled) {
|
||||
_lwip_eth_rx(this, from, to, etherType, data, len);
|
||||
zts_lwip_eth_rx(this, from, to, etherType, data, len);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -271,46 +268,6 @@ void VirtualTap::threadMain() throw()
|
||||
}
|
||||
}
|
||||
|
||||
void VirtualTap::phyOnDatagram(
|
||||
PhySocket* sock,
|
||||
void** uptr,
|
||||
const struct sockaddr* local_address,
|
||||
const struct sockaddr* from,
|
||||
void* data,
|
||||
unsigned long len)
|
||||
{
|
||||
// Intentionally empty
|
||||
}
|
||||
|
||||
void VirtualTap::phyOnTcpConnect(PhySocket* sock, void** uptr, bool success)
|
||||
{
|
||||
}
|
||||
|
||||
void VirtualTap::phyOnTcpAccept(
|
||||
PhySocket* sockL,
|
||||
PhySocket* sockN,
|
||||
void** uptrL,
|
||||
void** uptrN,
|
||||
const struct sockaddr* from)
|
||||
{
|
||||
}
|
||||
|
||||
void VirtualTap::phyOnTcpClose(PhySocket* sock, void** uptr)
|
||||
{
|
||||
}
|
||||
|
||||
void VirtualTap::phyOnTcpData(PhySocket* sock, void** uptr, void* data, unsigned long len)
|
||||
{
|
||||
}
|
||||
|
||||
void VirtualTap::phyOnTcpWritable(PhySocket* sock, void** uptr)
|
||||
{
|
||||
}
|
||||
|
||||
void VirtualTap::phyOnUnixClose(PhySocket* sock, void** uptr)
|
||||
{
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------//
|
||||
// Netif driver code for lwIP network stack //
|
||||
//----------------------------------------------------------------------------//
|
||||
@@ -322,20 +279,20 @@ bool _has_started = false;
|
||||
int netifCount = 0;
|
||||
|
||||
// Lock to guard access to network stack state changes
|
||||
Mutex stackLock;
|
||||
Mutex lwip_state_m;
|
||||
|
||||
// Callback for when the TCPIP thread has been successfully started
|
||||
static void _tcpip_init_done(void* arg)
|
||||
static void zts_tcpip_init_done(void* arg)
|
||||
{
|
||||
sys_sem_t* sem;
|
||||
sem = (sys_sem_t*)arg;
|
||||
zts_events->setState(ZTS_STATE_STACK_RUNNING);
|
||||
_has_started = true;
|
||||
zts_events->enqueue(ZTS_EVENT_STACK_UP, NULL);
|
||||
// zts_events->enqueue(ZTS_EVENT_STACK_UP, NULL);
|
||||
sys_sem_signal(sem);
|
||||
}
|
||||
|
||||
static void _main_lwip_driver_loop(void* arg)
|
||||
static void zts_main_lwip_driver_loop(void* arg)
|
||||
{
|
||||
#if defined(__linux__)
|
||||
pthread_setname_np(pthread_self(), ZTS_LWIP_THREAD_NAME);
|
||||
@@ -348,7 +305,7 @@ static void _main_lwip_driver_loop(void* arg)
|
||||
if (sys_sem_new(&sem, 0) != ERR_OK) {
|
||||
// DEBUG_ERROR("failed to create semaphore");
|
||||
}
|
||||
tcpip_init(_tcpip_init_done, &sem);
|
||||
tcpip_init(zts_tcpip_init_done, &sem);
|
||||
sys_sem_wait(&sem);
|
||||
// Main loop
|
||||
while (zts_events->getState(ZTS_STATE_STACK_RUNNING)) {
|
||||
@@ -358,33 +315,38 @@ static void _main_lwip_driver_loop(void* arg)
|
||||
zts_events->enqueue(ZTS_EVENT_STACK_DOWN, NULL);
|
||||
}
|
||||
|
||||
bool _lwip_is_up()
|
||||
bool zts_lwip_is_up()
|
||||
{
|
||||
Mutex::Lock _l(stackLock);
|
||||
Mutex::Lock _l(lwip_state_m);
|
||||
return zts_events->getState(ZTS_STATE_STACK_RUNNING);
|
||||
}
|
||||
|
||||
void _lwip_driver_init()
|
||||
void zts_lwip_driver_init()
|
||||
{
|
||||
if (_lwip_is_up()) {
|
||||
if (zts_lwip_is_up()) {
|
||||
return;
|
||||
}
|
||||
if (_has_exited) {
|
||||
return;
|
||||
}
|
||||
Mutex::Lock _l(stackLock);
|
||||
Mutex::Lock _l(lwip_state_m);
|
||||
#if defined(__WINDOWS__)
|
||||
sys_init(); // Required for win32 init of critical sections
|
||||
#endif
|
||||
sys_thread_new(ZTS_LWIP_THREAD_NAME, _main_lwip_driver_loop, NULL, DEFAULT_THREAD_STACKSIZE, DEFAULT_THREAD_PRIO);
|
||||
sys_thread_new(
|
||||
ZTS_LWIP_THREAD_NAME,
|
||||
zts_main_lwip_driver_loop,
|
||||
NULL,
|
||||
DEFAULT_THREAD_STACKSIZE,
|
||||
DEFAULT_THREAD_PRIO);
|
||||
}
|
||||
|
||||
void _lwip_driver_shutdown()
|
||||
void zts_lwip_driver_shutdown()
|
||||
{
|
||||
if (_has_exited) {
|
||||
return;
|
||||
}
|
||||
Mutex::Lock _l(stackLock);
|
||||
Mutex::Lock _l(lwip_state_m);
|
||||
// Set flag to stop sending frames into the core
|
||||
zts_events->clrState(ZTS_STATE_STACK_RUNNING);
|
||||
// Wait until the main lwIP thread has exited
|
||||
@@ -395,7 +357,7 @@ void _lwip_driver_shutdown()
|
||||
}
|
||||
}
|
||||
|
||||
void _lwip_remove_netif(void* netif)
|
||||
void zts_lwip_remove_netif(void* netif)
|
||||
{
|
||||
if (! netif) {
|
||||
return;
|
||||
@@ -408,7 +370,7 @@ void _lwip_remove_netif(void* netif)
|
||||
UNLOCK_TCPIP_CORE();
|
||||
}
|
||||
|
||||
err_t _lwip_eth_tx(struct netif* n, struct pbuf* p)
|
||||
signed char zts_lwip_eth_tx(struct netif* n, struct pbuf* p)
|
||||
{
|
||||
if (! n) {
|
||||
return ERR_IF;
|
||||
@@ -441,7 +403,7 @@ err_t _lwip_eth_tx(struct netif* n, struct pbuf* p)
|
||||
return ERR_OK;
|
||||
}
|
||||
|
||||
void _lwip_eth_rx(
|
||||
void zts_lwip_eth_rx(
|
||||
VirtualTap* tap,
|
||||
const MAC& from,
|
||||
const MAC& to,
|
||||
@@ -508,7 +470,7 @@ void _lwip_eth_rx(
|
||||
}
|
||||
}
|
||||
|
||||
bool _lwip_is_netif_up(void* n)
|
||||
bool zts_lwip_is_netif_up(void* n)
|
||||
{
|
||||
if (! n) {
|
||||
return false;
|
||||
@@ -519,7 +481,7 @@ bool _lwip_is_netif_up(void* n)
|
||||
return result;
|
||||
}
|
||||
|
||||
static err_t _netif_init4(struct netif* n)
|
||||
static err_t zts_netif_init4(struct netif* n)
|
||||
{
|
||||
if (! n || ! n->state) {
|
||||
return ERR_IF;
|
||||
@@ -529,7 +491,7 @@ static err_t _netif_init4(struct netif* n)
|
||||
n->hwaddr_len = 6;
|
||||
n->name[0] = '4';
|
||||
n->name[1] = 'a' + netifCount;
|
||||
n->linkoutput = _lwip_eth_tx;
|
||||
n->linkoutput = zts_lwip_eth_tx;
|
||||
n->output = etharp_output;
|
||||
n->mtu = std::min(LWIP_MTU, (int)tap->_mtu);
|
||||
n->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_ETHERNET | NETIF_FLAG_IGMP | NETIF_FLAG_MLD6
|
||||
@@ -539,7 +501,7 @@ static err_t _netif_init4(struct netif* n)
|
||||
return ERR_OK;
|
||||
}
|
||||
|
||||
static err_t _netif_init6(struct netif* n)
|
||||
static err_t zts_netif_init6(struct netif* n)
|
||||
{
|
||||
if (! n || ! n->state) {
|
||||
return ERR_IF;
|
||||
@@ -551,7 +513,7 @@ static err_t _netif_init6(struct netif* n)
|
||||
n->hwaddr_len = 6;
|
||||
n->name[0] = '6';
|
||||
n->name[1] = 'a' + netifCount;
|
||||
n->linkoutput = _lwip_eth_tx;
|
||||
n->linkoutput = zts_lwip_eth_tx;
|
||||
n->output_ip6 = ethip6_output;
|
||||
n->mtu = std::min(LWIP_MTU, (int)tap->_mtu);
|
||||
n->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_ETHERNET | NETIF_FLAG_IGMP | NETIF_FLAG_MLD6
|
||||
@@ -559,7 +521,7 @@ static err_t _netif_init6(struct netif* n)
|
||||
return ERR_OK;
|
||||
}
|
||||
|
||||
void _lwip_init_interface(void* tapref, const InetAddress& ip)
|
||||
void zts_lwip_init_interface(void* tapref, const InetAddress& ip)
|
||||
{
|
||||
char macbuf[ZTS_MAC_ADDRSTRLEN] = { 0 };
|
||||
|
||||
@@ -582,7 +544,7 @@ void _lwip_init_interface(void* tapref, const InetAddress& ip)
|
||||
ip4.addr = *((u32_t*)ip.rawIpData());
|
||||
netmask.addr = *((u32_t*)ip.netmask().rawIpData());
|
||||
LOCK_TCPIP_CORE();
|
||||
netif_add(n, &ip4, &netmask, &gw, (void*)vtap, _netif_init4, tcpip_input);
|
||||
netif_add(n, &ip4, &netmask, &gw, (void*)vtap, zts_netif_init4, tcpip_input);
|
||||
vtap->netif4 = (void*)n;
|
||||
UNLOCK_TCPIP_CORE();
|
||||
snprintf(
|
||||
@@ -610,7 +572,7 @@ void _lwip_init_interface(void* tapref, const InetAddress& ip)
|
||||
LOCK_TCPIP_CORE();
|
||||
if (isNewNetif) {
|
||||
vtap->netif6 = (void*)n;
|
||||
netif_add(n, NULL, NULL, NULL, (void*)vtap, _netif_init6, ethernet_input);
|
||||
netif_add(n, NULL, NULL, NULL, (void*)vtap, zts_netif_init6, ethernet_input);
|
||||
n->ip6_autoconfig_enabled = 1;
|
||||
vtap->_mac.copyTo(n->hwaddr, n->hwaddr_len);
|
||||
netif_create_ip6_linklocal_address(n, 1);
|
||||
@@ -634,7 +596,7 @@ void _lwip_init_interface(void* tapref, const InetAddress& ip)
|
||||
}
|
||||
}
|
||||
|
||||
void _lwip_remove_address_from_netif(void* tapref, const InetAddress& ip)
|
||||
void zts_lwip_remove_address_from_netif(void* tapref, const InetAddress& ip)
|
||||
{
|
||||
if (! tapref) {
|
||||
return;
|
||||
@@ -656,7 +618,7 @@ void _lwip_remove_address_from_netif(void* tapref, const InetAddress& ip)
|
||||
if (! n) {
|
||||
return;
|
||||
}
|
||||
_lwip_remove_netif(n);
|
||||
zts_lwip_remove_netif(n);
|
||||
}
|
||||
|
||||
} // namespace ZeroTier
|
||||
|
||||
@@ -20,8 +20,6 @@
|
||||
#ifndef ZTS_VIRTUAL_TAP_HPP
|
||||
#define ZTS_VIRTUAL_TAP_HPP
|
||||
|
||||
#include "lwip/err.h"
|
||||
|
||||
#define ZTS_LWIP_THREAD_NAME "ZTNetworkStackThread"
|
||||
#define VTAP_NAME_LEN 64
|
||||
|
||||
@@ -32,9 +30,11 @@
|
||||
|
||||
namespace ZeroTier {
|
||||
|
||||
/* Forward declarations */
|
||||
class Mutex;
|
||||
class MAC;
|
||||
class MulticastGroup;
|
||||
class Events;
|
||||
struct InetAddress;
|
||||
|
||||
/**
|
||||
@@ -162,7 +162,6 @@ class VirtualTap {
|
||||
MAC _mac;
|
||||
unsigned int _mtu;
|
||||
uint64_t _net_id;
|
||||
PhySocket* _unixListenSocket;
|
||||
Phy<VirtualTap*> _phy;
|
||||
|
||||
Thread _thread;
|
||||
@@ -172,23 +171,18 @@ class VirtualTap {
|
||||
std::vector<MulticastGroup> _multicastGroups;
|
||||
Mutex _multicastGroups_m;
|
||||
|
||||
//----------------------------------------------------------------------------//
|
||||
// Not used in this implementation //
|
||||
//----------------------------------------------------------------------------//
|
||||
|
||||
void phyOnDatagram(
|
||||
PhySocket* sock,
|
||||
void** uptr,
|
||||
const struct sockaddr* local_address,
|
||||
const struct sockaddr* from,
|
||||
void* data,
|
||||
unsigned long len);
|
||||
void phyOnTcpConnect(PhySocket* sock, void** uptr, bool success);
|
||||
void phyOnTcpAccept(PhySocket* sockL, PhySocket* sockN, void** uptrL, void** uptrN, const struct sockaddr* from);
|
||||
void phyOnTcpClose(PhySocket* sock, void** uptr);
|
||||
void phyOnTcpData(PhySocket* sock, void** uptr, void* data, unsigned long len);
|
||||
void phyOnTcpWritable(PhySocket* sock, void** uptr);
|
||||
void phyOnUnixClose(PhySocket* sock, void** uptr);
|
||||
void phyOnTcpConnect(PhySocket* sock, void** uptr, bool success)
|
||||
{
|
||||
}
|
||||
void phyOnTcpAccept(PhySocket* sockL, PhySocket* sockN, void** uptrL, void** uptrN, const struct sockaddr* from)
|
||||
{
|
||||
}
|
||||
void phyOnTcpClose(PhySocket* sock, void** uptr)
|
||||
{
|
||||
}
|
||||
void phyOnUnixClose(PhySocket* sock, void** uptr)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -196,7 +190,7 @@ class VirtualTap {
|
||||
*
|
||||
* @usage This is a convenience function to encapsulate a macro
|
||||
*/
|
||||
bool _lwip_is_netif_up(void* netif);
|
||||
bool zts_lwip_is_netif_up(void* netif);
|
||||
|
||||
/**
|
||||
* @brief Increase the delay multiplier for the main driver loop
|
||||
@@ -204,19 +198,19 @@ bool _lwip_is_netif_up(void* netif);
|
||||
* @usage This should be called when we know the stack won't be used by any
|
||||
* virtual taps
|
||||
*/
|
||||
void _lwip_hibernate_driver();
|
||||
void zts_lwip_hibernate_driver();
|
||||
|
||||
/**
|
||||
* @brief Decrease the delay multiplier for the main driver loop
|
||||
*
|
||||
* @usage This should be called when at least one virtual tap is active
|
||||
*/
|
||||
void _lwip_wake_driver();
|
||||
void zts_lwip_wake_driver();
|
||||
|
||||
/**
|
||||
* Returns whether the lwIP network stack is up and ready to process traffic
|
||||
*/
|
||||
bool _lwip_is_up();
|
||||
bool zts_lwip_is_up();
|
||||
|
||||
/**
|
||||
* @brief Initialize network stack semaphores, threads, and timers.
|
||||
@@ -224,7 +218,7 @@ bool _lwip_is_up();
|
||||
* @usage This is called during the initial setup of each VirtualTap but is
|
||||
* only allowed to execute once
|
||||
*/
|
||||
void _lwip_driver_init();
|
||||
void zts_lwip_driver_init();
|
||||
|
||||
/**
|
||||
* @brief Shutdown the stack as completely as possible (not officially
|
||||
@@ -235,41 +229,17 @@ void _lwip_driver_init();
|
||||
* interfaces will be brought down and all resources will be deallocated. A
|
||||
* full application restart will be required to bring the stack back online.
|
||||
*/
|
||||
void _lwip_driver_shutdown();
|
||||
void zts_lwip_driver_shutdown();
|
||||
|
||||
/**
|
||||
* @brief Requests that a netif be brought down and removed.
|
||||
*/
|
||||
void _lwip_remove_netif(void* netif);
|
||||
void zts_lwip_remove_netif(void* netif);
|
||||
|
||||
/**
|
||||
* @brief Starts DHCP timers
|
||||
*/
|
||||
void _lwip_start_dhcp(void* netif);
|
||||
|
||||
/**
|
||||
* @brief Called when the status of a netif changes:
|
||||
* - Interface is up/down (ZTS_EVENT_NETIF_UP, ZTS_EVENT_NETIF_DOWN)
|
||||
* - Address changes while up (ZTS_EVENT_NETIF_NEW_ADDRESS)
|
||||
*/
|
||||
#if LWIP_NETIF_STATUS_CALLBACK
|
||||
static void _netif_status_callback(struct netif* netif);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Called when a netif is removed (ZTS_EVENT_NETIF_INTERFACE_REMOVED)
|
||||
*/
|
||||
#if LWIP_NETIF_REMOVE_CALLBACK
|
||||
static void _netif_remove_callback(struct netif* netif);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Called when a link is brought up or down (ZTS_EVENT_NETIF_LINK_UP,
|
||||
* ZTS_EVENT_NETIF_LINK_DOWN)
|
||||
*/
|
||||
#if LWIP_NETIF_LINK_CALLBACK
|
||||
static void _netif_link_callback(struct netif* netif);
|
||||
#endif
|
||||
void zts_lwip_start_dhcp(void* netif);
|
||||
|
||||
/**
|
||||
* @brief Set up an interface in the network stack for the VirtualTap.
|
||||
@@ -278,7 +248,7 @@ static void _netif_link_callback(struct netif* netif);
|
||||
* sending and receiving data
|
||||
* @param ip Virtual IP address for this ZeroTier VirtualTap interface
|
||||
*/
|
||||
void _lwip_init_interface(void* tapref, const InetAddress& ip);
|
||||
void zts_lwip_init_interface(void* tapref, const InetAddress& ip);
|
||||
|
||||
/**
|
||||
* @brief Remove an assigned address from an lwIP netif
|
||||
@@ -286,7 +256,7 @@ void _lwip_init_interface(void* tapref, const InetAddress& ip);
|
||||
* @param tapref Reference to VirtualTap
|
||||
* @param ip Virtual IP address to remove from this interface
|
||||
*/
|
||||
void _lwip_remove_address_from_netif(void* tapref, const InetAddress& ip);
|
||||
void zts_lwip_remove_address_from_netif(void* tapref, const InetAddress& ip);
|
||||
|
||||
/**
|
||||
* @brief Called from the stack, outbound Ethernet frames from the network
|
||||
@@ -299,7 +269,7 @@ void _lwip_remove_address_from_netif(void* tapref, const InetAddress& ip);
|
||||
* @param p A pointer to the beginning of a chain pf struct pbufs
|
||||
* @return
|
||||
*/
|
||||
err_t _lwip_eth_tx(struct netif* netif, struct pbuf* p);
|
||||
signed char zts_lwip_eth_tx(struct netif* netif, struct pbuf* p);
|
||||
|
||||
/**
|
||||
* @brief Receives incoming Ethernet frames from the ZeroTier virtual wire
|
||||
@@ -314,7 +284,7 @@ err_t _lwip_eth_tx(struct netif* netif, struct pbuf* p);
|
||||
* @param data Pointer to Ethernet frame
|
||||
* @param len Length of Ethernet frame
|
||||
*/
|
||||
void _lwip_eth_rx(
|
||||
void zts_lwip_eth_rx(
|
||||
VirtualTap* tap,
|
||||
const MAC& from,
|
||||
const MAC& to,
|
||||
|
||||
Reference in New Issue
Block a user