Move some out-dated examples to attic, update README.md
This commit is contained in:
17
README.md
17
README.md
@@ -1,7 +1,7 @@
|
|||||||
<div align="center">
|
<div align="center">
|
||||||
|
|
||||||
<h1>ZeroTier SDK</h1>
|
<h1>ZeroTier SDK</h1>
|
||||||
<img alt="zts_socket()" src="https://i.imgur.com/BwSHwE3.png" class="doxyhidden"> </img>
|
<img alt="" src="https://i.imgur.com/BwSHwE3.png" class="doxyhidden"> </img>
|
||||||
|
|
||||||
Peer-to-peer and cross-platform encrypted connections built right into your app or service. No drivers, no root, and no host configuration.
|
Peer-to-peer and cross-platform encrypted connections built right into your app or service. No drivers, no root, and no host configuration.
|
||||||
|
|
||||||
@@ -25,16 +25,13 @@ Peer-to-peer and cross-platform encrypted connections built right into your app
|
|||||||
| Language/Platform | Installation | Version | Example |
|
| Language/Platform | Installation | Version | Example |
|
||||||
|:----------|:---------|:---|:---|
|
|:----------|:---------|:---|:---|
|
||||||
| C/C++ | [Build from source](#build-from-source) | <img alt="version" src="https://img.shields.io/github/v/tag/zerotier/libzt?label="/>|[C/C++](./examples/cpp) |
|
| C/C++ | [Build from source](#build-from-source) | <img alt="version" src="https://img.shields.io/github/v/tag/zerotier/libzt?label="/>|[C/C++](./examples/cpp) |
|
||||||
| Objective-C | See [examples/objective-c](./examples/objective-c) | <img alt="version" src="https://img.shields.io/github/v/tag/zerotier/libzt?label="/> |[Objective-C](./examples/objective-c) |
|
|
||||||
| C# | `Install-Package ZeroTier.Sockets` |<a href="https://www.nuget.org/packages/ZeroTier.Sockets/"><img src="https://img.shields.io/github/v/tag/zerotier/libzt?label=NuGet"/></a> |[C#](./examples/csharp) |
|
| C# | `Install-Package ZeroTier.Sockets` |<a href="https://www.nuget.org/packages/ZeroTier.Sockets/"><img src="https://img.shields.io/github/v/tag/zerotier/libzt?label=NuGet"/></a> |[C#](./examples/csharp) |
|
||||||
| Python | `pip install libzt`|<a href="https://pypi.org/project/libzt/"><img src="https://img.shields.io/pypi/v/libzt?label=PyPI"/></a> |[Python](./examples/python) |
|
| Python | `pip install libzt`|<a href="https://pypi.org/project/libzt/"><img src="https://img.shields.io/pypi/v/libzt?label=PyPI"/></a> |[Python](./examples/python) |
|
||||||
| Rust | Coming *very* soon | <img alt="version" src="https://img.shields.io/github/v/tag/zerotier/libzt?label="/>|[Rust](./examples/rust) |
|
| Rust | Coming *very* soon | <img alt="version" src="https://img.shields.io/github/v/tag/zerotier/libzt?label="/>|[Rust](./examples/rust) |
|
||||||
| Swift | See [examples/swift](./examples/swift) |<img alt="version" src="https://img.shields.io/github/v/tag/zerotier/libzt?label="/> |[Swift](./examples/swift) |
|
|
||||||
| Java | `./build.sh host-jar` |<img src="https://img.shields.io/github/v/tag/zerotier/libzt?label="/> |[Java](./examples/java) |
|
| Java | `./build.sh host-jar` |<img src="https://img.shields.io/github/v/tag/zerotier/libzt?label="/> |[Java](./examples/java) |
|
||||||
| Node.js | See [examples/nodejs](./examples/nodejs) |<img src="https://img.shields.io/badge/-help--wanted-green"/>|[Node.js](./examples/nodejs) |
|
|
||||||
| Linux | [Build from source](#build-from-source) | <img alt="version" src="https://img.shields.io/github/v/tag/zerotier/libzt?label="/></a>| [C/C++](./examples/cpp) |
|
| Linux | [Build from source](#build-from-source) | <img alt="version" src="https://img.shields.io/github/v/tag/zerotier/libzt?label="/></a>| [C/C++](./examples/cpp) |
|
||||||
| macOS | `brew install libzt`|<a href="https://formulae.brew.sh/formula/libzt#default"><img src="https://img.shields.io/homebrew/v/libzt?label=Homebrew"/></a> | [C/C++](./examples/cpp), [Objective-C](./examples/objective-c) |
|
| macOS | `brew install libzt`|<a href="https://formulae.brew.sh/formula/libzt#default"><img src="https://img.shields.io/homebrew/v/libzt?label=Homebrew"/></a> | [C/C++](./examples/cpp), [Objective-C](./attic/objective-c) |
|
||||||
| iOS / iPadOS | `./build.sh ios-framework` | <img src="https://img.shields.io/github/v/tag/zerotier/libzt?label="/>| [Objective-C](./examples/objective-c), [Swift](./examples/swift) |
|
| iOS / iPadOS | `./build.sh ios-framework` | <img src="https://img.shields.io/github/v/tag/zerotier/libzt?label="/>| [Objective-C](./attic/objective-c), [Swift](./attic/swift) |
|
||||||
| Android |`./build.sh android-aar` | <img src="https://img.shields.io/github/v/tag/zerotier/libzt?label="/> | [Java](./examples/java) |
|
| Android |`./build.sh android-aar` | <img src="https://img.shields.io/github/v/tag/zerotier/libzt?label="/> | [Java](./examples/java) |
|
||||||
|
|
||||||
<br>
|
<br>
|
||||||
@@ -46,10 +43,10 @@ Peer-to-peer and cross-platform encrypted connections built right into your app
|
|||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
zts_start(...)
|
zts_node_start();
|
||||||
zts_join(networkId);
|
zts_net_join(net_id);
|
||||||
int fd = zts_socket(ZTS_AF_INET, ZTS_SOCK_STREAM, 0);
|
int fd = zts_bsd_socket(ZTS_AF_INET, ZTS_SOCK_STREAM, 0);
|
||||||
zts_connect(fd, ...);
|
zts_bsd_connect(fd, ...);
|
||||||
...
|
...
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -195,7 +195,7 @@ zts_sockaddr_in sockaddr_in(const char *remoteAddr, const int remotePort)
|
|||||||
* ZTS_ERR_NO_RESULT // No result (not necessarily an error)
|
* ZTS_ERR_NO_RESULT // No result (not necessarily an error)
|
||||||
* ZTS_ERR_GENERAL // Consider filing a bug report
|
* ZTS_ERR_GENERAL // Consider filing a bug report
|
||||||
*
|
*
|
||||||
* Category 2: Sockets (zts_socket, zts_bind, zts_connect, zts_listen, etc).
|
* Category 2: Sockets (zts_bsd_socket, zts_bsd_bind, zts_bsd_connect, zts_bsd_listen, etc).
|
||||||
* Errors returned by these functions can be the same as the above. With
|
* Errors returned by these functions can be the same as the above. With
|
||||||
* the added possibility of zts_errno being set. Much like standard
|
* the added possibility of zts_errno being set. Much like standard
|
||||||
* errno this will provide a more specific reason for an error's occurrence.
|
* errno this will provide a more specific reason for an error's occurrence.
|
||||||
@@ -212,14 +212,14 @@ zts_sockaddr_in sockaddr_in(const char *remoteAddr, const int remotePort)
|
|||||||
*
|
*
|
||||||
* If you are calling a zts_* function, use the appropriate ZTS_* constants:
|
* If you are calling a zts_* function, use the appropriate ZTS_* constants:
|
||||||
*
|
*
|
||||||
* zts_socket(ZTS_AF_INET6, ZTS_SOCK_DGRAM, 0); (CORRECT)
|
* zts_bsd_socket(ZTS_AF_INET6, ZTS_SOCK_DGRAM, 0); (CORRECT)
|
||||||
* zts_socket(AF_INET6, SOCK_DGRAM, 0); (INCORRECT)
|
* zts_bsd_socket(AF_INET6, SOCK_DGRAM, 0); (INCORRECT)
|
||||||
*
|
*
|
||||||
* If you are calling a zts_* function, use the appropriate zts_* structure:
|
* If you are calling a zts_* function, use the appropriate zts_* structure:
|
||||||
*
|
*
|
||||||
* struct zts_sockaddr_in in4; <------ Note the zts_* prefix
|
* struct zts_sockaddr_in in4; <------ Note the zts_* prefix
|
||||||
* ...
|
* ...
|
||||||
* zts_bind(fd, (struct zts_sockaddr *)&in4, sizeof(struct zts_sockaddr_in)) < 0)
|
* zts_bsd_bind(fd, (struct zts_sockaddr *)&in4, sizeof(struct zts_sockaddr_in)) < 0)
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
class ZeroTier
|
class ZeroTier
|
||||||
@@ -356,7 +356,7 @@ public:
|
|||||||
static int open(const int socket_family, const int socket_type, const int protocol)
|
static int open(const int socket_family, const int socket_type, const int protocol)
|
||||||
{
|
{
|
||||||
int fd;
|
int fd;
|
||||||
if ((fd = zts_socket(socket_family, socket_type, protocol)) < 0) {
|
if ((fd = zts_bsd_socket(socket_family, socket_type, protocol)) < 0) {
|
||||||
printf("Error creating ZeroTier socket (fd=%d, zts_errno=%d).\n", fd, zts_errno);
|
printf("Error creating ZeroTier socket (fd=%d, zts_errno=%d).\n", fd, zts_errno);
|
||||||
}
|
}
|
||||||
return fd;
|
return fd;
|
||||||
@@ -370,7 +370,7 @@ public:
|
|||||||
*/
|
*/
|
||||||
static int close(int fd)
|
static int close(int fd)
|
||||||
{
|
{
|
||||||
return zts_close(fd);
|
return zts_bsd_close(fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -381,7 +381,7 @@ public:
|
|||||||
*/
|
*/
|
||||||
static int shutdown(int fd)
|
static int shutdown(int fd)
|
||||||
{
|
{
|
||||||
return zts_shutdown(fd, ZTS_SHUT_RDWR);
|
return zts_bsd_shutdown(fd, ZTS_SHUT_RDWR);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -397,7 +397,7 @@ public:
|
|||||||
struct zts_sockaddr_in in4 = sockaddr_in(localAddr, localPort);
|
struct zts_sockaddr_in in4 = sockaddr_in(localAddr, localPort);
|
||||||
|
|
||||||
int err = ZTS_ERR_OK;
|
int err = ZTS_ERR_OK;
|
||||||
if ((err = zts_bind(fd, (const struct zts_sockaddr *)&in4, sizeof(in4))) < 0) {
|
if ((err = zts_bsd_bind(fd, (const struct zts_sockaddr *)&in4, sizeof(in4))) < 0) {
|
||||||
printf("Error binding to interface (fd=%d, ret=%d, zts_errno=%d).\n",
|
printf("Error binding to interface (fd=%d, ret=%d, zts_errno=%d).\n",
|
||||||
fd, err, zts_errno);
|
fd, err, zts_errno);
|
||||||
}
|
}
|
||||||
@@ -424,7 +424,7 @@ public:
|
|||||||
|
|
||||||
// Retries are often required since ZT uses transport-triggered links (explained above)
|
// Retries are often required since ZT uses transport-triggered links (explained above)
|
||||||
int err = ZTS_ERR_OK;
|
int err = ZTS_ERR_OK;
|
||||||
if ((err = zts_connect(fd, (const struct zts_sockaddr *)&in4, sizeof(in4))) < 0) {
|
if ((err = zts_bsd_connect(fd, (const struct zts_sockaddr *)&in4, sizeof(in4))) < 0) {
|
||||||
printf("Error connecting to remote host (fd=%d, ret=%d, zts_errno=%d).\n",
|
printf("Error connecting to remote host (fd=%d, ret=%d, zts_errno=%d).\n",
|
||||||
fd, err, zts_errno);
|
fd, err, zts_errno);
|
||||||
} else {
|
} else {
|
||||||
@@ -436,12 +436,12 @@ public:
|
|||||||
// int err = ZTS_ERR_OK;
|
// int err = ZTS_ERR_OK;
|
||||||
// for (;;) {
|
// for (;;) {
|
||||||
// printf("Connecting to remote host...\n");
|
// printf("Connecting to remote host...\n");
|
||||||
// if ((err = zts_connect(fd, (const struct zts_sockaddr *)&in4, sizeof(in4))) < 0) {
|
// if ((err = zts_bsd_connect(fd, (const struct zts_sockaddr *)&in4, sizeof(in4))) < 0) {
|
||||||
// printf("Error connecting to remote host (fd=%d, ret=%d, zts_errno=%d). Trying again.\n",
|
// printf("Error connecting to remote host (fd=%d, ret=%d, zts_errno=%d). Trying again.\n",
|
||||||
// fd, err, zts_errno);
|
// fd, err, zts_errno);
|
||||||
// zts_close(fd);
|
// zts_bsd_close(fd);
|
||||||
// // printf("Creating socket...\n");
|
// // printf("Creating socket...\n");
|
||||||
// if ((fd = zts_socket(socket_family, socket_type, protocol)) < 0) {
|
// if ((fd = zts_bsd_socket(socket_family, socket_type, protocol)) < 0) {
|
||||||
// printf("Error creating ZeroTier socket (fd=%d, zts_errno=%d).\n", fd, zts_errno);
|
// printf("Error creating ZeroTier socket (fd=%d, zts_errno=%d).\n", fd, zts_errno);
|
||||||
// return -1;
|
// return -1;
|
||||||
// }
|
// }
|
||||||
@@ -469,7 +469,7 @@ public:
|
|||||||
*/
|
*/
|
||||||
static ssize_t read(int fd, nbind::Buffer buf)
|
static ssize_t read(int fd, nbind::Buffer buf)
|
||||||
{
|
{
|
||||||
return zts_read(fd, buf.data(), buf.length());
|
return zts_bsd_read(fd, buf.data(), buf.length());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -481,7 +481,7 @@ public:
|
|||||||
*/
|
*/
|
||||||
static ssize_t write(int fd, nbind::Buffer buf)
|
static ssize_t write(int fd, nbind::Buffer buf)
|
||||||
{
|
{
|
||||||
return zts_write(fd, buf.data(), buf.length());
|
return zts_bsd_write(fd, buf.data(), buf.length());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -499,7 +499,7 @@ public:
|
|||||||
iov[i].iov_base = bufs[i].data();
|
iov[i].iov_base = bufs[i].data();
|
||||||
iov[i].iov_len = bufs[i].length();
|
iov[i].iov_len = bufs[i].length();
|
||||||
}
|
}
|
||||||
return zts_writev(fd, iov, bufs.size());
|
return zts_bsd_writev(fd, iov, bufs.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -512,7 +512,7 @@ public:
|
|||||||
*/
|
*/
|
||||||
static ssize_t recv(int fd, nbind::Buffer buf, int flags)
|
static ssize_t recv(int fd, nbind::Buffer buf, int flags)
|
||||||
{
|
{
|
||||||
return zts_recv(fd, buf.data(), buf.length(), flags);
|
return zts_bsd_recv(fd, buf.data(), buf.length(), flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -525,7 +525,7 @@ public:
|
|||||||
*/
|
*/
|
||||||
static ssize_t send(int fd, nbind::Buffer buf, int flags)
|
static ssize_t send(int fd, nbind::Buffer buf, int flags)
|
||||||
{
|
{
|
||||||
return zts_send(fd, buf.data(), buf.length(), flags);
|
return zts_bsd_send(fd, buf.data(), buf.length(), flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int setBlocking(int fd, bool isBlocking)
|
static int setBlocking(int fd, bool isBlocking)
|
||||||
@@ -570,7 +570,7 @@ public:
|
|||||||
*/
|
*/
|
||||||
static int fcntl(int fd, int cmd, int flags)
|
static int fcntl(int fd, int cmd, int flags)
|
||||||
{
|
{
|
||||||
return zts_fcntl(fd, cmd, flags);
|
return zts_bsd_fcntl(fd, cmd, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -585,7 +585,7 @@ public:
|
|||||||
*/
|
*/
|
||||||
static int setsockopt(int fd, int level, int optname, const void *optval, zts_socklen_t optlen)
|
static int setsockopt(int fd, int level, int optname, const void *optval, zts_socklen_t optlen)
|
||||||
{
|
{
|
||||||
return zts_setsockopt(fd, level, optname, optval, optlen);
|
return zts_bsd_setsockopt(fd, level, optname, optval, optlen);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -600,7 +600,7 @@ public:
|
|||||||
*/
|
*/
|
||||||
static int getsockopt(int fd, int level, int optname, void *optval, zts_socklen_t *optlen)
|
static int getsockopt(int fd, int level, int optname, void *optval, zts_socklen_t *optlen)
|
||||||
{
|
{
|
||||||
return zts_getsockopt(fd, level, optname, optval, optlen);
|
return zts_bsd_getsockopt(fd, level, optname, optval, optlen);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -615,7 +615,7 @@ public:
|
|||||||
{
|
{
|
||||||
struct zts_sockaddr_in in4;
|
struct zts_sockaddr_in in4;
|
||||||
zts_socklen_t addrlen;
|
zts_socklen_t addrlen;
|
||||||
zts_getsockname(fd, (struct zts_sockaddr *)&in4, &addrlen);
|
zts_bsd_getsockname(fd, (struct zts_sockaddr *)&in4, &addrlen);
|
||||||
return in4;
|
return in4;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -623,7 +623,7 @@ public:
|
|||||||
{
|
{
|
||||||
struct zts_sockaddr_in6 in6;
|
struct zts_sockaddr_in6 in6;
|
||||||
zts_socklen_t addrlen;
|
zts_socklen_t addrlen;
|
||||||
zts_getsockname(fd, (struct zts_sockaddr *)&in6, &addrlen);
|
zts_bsd_getsockname(fd, (struct zts_sockaddr *)&in6, &addrlen);
|
||||||
return in6;
|
return in6;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -639,7 +639,7 @@ public:
|
|||||||
{
|
{
|
||||||
struct zts_sockaddr_in in4;
|
struct zts_sockaddr_in in4;
|
||||||
zts_socklen_t addrlen;
|
zts_socklen_t addrlen;
|
||||||
zts_getpeername(fd, (struct zts_sockaddr *)&in4, &addrlen);
|
zts_bsd_getpeername(fd, (struct zts_sockaddr *)&in4, &addrlen);
|
||||||
return in4;
|
return in4;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -647,7 +647,7 @@ public:
|
|||||||
{
|
{
|
||||||
struct zts_sockaddr_in6 in6;
|
struct zts_sockaddr_in6 in6;
|
||||||
zts_socklen_t addrlen;
|
zts_socklen_t addrlen;
|
||||||
zts_getpeername(fd, (struct zts_sockaddr *)&in6, &addrlen);
|
zts_bsd_getpeername(fd, (struct zts_sockaddr *)&in6, &addrlen);
|
||||||
return in6;
|
return in6;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -14,87 +14,6 @@
|
|||||||
|
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* IDENTITIES and AUTHORIZATION:
|
|
||||||
*
|
|
||||||
* - Upon the first execution of this code, a new identity will be generated and placed in
|
|
||||||
* the location given in the first argument to zts_start(path, ...). If you accidentally
|
|
||||||
* duplicate the identity files and use them simultaneously in a different node instance
|
|
||||||
* you will experience undefined behavior and it is likely nothing will work.
|
|
||||||
*
|
|
||||||
* - You must authorize the node ID provided by the ZTS_EVENT_NODE_ONLINE callback to join
|
|
||||||
* your network, otherwise nothing will happen. This can be done manually or via
|
|
||||||
* our web API: https://my.zerotier.com/help/api
|
|
||||||
*
|
|
||||||
* - An exception to the above rule is if you are using an Ad-hoc network, it has no
|
|
||||||
* controller and therefore requires no authorization.
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* ESTABLISHING A CONNECTION:
|
|
||||||
*
|
|
||||||
* - Creating a standard socket connection generally works the same as it would using
|
|
||||||
* an ordinary socket interface, however with libzt there is a subtle difference in
|
|
||||||
* how connections are established which may cause confusion:
|
|
||||||
*
|
|
||||||
* The underlying virtual ZT layer creates what are called "transport-triggered links"
|
|
||||||
* between nodes. That is, links are not established until an attempt to communicate
|
|
||||||
* with a peer has taken place. The side effect is that the first few packets sent from
|
|
||||||
* a libzt instance are usually relayed via our free infrastructure and it isn't until a
|
|
||||||
* root server has passed contact information to both peers that a direct connection will be
|
|
||||||
* established. Therefore, it is required that multiple connection attempts be undertaken
|
|
||||||
* when initially communicating with a peer. After a transport-triggered link is
|
|
||||||
* established libzt will inform you via ZTS_EVENT_PEER_DIRECT for a specific peer ID. No
|
|
||||||
* action is required on your part for this callback event.
|
|
||||||
*
|
|
||||||
* Note: In these initial moments before ZTS_EVENT_PEER_DIRECT has been received for a
|
|
||||||
* specific peer, traffic may be slow, jittery and there may be high packet loss.
|
|
||||||
* This will subside within a couple of seconds.
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* ERROR HANDLING:
|
|
||||||
*
|
|
||||||
* - libzt's API is actually composed of two categories of functions with slightly
|
|
||||||
* different error reporting mechanisms.
|
|
||||||
*
|
|
||||||
* Category 1: Control functions (zts_start, zts_join, zts_get_peer_status, etc). Errors
|
|
||||||
* returned by these functions can be any of the following:
|
|
||||||
*
|
|
||||||
* ZTS_ERR_OK // No error
|
|
||||||
* ZTS_ERR_SOCKET // Socket error, see zts_errno
|
|
||||||
* ZTS_ERR_SERVICE // You probably did something at the wrong time
|
|
||||||
* ZTS_ERR_ARG // Invalid argument
|
|
||||||
* ZTS_ERR_NO_RESULT // No result (not necessarily an error)
|
|
||||||
* ZTS_ERR_GENERAL // Consider filing a bug report
|
|
||||||
*
|
|
||||||
* Category 2: Sockets (zts_socket, zts_bind, zts_connect, zts_listen, etc).
|
|
||||||
* Errors returned by these functions can be the same as the above. With
|
|
||||||
* the added possibility of zts_errno being set. Much like standard
|
|
||||||
* errno this will provide a more specific reason for an error's occurrence.
|
|
||||||
* See ZeroTierSockets.h for values.
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* API COMPATIBILITY WITH HOST OS:
|
|
||||||
*
|
|
||||||
* - While the ZeroTier socket interface can coexist with your host OS's own interface in
|
|
||||||
* the same file with no type and naming conflicts, try not to mix and match host
|
|
||||||
* OS/libzt structures, functions, or constants. It may look similar and may even work
|
|
||||||
* some of the time but there enough differences that it will cause headaches. Here
|
|
||||||
* are a few guidelines:
|
|
||||||
*
|
|
||||||
* If you are calling a zts_* function, use the appropriate ZTS_* constants:
|
|
||||||
*
|
|
||||||
* zts_socket(ZTS_AF_INET6, ZTS_SOCK_DGRAM, 0); (CORRECT)
|
|
||||||
* zts_socket(AF_INET6, SOCK_DGRAM, 0); (INCORRECT)
|
|
||||||
*
|
|
||||||
* If you are calling a zts_* function, use the appropriate zts_* structure:
|
|
||||||
*
|
|
||||||
* struct zts_sockaddr_in in4; <------ Note the zts_* prefix
|
|
||||||
* ...
|
|
||||||
* zts_bind(fd, (struct zts_sockaddr *)&in4, sizeof(struct zts_sockaddr_in)) < 0)
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
void delay_ms(long ms) { usleep(ms*1000); }
|
void delay_ms(long ms) { usleep(ms*1000); }
|
||||||
|
|
||||||
bool nodeReady = false;
|
bool nodeReady = false;
|
||||||
@@ -1,91 +1,10 @@
|
|||||||
/**
|
/**
|
||||||
* I'll order you a pizza if you can rewrite this in modern idomatic Swift
|
* I'll order you a pizza if you can rewrite this in modern idiomatic Swift
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import Swift
|
import Swift
|
||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* IDENTITIES and AUTHORIZATION:
|
|
||||||
*
|
|
||||||
* - Upon the first execution of this code, a new identity will be generated and placed in
|
|
||||||
* the location given in the first argument to zts_start(path, ...). If you accidentally
|
|
||||||
* duplicate the identity files and use them simultaneously in a different node instance
|
|
||||||
* you will experience undefined behavior and it is likely nothing will work.
|
|
||||||
*
|
|
||||||
* - You must authorize the node ID provided by the ZTS_EVENT_NODE_ONLINE callback to join
|
|
||||||
* your network, otherwise nothing will happen. This can be done manually or via
|
|
||||||
* our web API: https://my.zerotier.com/help/api
|
|
||||||
*
|
|
||||||
* - An exception to the above rule is if you are using an Ad-hoc network, it has no
|
|
||||||
* controller and therefore requires no authorization.
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* ESTABLISHING A CONNECTION:
|
|
||||||
*
|
|
||||||
* - Creating a standard socket connection generally works the same as it would using
|
|
||||||
* an ordinary socket interface, however with libzt there is a subtle difference in
|
|
||||||
* how connections are established which may cause confusion:
|
|
||||||
*
|
|
||||||
* The underlying virtual ZT layer creates what are called "transport-triggered links"
|
|
||||||
* between nodes. That is, links are not established until an attempt to communicate
|
|
||||||
* with a peer has taken place. The side effect is that the first few packets sent from
|
|
||||||
* a libzt instance are usually relayed via our free infrastructure and it isn't until a
|
|
||||||
* root server has passed contact information to both peers that a direct connection will be
|
|
||||||
* established. Therefore, it is required that multiple connection attempts be undertaken
|
|
||||||
* when initially communicating with a peer. After a transport-triggered link is
|
|
||||||
* established libzt will inform you via ZTS_EVENT_PEER_DIRECT for a specific peer ID. No
|
|
||||||
* action is required on your part for this callback event.
|
|
||||||
*
|
|
||||||
* Note: In these initial moments before ZTS_EVENT_PEER_DIRECT has been received for a
|
|
||||||
* specific peer, traffic may be slow, jittery and there may be high packet loss.
|
|
||||||
* This will subside within a couple of seconds.
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* ERROR HANDLING:
|
|
||||||
*
|
|
||||||
* - libzt's API is actually composed of two categories of functions with slightly
|
|
||||||
* different error reporting mechanisms.
|
|
||||||
*
|
|
||||||
* Category 1: Control functions (zts_start, zts_join, zts_get_peer_status, etc). Errors
|
|
||||||
* returned by these functions can be any of the following:
|
|
||||||
*
|
|
||||||
* ZTS_ERR_OK // No error
|
|
||||||
* ZTS_ERR_SOCKET // Socket error, see zts_errno
|
|
||||||
* ZTS_ERR_SERVICE // You probably did something at the wrong time
|
|
||||||
* ZTS_ERR_ARG // Invalid argument
|
|
||||||
* ZTS_ERR_NO_RESULT // No result (not necessarily an error)
|
|
||||||
* ZTS_ERR_GENERAL // Consider filing a bug report
|
|
||||||
*
|
|
||||||
* Category 2: Sockets (zts_socket, zts_bind, zts_connect, zts_listen, etc).
|
|
||||||
* Errors returned by these functions can be the same as the above. With
|
|
||||||
* the added possibility of zts_errno being set. Much like standard
|
|
||||||
* errno this will provide a more specific reason for an error's occurrence.
|
|
||||||
* See ZeroTierSockets.h for values.
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* API COMPATIBILITY WITH HOST OS:
|
|
||||||
*
|
|
||||||
* - While the ZeroTier socket interface can coexist with your host OS's own interface in
|
|
||||||
* the same file with no type and naming conflicts, try not to mix and match host
|
|
||||||
* OS/libzt structures, functions, or constants. It may look similar and may even work
|
|
||||||
* some of the time but there enough differences that it will cause headaches. Here
|
|
||||||
* are a few guidelines:
|
|
||||||
*
|
|
||||||
* If you are calling a zts_* function, use the appropriate ZTS_* constants:
|
|
||||||
*
|
|
||||||
* zts_socket(ZTS_AF_INET6, ZTS_SOCK_DGRAM, 0); (CORRECT)
|
|
||||||
* zts_socket(AF_INET6, SOCK_DGRAM, 0); (INCORRECT)
|
|
||||||
*
|
|
||||||
* If you are calling a zts_* function, use the appropriate zts_* structure:
|
|
||||||
*
|
|
||||||
* struct zts_sockaddr_in in4; <------ Note the zts_* prefix
|
|
||||||
* ...
|
|
||||||
* zts_bind(fd, (struct zts_sockaddr *)&in4, sizeof(struct zts_sockaddr_in)) < 0)
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
let printNodeDetails : @convention(c) (UnsafeMutableRawPointer?) -> Void =
|
let printNodeDetails : @convention(c) (UnsafeMutableRawPointer?) -> Void =
|
||||||
{
|
{
|
||||||
(msgPtr) -> Void in
|
(msgPtr) -> Void in
|
||||||
@@ -341,7 +260,7 @@ func main()
|
|||||||
sin_zero: (0,0,0,0,0,0,0,0))
|
sin_zero: (0,0,0,0,0,0,0,0))
|
||||||
zts_inet_pton(ZTS_AF_INET, addr_str, &(in4.sin_addr));
|
zts_inet_pton(ZTS_AF_INET, addr_str, &(in4.sin_addr));
|
||||||
|
|
||||||
print("fd=", zts_socket(ZTS_AF_INET, ZTS_SOCK_STREAM, 0));
|
print("fd=", zts_bsd_socket(ZTS_AF_INET, ZTS_SOCK_STREAM, 0));
|
||||||
|
|
||||||
// ...
|
// ...
|
||||||
|
|
||||||
Reference in New Issue
Block a user