Change event code numbering scheme, fix Windows startup bug, fix zts_free(), remove vestigial API functions, update documentation
This commit is contained in:
275
README.md
275
README.md
@@ -2,17 +2,13 @@
|
||||
Connect physical devices, virtual devices, and application instances as if everything is on a single LAN.
|
||||
***
|
||||
|
||||
The ZeroTier SDK brings your network into userspace. We've paired our network hypervisor core with a network stack ([lwIP](https://savannah.nongnu.org/projects/lwip/)) to provide your application with an exclusive and private virtual network interface. All traffic on this interface is end-to-end encrypted between each peer and we provide an easy-to-use socket interface derived from [Berkeley Sockets](https://en.wikipedia.org/wiki/Berkeley_sockets). Since we aren't using the kernel's network stack that means, no drivers, no root, and no host configuration requirements. For a more in-depth discussion on the technical side of ZeroTier, check out our [Manual](https://www.zerotier.com/manual.shtml). For troubleshooting advice see our [Knowledgebase](https://zerotier.atlassian.net/wiki/spaces/SD/overview). If you need further assistance, create an account at [my.zerotier.com](https://my.zerotier.com) and join our community of users and professionals.
|
||||
The ZeroTier SDK brings your network into user-space. We've paired our network hypervisor core with a network stack ([lwIP](https://savannah.nongnu.org/projects/lwip/)) to provide your application with an exclusive and private virtual network interface. All traffic on this interface is end-to-end encrypted between each peer and we provide an easy-to-use socket interface derived from [Berkeley Sockets](https://en.wikipedia.org/wiki/Berkeley_sockets). Since we aren't using the kernel's network stack that means, no drivers, no root, and no host configuration requirements. For a more in-depth discussion on the technical side of ZeroTier, check out our [Manual](https://www.zerotier.com/manual.shtml). For troubleshooting advice see our [Knowledgebase](https://zerotier.atlassian.net/wiki/spaces/SD/overview). If you need further assistance, create an account at [my.zerotier.com](https://my.zerotier.com) and join our community of users and professionals.
|
||||
|
||||
***
|
||||
Downloads: [download.zerotier.com/dist/sdk](https://download.zerotier.com/dist/sdk)
|
||||
|
||||
<div style="page-break-after: always;"></div>
|
||||
|
||||
# Usage
|
||||
|
||||
### Downloads and examples: [download.zerotier.com/dist/sdk](https://download.zerotier.com/dist/sdk)
|
||||
|
||||
### Building from source
|
||||
## Building from source
|
||||
|
||||
To build both `release` and `debug` libraries for only your host's architecture use `make host`. Or optionally `make host_release` for release only. To build everything including things like iOS frameworks, Android packages, etc, use `make all`. Possible build targets can be seen by using `make list`. Resultant libraries will be placed in `./lib`, test and example programs will be placed in `./bin`:
|
||||
|
||||
@@ -29,15 +25,11 @@ lib
|
||||
| ├── libzt.a
|
||||
| └── libzt.so
|
||||
└── debug
|
||||
└── linux-x86_64
|
||||
├── libzt.a
|
||||
└── libzt.so
|
||||
└── ...
|
||||
bin
|
||||
└── release
|
||||
└── linux-x86_64
|
||||
├── adhoc
|
||||
├── client
|
||||
├── comprehensive
|
||||
└── server
|
||||
```
|
||||
|
||||
@@ -49,9 +41,9 @@ clang++ -o yourApp yourApp.cpp -L./lib/release/linux-x86_64/ -lzt; ./yourApp
|
||||
|
||||
<div style="page-break-after: always;"></div>
|
||||
|
||||
# Starting the service
|
||||
## Starting ZeroTier
|
||||
|
||||
The next few sections explain how to use the network control interface portion of the API. These functions are non-blocking and will return an error code specified in the **Error handling** section and will result in the generation of callback events detailed in the **Event handling** section. It is your responsibility to handle these events. To start the service, simply call:
|
||||
The next few sections explain how to use the network control interface portion of the API. These functions are non-blocking and will return an error code specified in the [Error Handling](#error-handling) section and will result in the generation of callback events detailed in the [Event Handling](#event-handling) section. It is your responsibility to handle these events. To start the service, simply call:
|
||||
|
||||
`zts_start(char *path, void (*userCallbackFunc)(struct zts_callback_msg*), int port)`
|
||||
|
||||
@@ -90,47 +82,23 @@ For more complete examples see `./examples/`
|
||||
|
||||
<div style="page-break-after: always;"></div>
|
||||
|
||||
After calling `zts_start()` you will receive one or more of the following events:
|
||||
|
||||
```
|
||||
ZTS_EVENT_NODE_ONLINE
|
||||
ZTS_EVENT_NODE_OFFLINE
|
||||
ZTS_EVENT_NODE_DOWN
|
||||
ZTS_EVENT_NODE_IDENTITY_COLLISION
|
||||
ZTS_EVENT_NODE_UNRECOVERABLE_ERROR
|
||||
ZTS_EVENT_NODE_NORMAL_TERMINATION
|
||||
```
|
||||
|
||||
After receiving `ZTS_EVENT_NODE_ONLINE` you will be allowed to join or leave networks. You must authorize the node ID provided by the this callback event to join your network. This can be done manually or via our [Web API](https://my.zerotier.com/help/api). Note however that if you are using an Ad-hoc network, it has no controller and therefore requires no authorization.
|
||||
After calling `zts_start()` you will receive one or more events specified in the [Node Events](#node-events) section. After receiving `ZTS_EVENT_NODE_ONLINE` you will be allowed to join or leave networks. You must authorize the node ID provided by the this callback event to join your network. This can be done manually or via our [Web API](https://my.zerotier.com/help/api). Note however that if you are using an Ad-hoc network, it has no controller and therefore requires no authorization.
|
||||
|
||||
At the end of your program or when no more network activity is anticipated, the user application can shut down the service with `zts_stop()`. However, it is safe to leave the service running in the background indefinitely as it doesn't consume much memory or CPU while at idle. `zts_stop()` is a non-blocking call and will itself issue a series of events indicating that various aspects of the ZeroTier service have successfully shut down.
|
||||
|
||||
It is worth noting that while `zts_stop()` will stop the service, but the user-space network stack will continue operating in a headless hibernation mode. This is intended behavior due to the fact that the network stack we've chosen doesn't currently support the notion of shutdown since it was initially designed for embedded applications that are simply switched off. If you do need a way to shut everything down and free all resources you can call `zts_free()`, but please note that calling this function will prevent all subsequent `zts_start()` calls from succeeding and will require a full application restart if you want to run the service again. The events `ZTS_EVENT_NODE_ONLINE` and `ZTS_EVENT_NODE_OFFLINE` can be seen periodically throughout the lifetime of your application depending on the reliability of your underlying network link, these events are lagging indicators and are typically only triggered every thirty (30) seconds.
|
||||
It is worth noting that while `zts_stop()` will stop the service, the user-space network stack will continue operating in a headless hibernation mode. This is intended behavior due to the fact that the network stack we've chosen doesn't currently support the notion of shutdown since it was initially designed for embedded applications that are simply switched off. If you do need a way to shut everything down and free all resources you can call `zts_free()`, but please note that calling this function will prevent all subsequent `zts_start()` calls from succeeding and will require a full application restart if you want to run the service again. The events `ZTS_EVENT_NODE_ONLINE` and `ZTS_EVENT_NODE_OFFLINE` can be seen periodically throughout the lifetime of your application depending on the reliability of your underlying network link, these events are lagging indicators and are typically only triggered every thirty (30) seconds.
|
||||
|
||||
Lastly, the function `zts_restart()` is provided as a way to restart the ZeroTier service along with all of its virtual interfaces. The network stack will remain online and undisturbed during this call. Note that this call will temporarily block until the service has fully shut down, then will return and you may then watch for the appropriate startup callbacks mentioned above.
|
||||
|
||||
<div style="page-break-after: always;"></div>
|
||||
|
||||
# Joining a network
|
||||
## Joining a network
|
||||
|
||||
Joining a ZeroTier virtual network is as easy as calling `zts_join(uint64_t networkId)`. Similarly there is a `zts_leave(uint64_t networkId)`. Note that `zts_start()` must be called and a `ZTS_EVENT_NODE_ONLINE` event must be received before these calls will succeed. After calling `zts_join()` any one of the following events may be generated:
|
||||
|
||||
```
|
||||
ZTS_EVENT_NETWORK_NOT_FOUND
|
||||
ZTS_EVENT_NETWORK_CLIENT_TOO_OLD
|
||||
ZTS_EVENT_NETWORK_REQ_CONFIG
|
||||
ZTS_EVENT_NETWORK_OK
|
||||
ZTS_EVENT_NETWORK_ACCESS_DENIED
|
||||
ZTS_EVENT_NETWORK_READY_IP4
|
||||
ZTS_EVENT_NETWORK_READY_IP6
|
||||
ZTS_EVENT_NETWORK_DOWN
|
||||
```
|
||||
|
||||
`ZTS_EVENT_NETWORK_READY_IP4` and `ZTS_EVENT_NETWORK_READY_IP6` are combinations of a few different events. They signal that the network was found, joined successfully, an IP address was assigned and the network stack's interface is ready to process traffic of the indicated type. After this point you should be able to communicate with peers on the network.
|
||||
Joining a ZeroTier virtual network is as easy as calling `zts_join(uint64_t networkId)`. Similarly there is a `zts_leave(uint64_t networkId)`. Note that `zts_start()` must be called and a `ZTS_EVENT_NODE_ONLINE` event must have been received before these calls will succeed. After calling `zts_join()` any one of the events detailed in the [Network Events](#network-events) section may be generated.
|
||||
|
||||
<div style="page-break-after: always;"></div>
|
||||
|
||||
# Connecting and communicating with peers
|
||||
## Connecting and communicating with peers
|
||||
|
||||
Creating a standard socket connection generally works the same as it would using an ordinary socket interface, however with ZeroTier there is a subtle difference in how connections are established which may cause confusion. Since ZeroTier employs transport-triggered link provisioning a direct connection between peers will not exist until contact has been attempted by at least one peer. During this time before a direct link is available traffic will be handled via our free relay service. The provisioning of this direct link usually only takes a couple of seconds but it is important to understand that if you attempt something like s `zts_connect(...)` call during this time it may fail due to packet loss. Therefore it is advised to repeatedly call `zts_connect(...)` until it succeeds and to wait to send additional traffic until `ZTS_EVENT_PEER_DIRECT` has been received for the peer you are attempting to communicate with. All of the above is optional, but it will improve your experience.
|
||||
|
||||
@@ -138,11 +106,9 @@ Creating a standard socket connection generally works the same as it would using
|
||||
|
||||
As a mitigation for the above behavior, ZeroTier will by default cache details about how to contact a peer in the `peers.d` subdirectory of the config path you passed to `zts_start(...)`. In scenarios where paths do not often change, this can almost completely eliminate the issue and will make connections nearly instantaneous. If however you do not wish to cache these details you can disable it via `zts_set_peer_caching(false)`.
|
||||
|
||||
One can use `zts_get_peer_status(uint64_t peerId)` to query the current reachability state of another peer. This function will actually **return** value of the previously observed callback event for the given peer, plus an additional possible value `ZTS_EVENT_PEER_UNREACHABLE` if no known path exists between the calling node and the remote node.
|
||||
|
||||
<div style="page-break-after: always;"></div>
|
||||
|
||||
# Event handling
|
||||
## Event handling
|
||||
|
||||
As mentioned in previous sections, the control API works by use of non-blocking calls and the generation of a few dozen different event types. Depending on the type of event there may be additional contextual information attached to the `zts_callback_msg` object that you can use. This contextual information will be housed in one of the following structures which are defined in `include/ZeroTierSockets.h`:
|
||||
|
||||
@@ -154,7 +120,6 @@ struct zts_callback_msg
|
||||
struct zts_network_details *network;
|
||||
struct zts_netif_details *netif;
|
||||
struct zts_virtual_network_route *route;
|
||||
struct zts_physical_path *path;
|
||||
struct zts_peer_details *peer;
|
||||
struct zts_addr_details *addr;
|
||||
};
|
||||
@@ -179,106 +144,145 @@ In this callback function you can perform additional non-blocking API calls or o
|
||||
A typical ordering of messages may look like the following:
|
||||
|
||||
```
|
||||
ZTS_EVENT_NETIF_UP --- network=a09acf023be465c1, mac=73b7abcfc207, mtu=10000
|
||||
ZTS_EVENT_ADDR_NEW_IP4 --- addr=11.7.7.184 (on network=a09acf023be465c1)
|
||||
ZTS_EVENT_ADDR_NEW_IP6 --- addr=fda0:9acf:233:e4b0:7099:9309:4c9b:c3c7
|
||||
ZTS_EVENT_NODE_ONLINE, node=c4c7ba3cf
|
||||
ZTS_EVENT_NETWORK_READY_IP4 --- network=a09acf023be465c1
|
||||
ZTS_EVENT_NETWORK_READY_IP6 --- network=a09acf023be465c1
|
||||
ZTS_EVENT_PEER_DIRECT --- node=74d0f5e89d
|
||||
ZTS_EVENT_PEER_DIRECT --- node=9d219039f3
|
||||
ZTS_EVENT_PEER_DIRECT --- node=a09acf0233
|
||||
...
|
||||
ZTS_EVENT_NODE_ONLINE // Your node is ready to be used.
|
||||
ZTS_EVENT_ADDR_ADDED_IP4 // Your node received an IP address assignment on a given network.
|
||||
ZTS_EVENT_NETWORK_UPDATE // Something about a network changed.
|
||||
ZTS_EVENT_NETWORK_READY_IP4 // Your node has joined a network, has an address, and can send/receive traffic.
|
||||
ZTS_EVENT_PEER_RELAY // A peer was discovered but no direct path exists (yet.)
|
||||
...
|
||||
ZTS_EVENT_PEER_DIRECT // One or more direct paths to a peer were discovered.
|
||||
```
|
||||
|
||||
## Node Events
|
||||
|
||||
These events pertain to the state of the current node. This message type will arrive with a `zts_node_details` object accessible via `msg->node`. Additionally, one can query the status of the node with `zts_get_node_status()`, this will **return** the status as an integer value only.
|
||||
Accessible via `msg->node` as a `zts_node_details` object, this message type will contain information about the status of your node. *Possible values of `msg->eventCode`:*
|
||||
|
||||
```
|
||||
ZTS_EVENT_NODE_OFFLINE
|
||||
ZTS_EVENT_NODE_ONLINE
|
||||
ZTS_EVENT_NODE_DOWN
|
||||
ZTS_EVENT_NODE_IDENTITY_COLLISION
|
||||
ZTS_EVENT_NODE_UNRECOVERABLE_ERROR
|
||||
ZTS_EVENT_NODE_NORMAL_TERMINATION
|
||||
ZTS_EVENT_NODE_OFFLINE // Your node is offline.
|
||||
ZTS_EVENT_NODE_ONLINE // Your node is online and ready to communicate!
|
||||
ZTS_EVENT_NODE_DOWN // The node is down (for any reason.)
|
||||
ZTS_EVENT_NODE_IDENTITY_COLLISION // There is another node with the same identity causing a conflict.
|
||||
ZTS_EVENT_NODE_UNRECOVERABLE_ERROR // Something went wrong internally.
|
||||
ZTS_EVENT_NODE_NORMAL_TERMINATION // Your node has terminated.
|
||||
```
|
||||
|
||||
*Example contents of `msg->node`:*
|
||||
|
||||
```
|
||||
id : f746d550dd
|
||||
version : 1.4.6
|
||||
primaryPort : 9995
|
||||
secondaryPort : 0
|
||||
```
|
||||
|
||||
## Network Events
|
||||
|
||||
These events pertain to the state of the indicated network. This event type will arrive with a `zts_network_details` object accessible via `msg->network`. If for example you want to know the number of assigned routes for your network you can use `msg->network->num_routes`. Similarly for the MTU, use `msg->network->mtu`. Additionally, one can query the status of the network with `zts_get_network_status(uint64_t networkId)`, this will **return** the status as an integer value only.
|
||||
Accessible via `msg->network` as a `zts_network_details` object, this message type will contain information about the status of a particular network your node has joined. *Possible values of `msg->eventCode`:*
|
||||
|
||||
```
|
||||
ZTS_EVENT_NETWORK_NOT_FOUND
|
||||
ZTS_EVENT_NETWORK_CLIENT_TOO_OLD
|
||||
ZTS_EVENT_NETWORK_REQ_CONFIG
|
||||
ZTS_EVENT_NETWORK_OK
|
||||
ZTS_EVENT_NETWORK_ACCESS_DENIED
|
||||
ZTS_EVENT_NETWORK_READY_IP4
|
||||
ZTS_EVENT_NETWORK_READY_IP6
|
||||
ZTS_EVENT_NETWORK_DOWN
|
||||
ZTS_EVENT_NETWORK_NOT_FOUND // The network does not exist. The provided networkID may be incorrect.
|
||||
ZTS_EVENT_NETWORK_CLIENT_TOO_OLD // This client is too old.
|
||||
ZTS_EVENT_NETWORK_REQ_CONFIG // Waiting for network config, this might take a few seconds.
|
||||
ZTS_EVENT_NETWORK_OK // Node successfully joined.
|
||||
ZTS_EVENT_NETWORK_ACCESS_DENIED // The network is private. Your node requires authorization.
|
||||
ZTS_EVENT_NETWORK_READY_IP4 // Your node successfully received an IPv4 address.
|
||||
ZTS_EVENT_NETWORK_READY_IP6 // Your node successfully received an IPv6 address.
|
||||
ZTS_EVENT_NETWORK_DOWN // For some reason the network is no longer available.
|
||||
ZTS_EVENT_NETWORK_UPDATE // The network's config has changed: mtu, name, managed route, etc.
|
||||
```
|
||||
|
||||
*Example contents of `msg->network`:*
|
||||
|
||||
```
|
||||
nwid : 8bd712bf36bdae5f
|
||||
mac : ae53fa031fcf
|
||||
name : cranky_hayes
|
||||
type : 0
|
||||
mtu : 2800
|
||||
dhcp : 0
|
||||
bridge : 0
|
||||
broadcastEnabled : 1
|
||||
portError : 0
|
||||
netconfRevision : 34
|
||||
routeCount : 1
|
||||
multicastSubscriptionCount : 1
|
||||
- mac=ffffffffffff, adi=ac1b2561
|
||||
addresses:
|
||||
- FC5D:69B6:E0F7:46D5:50DD::1
|
||||
- 172.27.37.97
|
||||
routes:
|
||||
- target : 172.27.0.0
|
||||
- via : 0.0.0.0
|
||||
- flags : 0
|
||||
- metric : 0
|
||||
```
|
||||
|
||||
<div style="page-break-after: always;"></div>
|
||||
|
||||
## Peer Events
|
||||
|
||||
These events are triggered when the reachability status of a peer has changed, this can happen at any time. This event type will arrive with a `zts_peer_details` object for additional context. Additionally, one can query the status of the network with `zts_get_peer_status(uint64_t peerId)`, this will **return** the status as an integer value only.
|
||||
Accessible via `msg->peer` as a `zts_peer_details` object, this message type will contain information about a peer that was discovered by your node. These events are triggered when the reachability status of a peer has changed. *Possible values of `msg->eventCode`:*
|
||||
|
||||
```
|
||||
ZTS_EVENT_PEER_DIRECT
|
||||
ZTS_EVENT_PEER_RELAY
|
||||
ZTS_EVENT_PEER_UNREACHABLE
|
||||
ZTS_EVENT_PEER_DIRECT // At least one direct path to this peer is known.
|
||||
ZTS_EVENT_PEER_RELAY // No direct path to this peer is known. It will be relayed, (high packet loss and jitter.)
|
||||
ZTS_EVENT_PEER_UNREACHABLE // Peer is not reachable by any means.
|
||||
ZTS_EVENT_PEER_PATH_DISCOVERED // A new direct path to this peer has been discovered.
|
||||
ZTS_EVENT_PEER_PATH_DEAD // A direct path to this peer has expired.
|
||||
```
|
||||
|
||||
## Path Events
|
||||
|
||||
These events are triggered when a direct path to a peer has been discovered or is now considered too old to be used. You will see these in conjunction with peer events. This event type will arrive with a `zts_physical_path` object for additional context.
|
||||
*Example contents of `msg->peer`:*
|
||||
|
||||
```
|
||||
ZTS_EVENT_PATH_DISCOVERED
|
||||
ZTS_EVENT_PATH_ALIVE
|
||||
ZTS_EVENT_PATH_DEAD
|
||||
```
|
||||
|
||||
## Route Events
|
||||
|
||||
This event type will arrive with a `zts_virtual_network_route` object for additional context.
|
||||
|
||||
```
|
||||
ZTS_EVENT_ROUTE_ADDED
|
||||
ZTS_EVENT_ROUTE_REMOVED
|
||||
peer : a747d5502d
|
||||
role : 0
|
||||
latency : 4
|
||||
version : 1.4.6
|
||||
pathCount : 2
|
||||
- 172.27.37.97
|
||||
- F75D:69B6:E0C7:47D5:51DB::1
|
||||
```
|
||||
|
||||
## Address Events
|
||||
|
||||
These events are triggered when new addresses are assigned to the node on a particular virtual network. This event type will arrive with a `zts_addr_details` object for additional context.
|
||||
Accessible via `msg->addr` as a `zts_addr_details` object, this message type will contain information about addresses assign to your node on a particular network. The information contained in these events is also available via `ZTS_EVENT_NETWORK_UPDATE` events. *Possible values of `msg->eventCode`:*
|
||||
|
||||
```
|
||||
ZTS_EVENT_ADDR_ADDED_IP4
|
||||
ZTS_EVENT_ADDR_REMOVED_IP4
|
||||
ZTS_EVENT_ADDR_ADDED_IP6
|
||||
ZTS_EVENT_ADDR_REMOVED_IP6
|
||||
ZTS_EVENT_ADDR_ADDED_IP4 // A new IPv4 address was assigned to your node on the indicated network.
|
||||
ZTS_EVENT_ADDR_REMOVED_IP4 // An IPv4 address assignment to your node was removed on the indicated network.
|
||||
ZTS_EVENT_ADDR_ADDED_IP6 // A new IPv6 address was assigned to your node on the indicated network.
|
||||
ZTS_EVENT_ADDR_REMOVED_IP6 // An IPv6 address assignment to your node was removed on the indicated network.
|
||||
```
|
||||
|
||||
*Example contents of `msg->addr`:*
|
||||
|
||||
```
|
||||
nwid : a747d5502d
|
||||
addr : 172.27.37.97
|
||||
```
|
||||
|
||||
<div style="page-break-after: always;"></div>
|
||||
|
||||
# Error handling
|
||||
## Error handling
|
||||
|
||||
Calling a `zts_*` function will result in one of the following return codes. Only when `ZTS_ERR` is returned will `zts_errno` be set. Its values closely mirror those used in standard socket interfaces and are defined in `include/ZeroTierSockets.h`.
|
||||
|
||||
- `ZTS_ERR_OK`: No error
|
||||
- `ZTS_ERR_SOCKET`: Socket error (see `zts_errno`for more information)
|
||||
- `ZTS_ERR_SERVICE`: General ZeroTier internal error. Maybe you called something out of order?
|
||||
- `ZTS_ERR_ARG`: An argument provided is invalid.
|
||||
- `ZTS_ERR_NO_RESULT`: Call succeeded but no result was available. Not necessarily an error.
|
||||
- `ZTS_ERR_GENERAL`: General internal failure. Consider filing a bug report.
|
||||
```
|
||||
ZTS_ERR_OK // No error
|
||||
ZTS_ERR_SOCKET // Socket error (see zts_errno for more information)
|
||||
ZTS_ERR_SERVICE // General ZeroTier internal error. Maybe you called something out of order?
|
||||
ZTS_ERR_ARG // An argument provided is invalid.
|
||||
ZTS_ERR_NO_RESULT // Call succeeded but no result was available. Not necessarily an error.
|
||||
ZTS_ERR_GENERAL // General internal failure. Consider filing a bug report.
|
||||
```
|
||||
|
||||
*NOTE: For Android/Java (or similar) which use JNI, the socket API's error codes are negative values encoded in the return values of function calls*
|
||||
*NOTE: For protocol-level errors (such as dropped packets) or internal network stack errors, see the section `Statistics`*
|
||||
|
||||
<div style="page-break-after: always;"></div>
|
||||
|
||||
# Common pitfalls
|
||||
## Common pitfalls
|
||||
|
||||
- If you have started a node but have not received a `ZTS_EVENT_NODE_ONLINE`:
|
||||
- You may need to view our [Router Config Tips](https://zerotier.atlassian.net/wiki/spaces/SD/pages/6815768/Router+Configuration+Tips) knowledgebase article. Sometimes this is due to firewall/NAT settings.
|
||||
@@ -288,18 +292,18 @@ Calling a `zts_*` function will result in one of the following return codes. Onl
|
||||
- Used an improper integer representation for your network ID (e.g. `int` instead of `uint64_t`).
|
||||
|
||||
- If you are unable to reliably connect to peers:
|
||||
- You should first read the section on **Connecting and communicating with peers**.
|
||||
- You should first read the section on [Connecting and communicating with peers](#connecting-and-communicating-with-peers).
|
||||
- If the previous step doesn't help move onto our knowledgebase article [Router Config Tips](https://zerotier.atlassian.net/wiki/spaces/SD/pages/6815768/Router+Configuration+Tips). Sometimes this can be a transport-triggered link issue, and sometimes it can be a firewall/NAT issue.
|
||||
|
||||
- API calls seem to fail in nonsensical ways and you're tearing your hair out:
|
||||
- Be sure to read and understand the **API compatibility with host OS** section.
|
||||
- See the **Debugging** section for more advice.
|
||||
- Be sure to read and understand the [API compatibility with host OS](#api-compatibility-with-host-os) section.
|
||||
- See the [Debugging](#debugging) section for more advice.
|
||||
|
||||
<div style="page-break-after: always;"></div>
|
||||
|
||||
# API compatibility with host OS
|
||||
## API compatibility with host OS
|
||||
|
||||
Since libzt re-implements a socket interface likely very similar to your host OS's own interface it may be tempting to mix and match host OS structures and functions with those of libzt. This may work on occasion, but you are tempting fate, here are a few important guidelines:
|
||||
Since libzt re-implements a socket interface likely very similar to your host OS's own interface it may be tempting to mix and match host OS structures and functions with those of libzt. This may work on occasion, but you are tempting fate. Here are a few important guidelines:
|
||||
|
||||
If you are calling a `zts_*` function, use the appropriate `ZTS_*` constants:
|
||||
```
|
||||
@@ -330,21 +334,21 @@ inet_ntop(AF_INET6, &(in6->sin6_addr), dstStr, INET6_ADDRSTRLEN);
|
||||
|
||||
<div style="page-break-after: always;"></div>
|
||||
|
||||
# Thread model
|
||||
## Thread model (advanced)
|
||||
|
||||
The control API for `libzt` is thread safe and can be called at any time from any thread. There is a single internal lock guarding access to this API. The socket API is similar in this regard. Callback events are generated by a separate thread and are independent from the rest of the API's internal locking mechanism. Not returning from a callback event won't impact the rest of the API but it will prevent your application from receiving future events so it is in your application's best interest to perform as little work as possible in the callback function and promptly return control back to ZeroTier.
|
||||
Both the **socket** and **control** interfaces are thread-safe but are implemented differently. The socket interface is implemented using a relatively performant core locking mechanism in lwIP. This can be disabled if you know what you're doing. The control interface is implemented by a single coarse-grained lock. This lock is not a performance bottleneck since it only applies to functions that manipulate the ZeroTier service and are called seldomly. Callback events are generated by a separate thread and are independent from the rest of the API's internal locking mechanism. Not returning from a callback event won't impact the rest of the API but it will prevent your application from receiving future events so it is in your application's best interest to perform as little work as possible in the callback function and promptly return control back to ZeroTier.
|
||||
|
||||
*Note: Internally, `libzt` will spawn a number of threads for various purposes: a thread for the core service, a thread for the network stack, a low priority thread to process callback events, and a thread for each network joined. The vast majority of work is performed by the core service and stack threads.*
|
||||
|
||||
<div style="page-break-after: always;"></div>
|
||||
|
||||
# Debugging
|
||||
## Debugging
|
||||
|
||||
If you're experiencing odd behavior or something that looks like a bug I would suggest first reading and understanding the following sections:
|
||||
|
||||
* **Common pitfalls**
|
||||
* **API compatibility with host OS**
|
||||
* **Thread model**
|
||||
* [Common pitfalls](#common-pitfalls)
|
||||
* [API compatibility with host OS](#api-compatibility-with-host-os)
|
||||
* [Thread model](#thread-model)
|
||||
|
||||
If the information in those sections hasn't helped, there are a couple of ways to get debug traces out of various parts of the library.
|
||||
|
||||
@@ -356,52 +360,19 @@ If the information in those sections hasn't helped, there are a couple of ways t
|
||||
|
||||
```
|
||||
struct zts_stats_proto stats;
|
||||
|
||||
// Get count of received pings
|
||||
if (zts_get_protocol_stats(ZTS_STATS_PROTOCOL_ICMP, &stats) == ZTS_ERR_OK) {
|
||||
printf("icmp.recv=%d\n", stats.recv);
|
||||
printf("icmp.recv=%d\n", stats.recv); // Count of received pings
|
||||
}
|
||||
|
||||
// Get count of dropped TCP packets
|
||||
if (zts_get_protocol_stats(ZTS_STATS_PROTOCOL_TCP, &stats) == ZTS_ERR_OK) {
|
||||
printf("tcp.drop=%d\n", stats.drop);
|
||||
printf("tcp.drop=%d\n", stats.drop); // Count of dropped TCP packets
|
||||
}
|
||||
```
|
||||
|
||||
4) There are a series of additional events which can signal whether the network stack or its virtual network interfaces have been set up properly:
|
||||
4) There are a series of additional events which can signal whether the network stack or its virtual network interfaces have been set up properly. See `ZTS_EVENT_STACK_*` and `ZTS_EVENT_NETIF_*`.
|
||||
|
||||
<div style="page-break-after: always;"></div>
|
||||
|
||||
**Network stack events** - These signal whether the userspace networking stack was brought up successfully. You can ignore these in most cases. This event type will arrive with no additional contextual information.
|
||||
|
||||
```
|
||||
ZTS_EVENT_STACK_UP
|
||||
ZTS_EVENT_STACK_DOWN
|
||||
```
|
||||
|
||||
**Netif events** - These signal whether the userspace networking stack was brought up successfully. You can ignore these in most cases. This event type will arrive with a `zts_netif_details` object for additional context.
|
||||
|
||||
```
|
||||
ZTS_EVENT_NETIF_UP
|
||||
ZTS_EVENT_NETIF_DOWN
|
||||
ZTS_EVENT_NETIF_REMOVED
|
||||
ZTS_EVENT_NETIF_LINK_UP
|
||||
ZTS_EVENT_NETIF_LINK_DOWN
|
||||
```
|
||||
|
||||
<div style="page-break-after: always;"></div>
|
||||
|
||||
# Network controller mode
|
||||
|
||||
The library form of ZeroTier can act as a network controller and in `libzt` this is controlled via the `zts_controller_*` API calls specified in `include/ZeroTierSockets.h`. Currently controller mode is not available in the `iOS` and `macOS` framework builds.
|
||||
|
||||
# Multipath
|
||||
|
||||
The multipath features available in ZeroTier haven't yet been exposed via the `libzt` API but this is coming in the version `2.X` series.
|
||||
|
||||
<div style="page-break-after: always;"></div>
|
||||
|
||||
# Licensing
|
||||
## Licensing
|
||||
|
||||
ZeroTier is licensed under the BSL version 1.1. See [LICENSE.txt](./LICENSE.txt) and the ZeroTier pricing page for details. ZeroTier is free to use internally in businesses and academic institutions and for non-commercial purposes. Certain types of commercial use such as building closed-source apps and devices based on ZeroTier or offering ZeroTier network controllers and network management as a SaaS service require a commercial license.
|
||||
|
||||
|
||||
@@ -92,8 +92,9 @@
|
||||
|
||||
#include "ZeroTierSockets.h"
|
||||
|
||||
#ifdef __WINDOWS__
|
||||
#include "winsock.h"
|
||||
|
||||
#endif
|
||||
struct Node
|
||||
{
|
||||
Node() : online(false), joinedAtLeastOneNetwork(false), id(0) {}
|
||||
@@ -117,8 +118,7 @@ void printPeerDetails(const char *msgStr, struct zts_peer_details *d)
|
||||
printf("\n%s\n", msgStr);
|
||||
printf("\t- peer : %llx\n", d->address);
|
||||
printf("\t- role : %llx\n", d->role);
|
||||
printf("\t- latency : %llx\n", d->latency);
|
||||
printf("\t- pathCount : %llx\n", d->pathCount);
|
||||
printf("\t- latency : %d\n", d->latency);
|
||||
printf("\t- version : %d.%d.%d\n", d->versionMajor, d->versionMinor, d->versionRev);
|
||||
printf("\t- pathCount : %d\n", d->pathCount);
|
||||
printf("\t- paths:\n");
|
||||
@@ -128,7 +128,7 @@ void printPeerDetails(const char *msgStr, struct zts_peer_details *d)
|
||||
char ipstr[ZTS_INET6_ADDRSTRLEN];
|
||||
int port = 0;
|
||||
struct zts_sockaddr *sa = (struct zts_sockaddr *)&(d->paths[j].address);
|
||||
if (sa->sa_family == ZTS_AF_INET) { // TODO: Probably broken
|
||||
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), ipstr, ZTS_INET_ADDRSTRLEN);
|
||||
port = zts_ntohs(in4->sin_port);
|
||||
@@ -373,7 +373,6 @@ void display_stack_stats()
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
fprintf(stderr, "AF_INET=%d, SOCK_STREAM=%d, IPPROTO_TCP=%d", AF_INET, SOCK_STREAM, IPPROTO_TCP);
|
||||
if (argc != 4) {
|
||||
printf("\nlibzt example server\n");
|
||||
printf("comprehensive <config_file_path> <nwid> <ztServicePort>\n");
|
||||
|
||||
@@ -59,6 +59,7 @@ extern "C" {
|
||||
#define ZTS_EVENT_NETWORK_READY_IP6 216
|
||||
#define ZTS_EVENT_NETWORK_READY_IP4_IP6 217
|
||||
#define ZTS_EVENT_NETWORK_DOWN 218
|
||||
#define ZTS_EVENT_NETWORK_UPDATE 219
|
||||
// Network Stack events
|
||||
#define ZTS_EVENT_STACK_UP 220
|
||||
#define ZTS_EVENT_STACK_DOWN 221
|
||||
@@ -72,18 +73,16 @@ extern "C" {
|
||||
#define ZTS_EVENT_PEER_DIRECT 240
|
||||
#define ZTS_EVENT_PEER_RELAY 241
|
||||
#define ZTS_EVENT_PEER_UNREACHABLE 242
|
||||
// Path events
|
||||
#define ZTS_EVENT_PATH_DISCOVERED 250
|
||||
#define ZTS_EVENT_PATH_ALIVE 251
|
||||
#define ZTS_EVENT_PATH_DEAD 252
|
||||
#define ZTS_EVENT_PEER_PATH_DISCOVERED 243
|
||||
#define ZTS_EVENT_PEER_PATH_DEAD 244
|
||||
// Route events
|
||||
#define ZTS_EVENT_ROUTE_ADDED 260
|
||||
#define ZTS_EVENT_ROUTE_REMOVED 261
|
||||
#define ZTS_EVENT_ROUTE_ADDED 250
|
||||
#define ZTS_EVENT_ROUTE_REMOVED 251
|
||||
// Address events
|
||||
#define ZTS_EVENT_ADDR_ADDED_IP4 270
|
||||
#define ZTS_EVENT_ADDR_REMOVED_IP4 271
|
||||
#define ZTS_EVENT_ADDR_ADDED_IP6 272
|
||||
#define ZTS_EVENT_ADDR_REMOVED_IP6 273
|
||||
#define ZTS_EVENT_ADDR_ADDED_IP4 260
|
||||
#define ZTS_EVENT_ADDR_REMOVED_IP4 261
|
||||
#define ZTS_EVENT_ADDR_ADDED_IP6 262
|
||||
#define ZTS_EVENT_ADDR_REMOVED_IP6 263
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// Return Error codes //
|
||||
@@ -345,7 +344,7 @@ typedef uint16_t zts_in_port_t;
|
||||
typedef uint8_t zts_sa_family_t;
|
||||
|
||||
struct zts_in_addr {
|
||||
#if defined(__WINDOWS__)
|
||||
#if defined(_WIN32)
|
||||
zts_in_addr_t S_addr;
|
||||
#else
|
||||
// A definition in winsock may conflict with s_addr
|
||||
@@ -394,9 +393,7 @@ struct zts_sockaddr_storage {
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// Subset of: ZeroTierOne.h //
|
||||
// We redefine a few ZT structures here so that we don't need to drag the //
|
||||
// entire ZeroTierOne.h file into the user application //
|
||||
// Structures used to convey details during various callback events //
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
@@ -412,7 +409,7 @@ struct zts_sockaddr_storage {
|
||||
/**
|
||||
* Maximum number of direct network paths to a given peer
|
||||
*/
|
||||
#define ZT_MAX_PEER_NETWORK_PATHS 16
|
||||
#define ZTS_MAX_PEER_NETWORK_PATHS 16
|
||||
|
||||
/**
|
||||
* What trust hierarchy role does this peer have?
|
||||
@@ -424,10 +421,6 @@ enum zts_peer_role
|
||||
ZTS_PEER_ROLE_PLANET = 2 // planetary root
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// Structures used to convey details during various callback events //
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
* A structure used to convey details about the current node
|
||||
* to the user application
|
||||
@@ -439,41 +432,17 @@ struct zts_node_details
|
||||
*/
|
||||
uint64_t address;
|
||||
|
||||
/**
|
||||
* The current clock value accord to the node
|
||||
*/
|
||||
uint64_t clock;
|
||||
|
||||
/**
|
||||
* Whether or not this node is online
|
||||
*/
|
||||
uint8_t online;
|
||||
|
||||
/**
|
||||
* Whether port mapping is enabled
|
||||
*/
|
||||
uint8_t portMappingEnabled;
|
||||
|
||||
/**
|
||||
* Whether multipath support is enabled. If true, this node will
|
||||
* be capable of utilizing multiple physical links simultaneously
|
||||
* to create higher quality or more robust aggregate links.
|
||||
*
|
||||
* See: https://www.zerotier.com/manual.shtml#2_1_5
|
||||
*/
|
||||
uint8_t multipathEnabled;
|
||||
|
||||
/**
|
||||
* The port used by the service to send and receive
|
||||
* all encapsulated traffic
|
||||
*/
|
||||
uint16_t primaryPort;
|
||||
uint16_t secondaryPort;
|
||||
uint16_t tertiaryPort;
|
||||
|
||||
/**
|
||||
* Planet ID
|
||||
* ZT version
|
||||
*/
|
||||
uint64_t planetWorldId;
|
||||
uint64_t planetWorldTimestamp;
|
||||
uint8_t versionMajor;
|
||||
uint8_t versionMinor;
|
||||
uint8_t versionRev;
|
||||
@@ -494,7 +463,6 @@ struct zts_callback_msg
|
||||
struct zts_network_details *network;
|
||||
struct zts_netif_details *netif;
|
||||
struct zts_virtual_network_route *route;
|
||||
struct zts_physical_path *path;
|
||||
struct zts_peer_details *peer;
|
||||
struct zts_addr_details *addr;
|
||||
};
|
||||
@@ -525,26 +493,6 @@ struct zts_netif_details
|
||||
* The MTU for this interface
|
||||
*/
|
||||
int mtu;
|
||||
|
||||
/**
|
||||
* The IPv4 address assigned to this interface.
|
||||
*/
|
||||
//struct sockaddr_in ip4_addr;
|
||||
|
||||
/**
|
||||
* The IPv6 addresses assigned to this interface.
|
||||
*/
|
||||
//struct sockaddr_in6 ip6_addr[LWIP_IPV6_NUM_ADDRESSES];
|
||||
|
||||
/**
|
||||
* Number of IPv4 addresses assigned to this interface
|
||||
*/
|
||||
//int num_ip4_addr;
|
||||
|
||||
/**
|
||||
* Number of IPv6 addresses assigned to this interface
|
||||
*/
|
||||
//int num_ip6_addr;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -573,42 +521,216 @@ struct zts_virtual_network_route
|
||||
uint16_t metric;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* A structure used to convey network-specific details to the user application
|
||||
* Maximum length of network short name
|
||||
*/
|
||||
#define ZTS_MAX_NETWORK_SHORT_NAME_LENGTH 127
|
||||
|
||||
/**
|
||||
* Maximum number of pushed routes on a network
|
||||
*/
|
||||
#define ZTS_MAX_NETWORK_ROUTES 32
|
||||
|
||||
/**
|
||||
* Maximum number of statically assigned IP addresses per network endpoint using ZT address management (not DHCP)
|
||||
*/
|
||||
#define ZTS_MAX_ZT_ASSIGNED_ADDRESSES 16
|
||||
|
||||
/**
|
||||
* Maximum number of multicast groups a device / network interface can be subscribed to at once
|
||||
*/
|
||||
#define ZTS_MAX_MULTICAST_SUBSCRIPTIONS 1024
|
||||
|
||||
/**
|
||||
* Virtual network status codes
|
||||
*/
|
||||
enum ZTS_VirtualNetworkStatus
|
||||
{
|
||||
/**
|
||||
* Waiting for network configuration (also means revision == 0)
|
||||
*/
|
||||
ZTS_NETWORK_STATUS_REQUESTING_CONFIGURATION = 0,
|
||||
|
||||
/**
|
||||
* Configuration received and we are authorized
|
||||
*/
|
||||
ZTS_NETWORK_STATUS_OK = 1,
|
||||
|
||||
/**
|
||||
* Netconf master told us 'nope'
|
||||
*/
|
||||
ZTS_NETWORK_STATUS_ACCESS_DENIED = 2,
|
||||
|
||||
/**
|
||||
* Netconf master exists, but this virtual network does not
|
||||
*/
|
||||
ZTS_NETWORK_STATUS_NOT_FOUND = 3,
|
||||
|
||||
/**
|
||||
* Initialization of network failed or other internal error
|
||||
*/
|
||||
ZTS_NETWORK_STATUS_PORT_ERROR = 4,
|
||||
|
||||
/**
|
||||
* ZeroTier core version too old
|
||||
*/
|
||||
ZTS_NETWORK_STATUS_CLIENT_TOO_OLD = 5
|
||||
};
|
||||
|
||||
/**
|
||||
* Virtual network type codes
|
||||
*/
|
||||
enum ZTS_VirtualNetworkType
|
||||
{
|
||||
/**
|
||||
* Private networks are authorized via certificates of membership
|
||||
*/
|
||||
ZTS_NETWORK_TYPE_PRIVATE = 0,
|
||||
|
||||
/**
|
||||
* Public networks have no access control -- they'll always be AUTHORIZED
|
||||
*/
|
||||
ZTS_NETWORK_TYPE_PUBLIC = 1
|
||||
};
|
||||
|
||||
/**
|
||||
* A route to be pushed on a virtual network
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
/**
|
||||
* Target network / netmask bits (in port field) or NULL or 0.0.0.0/0 for default
|
||||
*/
|
||||
struct zts_sockaddr_storage target;
|
||||
|
||||
/**
|
||||
* Gateway IP address (port ignored) or NULL (family == 0) for LAN-local (no gateway)
|
||||
*/
|
||||
struct zts_sockaddr_storage via;
|
||||
|
||||
/**
|
||||
* Route flags
|
||||
*/
|
||||
uint16_t flags;
|
||||
|
||||
/**
|
||||
* Route metric (not currently used)
|
||||
*/
|
||||
uint16_t metric;
|
||||
} ZTS_VirtualNetworkRoute;
|
||||
|
||||
/**
|
||||
* Virtual network configuration
|
||||
*/
|
||||
struct zts_network_details
|
||||
{
|
||||
/**
|
||||
* Network ID
|
||||
* 64-bit ZeroTier network ID
|
||||
*/
|
||||
uint64_t nwid;
|
||||
|
||||
/**
|
||||
* Maximum Transmission Unit size for this network
|
||||
* Ethernet MAC (48 bits) that should be assigned to port
|
||||
*/
|
||||
int mtu;
|
||||
uint64_t mac;
|
||||
|
||||
/**
|
||||
* Number of addresses (actually) assigned to the node on this network
|
||||
* Network name (from network configuration master)
|
||||
*/
|
||||
short num_addresses;
|
||||
char name[ZTS_MAX_NETWORK_SHORT_NAME_LENGTH + 1];
|
||||
|
||||
/**
|
||||
* Array of IPv4 and IPv6 addresses assigned to the node on this network
|
||||
* Network configuration request status
|
||||
*/
|
||||
struct zts_sockaddr_storage addr[ZTS_MAX_ASSIGNED_ADDRESSES];
|
||||
enum ZTS_VirtualNetworkStatus status;
|
||||
|
||||
/**
|
||||
* Number of routes
|
||||
* Network type
|
||||
*/
|
||||
unsigned int num_routes;
|
||||
enum ZTS_VirtualNetworkType type;
|
||||
|
||||
/**
|
||||
* Array of IPv4 and IPv6 addresses assigned to the node on this network
|
||||
* Maximum interface MTU
|
||||
*/
|
||||
struct zts_virtual_network_route routes[ZTS_MAX_NETWORK_ROUTES];
|
||||
unsigned int mtu;
|
||||
|
||||
/**
|
||||
* If nonzero, the network this port belongs to indicates DHCP availability
|
||||
*
|
||||
* This is a suggestion. The underlying implementation is free to ignore it
|
||||
* for security or other reasons. This is simply a netconf parameter that
|
||||
* means 'DHCP is available on this network.'
|
||||
*/
|
||||
int dhcp;
|
||||
|
||||
/**
|
||||
* If nonzero, this port is allowed to bridge to other networks
|
||||
*
|
||||
* This is informational. If this is false (0), bridged packets will simply
|
||||
* be dropped and bridging won't work.
|
||||
*/
|
||||
int bridge;
|
||||
|
||||
/**
|
||||
* If nonzero, this network supports and allows broadcast (ff:ff:ff:ff:ff:ff) traffic
|
||||
*/
|
||||
int broadcastEnabled;
|
||||
|
||||
/**
|
||||
* If the network is in PORT_ERROR state, this is the (negative) error code most recently reported
|
||||
*/
|
||||
int portError;
|
||||
|
||||
/**
|
||||
* Revision number as reported by controller or 0 if still waiting for config
|
||||
*/
|
||||
unsigned long netconfRevision;
|
||||
|
||||
/**
|
||||
* Number of assigned addresses
|
||||
*/
|
||||
unsigned int assignedAddressCount;
|
||||
|
||||
/**
|
||||
* ZeroTier-assigned addresses (in sockaddr_storage structures)
|
||||
*
|
||||
* For IP, the port number of the sockaddr_XX structure contains the number
|
||||
* of bits in the address netmask. Only the IP address and port are used.
|
||||
* Other fields like interface number can be ignored.
|
||||
*
|
||||
* This is only used for ZeroTier-managed address assignments sent by the
|
||||
* virtual network's configuration master.
|
||||
*/
|
||||
struct zts_sockaddr_storage assignedAddresses[ZTS_MAX_ZT_ASSIGNED_ADDRESSES];
|
||||
|
||||
/**
|
||||
* Number of ZT-pushed routes
|
||||
*/
|
||||
unsigned int routeCount;
|
||||
|
||||
/**
|
||||
* Routes (excluding those implied by assigned addresses and their masks)
|
||||
*/
|
||||
ZTS_VirtualNetworkRoute routes[ZTS_MAX_NETWORK_ROUTES];
|
||||
|
||||
/**
|
||||
* Number of multicast groups subscribed
|
||||
*/
|
||||
unsigned int multicastSubscriptionCount;
|
||||
|
||||
/**
|
||||
* Multicast groups to which this network's device is subscribed
|
||||
*/
|
||||
struct {
|
||||
uint64_t mac; /* MAC in lower 48 bits */
|
||||
uint32_t adi; /* Additional distinguishing information, usually zero except for IPv4 ARP groups */
|
||||
} multicastSubscriptions[ZTS_MAX_MULTICAST_SUBSCRIPTIONS];
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Physical network path to a peer
|
||||
*/
|
||||
@@ -688,7 +810,7 @@ struct zts_peer_details
|
||||
/**
|
||||
* Known network paths to peer
|
||||
*/
|
||||
struct zts_physical_path paths[ZT_MAX_PEER_NETWORK_PATHS];
|
||||
struct zts_physical_path paths[ZTS_MAX_PEER_NETWORK_PATHS];
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -704,15 +826,15 @@ struct zts_peer_list
|
||||
// ZeroTier Service Controls //
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#if defined(__WINDOWS__)
|
||||
#if defined(_WIN32)
|
||||
#ifdef ADD_EXPORTS
|
||||
#define ZT_SOCKET_API __declspec(dllexport)
|
||||
#define ZTS_API __declspec(dllexport)
|
||||
#else
|
||||
#define ZT_SOCKET_API __declspec(dllimport)
|
||||
#define ZTS_API __declspec(dllimport)
|
||||
#endif
|
||||
#define ZTCALL __cdecl
|
||||
#else
|
||||
#define ZT_SOCKET_API
|
||||
#define ZTS_API
|
||||
#define ZTCALL
|
||||
#endif
|
||||
|
||||
@@ -730,7 +852,7 @@ struct zts_peer_list
|
||||
* @param enabled Whether or not this feature is enabled
|
||||
* @return ZTS_ERR_OK on success. ZTS_ERR_SERVICE on failure.
|
||||
*/
|
||||
ZT_SOCKET_API int ZTCALL zts_allow_network_caching(uint8_t allowed);
|
||||
ZTS_API int ZTCALL zts_allow_network_caching(uint8_t allowed);
|
||||
|
||||
/**
|
||||
* @brief Enable or disable whether the service will cache peer details (enabled by default)
|
||||
@@ -746,7 +868,7 @@ ZT_SOCKET_API int ZTCALL zts_allow_network_caching(uint8_t allowed);
|
||||
* @param enabled Whether or not this feature is enabled
|
||||
* @return ZTS_ERR_OK on success. ZTS_ERR_SERVICE on failure.
|
||||
*/
|
||||
ZT_SOCKET_API int ZTCALL zts_allow_peer_caching(uint8_t allowed);
|
||||
ZTS_API int ZTCALL zts_allow_peer_caching(uint8_t allowed);
|
||||
|
||||
/**
|
||||
* @brief Enable or disable whether the service will read from a local.conf
|
||||
@@ -756,7 +878,7 @@ ZT_SOCKET_API int ZTCALL zts_allow_peer_caching(uint8_t allowed);
|
||||
* @param enabled Whether or not this feature is enabled
|
||||
* @return ZTS_ERR_OK on success. ZTS_ERR_SERVICE on failure.
|
||||
*/
|
||||
ZT_SOCKET_API int ZTCALL zts_allow_local_conf(uint8_t allowed);
|
||||
ZTS_API int ZTCALL zts_allow_local_conf(uint8_t allowed);
|
||||
|
||||
/**
|
||||
* @brief Starts the ZeroTier service and notifies user application of events via callback
|
||||
@@ -765,7 +887,7 @@ ZT_SOCKET_API int ZTCALL zts_allow_local_conf(uint8_t allowed);
|
||||
* @param callback User-specified callback for ZTS_EVENT_* events
|
||||
* @return ZTS_ERR_OK on success. ZTS_ERR_SERVICE or ZTS_ERR_ARG on failure
|
||||
*/
|
||||
ZT_SOCKET_API int ZTCALL zts_start(const char *path, void (*callback)(void *), uint16_t port);
|
||||
ZTS_API int ZTCALL zts_start(const char *path, void (*callback)(void *), uint16_t port);
|
||||
|
||||
/**
|
||||
* @brief Stops the ZeroTier service and brings down all virtual network interfaces
|
||||
@@ -775,7 +897,7 @@ ZT_SOCKET_API int ZTCALL zts_start(const char *path, void (*callback)(void *), u
|
||||
* and free all resources use zts_free() instead.
|
||||
* @return ZTS_ERR_OK on success. ZTS_ERR_SERVICE on failure.
|
||||
*/
|
||||
ZT_SOCKET_API int ZTCALL zts_stop();
|
||||
ZTS_API int ZTCALL zts_stop();
|
||||
|
||||
/**
|
||||
* @brief Restart the ZeroTier service.
|
||||
@@ -785,7 +907,7 @@ ZT_SOCKET_API int ZTCALL zts_stop();
|
||||
* startup callback events.
|
||||
* @return ZTS_ERR_OK on success. ZTS_ERR_SERVICE on failure.
|
||||
*/
|
||||
ZT_SOCKET_API int ZTCALL zts_restart();
|
||||
ZTS_API int ZTCALL zts_restart();
|
||||
|
||||
/**
|
||||
* @brief Stop all background services, bring down all interfaces, free all resources. After
|
||||
@@ -796,49 +918,23 @@ ZT_SOCKET_API int ZTCALL zts_restart();
|
||||
* communicating over ZeroTier
|
||||
* @return ZTS_ERR_OK on success. ZTS_ERR_SERVICE on failure.
|
||||
*/
|
||||
ZT_SOCKET_API int ZTCALL zts_free();
|
||||
|
||||
/**
|
||||
* @brief Populate a structure with details for a given network
|
||||
*
|
||||
* @param nwid A 16-digit hexadecimal virtual network ID
|
||||
* @param nd Pointer to a zts_network_details structure to populate
|
||||
* @return ZTS_ERR_OK on success. ZTS_ERR_SERVICE or ZTS_ERR_ARG on failure.
|
||||
*/
|
||||
ZT_SOCKET_API int ZTCALL zts_get_network_details(uint64_t nwid, struct zts_network_details *nd);
|
||||
|
||||
/**
|
||||
* @brief Populate an array of structures with details for any given number of networks
|
||||
*
|
||||
* @param nds Pointer to an array of zts_network_details structures to populate
|
||||
* @param num Number of zts_network_details structures available to copy data into, will be updated
|
||||
* to reflect number of structures that were actually populated
|
||||
* @return ZTS_ERR_OK on success. ZTS_ERR_SERVICE or ZTS_ERR_ARG on failure.
|
||||
*/
|
||||
ZT_SOCKET_API int ZTCALL zts_get_all_network_details(struct zts_network_details *nds, int *num);
|
||||
ZTS_API int ZTCALL zts_free();
|
||||
|
||||
/**
|
||||
* @brief Join a network
|
||||
*
|
||||
* @param nwid A 16-digit hexadecimal virtual network ID
|
||||
* @param networkId A 16-digit hexadecimal virtual network ID
|
||||
* @return ZTS_ERR_OK on success. ZTS_ERR_SERVICE or ZTS_ERR_ARG on failure.
|
||||
*/
|
||||
ZT_SOCKET_API int ZTCALL zts_join(const uint64_t nwid);
|
||||
ZTS_API int ZTCALL zts_join(const uint64_t networkId);
|
||||
|
||||
/**
|
||||
* @brief Leave a network
|
||||
*
|
||||
* @param nwid A 16-digit hexadecimal virtual network ID
|
||||
* @param networkId A 16-digit hexadecimal virtual network ID
|
||||
* @return ZTS_ERR_OK on success. ZTS_ERR_SERVICE or ZTS_ERR_ARG on failure.
|
||||
*/
|
||||
ZT_SOCKET_API int ZTCALL zts_leave(const uint64_t nwid);
|
||||
|
||||
/**
|
||||
* @brief Leave all networks
|
||||
*
|
||||
* @return ZTS_ERR_OK on success. ZTS_ERR_SERVICE or ZTS_ERR_ARG on failure.
|
||||
*/
|
||||
ZT_SOCKET_API int ZTCALL zts_leave_all();
|
||||
ZTS_API int ZTCALL zts_leave(const uint64_t networkId);
|
||||
|
||||
/**
|
||||
* @brief Orbit a given moon (user-defined root server)
|
||||
@@ -847,7 +943,7 @@ ZT_SOCKET_API int ZTCALL zts_leave_all();
|
||||
* @param moonSeed A 16-digit hexadecimal seed ID
|
||||
* @return ZTS_ERR_OK on success. ZTS_ERR_SERVICE or ZTS_ERR_ARG on failure.
|
||||
*/
|
||||
ZT_SOCKET_API int ZTCALL zts_orbit(uint64_t moonWorldId, uint64_t moonSeed);
|
||||
ZTS_API int ZTCALL zts_orbit(uint64_t moonWorldId, uint64_t moonSeed);
|
||||
|
||||
/**
|
||||
* @brief De-orbit a given moon (user-defined root server)
|
||||
@@ -855,36 +951,28 @@ ZT_SOCKET_API int ZTCALL zts_orbit(uint64_t moonWorldId, uint64_t moonSeed);
|
||||
* @param moonWorldId A 16-digit world ID
|
||||
* @return ZTS_ERR_OK on success. ZTS_ERR_SERVICE or ZTS_ERR_ARG on failure.
|
||||
*/
|
||||
ZT_SOCKET_API int ZTCALL zts_deorbit(uint64_t moonWorldId);
|
||||
|
||||
/**
|
||||
* @brief Return the node ID of this instance
|
||||
*
|
||||
* @return 64-bit node ID
|
||||
*/
|
||||
ZT_SOCKET_API uint64_t ZTCALL zts_get_node_id();
|
||||
ZTS_API int ZTCALL zts_deorbit(uint64_t moonWorldId);
|
||||
|
||||
/**
|
||||
* @brief Compute a 6PLANE IPv6 address for the given Network ID and Node ID
|
||||
*
|
||||
* @param addr Destination structure for address
|
||||
* @param nwid Network ID
|
||||
* @param networkId Network ID
|
||||
* @param nodeId Node ID
|
||||
* @return ZTS_ERR_OK on success. ZTS_ERR_ARG on failure.
|
||||
*/
|
||||
ZT_SOCKET_API int ZTCALL zts_get_6plane_addr(
|
||||
struct zts_sockaddr_storage *addr, const uint64_t nwid, const uint64_t nodeId);
|
||||
ZTS_API int ZTCALL zts_get_6plane_addr(struct zts_sockaddr_storage *addr, const uint64_t networkId, const uint64_t nodeId);
|
||||
|
||||
/**
|
||||
* @brief Compute a RFC4193 IPv6 address for the given Network ID and Node ID
|
||||
*
|
||||
* @param addr Destination structure for address
|
||||
* @param nwid Network ID
|
||||
* @param networkId Network ID
|
||||
* @param nodeId Node ID
|
||||
* @return ZTS_ERR_OK on success. ZTS_ERR_ARG on failure.
|
||||
*/
|
||||
ZT_SOCKET_API int ZTCALL zts_get_rfc4193_addr(
|
||||
struct zts_sockaddr_storage *addr, const uint64_t nwid, const uint64_t nodeId);
|
||||
ZTS_API int ZTCALL zts_get_rfc4193_addr(
|
||||
struct zts_sockaddr_storage *addr, const uint64_t networkId, const uint64_t nodeId);
|
||||
|
||||
/**
|
||||
* @brief Compute a RFC4193 IPv6 address for the given Network ID and Node ID
|
||||
@@ -915,71 +1003,15 @@ ZT_SOCKET_API int ZTCALL zts_get_rfc4193_addr(
|
||||
* @param endPortOfRange End of allowed port range
|
||||
* @return An Ad-hoc network ID
|
||||
*/
|
||||
ZT_SOCKET_API uint64_t ZTCALL zts_generate_adhoc_nwid_from_range(
|
||||
ZTS_API uint64_t ZTCALL zts_generate_adhoc_nwid_from_range(
|
||||
uint16_t startPortOfRange, uint16_t endPortOfRange);
|
||||
|
||||
/**
|
||||
* @brief Return details of all peers
|
||||
*
|
||||
* @param pds Pointer to array of zts_peer_details structs to be filled out
|
||||
* @param num Length of destination array, will be filled out with actual number
|
||||
* of peers that details were available for.
|
||||
* @return ZTS_ERR_OK on success. ZTS_ERR_SERVICE or ZTS_ERR_ARG on failure.
|
||||
*/
|
||||
ZT_SOCKET_API int ZTCALL zts_get_peers(struct zts_peer_details *pds, uint32_t *num);
|
||||
|
||||
/**
|
||||
* @brief Return details of a given peer.
|
||||
*
|
||||
* @param pds Pointer to zts_peer_details struct to be filled out
|
||||
* @param peerId ID of peer that the caller wants details of
|
||||
* @return ZTS_ERR_OK on success. ZTS_ERR_SERVICE or ZTS_ERR_ARG on failure.
|
||||
*/
|
||||
ZT_SOCKET_API int ZTCALL zts_get_peer(struct zts_peer_details *pds, uint64_t peerId);
|
||||
|
||||
#define ZTS_STATE_NODE_OFFLINE ZTS_EVENT_NODE_OFFLINE
|
||||
#define ZTS_STATE_NODE_ONLINE ZTS_EVENT_NODE_ONLINE
|
||||
|
||||
/**
|
||||
* @brief Return the state of this node
|
||||
*
|
||||
* @return ZTS_STATE_NODE_ONLINE, ZTS_STATE_NODE_OFFLINE
|
||||
*/
|
||||
ZT_SOCKET_API int ZTCALL zts_get_node_status();
|
||||
|
||||
#define ZTS_STATE_NETWORK_NOT_FOUND ZTS_EVENT_NETWORK_NOT_FOUND
|
||||
#define ZTS_STATE_NETWORK_CLIENT_TOO_OLD ZTS_EVENT_NETWORK_CLIENT_TOO_OLD
|
||||
#define ZTS_STATE_NETWORK_REQUESTING_CONFIG ZTS_EVENT_NETWORK_REQUESTING_CONFIG
|
||||
#define ZTS_STATE_NETWORK_OK ZTS_EVENT_NETWORK_OK
|
||||
#define ZTS_STATE_NETWORK_ACCESS_DENIED ZTS_EVENT_NETWORK_ACCESS_DENIED
|
||||
#define ZTS_STATE_NETWORK_DOWN ZTS_EVENT_NETWORK_DOWN
|
||||
|
||||
/**
|
||||
* @brief Return the state of a given network
|
||||
*
|
||||
* @param nwid Network ID
|
||||
* @return ZTS_STATE_NETWORK_OK, ZTS_STATE_NETWORK_REQUESTING_CONFIG, etc
|
||||
*/
|
||||
ZT_SOCKET_API int ZTCALL zts_get_network_status(uint64_t nwid);
|
||||
|
||||
#define ZTS_STATE_PEER_DIRECT ZTS_EVENT_PEER_DIRECT
|
||||
#define ZTS_STATE_PEER_RELAY ZTS_EVENT_PEER_RELAY
|
||||
#define ZTS_STATE_PEER_UNREACHABLE ZTS_EVENT_PEER_UNREACHABLE
|
||||
|
||||
/**
|
||||
* @brief Return the reachability state of a given remote peer
|
||||
*
|
||||
* @param peerId Remote peer ID
|
||||
* @return ZTS_STATE_PEER_DIRECT, ZTS_STATE_PEER_RELAY, or ZTS_STATE_PEER_UNREACHABLE
|
||||
*/
|
||||
ZT_SOCKET_API int ZTCALL zts_get_peer_status(uint64_t peerId);
|
||||
|
||||
/**
|
||||
* @brief Platform-agnostic delay (provided for convenience)
|
||||
*
|
||||
* @param interval_ms Number of milliseconds to delay
|
||||
*/
|
||||
ZT_SOCKET_API void ZTCALL zts_delay_ms(long interval_ms);
|
||||
ZTS_API void ZTCALL zts_delay_ms(long interval_ms);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// Statistics //
|
||||
@@ -1082,7 +1114,7 @@ struct zts_stats {
|
||||
* @usage This function can only be used in debug builds.
|
||||
* @return ZTS_ERR_OK on success. ZTS_ERR_ARG or ZTS_ERR_NO_RESULT on failure.
|
||||
*/
|
||||
ZT_SOCKET_API int ZTCALL zts_get_all_stats(struct zts_stats *statsDest);
|
||||
ZTS_API int ZTCALL zts_get_all_stats(struct zts_stats *statsDest);
|
||||
|
||||
/**
|
||||
* @brief Populate the given structure with the requested protocol's
|
||||
@@ -1091,7 +1123,7 @@ ZT_SOCKET_API int ZTCALL zts_get_all_stats(struct zts_stats *statsDest);
|
||||
* @usage This function can only be used in debug builds.
|
||||
* @return ZTS_ERR_OK on success. ZTS_ERR_ARG or ZTS_ERR_NO_RESULT on failure.
|
||||
*/
|
||||
ZT_SOCKET_API int ZTCALL zts_get_protocol_stats(int protocolType, void *protoStatsDest);
|
||||
ZTS_API int ZTCALL zts_get_protocol_stats(int protocolType, void *protoStatsDest);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// Socket API //
|
||||
@@ -1105,7 +1137,7 @@ ZT_SOCKET_API int ZTCALL zts_get_protocol_stats(int protocolType, void *protoSta
|
||||
* @param protocol Protocols supported on this socket
|
||||
* @return Numbered file descriptor on success. ZTS_ERR_SERVICE or ZTS_ERR_SOCKET on failure.
|
||||
*/
|
||||
ZT_SOCKET_API int ZTCALL zts_socket(
|
||||
ZTS_API int ZTCALL zts_socket(
|
||||
const int socket_family, const int socket_type, const int protocol);
|
||||
|
||||
/**
|
||||
@@ -1116,7 +1148,7 @@ ZT_SOCKET_API int ZTCALL zts_socket(
|
||||
* @param addrlen Length of address
|
||||
* @return ZTS_ERR_OK on success. ZTS_ERR_SOCKET, ZTS_ERR_SERVICE, ZTS_ERR_ARG on failure.
|
||||
*/
|
||||
ZT_SOCKET_API int ZTCALL zts_connect(
|
||||
ZTS_API int ZTCALL zts_connect(
|
||||
int fd, const struct zts_sockaddr *addr, zts_socklen_t addrlen);
|
||||
|
||||
/**
|
||||
@@ -1127,7 +1159,7 @@ ZT_SOCKET_API int ZTCALL zts_connect(
|
||||
* @param addrlen Length of address
|
||||
* @return ZTS_ERR_OK on success. ZTS_ERR_SOCKET, ZTS_ERR_SERVICE, ZTS_ERR_ARG on failure.
|
||||
*/
|
||||
ZT_SOCKET_API int ZTCALL zts_bind(
|
||||
ZTS_API int ZTCALL zts_bind(
|
||||
int fd, const struct zts_sockaddr *addr, zts_socklen_t addrlen);
|
||||
|
||||
/**
|
||||
@@ -1137,7 +1169,7 @@ ZT_SOCKET_API int ZTCALL zts_bind(
|
||||
* @param backlog Number of backlogged connections allowed
|
||||
* @return ZTS_ERR_OK on success. ZTS_ERR_SOCKET, ZTS_ERR_SERVICE, ZTS_ERR_ARG on failure.
|
||||
*/
|
||||
ZT_SOCKET_API int ZTCALL zts_listen(int fd, int backlog);
|
||||
ZTS_API int ZTCALL zts_listen(int fd, int backlog);
|
||||
|
||||
/**
|
||||
* @brief Accept an incoming connection (sets zts_errno)
|
||||
@@ -1147,7 +1179,7 @@ ZT_SOCKET_API int ZTCALL zts_listen(int fd, int backlog);
|
||||
* @param addrlen Length of address
|
||||
* @return New socket file descriptor on success. ZTS_ERR_SOCKET, ZTS_ERR_SERVICE, ZTS_ERR_ARG on failure.
|
||||
*/
|
||||
ZT_SOCKET_API int ZTCALL zts_accept(int fd, struct zts_sockaddr *addr, zts_socklen_t *addrlen);
|
||||
ZTS_API int ZTCALL zts_accept(int fd, struct zts_sockaddr *addr, zts_socklen_t *addrlen);
|
||||
|
||||
/**
|
||||
* @brief Accept an incoming connection (sets zts_errno)
|
||||
@@ -1295,7 +1327,7 @@ typedef struct zts_ipv6_mreq {
|
||||
* @param optlen Length of option value
|
||||
* @return ZTS_ERR_OK on success. ZTS_ERR_SOCKET, ZTS_ERR_SERVICE, ZTS_ERR_ARG on failure.
|
||||
*/
|
||||
ZT_SOCKET_API int ZTCALL zts_setsockopt(
|
||||
ZTS_API int ZTCALL zts_setsockopt(
|
||||
int fd, int level, int optname, const void *optval, zts_socklen_t optlen);
|
||||
|
||||
/**
|
||||
@@ -1308,7 +1340,7 @@ ZT_SOCKET_API int ZTCALL zts_setsockopt(
|
||||
* @param optlen Length of value
|
||||
* @return ZTS_ERR_OK on success. ZTS_ERR_SOCKET, ZTS_ERR_SERVICE, ZTS_ERR_ARG on failure.
|
||||
*/
|
||||
ZT_SOCKET_API int ZTCALL zts_getsockopt(
|
||||
ZTS_API int ZTCALL zts_getsockopt(
|
||||
int fd, int level, int optname, void *optval, zts_socklen_t *optlen);
|
||||
|
||||
/**
|
||||
@@ -1319,7 +1351,7 @@ ZT_SOCKET_API int ZTCALL zts_getsockopt(
|
||||
* @param addrlen Length of name
|
||||
* @return ZTS_ERR_OK on success. ZTS_ERR_SOCKET, ZTS_ERR_SERVICE, ZTS_ERR_ARG on failure.
|
||||
*/
|
||||
ZT_SOCKET_API int ZTCALL zts_getsockname(int fd, struct zts_sockaddr *addr, zts_socklen_t *addrlen);
|
||||
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
|
||||
@@ -1329,7 +1361,7 @@ ZT_SOCKET_API int ZTCALL zts_getsockname(int fd, struct zts_sockaddr *addr, zts_
|
||||
* @param addrlen Length of name
|
||||
* @return ZTS_ERR_OK on success. ZTS_ERR_SOCKET, ZTS_ERR_SERVICE, ZTS_ERR_ARG on failure.
|
||||
*/
|
||||
ZT_SOCKET_API int ZTCALL zts_getpeername(int fd, struct zts_sockaddr *addr, zts_socklen_t *addrlen);
|
||||
ZTS_API int ZTCALL zts_getpeername(int fd, struct zts_sockaddr *addr, zts_socklen_t *addrlen);
|
||||
|
||||
/**
|
||||
* @brief Close a socket (sets zts_errno)
|
||||
@@ -1337,10 +1369,11 @@ ZT_SOCKET_API int ZTCALL zts_getpeername(int fd, struct zts_sockaddr *addr, zts_
|
||||
* @param fd Socket file descriptor
|
||||
* @return ZTS_ERR_OK on success. ZTS_ERR_SOCKET, ZTS_ERR_SERVICE on failure.
|
||||
*/
|
||||
ZT_SOCKET_API int ZTCALL zts_close(int fd);
|
||||
ZTS_API int ZTCALL zts_close(int fd);
|
||||
|
||||
/* FD_SET used for lwip_select */
|
||||
|
||||
#define LWIP_SOCKET_OFFSET 0
|
||||
#define MEMP_NUM_NETCONN 1024
|
||||
|
||||
#ifndef ZTS_FD_SET
|
||||
@@ -1387,7 +1420,7 @@ struct zts_timeval {
|
||||
* @param timeout How long this call should block
|
||||
* @return Number of ready file descriptors on success. ZTS_ERR_SOCKET, ZTS_ERR_SERVICE on failure.
|
||||
*/
|
||||
ZT_SOCKET_API int ZTCALL zts_select(
|
||||
ZTS_API int ZTCALL zts_select(
|
||||
int nfds, zts_fd_set *readfds, zts_fd_set *writefds, zts_fd_set *exceptfds, struct zts_timeval *timeout);
|
||||
|
||||
// fnctl() commands
|
||||
@@ -1409,7 +1442,7 @@ ZT_SOCKET_API int ZTCALL zts_select(
|
||||
* @param flags
|
||||
* @return
|
||||
*/
|
||||
ZT_SOCKET_API int ZTCALL zts_fcntl(int fd, int cmd, int flags);
|
||||
ZTS_API int ZTCALL zts_fcntl(int fd, int cmd, int flags);
|
||||
|
||||
#define ZTS_POLLIN 0x001
|
||||
#define ZTS_POLLOUT 0x002
|
||||
@@ -1440,7 +1473,7 @@ struct zts_pollfd
|
||||
* @param timeout How long this call should block
|
||||
* @return Number of ready file descriptors on success. ZTS_ERR_SOCKET, ZTS_ERR_SERVICE on failure.
|
||||
*/
|
||||
ZT_SOCKET_API int ZTCALL zts_poll(struct zts_pollfd *fds, zts_nfds_t nfds, int timeout);
|
||||
ZTS_API int ZTCALL zts_poll(struct zts_pollfd *fds, zts_nfds_t nfds, int timeout);
|
||||
|
||||
/**
|
||||
* @brief Control a device (sets zts_errno)
|
||||
@@ -1450,7 +1483,7 @@ ZT_SOCKET_API int ZTCALL zts_poll(struct zts_pollfd *fds, zts_nfds_t nfds, int t
|
||||
* @param argp
|
||||
* @return ZTS_ERR_OK on success, ZTS_ERR_SERVICE on failure.
|
||||
*/
|
||||
ZT_SOCKET_API int ZTCALL zts_ioctl(int fd, unsigned long request, void *argp);
|
||||
ZTS_API int ZTCALL zts_ioctl(int fd, unsigned long request, void *argp);
|
||||
|
||||
/**
|
||||
* @brief Send data to remote host (sets zts_errno)
|
||||
@@ -1461,7 +1494,7 @@ ZT_SOCKET_API int ZTCALL zts_ioctl(int fd, unsigned long request, void *argp);
|
||||
* @param flags
|
||||
* @return Byte count sent on success. ZTS_ERR_SOCKET, ZTS_ERR_SERVICE, ZTS_ERR_ARG on failure.
|
||||
*/
|
||||
ZT_SOCKET_API ssize_t ZTCALL zts_send(int fd, const void *buf, size_t len, int flags);
|
||||
ZTS_API ssize_t ZTCALL zts_send(int fd, const void *buf, size_t len, int flags);
|
||||
|
||||
/**
|
||||
* @brief Send data to remote host (sets zts_errno)
|
||||
@@ -1474,7 +1507,7 @@ ZT_SOCKET_API ssize_t ZTCALL zts_send(int fd, const void *buf, size_t len, int f
|
||||
* @param addrlen Length of destination address
|
||||
* @return Byte count sent on success. ZTS_ERR_SOCKET, ZTS_ERR_SERVICE, ZTS_ERR_ARG on failure.
|
||||
*/
|
||||
ZT_SOCKET_API ssize_t ZTCALL zts_sendto(
|
||||
ZTS_API ssize_t ZTCALL zts_sendto(
|
||||
int fd, const void *buf, size_t len, int flags, const struct zts_sockaddr *addr, zts_socklen_t addrlen);
|
||||
|
||||
struct zts_iovec {
|
||||
@@ -1505,7 +1538,7 @@ struct zts_msghdr {
|
||||
* @param flags
|
||||
* @return Byte count sent on success. ZTS_ERR_SOCKET, ZTS_ERR_SERVICE, ZTS_ERR_ARG on failure.
|
||||
*/
|
||||
ZT_SOCKET_API ssize_t ZTCALL zts_sendmsg(int fd, const struct msghdr *msg, int flags);
|
||||
ZTS_API ssize_t ZTCALL zts_sendmsg(int fd, const struct msghdr *msg, int flags);
|
||||
|
||||
/**
|
||||
* @brief Receive data from remote host (sets zts_errno)
|
||||
@@ -1516,7 +1549,7 @@ ZT_SOCKET_API ssize_t ZTCALL zts_sendmsg(int fd, const struct msghdr *msg, int f
|
||||
* @param flags
|
||||
* @return Byte count received on success. ZTS_ERR_SOCKET, ZTS_ERR_SERVICE, ZTS_ERR_ARG on failure.
|
||||
*/
|
||||
ZT_SOCKET_API ssize_t ZTCALL zts_recv(int fd, void *buf, size_t len, int flags);
|
||||
ZTS_API ssize_t ZTCALL zts_recv(int fd, void *buf, size_t len, int flags);
|
||||
|
||||
/**
|
||||
* @brief Receive data from remote host (sets zts_errno)
|
||||
@@ -1529,7 +1562,7 @@ ZT_SOCKET_API ssize_t ZTCALL zts_recv(int fd, void *buf, size_t len, int flags);
|
||||
* @param addrlen
|
||||
* @return Byte count received on success. ZTS_ERR_SOCKET, ZTS_ERR_SERVICE, ZTS_ERR_ARG on failure.
|
||||
*/
|
||||
ZT_SOCKET_API ssize_t ZTCALL zts_recvfrom(
|
||||
ZTS_API ssize_t ZTCALL zts_recvfrom(
|
||||
int fd, void *buf, size_t len, int flags, struct zts_sockaddr *addr, zts_socklen_t *addrlen);
|
||||
|
||||
/**
|
||||
@@ -1540,7 +1573,7 @@ ZT_SOCKET_API ssize_t ZTCALL zts_recvfrom(
|
||||
* @param flags
|
||||
* @return Byte count received on success. ZTS_ERR_SOCKET, ZTS_ERR_SERVICE, ZTS_ERR_ARG on failure.
|
||||
*/
|
||||
ZT_SOCKET_API ssize_t ZTCALL zts_recvmsg(int fd, struct msghdr *msg,int flags);
|
||||
ZTS_API ssize_t ZTCALL zts_recvmsg(int fd, struct msghdr *msg,int flags);
|
||||
|
||||
/**
|
||||
* @brief Read bytes from socket onto buffer (sets zts_errno)
|
||||
@@ -1550,7 +1583,7 @@ ZT_SOCKET_API ssize_t ZTCALL zts_recvmsg(int fd, struct msghdr *msg,int flags);
|
||||
* @param len Length of data buffer to receive data
|
||||
* @return Byte count received on success. ZTS_ERR_SOCKET, ZTS_ERR_SERVICE, ZTS_ERR_ARG on failure.
|
||||
*/
|
||||
ZT_SOCKET_API ssize_t ZTCALL zts_read(int fd, void *buf, size_t len);
|
||||
ZTS_API ssize_t ZTCALL zts_read(int fd, void *buf, size_t len);
|
||||
|
||||
/**
|
||||
* @brief Read bytes from socket into multiple buffers (sets zts_errno)
|
||||
@@ -1560,7 +1593,7 @@ ZT_SOCKET_API ssize_t ZTCALL zts_read(int fd, void *buf, size_t len);
|
||||
* @param iovcnt Number of buffers to read into
|
||||
* @return Byte count received on success. ZTS_ERR_SOCKET, ZTS_ERR_SERVICE, ZTS_ERR_ARG on failure.
|
||||
*/
|
||||
ZT_SOCKET_API ssize_t ZTCALL zts_readv(int fd, const struct zts_iovec *iov, int iovcnt);
|
||||
ZTS_API ssize_t ZTCALL zts_readv(int fd, const struct zts_iovec *iov, int iovcnt);
|
||||
|
||||
/**
|
||||
* @brief Write bytes from buffer to socket (sets zts_errno)
|
||||
@@ -1570,7 +1603,7 @@ ZT_SOCKET_API ssize_t ZTCALL zts_readv(int fd, const struct zts_iovec *iov, int
|
||||
* @param len Length of buffer to write
|
||||
* @return Byte count sent on success. ZTS_ERR_SOCKET, ZTS_ERR_SERVICE, ZTS_ERR_ARG on failure.
|
||||
*/
|
||||
ZT_SOCKET_API ssize_t ZTCALL zts_write(int fd, const void *buf, size_t len);
|
||||
ZTS_API ssize_t ZTCALL zts_write(int fd, const void *buf, size_t len);
|
||||
|
||||
/**
|
||||
* @brief Write data from multiple buffers to socket. (sets zts_errno)
|
||||
@@ -1580,7 +1613,7 @@ ZT_SOCKET_API ssize_t ZTCALL zts_write(int fd, const void *buf, size_t len);
|
||||
* @param iovcnt Number of buffers to read from
|
||||
* @return Byte count sent on success. ZTS_ERR_SOCKET, ZTS_ERR_SERVICE, ZTS_ERR_ARG on failure.
|
||||
*/
|
||||
ZT_SOCKET_API ssize_t ZTCALL zts_writev(int fd, const struct zts_iovec *iov, int iovcnt);
|
||||
ZTS_API ssize_t ZTCALL zts_writev(int fd, const struct zts_iovec *iov, int iovcnt);
|
||||
|
||||
#define ZTS_SHUT_RD 0x0
|
||||
#define ZTS_SHUT_WR 0x1
|
||||
@@ -1593,7 +1626,7 @@ ZT_SOCKET_API ssize_t ZTCALL zts_writev(int fd, const struct zts_iovec *iov, int
|
||||
* @param how Which aspects of the socket should be shut down
|
||||
* @return ZTS_ERR_OK on success. ZTS_ERR_SOCKET, ZTS_ERR_SERVICE, ZTS_ERR_ARG on failure.
|
||||
*/
|
||||
ZT_SOCKET_API int ZTCALL zts_shutdown(int fd, int how);
|
||||
ZTS_API int ZTCALL zts_shutdown(int fd, int how);
|
||||
|
||||
/**
|
||||
* @brief Add a DNS nameserver for the network stack to use
|
||||
@@ -1601,7 +1634,7 @@ ZT_SOCKET_API int ZTCALL zts_shutdown(int fd, int how);
|
||||
* @param addr Address for DNS nameserver
|
||||
* @return ZTS_ERR_SERVICE
|
||||
*/
|
||||
ZT_SOCKET_API int ZTCALL zts_add_dns_nameserver(struct zts_sockaddr *addr);
|
||||
ZTS_API int ZTCALL zts_add_dns_nameserver(struct zts_sockaddr *addr);
|
||||
|
||||
/**
|
||||
* @brief Remove a DNS nameserver
|
||||
@@ -1609,7 +1642,7 @@ ZT_SOCKET_API int ZTCALL zts_add_dns_nameserver(struct zts_sockaddr *addr);
|
||||
* @param addr Address for DNS nameserver
|
||||
* @return ZTS_ERR_SERVICE
|
||||
*/
|
||||
ZT_SOCKET_API int ZTCALL zts_del_dns_nameserver(struct zts_sockaddr *addr);
|
||||
ZTS_API int ZTCALL zts_del_dns_nameserver(struct zts_sockaddr *addr);
|
||||
|
||||
/**
|
||||
* Convert an uint16_t from host to network byte order.
|
||||
@@ -1617,7 +1650,7 @@ ZT_SOCKET_API int ZTCALL zts_del_dns_nameserver(struct zts_sockaddr *addr);
|
||||
* @param n uint16_t in host byte order
|
||||
* @return n in network byte order
|
||||
*/
|
||||
ZT_SOCKET_API uint16_t ZTCALL zts_htons(uint16_t n);
|
||||
ZTS_API uint16_t ZTCALL zts_htons(uint16_t n);
|
||||
|
||||
/**
|
||||
* Convert an uint32_t from host to network byte order.
|
||||
@@ -1625,7 +1658,7 @@ ZT_SOCKET_API uint16_t ZTCALL zts_htons(uint16_t n);
|
||||
* @param n uint32_t in host byte order
|
||||
* @return n in network byte order
|
||||
*/
|
||||
ZT_SOCKET_API uint32_t ZTCALL zts_htonl(uint32_t n);
|
||||
ZTS_API uint32_t ZTCALL zts_htonl(uint32_t n);
|
||||
|
||||
/**
|
||||
* Length of human-readable MAC address string
|
||||
@@ -1642,7 +1675,7 @@ ZT_SOCKET_API uint32_t ZTCALL zts_htonl(uint32_t n);
|
||||
* @param n uint16_t in network byte order
|
||||
* @return n in host byte order
|
||||
*/
|
||||
ZT_SOCKET_API uint16_t ZTCALL zts_ntohs(uint16_t n);
|
||||
ZTS_API uint16_t ZTCALL zts_ntohs(uint16_t n);
|
||||
|
||||
/**
|
||||
* Convert an uint32_t from network to host byte order.
|
||||
@@ -1650,7 +1683,7 @@ ZT_SOCKET_API uint16_t ZTCALL zts_ntohs(uint16_t n);
|
||||
* @param n uint32_t in network byte order
|
||||
* @return n in host byte order
|
||||
*/
|
||||
ZT_SOCKET_API uint32_t ZTCALL zts_ntohl(uint32_t n);
|
||||
ZTS_API uint32_t ZTCALL zts_ntohl(uint32_t n);
|
||||
|
||||
/**
|
||||
* Convert IPv4 and IPv6 address structures to human-readable text form.
|
||||
@@ -1661,7 +1694,7 @@ ZT_SOCKET_API uint32_t ZTCALL zts_ntohl(uint32_t n);
|
||||
* @param size Size of the destination buffer
|
||||
* @return On success, returns a non-null pointer to the destination character array
|
||||
*/
|
||||
ZT_SOCKET_API const char * ZTCALL zts_inet_ntop(int af, const void *src, char *dst, zts_socklen_t size);
|
||||
ZTS_API const char * ZTCALL zts_inet_ntop(int af, const void *src, char *dst, zts_socklen_t size);
|
||||
|
||||
/**
|
||||
* Convert C-string IPv4 and IPv6 addresses to binary form.
|
||||
@@ -1671,7 +1704,7 @@ ZT_SOCKET_API const char * ZTCALL zts_inet_ntop(int af, const void *src, char *d
|
||||
* @param dst Pointer to destination address structure
|
||||
* @return return 1 on success. 0 or -1 on failure. (Does not follow zts_* conventions)
|
||||
*/
|
||||
ZT_SOCKET_API int ZTCALL zts_inet_pton(int af, const char *src, void *dst);
|
||||
ZTS_API int ZTCALL zts_inet_pton(int af, const char *src, void *dst);
|
||||
|
||||
/**
|
||||
* Convert a C-string IPv4 address to integer representation.
|
||||
@@ -1679,7 +1712,7 @@ ZT_SOCKET_API int ZTCALL zts_inet_pton(int af, const char *src, void *dst);
|
||||
* @param cp Human-readable IPv4 string
|
||||
* @return 32-bit integer representation of address
|
||||
*/
|
||||
ZT_SOCKET_API uint32_t ZTCALL zts_inet_addr(const char *cp);
|
||||
ZTS_API uint32_t ZTCALL zts_inet_addr(const char *cp);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
|
||||
334
src/Controls.cpp
334
src/Controls.cpp
@@ -20,6 +20,7 @@
|
||||
#include <inttypes.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include "Constants.hpp"
|
||||
#include "Node.hpp"
|
||||
#include "Mutex.hpp"
|
||||
#include "OSUtils.hpp"
|
||||
@@ -36,7 +37,10 @@ using namespace ZeroTier;
|
||||
#include <jni.h>
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef __WINDOWS__
|
||||
#include <Windows.h>
|
||||
WSADATA wsaData;
|
||||
#endif
|
||||
|
||||
namespace ZeroTier
|
||||
{
|
||||
@@ -55,6 +59,10 @@ namespace ZeroTier
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
int zts_allow_network_caching(uint8_t allowed = 1)
|
||||
{
|
||||
Mutex::Lock _l(serviceLock);
|
||||
@@ -121,15 +129,14 @@ int zts_start(const char *path, void (*callback)(void *), uint16_t port)
|
||||
if (params->path.length() == 0) {
|
||||
return ZTS_ERR_ARG;
|
||||
}
|
||||
|
||||
int err;
|
||||
int retval = ZTS_ERR_OK;
|
||||
|
||||
_setState(ZTS_STATE_CALLBACKS_RUNNING);
|
||||
_setState(ZTS_STATE_NODE_RUNNING);
|
||||
|
||||
// Start the ZT service thread
|
||||
#if defined(__WINDOWS__)
|
||||
WSAStartup(MAKEWORD(2, 2), &wsaData);
|
||||
HANDLE serviceThread = CreateThread(NULL, 0, _runNodeService, (void*)params, 0, NULL);
|
||||
HANDLE callbackThread = CreateThread(NULL, 0, _runCallbacks, NULL, 0, NULL);
|
||||
#else
|
||||
@@ -155,11 +162,6 @@ int zts_start(const char *path, void (*callback)(void *), uint16_t port)
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifdef SDK_JNI
|
||||
JNIEXPORT jint JNICALL Java_com_zerotier_libzt_ZeroTier_start(
|
||||
JNIEnv *env, jobject thisObj, jstring path, jobject callback, jint port)
|
||||
@@ -264,13 +266,14 @@ int zts_restart()
|
||||
|
||||
int zts_free()
|
||||
{
|
||||
Mutex::Lock _l(serviceLock);
|
||||
if (_getState(ZTS_STATE_FREE_CALLED)) {
|
||||
return ZTS_ERR_SERVICE;
|
||||
}
|
||||
_setState(ZTS_STATE_FREE_CALLED);
|
||||
return zts_stop();
|
||||
// TODO: add stack shutdown logic
|
||||
int err = zts_stop();
|
||||
Mutex::Lock _l(serviceLock);
|
||||
_lwip_driver_shutdown();
|
||||
return err;
|
||||
}
|
||||
#ifdef SDK_JNI
|
||||
JNIEXPORT void JNICALL Java_com_zerotier_libzt_ZeroTier_free(
|
||||
@@ -280,80 +283,6 @@ int zts_free()
|
||||
}
|
||||
#endif
|
||||
|
||||
uint64_t zts_get_node_id()
|
||||
{
|
||||
Mutex::Lock _l(serviceLock);
|
||||
if (!_canPerformServiceOperation()) {
|
||||
return ZTS_ERR_OK; // Not really
|
||||
}
|
||||
return service->getNode()->address();
|
||||
}
|
||||
#ifdef SDK_JNI
|
||||
JNIEXPORT jlong JNICALL Java_com_zerotier_libzt_ZeroTier_get_1node_1id(
|
||||
JNIEnv *env, jobject thisObj)
|
||||
{
|
||||
return zts_get_node_id();
|
||||
}
|
||||
#endif
|
||||
|
||||
int zts_get_node_status()
|
||||
{
|
||||
Mutex::Lock _l(serviceLock);
|
||||
// Don't check _canPerformServiceOperation() here.
|
||||
return service
|
||||
&& service->getNode()
|
||||
&& service->getNode()->online() ? ZTS_EVENT_NODE_ONLINE : ZTS_EVENT_NODE_OFFLINE;
|
||||
}
|
||||
#ifdef SDK_JNI
|
||||
JNIEXPORT jint JNICALL Java_com_zerotier_libzt_ZeroTier_get_1node_1status(
|
||||
JNIEnv *env, jobject thisObj)
|
||||
{
|
||||
return zts_get_node_status();
|
||||
}
|
||||
#endif
|
||||
|
||||
int zts_get_network_status(uint64_t networkId)
|
||||
{
|
||||
Mutex::Lock _l(serviceLock);
|
||||
if (!networkId) {
|
||||
return ZTS_ERR_ARG;
|
||||
}
|
||||
if (!_canPerformServiceOperation()) {
|
||||
return ZTS_ERR_SERVICE;
|
||||
}
|
||||
/*
|
||||
TODO:
|
||||
ZTS_EVENT_NETWORK_READY_IP4
|
||||
ZTS_EVENT_NETWORK_READY_IP6
|
||||
ZTS_EVENT_NETWORK_READY_IP4_IP6
|
||||
*/
|
||||
return ZTS_ERR_NO_RESULT;
|
||||
}
|
||||
#ifdef SDK_JNI
|
||||
JNIEXPORT jint JNICALL Java_com_zerotier_libzt_ZeroTier_get_1network_1status(
|
||||
JNIEnv *env, jobject thisObj, jlong networkId)
|
||||
{
|
||||
return zts_get_network_status(networkId);
|
||||
}
|
||||
#endif
|
||||
|
||||
int zts_get_peer_status(uint64_t peerId)
|
||||
{
|
||||
Mutex::Lock _l(serviceLock);
|
||||
int retval = ZTS_ERR_OK;
|
||||
if (!_canPerformServiceOperation()) {
|
||||
return ZTS_ERR_SERVICE;
|
||||
}
|
||||
return service->getPeerStatus(peerId);
|
||||
}
|
||||
#ifdef SDK_JNI
|
||||
JNIEXPORT jlong JNICALL Java_com_zerotier_libzt_ZeroTier_get_1peer_1status(
|
||||
JNIEnv *env, jobject thisObj, jlong peerId)
|
||||
{
|
||||
return zts_get_peer_status(peerId);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef SDK_JNI
|
||||
/*
|
||||
* Called from Java, saves a static reference to the VM so it can be used
|
||||
@@ -367,63 +296,44 @@ int zts_get_peer_status(uint64_t peerId)
|
||||
}
|
||||
#endif
|
||||
|
||||
int zts_join(const uint64_t nwid)
|
||||
int zts_join(const uint64_t networkId)
|
||||
{
|
||||
Mutex::Lock _l(serviceLock);
|
||||
if (!_canPerformServiceOperation()) {
|
||||
return ZTS_ERR_SERVICE;
|
||||
}
|
||||
else {
|
||||
service->join(nwid);
|
||||
service->join(networkId);
|
||||
}
|
||||
return ZTS_ERR_OK;
|
||||
}
|
||||
#ifdef SDK_JNI
|
||||
JNIEXPORT jint JNICALL Java_com_zerotier_libzt_ZeroTier_join(
|
||||
JNIEnv *env, jobject thisObj, jlong nwid)
|
||||
JNIEnv *env, jobject thisObj, jlong networkId)
|
||||
{
|
||||
return zts_join((uint64_t)nwid);
|
||||
return zts_join((uint64_t)networkId);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
int zts_leave(const uint64_t nwid)
|
||||
int zts_leave(const uint64_t networkId)
|
||||
{
|
||||
Mutex::Lock _l(serviceLock);
|
||||
if (!_canPerformServiceOperation()) {
|
||||
return ZTS_ERR_SERVICE;
|
||||
}
|
||||
else {
|
||||
service->leave(nwid);
|
||||
service->leave(networkId);
|
||||
}
|
||||
return ZTS_ERR_OK;
|
||||
}
|
||||
#ifdef SDK_JNI
|
||||
JNIEXPORT jint JNICALL Java_com_zerotier_libzt_ZeroTier_leave(
|
||||
JNIEnv *env, jobject thisObj, jlong nwid)
|
||||
JNIEnv *env, jobject thisObj, jlong networkId)
|
||||
{
|
||||
return zts_leave((uint64_t)nwid);
|
||||
return zts_leave((uint64_t)networkId);
|
||||
}
|
||||
#endif
|
||||
|
||||
int zts_leave_all()
|
||||
{
|
||||
Mutex::Lock _l(serviceLock);
|
||||
if (!_canPerformServiceOperation()) {
|
||||
return ZTS_ERR_SERVICE;
|
||||
}
|
||||
else {
|
||||
service->leaveAll();
|
||||
}
|
||||
return ZTS_ERR_OK;
|
||||
}
|
||||
#ifdef SDK_JNI
|
||||
#endif
|
||||
|
||||
int zts_orbit(uint64_t moonWorldId, uint64_t moonSeed)
|
||||
{
|
||||
Mutex::Lock _l(serviceLock);
|
||||
@@ -452,197 +362,57 @@ int zts_deorbit(uint64_t moonWorldId)
|
||||
#ifdef SDK_JNI
|
||||
#endif
|
||||
|
||||
int zts_get_6plane_addr(struct zts_sockaddr_storage *addr, const uint64_t nwid, const uint64_t nodeId)
|
||||
int zts_get_6plane_addr(struct zts_sockaddr_storage *addr, const uint64_t networkId, const uint64_t nodeId)
|
||||
{
|
||||
if (!addr || !nwid || !nodeId) {
|
||||
if (!addr || !networkId || !nodeId) {
|
||||
return ZTS_ERR_ARG;
|
||||
}
|
||||
InetAddress _6planeAddr = InetAddress::makeIpv66plane(nwid,nodeId);
|
||||
InetAddress _6planeAddr = InetAddress::makeIpv66plane(networkId,nodeId);
|
||||
struct sockaddr_in6 *in6 = (struct sockaddr_in6*)addr;
|
||||
memcpy(in6->sin6_addr.s6_addr, _6planeAddr.rawIpData(), sizeof(struct in6_addr));
|
||||
return ZTS_ERR_OK;
|
||||
}
|
||||
|
||||
int zts_get_rfc4193_addr(struct zts_sockaddr_storage *addr, const uint64_t nwid, const uint64_t nodeId)
|
||||
int zts_get_rfc4193_addr(struct zts_sockaddr_storage *addr, const uint64_t networkId, const uint64_t nodeId)
|
||||
{
|
||||
if (!addr || !nwid || !nodeId) {
|
||||
if (!addr || !networkId || !nodeId) {
|
||||
return ZTS_ERR_ARG;
|
||||
}
|
||||
InetAddress _rfc4193Addr = InetAddress::makeIpv6rfc4193(nwid,nodeId);
|
||||
InetAddress _rfc4193Addr = InetAddress::makeIpv6rfc4193(networkId,nodeId);
|
||||
struct sockaddr_in6 *in6 = (struct sockaddr_in6*)addr;
|
||||
memcpy(in6->sin6_addr.s6_addr, _rfc4193Addr.rawIpData(), sizeof(struct in6_addr));
|
||||
return ZTS_ERR_OK;
|
||||
}
|
||||
|
||||
|
||||
uint64_t zts_generate_adhoc_nwid_from_range(uint16_t startPortOfRange, uint16_t endPortOfRange)
|
||||
{
|
||||
char nwidStr[INET6_ADDRSTRLEN];
|
||||
sprintf(nwidStr, "ff%04x%04x000000", startPortOfRange, endPortOfRange);
|
||||
return strtoull(nwidStr, NULL, 16);
|
||||
char networkIdStr[INET6_ADDRSTRLEN];
|
||||
sprintf(networkIdStr, "ff%04x%04x000000", startPortOfRange, endPortOfRange);
|
||||
return strtoull(networkIdStr, NULL, 16);
|
||||
}
|
||||
|
||||
int zts_get_peers(struct zts_peer_details *pds, uint32_t *num)
|
||||
{
|
||||
Mutex::Lock _l(serviceLock);
|
||||
if (!pds || !num) {
|
||||
return ZTS_ERR_ARG;
|
||||
}
|
||||
if (!_canPerformServiceOperation()) {
|
||||
return ZTS_ERR_SERVICE;
|
||||
}
|
||||
ZT_PeerList *pl = service->getNode()->peers();
|
||||
if (pl) {
|
||||
if (*num < pl->peerCount) {
|
||||
service->getNode()->freeQueryResult((void *)pl);
|
||||
return ZTS_ERR_ARG;
|
||||
}
|
||||
*num = pl->peerCount;
|
||||
for(unsigned long i=0;i<pl->peerCount;++i) {
|
||||
memcpy(&(pds[i]), &(pl->peers[i]), sizeof(struct zts_peer_details));
|
||||
for (unsigned int j=0; j<pl->peers[i].pathCount; j++) {
|
||||
memcpy(&(pds[i].paths[j].address),
|
||||
&(pl->peers[i].paths[j].address), sizeof(struct sockaddr_storage));
|
||||
}
|
||||
}
|
||||
}
|
||||
service->getNode()->freeQueryResult((void *)pl);
|
||||
return ZTS_ERR_OK;
|
||||
}
|
||||
#ifdef SDK_JNI
|
||||
#endif
|
||||
|
||||
int zts_get_peer(struct zts_peer_details *pd, uint64_t peerId)
|
||||
{
|
||||
Mutex::Lock _l(serviceLock);
|
||||
if (!pd || !peerId) {
|
||||
return ZTS_ERR_ARG;
|
||||
}
|
||||
if (!_canPerformServiceOperation()) {
|
||||
return ZTS_ERR_SERVICE;
|
||||
}
|
||||
ZT_PeerList *pl = service->getNode()->peers();
|
||||
int retval = ZTS_ERR_NO_RESULT;
|
||||
if (pl) {
|
||||
for(unsigned long i=0;i<pl->peerCount;++i) {
|
||||
if (pl->peers[i].address == peerId) {
|
||||
memcpy(pd, &(pl->peers[i]), sizeof(struct zts_peer_details));
|
||||
for (unsigned int j=0; j<pl->peers[i].pathCount; j++) {
|
||||
memcpy(&(pd->paths[j].address),
|
||||
&(pl->peers[i].paths[j].address), sizeof(struct sockaddr_storage));
|
||||
}
|
||||
retval = ZTS_ERR_OK;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
service->getNode()->freeQueryResult((void *)pl);
|
||||
return retval;
|
||||
}
|
||||
#ifdef SDK_JNI
|
||||
#endif
|
||||
|
||||
void _get_network_details_helper(uint64_t nwid, struct zts_network_details *nd)
|
||||
{
|
||||
/*
|
||||
socklen_t addrlen;
|
||||
VirtualTap *tap = vtapMap[nwid];
|
||||
nd->nwid = tap->_nwid;
|
||||
nd->mtu = tap->_mtu;
|
||||
// assigned addresses
|
||||
nd->num_addresses = tap->_ips.size() < ZTS_MAX_ASSIGNED_ADDRESSES ? tap->_ips.size() : ZTS_MAX_ASSIGNED_ADDRESSES;
|
||||
for (int j=0; j<nd->num_addresses; j++) {
|
||||
addrlen = tap->_ips[j].isV4() ? sizeof(struct sockaddr_in) : sizeof(struct sockaddr_in6);
|
||||
memcpy(&(nd->addr[j]), &(tap->_ips[j]), addrlen);
|
||||
}
|
||||
// routes
|
||||
nd->num_routes = ZTS_MAX_NETWORK_ROUTES;;
|
||||
service->getRoutes(nwid, (ZT_VirtualNetworkRoute*)&(nd->routes)[0], &(nd->num_routes));
|
||||
*/
|
||||
}
|
||||
|
||||
void _get_network_details(uint64_t nwid, struct zts_network_details *nd)
|
||||
{
|
||||
/*
|
||||
_vtaps_lock.lock();
|
||||
_get_network_details_helper(nwid, nd);
|
||||
_vtaps_lock.unlock();
|
||||
*/
|
||||
}
|
||||
|
||||
void _get_all_network_details(struct zts_network_details *nds, int *num)
|
||||
{
|
||||
/*
|
||||
_vtaps_lock.lock();
|
||||
*num = vtapMap.size();
|
||||
int idx = 0;
|
||||
std::map<uint64_t, VirtualTap*>::iterator it;
|
||||
for (it = vtapMap.begin(); it != vtapMap.end(); it++) {
|
||||
_get_network_details(it->first, &nds[idx]);
|
||||
idx++;
|
||||
}
|
||||
_vtaps_lock.unlock();
|
||||
*/
|
||||
}
|
||||
|
||||
int zts_get_network_details(uint64_t nwid, struct zts_network_details *nd)
|
||||
{
|
||||
/*
|
||||
serviceLock.lock();
|
||||
int retval = ZTS_ERR_OK;
|
||||
if (!nd || nwid == 0) {
|
||||
retval = ZTS_ERR_ARG;
|
||||
}
|
||||
if (!service || _freeHasBeenCalled || _serviceIsShuttingDown) {
|
||||
retval = ZTS_ERR_SERVICE;
|
||||
}
|
||||
if (retval == ZTS_ERR_OK) {
|
||||
_get_network_details(nwid, nd);
|
||||
}
|
||||
serviceLock.unlock();
|
||||
return retval;
|
||||
*/
|
||||
return 0;
|
||||
}
|
||||
#ifdef SDK_JNI
|
||||
#endif
|
||||
|
||||
int zts_get_all_network_details(struct zts_network_details *nds, int *num)
|
||||
{
|
||||
/*
|
||||
serviceLock.lock();
|
||||
int retval = ZTS_ERR_OK;
|
||||
if (!nds || !num) {
|
||||
retval = ZTS_ERR_ARG;
|
||||
}
|
||||
if (!service || _freeHasBeenCalled || _serviceIsShuttingDown) {
|
||||
retval = ZTS_ERR_SERVICE;
|
||||
}
|
||||
if (retval == ZTS_ERR_OK) {
|
||||
_get_all_network_details(nds, num);
|
||||
}
|
||||
serviceLock.unlock();
|
||||
return retval;
|
||||
*/
|
||||
return 0;
|
||||
}
|
||||
#ifdef SDK_JNI
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
void zts_delay_ms(long interval_ms)
|
||||
{
|
||||
#if defined(__WINDOWS__)
|
||||
Sleep(interval_ms);
|
||||
#ifdef __WINDOWS__
|
||||
#include <windows.h>
|
||||
#elif _POSIX_C_SOURCE >= 199309L
|
||||
#include <time.h> // for nanosleep
|
||||
#else
|
||||
struct timespec sleepValue = {0};
|
||||
sleepValue.tv_nsec = interval_ms * 500000;
|
||||
nanosleep(&sleepValue, NULL);
|
||||
#include <unistd.h> // for usleep
|
||||
#endif
|
||||
|
||||
void zts_delay_ms(long milliseconds)
|
||||
{
|
||||
#ifdef __WINDOWS__
|
||||
Sleep(milliseconds);
|
||||
#elif _POSIX_C_SOURCE >= 199309L
|
||||
struct timespec ts;
|
||||
ts.tv_sec = milliseconds / 1000;
|
||||
ts.tv_nsec = (milliseconds % 1000) * 1000000;
|
||||
nanosleep(&ts, NULL);
|
||||
#else
|
||||
usleep(milliseconds * 1000);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
@@ -136,7 +136,6 @@
|
||||
#else
|
||||
#define DEBUG_TRANS(fmt, args...)
|
||||
#endif
|
||||
|
||||
#else // !LIBZT_DEBUG || !__NATIVE_TEST__
|
||||
#if defined(_WIN32)
|
||||
#define DEBUG_ERROR(...)
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
#include <jni.h>
|
||||
#endif
|
||||
|
||||
#include "Constants.hpp"
|
||||
#include "Node.hpp"
|
||||
#include "OSUtils.hpp"
|
||||
|
||||
@@ -32,11 +33,10 @@
|
||||
#include "NodeService.hpp"
|
||||
|
||||
#define NODE_EVENT_TYPE(code) code >= ZTS_EVENT_NODE_UP && code <= ZTS_EVENT_NODE_NORMAL_TERMINATION
|
||||
#define NETWORK_EVENT_TYPE(code) code >= ZTS_EVENT_NETWORK_NOT_FOUND && code <= ZTS_EVENT_NETWORK_DOWN
|
||||
#define NETWORK_EVENT_TYPE(code) code >= ZTS_EVENT_NETWORK_NOT_FOUND && code <= ZTS_EVENT_NETWORK_UPDATE
|
||||
#define STACK_EVENT_TYPE(code) code >= ZTS_EVENT_STACK_UP && code <= ZTS_EVENT_STACK_DOWN
|
||||
#define NETIF_EVENT_TYPE(code) code >= ZTS_EVENT_NETIF_UP && code <= ZTS_EVENT_NETIF_LINK_DOWN
|
||||
#define PEER_EVENT_TYPE(code) code >= ZTS_EVENT_PEER_DIRECT && code <= ZTS_EVENT_PEER_UNREACHABLE
|
||||
#define PATH_EVENT_TYPE(code) code >= ZTS_EVENT_PATH_DISCOVERED && code <= ZTS_EVENT_PATH_DEAD
|
||||
#define PEER_EVENT_TYPE(code) code >= ZTS_EVENT_PEER_DIRECT && code <= ZTS_EVENT_PEER_PATH_DEAD
|
||||
#define ROUTE_EVENT_TYPE(code) code >= ZTS_EVENT_ROUTE_ADDED && code <= ZTS_EVENT_ROUTE_REMOVED
|
||||
#define ADDR_EVENT_TYPE(code) code >= ZTS_EVENT_ADDR_ADDED_IP4 && code <= ZTS_EVENT_ADDR_REMOVED_IP6
|
||||
|
||||
@@ -52,41 +52,39 @@ Mutex _callbackLock;
|
||||
|
||||
void (*_userEventCallbackFunc)(void *);
|
||||
|
||||
moodycamel::ConcurrentQueue<struct ::zts_callback_msg*> _callbackMsgQueue;
|
||||
moodycamel::ConcurrentQueue<struct zts_callback_msg*> _callbackMsgQueue;
|
||||
|
||||
void _enqueueEvent(int16_t eventCode, void *arg)
|
||||
{
|
||||
struct ::zts_callback_msg *msg = new ::zts_callback_msg();
|
||||
|
||||
msg->node = NULL;
|
||||
msg->network = NULL;
|
||||
msg->netif = NULL;
|
||||
msg->route = NULL;
|
||||
msg->path = NULL;
|
||||
msg->peer = NULL;
|
||||
msg->addr = NULL;
|
||||
|
||||
struct zts_callback_msg *msg = new zts_callback_msg();
|
||||
msg->eventCode = eventCode;
|
||||
|
||||
if (NODE_EVENT_TYPE(eventCode)) {
|
||||
msg->node = (struct zts_node_details*)arg;
|
||||
} if (NETWORK_EVENT_TYPE(eventCode)) {
|
||||
msg->network = (struct zts_network_details*)arg;
|
||||
} if (STACK_EVENT_TYPE(eventCode)) {
|
||||
/* nothing to convey to user */
|
||||
} if (NETIF_EVENT_TYPE(eventCode)) {
|
||||
msg->netif = (struct zts_netif_details*)arg;
|
||||
} if (ROUTE_EVENT_TYPE(eventCode)) {
|
||||
msg->route = (struct zts_virtual_network_route*)arg;
|
||||
} if (PATH_EVENT_TYPE(eventCode)) {
|
||||
msg->path = (struct zts_physical_path*)arg;
|
||||
} if (PEER_EVENT_TYPE(eventCode)) {
|
||||
msg->peer = (struct zts_peer_details*)arg;
|
||||
} if (ADDR_EVENT_TYPE(eventCode)) {
|
||||
msg->addr = (struct zts_addr_details*)arg;
|
||||
}
|
||||
|
||||
if (msg && _callbackMsgQueue.size_approx() > 1024) {
|
||||
// Rate-limit number of events
|
||||
_freeEvent(msg);
|
||||
}
|
||||
else {
|
||||
_callbackMsgQueue.enqueue(msg);
|
||||
}
|
||||
}
|
||||
|
||||
void _freeEvent(struct ::zts_callback_msg *msg)
|
||||
void _freeEvent(struct zts_callback_msg *msg)
|
||||
{
|
||||
if (!msg) {
|
||||
return;
|
||||
@@ -95,13 +93,13 @@ void _freeEvent(struct ::zts_callback_msg *msg)
|
||||
if (msg->network) { delete msg->network; }
|
||||
if (msg->netif) { delete msg->netif; }
|
||||
if (msg->route) { delete msg->route; }
|
||||
if (msg->path) { delete msg->path; }
|
||||
if (msg->peer) { delete msg->peer; }
|
||||
if (msg->addr) { delete msg->addr; }
|
||||
}
|
||||
|
||||
void _passDequeuedEventToUser(struct ::zts_callback_msg *msg)
|
||||
void _passDequeuedEventToUser(struct zts_callback_msg *msg)
|
||||
{
|
||||
bool bShouldStopCallbackThread = (msg->eventCode == ZTS_EVENT_STACK_DOWN);
|
||||
#ifdef SDK_JNI
|
||||
if(_userCallbackMethodRef) {
|
||||
JNIEnv *env;
|
||||
@@ -131,6 +129,11 @@ void _passDequeuedEventToUser(struct ::zts_callback_msg *msg)
|
||||
_freeEvent(msg);
|
||||
}
|
||||
#endif
|
||||
if (bShouldStopCallbackThread) {
|
||||
/* Ensure last possible callback ZTS_EVENT_STACK_DOWN is
|
||||
delivered before callback thread is finally stopped. */
|
||||
_clrState(ZTS_STATE_CALLBACKS_RUNNING);
|
||||
}
|
||||
}
|
||||
|
||||
bool _isCallbackRegistered()
|
||||
@@ -222,7 +225,7 @@ void *_runCallbacks(void *thread_id)
|
||||
#endif
|
||||
while (_getState(ZTS_STATE_CALLBACKS_RUNNING) || _callbackMsgQueue.size_approx() > 0)
|
||||
{
|
||||
struct ::zts_callback_msg *msg;
|
||||
struct zts_callback_msg *msg;
|
||||
size_t sz = _callbackMsgQueue.size_approx();
|
||||
for (size_t j = 0; j < sz; j++) {
|
||||
if (_callbackMsgQueue.try_dequeue(msg)) {
|
||||
|
||||
@@ -22,8 +22,13 @@
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "Constants.hpp"
|
||||
#include "ZeroTierSockets.h"
|
||||
|
||||
#ifdef __WINDOWS__
|
||||
#include <BaseTsd.h>
|
||||
#endif
|
||||
|
||||
#ifdef SDK_JNI
|
||||
#include <jni.h>
|
||||
#endif
|
||||
|
||||
@@ -18,6 +18,9 @@
|
||||
*/
|
||||
|
||||
#include <thread>
|
||||
#include <iostream>
|
||||
|
||||
#include "../version.h"
|
||||
|
||||
#include "Debug.hpp"
|
||||
#include "Events.hpp"
|
||||
@@ -39,7 +42,7 @@
|
||||
#include "BlockingQueue.hpp"
|
||||
|
||||
#if defined(__WINDOWS__)
|
||||
WSADATA wsaData;
|
||||
//WSADATA wsaData;
|
||||
#include <WinSock2.h>
|
||||
#include <Windows.h>
|
||||
#include <ShlObj.h>
|
||||
@@ -123,7 +126,7 @@ public:
|
||||
volatile unsigned int _udpPortPickerCounter;
|
||||
|
||||
//
|
||||
std::map<uint64_t, bool> peerCache;
|
||||
std::map<uint64_t, int> peerCache;
|
||||
|
||||
//
|
||||
unsigned long _incomingPacketConcurrency;
|
||||
@@ -230,10 +233,6 @@ public:
|
||||
allowNetworkCaching = true;
|
||||
allowPeerCaching = true;
|
||||
allowLocalConf = false;
|
||||
#ifdef __WINDOWS__
|
||||
// Initialize WinSock. Used in Phy for loopback pipe
|
||||
WSAStartup(MAKEWORD(2, 2), &wsaData);
|
||||
#endif
|
||||
}
|
||||
|
||||
virtual ~NodeServiceImpl()
|
||||
@@ -609,14 +608,42 @@ public:
|
||||
newManagedIps.erase(std::unique(newManagedIps.begin(),newManagedIps.end()),newManagedIps.end());
|
||||
for(std::vector<InetAddress>::iterator ip(n.managedIps.begin());ip!=n.managedIps.end();++ip) {
|
||||
if (std::find(newManagedIps.begin(),newManagedIps.end(),*ip) == newManagedIps.end()) {
|
||||
if (!n.tap->removeIp(*ip))
|
||||
if (!n.tap->removeIp(*ip)) {
|
||||
fprintf(stderr,"ERROR: unable to remove ip address %s" ZT_EOL_S, ip->toString(ipbuf));
|
||||
} else {
|
||||
struct zts_addr_details *ad = new zts_addr_details();
|
||||
ad->nwid = n.tap->_nwid;
|
||||
if ((*ip).isV4()) {
|
||||
struct sockaddr_in *in4 = (struct sockaddr_in*)&(ad->addr);
|
||||
memcpy(&(in4->sin_addr.s_addr), (*ip).rawIpData(), 4);
|
||||
_enqueueEvent(ZTS_EVENT_ADDR_REMOVED_IP4, (void*)ad);
|
||||
}
|
||||
if ((*ip).isV6()) {
|
||||
struct sockaddr_in6 *in6 = (struct sockaddr_in6*)&(ad->addr);
|
||||
memcpy(&(in6->sin6_addr.s6_addr), (*ip).rawIpData(), 16);
|
||||
_enqueueEvent(ZTS_EVENT_ADDR_REMOVED_IP6, (void*)ad);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for(std::vector<InetAddress>::iterator ip(newManagedIps.begin());ip!=newManagedIps.end();++ip) {
|
||||
if (std::find(n.managedIps.begin(),n.managedIps.end(),*ip) == n.managedIps.end()) {
|
||||
if (!n.tap->addIp(*ip))
|
||||
if (!n.tap->addIp(*ip)) {
|
||||
fprintf(stderr,"ERROR: unable to add ip address %s" ZT_EOL_S, ip->toString(ipbuf));
|
||||
} else {
|
||||
struct zts_addr_details *ad = new zts_addr_details();
|
||||
ad->nwid = n.tap->_nwid;
|
||||
if ((*ip).isV4()) {
|
||||
struct sockaddr_in *in4 = (struct sockaddr_in*)&(ad->addr);
|
||||
memcpy(&(in4->sin_addr.s_addr), (*ip).rawIpData(), 4);
|
||||
_enqueueEvent(ZTS_EVENT_ADDR_ADDED_IP4, (void*)ad);
|
||||
}
|
||||
if ((*ip).isV6()) {
|
||||
struct sockaddr_in6 *in6 = (struct sockaddr_in6*)&(ad->addr);
|
||||
memcpy(&(in6->sin6_addr.s6_addr), (*ip).rawIpData(), 16);
|
||||
_enqueueEvent(ZTS_EVENT_ADDR_ADDED_IP6, (void*)ad);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
n.managedIps.swap(newManagedIps);
|
||||
@@ -694,6 +721,9 @@ public:
|
||||
_nets.erase(nwid);
|
||||
return -999; // tap init failed
|
||||
}
|
||||
if (op == ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_CONFIG_UPDATE) { // Prevent junk from ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_UP
|
||||
_enqueueEvent(ZTS_EVENT_NETWORK_UPDATE, (void*)prepare_network_details_msg(n));
|
||||
}
|
||||
break;
|
||||
|
||||
case ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_DOWN:
|
||||
@@ -727,6 +757,12 @@ public:
|
||||
case ZT_EVENT_ONLINE: {
|
||||
struct zts_node_details *nd = new zts_node_details;
|
||||
nd->address = _node->address();
|
||||
nd->versionMajor = ZEROTIER_ONE_VERSION_MAJOR;
|
||||
nd->versionMinor = ZEROTIER_ONE_VERSION_MINOR;
|
||||
nd->versionRev = ZEROTIER_ONE_VERSION_REVISION;
|
||||
nd->primaryPort = _primaryPort;
|
||||
nd->secondaryPort = _secondaryPort;
|
||||
nd->tertiaryPort = _tertiaryPort;
|
||||
_enqueueEvent(ZTS_EVENT_NODE_ONLINE, (void*)nd);
|
||||
} break;
|
||||
case ZT_EVENT_OFFLINE: {
|
||||
@@ -758,10 +794,65 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
inline struct zts_network_details *prepare_network_details_msg(uint64_t nwid)
|
||||
void native_ss_to_zts_ss(struct zts_sockaddr_storage *ss_out, const struct sockaddr_storage *ss_in)
|
||||
{
|
||||
struct zts_network_details *nd = new zts_network_details;
|
||||
nd->nwid = nwid;
|
||||
if (ss_in->ss_family == AF_INET) {
|
||||
struct sockaddr_in *s_in4 = (struct sockaddr_in *)ss_in;
|
||||
struct zts_sockaddr_in *d_in4 = (struct zts_sockaddr_in *)ss_out;
|
||||
#ifndef __WINDOWS__
|
||||
d_in4->sin_len = 0; // s_in4->sin_len;
|
||||
#endif
|
||||
d_in4->sin_family = ZTS_AF_INET;
|
||||
d_in4->sin_port = s_in4->sin_port;
|
||||
memcpy(&(d_in4->sin_addr), &(s_in4->sin_addr), sizeof(s_in4->sin_addr));
|
||||
}
|
||||
if (ss_in->ss_family == AF_INET6) {
|
||||
struct sockaddr_in6 *s_in6 = (struct sockaddr_in6 *)ss_in;
|
||||
struct zts_sockaddr_in6 *d_in6 = (struct zts_sockaddr_in6 *)ss_out;
|
||||
#ifndef __WINDOWS__
|
||||
d_in6->sin6_len = 0; // s_in6->sin6_len;
|
||||
#endif
|
||||
d_in6->sin6_family = ZTS_AF_INET6;
|
||||
d_in6->sin6_port = s_in6->sin6_port;
|
||||
d_in6->sin6_flowinfo = s_in6->sin6_flowinfo;
|
||||
memcpy(&(d_in6->sin6_addr), &(s_in6->sin6_addr), sizeof(s_in6->sin6_addr));
|
||||
d_in6->sin6_scope_id = s_in6->sin6_scope_id;
|
||||
}
|
||||
}
|
||||
|
||||
struct zts_network_details *prepare_network_details_msg(const NetworkState &n)
|
||||
{
|
||||
struct zts_network_details *nd = new zts_network_details();
|
||||
|
||||
nd->nwid = n.config.nwid;
|
||||
nd->mac = n.config.mac;
|
||||
memcpy(nd->name, n.config.name, sizeof(n.config.name));
|
||||
nd->status = (ZTS_VirtualNetworkStatus)n.config.status;
|
||||
nd->type = (ZTS_VirtualNetworkType)n.config.type;
|
||||
nd->mtu = n.config.mtu;
|
||||
nd->dhcp = n.config.dhcp;
|
||||
nd->bridge = n.config.bridge;
|
||||
nd->broadcastEnabled = n.config.broadcastEnabled;
|
||||
nd->portError = n.config.portError;
|
||||
nd->netconfRevision = n.config.netconfRevision;
|
||||
|
||||
// Copy and convert address structures
|
||||
nd->assignedAddressCount = n.config.assignedAddressCount;
|
||||
for (int i=0; i<n.config.assignedAddressCount; i++) {
|
||||
native_ss_to_zts_ss(&(nd->assignedAddresses[i]), &(n.config.assignedAddresses[i]));
|
||||
}
|
||||
|
||||
nd->routeCount = n.config.routeCount;
|
||||
for (int i=0; i<n.config.routeCount; i++) {
|
||||
native_ss_to_zts_ss(&(nd->routes[i].target), &(n.config.routes[i].target));
|
||||
native_ss_to_zts_ss(&(nd->routes[i].via), &(n.config.routes[i].via));
|
||||
nd->routes[i].flags = n.config.routes[i].flags;
|
||||
nd->routes[i].metric = n.config.routes[i].metric;
|
||||
}
|
||||
|
||||
nd->multicastSubscriptionCount = n.config.multicastSubscriptionCount;
|
||||
memcpy(nd->multicastSubscriptions, &(n.config.multicastSubscriptions), sizeof(n.config.multicastSubscriptions));
|
||||
|
||||
return nd;
|
||||
}
|
||||
|
||||
@@ -783,34 +874,34 @@ public:
|
||||
}
|
||||
switch (mostRecentStatus) {
|
||||
case ZT_NETWORK_STATUS_NOT_FOUND:
|
||||
_enqueueEvent(ZTS_EVENT_NETWORK_NOT_FOUND, (void*)prepare_network_details_msg(nwid));
|
||||
_enqueueEvent(ZTS_EVENT_NETWORK_NOT_FOUND, (void*)prepare_network_details_msg(n->second));
|
||||
break;
|
||||
case ZT_NETWORK_STATUS_CLIENT_TOO_OLD:
|
||||
_enqueueEvent(ZTS_EVENT_NETWORK_CLIENT_TOO_OLD, (void*)prepare_network_details_msg(nwid));
|
||||
_enqueueEvent(ZTS_EVENT_NETWORK_CLIENT_TOO_OLD, (void*)prepare_network_details_msg(n->second));
|
||||
break;
|
||||
case ZT_NETWORK_STATUS_REQUESTING_CONFIGURATION:
|
||||
_enqueueEvent(ZTS_EVENT_NETWORK_REQ_CONFIG, (void*)prepare_network_details_msg(nwid));
|
||||
_enqueueEvent(ZTS_EVENT_NETWORK_REQ_CONFIG, (void*)prepare_network_details_msg(n->second));
|
||||
break;
|
||||
case ZT_NETWORK_STATUS_OK:
|
||||
if (tap->hasIpv4Addr() && _lwip_is_netif_up(tap->netif4)) {
|
||||
_enqueueEvent(ZTS_EVENT_NETWORK_READY_IP4, (void*)prepare_network_details_msg(nwid));
|
||||
_enqueueEvent(ZTS_EVENT_NETWORK_READY_IP4, (void*)prepare_network_details_msg(n->second));
|
||||
}
|
||||
if (tap->hasIpv6Addr() && _lwip_is_netif_up(tap->netif6)) {
|
||||
_enqueueEvent(ZTS_EVENT_NETWORK_READY_IP6, (void*)prepare_network_details_msg(nwid));
|
||||
_enqueueEvent(ZTS_EVENT_NETWORK_READY_IP6, (void*)prepare_network_details_msg(n->second));
|
||||
}
|
||||
// In addition to the READY messages, send one OK message
|
||||
_enqueueEvent(ZTS_EVENT_NETWORK_OK, (void*)prepare_network_details_msg(nwid));
|
||||
_enqueueEvent(ZTS_EVENT_NETWORK_OK, (void*)prepare_network_details_msg(n->second));
|
||||
break;
|
||||
case ZT_NETWORK_STATUS_ACCESS_DENIED:
|
||||
_enqueueEvent(ZTS_EVENT_NETWORK_ACCESS_DENIED, (void*)prepare_network_details_msg(nwid));
|
||||
_enqueueEvent(ZTS_EVENT_NETWORK_ACCESS_DENIED, (void*)prepare_network_details_msg(n->second));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
n->second.tap->_networkStatus = mostRecentStatus;
|
||||
}
|
||||
|
||||
// TODO: Add ZTS_EVENT_PEER_NEW
|
||||
bool bShouldCopyPeerInfo = false;
|
||||
int eventCode = 0;
|
||||
ZT_PeerList *pl = _node->peers();
|
||||
struct zts_peer_details *pd;
|
||||
if (pl) {
|
||||
@@ -818,28 +909,41 @@ public:
|
||||
if (!peerCache.count(pl->peers[i].address)) {
|
||||
// New peer, add status
|
||||
if (pl->peers[i].pathCount > 0) {
|
||||
pd = new zts_peer_details;
|
||||
memcpy(pd, &(pl->peers[i]), sizeof(struct zts_peer_details));
|
||||
_enqueueEvent(ZTS_EVENT_PEER_DIRECT, (void*)pd);
|
||||
bShouldCopyPeerInfo=true;
|
||||
eventCode = ZTS_EVENT_PEER_DIRECT;
|
||||
}
|
||||
if (pl->peers[i].pathCount == 0) {
|
||||
pd = new zts_peer_details;
|
||||
memcpy(pd, &(pl->peers[i]), sizeof(struct zts_peer_details));
|
||||
_enqueueEvent(ZTS_EVENT_PEER_RELAY, (void*)pd);
|
||||
bShouldCopyPeerInfo=true;
|
||||
eventCode = ZTS_EVENT_PEER_RELAY, (void*)pd;
|
||||
}
|
||||
}
|
||||
// Previously known peer, update status
|
||||
else {
|
||||
if ((peerCache[pl->peers[i].address] == false) && pl->peers[i].pathCount > 0) {
|
||||
pd = new zts_peer_details;
|
||||
memcpy(pd, &(pl->peers[i]), sizeof(struct zts_peer_details));
|
||||
_enqueueEvent(ZTS_EVENT_PEER_DIRECT, (void*)pd);
|
||||
if (peerCache[pl->peers[i].address] < pl->peers[i].pathCount) {
|
||||
bShouldCopyPeerInfo=true;
|
||||
eventCode = ZTS_EVENT_PEER_PATH_DISCOVERED, (void*)pd;
|
||||
}
|
||||
if ((peerCache[pl->peers[i].address] == true) && pl->peers[i].pathCount == 0) {
|
||||
pd = new zts_peer_details;
|
||||
memcpy(pd, &(pl->peers[i]), sizeof(struct zts_peer_details));
|
||||
_enqueueEvent(ZTS_EVENT_PEER_RELAY, (void*)pd);
|
||||
if (peerCache[pl->peers[i].address] > pl->peers[i].pathCount) {
|
||||
bShouldCopyPeerInfo=true;
|
||||
eventCode = ZTS_EVENT_PEER_PATH_DEAD, (void*)pd;
|
||||
}
|
||||
if (peerCache[pl->peers[i].address] == 0 && pl->peers[i].pathCount > 0) {
|
||||
bShouldCopyPeerInfo=true;
|
||||
eventCode = ZTS_EVENT_PEER_DIRECT, (void*)pd;
|
||||
}
|
||||
if (peerCache[pl->peers[i].address] > 0 && pl->peers[i].pathCount == 0) {
|
||||
bShouldCopyPeerInfo=true;
|
||||
eventCode = ZTS_EVENT_PEER_RELAY, (void*)pd;
|
||||
}
|
||||
}
|
||||
if (bShouldCopyPeerInfo) {
|
||||
pd = new zts_peer_details();
|
||||
memcpy(pd, &(pl->peers[i]), sizeof(struct zts_peer_details));
|
||||
for (unsigned int j=0; j<pl->peers[i].pathCount; j++) {
|
||||
native_ss_to_zts_ss(&(pd->paths[j].address), &(pl->peers[i].paths[j].address));
|
||||
}
|
||||
_enqueueEvent(eventCode, (void*)pd);
|
||||
bShouldCopyPeerInfo = false;
|
||||
}
|
||||
// Update our cache with most recently observed path count
|
||||
peerCache[pl->peers[i].address] = pl->peers[i].pathCount;
|
||||
@@ -848,12 +952,6 @@ public:
|
||||
_node->freeQueryResult((void *)pl);
|
||||
}
|
||||
|
||||
inline size_t networkCount()
|
||||
{
|
||||
Mutex::Lock _l(_nets_m);
|
||||
return _nets.size();
|
||||
}
|
||||
|
||||
inline void join(uint64_t nwid)
|
||||
{
|
||||
_node->join(nwid, NULL, NULL);
|
||||
@@ -864,30 +962,6 @@ public:
|
||||
_node->leave(nwid, NULL, NULL);
|
||||
}
|
||||
|
||||
inline void leaveAll()
|
||||
{
|
||||
Mutex::Lock _l(_nets_m);
|
||||
for(std::map<uint64_t,NetworkState>::iterator n(_nets.begin());n!=_nets.end();++n) {
|
||||
_node->leave(n->first, NULL, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
inline int getPeerStatus(uint64_t id)
|
||||
{
|
||||
ZT_PeerList *pl = _node->peers();
|
||||
int status = ZTS_EVENT_PEER_UNREACHABLE;
|
||||
if (pl) {
|
||||
for(unsigned long i=0;i<pl->peerCount;++i) {
|
||||
if (pl->peers[i].address == id) {
|
||||
status = pl->peers[i].pathCount > 0 ? ZTS_EVENT_PEER_DIRECT : ZTS_EVENT_PEER_RELAY;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
_node->freeQueryResult((void *)pl);
|
||||
return status;
|
||||
}
|
||||
|
||||
inline void nodeStatePutFunction(enum ZT_StateObjectType type,const uint64_t id[2],const void *data,int len)
|
||||
{
|
||||
char p[1024];
|
||||
@@ -1295,12 +1369,12 @@ void *_runNodeService(void *arg)
|
||||
service = (NodeService *)0;
|
||||
serviceLock.unlock();
|
||||
_enqueueEvent(ZTS_EVENT_NODE_DOWN,NULL);
|
||||
} catch ( ... ) {
|
||||
}
|
||||
catch ( ... ) {
|
||||
DEBUG_ERROR("unexpected exception starting ZeroTier instance");
|
||||
}
|
||||
delete params;
|
||||
zts_delay_ms(ZTS_CALLBACK_PROCESSING_INTERVAL*2);
|
||||
_clrState(ZTS_STATE_CALLBACKS_RUNNING);
|
||||
#ifndef __WINDOWS__
|
||||
pthread_exit(0);
|
||||
#endif
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "Constants.hpp"
|
||||
#include "Node.hpp"
|
||||
#include "InetAddress.hpp"
|
||||
#include "Mutex.hpp"
|
||||
@@ -168,11 +169,8 @@ public:
|
||||
*/
|
||||
virtual void getRoutes(uint64_t nwid, void *routeArray, unsigned int *numRoutes) = 0;
|
||||
|
||||
virtual size_t networkCount() = 0;
|
||||
virtual void leaveAll() = 0;
|
||||
virtual void join(uint64_t nwid) = 0;
|
||||
virtual void leave(uint64_t nwid) = 0;
|
||||
virtual int getPeerStatus(uint64_t id) = 0;
|
||||
|
||||
/**
|
||||
* Terminate background service (can be called from other threads)
|
||||
|
||||
@@ -23,7 +23,13 @@
|
||||
#include "lwip/stats.h"
|
||||
|
||||
#include "ZeroTierSockets.h"
|
||||
#include "Events.hpp"
|
||||
//#include "Events.hpp"
|
||||
|
||||
#define ZTS_STATE_NODE_RUNNING 0x01
|
||||
#define ZTS_STATE_STACK_RUNNING 0x02
|
||||
#define ZTS_STATE_NET_SERVICE_RUNNING 0x04
|
||||
#define ZTS_STATE_CALLBACKS_RUNNING 0x08
|
||||
#define ZTS_STATE_FREE_CALLED 0x10
|
||||
|
||||
#ifdef SDK_JNI
|
||||
#include <jni.h>
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
* Virtual ethernet tap device and combined network stack driver
|
||||
*/
|
||||
|
||||
#include "Constants.hpp"
|
||||
#include "MAC.hpp"
|
||||
#include "Mutex.hpp"
|
||||
#include "InetAddress.hpp"
|
||||
@@ -90,7 +91,6 @@ VirtualTap::~VirtualTap()
|
||||
{
|
||||
struct zts_network_details *nd = new zts_network_details;
|
||||
nd->nwid = _nwid;
|
||||
_enqueueEvent(ZTS_EVENT_NETWORK_DOWN, (void*)nd);
|
||||
_run = false;
|
||||
#ifndef __WINDOWS__
|
||||
::write(_shutdownSignalPipe[1],"\0",1);
|
||||
@@ -100,6 +100,7 @@ VirtualTap::~VirtualTap()
|
||||
netif4 = NULL;
|
||||
_lwip_remove_netif(netif6);
|
||||
netif6 = NULL;
|
||||
_enqueueEvent(ZTS_EVENT_NETWORK_DOWN, (void*)nd);
|
||||
Thread::join(_thread);
|
||||
#ifndef __WINDOWS__
|
||||
::close(_shutdownSignalPipe[0]);
|
||||
@@ -170,21 +171,7 @@ bool VirtualTap::addIp(const InetAddress &ip)
|
||||
}
|
||||
if (std::find(_ips.begin(),_ips.end(),ip) == _ips.end()) {
|
||||
_lwip_init_interface((void*)this, ip);
|
||||
// TODO: Add ZTS_EVENT_ADDR_NEW ?
|
||||
_ips.push_back(ip);
|
||||
// Send callback message
|
||||
struct zts_addr_details *ad = new zts_addr_details;
|
||||
ad->nwid = _nwid;
|
||||
if (ip.isV4()) {
|
||||
struct sockaddr_in *in4 = (struct sockaddr_in*)&(ad->addr);
|
||||
memcpy(&(in4->sin_addr.s_addr), ip.rawIpData(), 4);
|
||||
_enqueueEvent(ZTS_EVENT_ADDR_ADDED_IP4, (void*)ad);
|
||||
}
|
||||
if (ip.isV6()) {
|
||||
struct sockaddr_in6 *in6 = (struct sockaddr_in6*)&(ad->addr);
|
||||
memcpy(&(in6->sin6_addr.s6_addr), ip.rawIpData(), 16);
|
||||
_enqueueEvent(ZTS_EVENT_ADDR_ADDED_IP6, (void*)ad);
|
||||
}
|
||||
std::sort(_ips.begin(),_ips.end());
|
||||
}
|
||||
return true;
|
||||
@@ -195,20 +182,7 @@ bool VirtualTap::removeIp(const InetAddress &ip)
|
||||
Mutex::Lock _l(_ips_m);
|
||||
std::vector<InetAddress>::iterator i(std::find(_ips.begin(),_ips.end(),ip));
|
||||
if (std::find(_ips.begin(),_ips.end(),ip) != _ips.end()) {
|
||||
struct zts_addr_details *ad = new zts_addr_details;
|
||||
ad->nwid = _nwid;
|
||||
if (ip.isV4()) {
|
||||
struct sockaddr_in *in4 = (struct sockaddr_in*)&(ad->addr);
|
||||
memcpy(&(in4->sin_addr.s_addr), ip.rawIpData(), 4);
|
||||
_enqueueEvent(ZTS_EVENT_ADDR_REMOVED_IP4, (void*)ad);
|
||||
// FIXME: De-register from network stack
|
||||
}
|
||||
if (ip.isV6()) {
|
||||
// FIXME: De-register from network stack
|
||||
struct sockaddr_in6 *in6 = (struct sockaddr_in6*)&(ad->addr);
|
||||
memcpy(&(in6->sin6_addr.s6_addr), ip.rawIpData(), 16);
|
||||
_enqueueEvent(ZTS_EVENT_ADDR_REMOVED_IP6, (void*)ad);
|
||||
}
|
||||
_lwip_remove_address_from_netif((void*)this, ip);
|
||||
_ips.erase(i);
|
||||
}
|
||||
return true;
|
||||
@@ -361,18 +335,12 @@ bool _lwip_is_up()
|
||||
return _getState(ZTS_STATE_STACK_RUNNING);
|
||||
}
|
||||
|
||||
bool _lwip_has_previously_shutdown()
|
||||
{
|
||||
Mutex::Lock _l(stackLock);
|
||||
return _has_exited;
|
||||
}
|
||||
|
||||
void _lwip_driver_init()
|
||||
{
|
||||
if (_lwip_is_up()) {
|
||||
return;
|
||||
}
|
||||
if (_lwip_has_previously_shutdown()) {
|
||||
if (_has_exited) {
|
||||
return;
|
||||
}
|
||||
Mutex::Lock _l(stackLock);
|
||||
@@ -385,7 +353,7 @@ void _lwip_driver_init()
|
||||
|
||||
void _lwip_driver_shutdown()
|
||||
{
|
||||
if (_lwip_has_previously_shutdown()) {
|
||||
if (_has_exited) {
|
||||
return;
|
||||
}
|
||||
Mutex::Lock _l(stackLock);
|
||||
@@ -393,11 +361,6 @@ void _lwip_driver_shutdown()
|
||||
_clrState(ZTS_STATE_STACK_RUNNING);
|
||||
// Wait until the main lwIP thread has exited
|
||||
while (!_has_exited) { zts_delay_ms(LWIP_DRIVER_LOOP_INTERVAL); }
|
||||
/*
|
||||
if (tcpip_shutdown() == ERR_OK) {
|
||||
sys_timeouts_free();
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
void _lwip_remove_netif(void *netif)
|
||||
@@ -532,28 +495,6 @@ void _lwip_eth_rx(VirtualTap *tap, const MAC &from, const MAC &to, unsigned int
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
static void print_netif_info(struct netif *n) {
|
||||
DEBUG_INFO("n=%p, %c%c, %d, o=%p, o6=%p, mc=%x:%x:%x:%x:%x:%x, hwln=%d, st=%p, flgs=%d\n",
|
||||
n,
|
||||
n->name[0],
|
||||
n->name[1],
|
||||
n->mtu,
|
||||
n->output,
|
||||
n->output_ip6,
|
||||
n->hwaddr[0],
|
||||
n->hwaddr[1],
|
||||
n->hwaddr[2],
|
||||
n->hwaddr[3],
|
||||
n->hwaddr[4],
|
||||
n->hwaddr[5],
|
||||
n->hwaddr_len,
|
||||
n->state,
|
||||
n->flags
|
||||
);
|
||||
}
|
||||
*/
|
||||
|
||||
bool _lwip_is_netif_up(void *n)
|
||||
{
|
||||
if (!n) {
|
||||
@@ -565,10 +506,19 @@ bool _lwip_is_netif_up(void *n)
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when a netif is removed (ZTS_EVENT_NETIF_INTERFACE_REMOVED)
|
||||
*/
|
||||
#if LWIP_NETIF_REMOVE_CALLBACK
|
||||
static struct zts_netif_details *_lwip_prepare_netif_status_msg(struct netif *n)
|
||||
{
|
||||
if (!n || !n->state) {
|
||||
return NULL;
|
||||
}
|
||||
VirtualTap *tap = (VirtualTap *)n->state;
|
||||
struct zts_netif_details *details = new zts_netif_details();
|
||||
details->nwid = tap->_nwid;
|
||||
memcpy(&(details->mac), n->hwaddr, n->hwaddr_len);
|
||||
details->mtu = n->mtu;
|
||||
return details;
|
||||
}
|
||||
|
||||
static void _netif_remove_callback(struct netif *n)
|
||||
{
|
||||
// Called from core, no need to lock
|
||||
@@ -576,75 +526,35 @@ static void _netif_remove_callback(struct netif *n)
|
||||
return;
|
||||
}
|
||||
VirtualTap *tap = (VirtualTap *)n->state;
|
||||
uint64_t mac = 0;
|
||||
memcpy(&mac, n->hwaddr, n->hwaddr_len);
|
||||
struct zts_netif_details *ifd = new zts_netif_details;
|
||||
ifd->nwid = tap->_nwid;
|
||||
memcpy(&(ifd->mac), n->hwaddr, n->hwaddr_len);
|
||||
ifd->mac = lwip_htonl(ifd->mac) >> 16;
|
||||
_enqueueEvent(ZTS_EVENT_NETIF_REMOVED, (void*)ifd);
|
||||
struct zts_netif_details *details = new zts_netif_details();
|
||||
details->nwid = tap->_nwid;
|
||||
details->mac = 0;
|
||||
details->mtu = 0;
|
||||
_enqueueEvent(ZTS_EVENT_NETIF_REMOVED, (void*)details);
|
||||
}
|
||||
|
||||
static void _netif_status_callback(struct netif *n)
|
||||
{
|
||||
// Called from core, no need to lock
|
||||
if (!n) {
|
||||
return;
|
||||
} if (netif_is_up(n)) {
|
||||
_enqueueEvent(ZTS_EVENT_NETIF_UP, (void*)_lwip_prepare_netif_status_msg(n));
|
||||
} else {
|
||||
_enqueueEvent(ZTS_EVENT_NETIF_DOWN, (void*)_lwip_prepare_netif_status_msg(n));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* 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 *n)
|
||||
{
|
||||
// Called from core, no need to lock
|
||||
if (!n || !n->state) {
|
||||
return;
|
||||
}
|
||||
VirtualTap *tap = (VirtualTap *)n->state;
|
||||
uint64_t mac = 0;
|
||||
memcpy(&mac, n->hwaddr, n->hwaddr_len);
|
||||
if (n->flags & NETIF_FLAG_LINK_UP) {
|
||||
struct zts_netif_details *ifd = new zts_netif_details;
|
||||
ifd->nwid = tap->_nwid;
|
||||
memcpy(&(ifd->mac), n->hwaddr, n->hwaddr_len);
|
||||
ifd->mac = lwip_htonl(ifd->mac) >> 16;
|
||||
_enqueueEvent(ZTS_EVENT_NETIF_LINK_UP, (void*)ifd);
|
||||
}
|
||||
if (n->flags & NETIF_FLAG_LINK_UP) {
|
||||
struct zts_netif_details *ifd = new zts_netif_details;
|
||||
ifd->nwid = tap->_nwid;
|
||||
memcpy(&(ifd->mac), n->hwaddr, n->hwaddr_len);
|
||||
ifd->mac = lwip_htonl(ifd->mac) >> 16;
|
||||
_enqueueEvent(ZTS_EVENT_NETIF_LINK_DOWN, (void*)ifd);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void _lwip_set_callbacks(struct netif *n)
|
||||
{
|
||||
if (!n) {
|
||||
return;
|
||||
} if (netif_is_link_up(n)) {
|
||||
_enqueueEvent(ZTS_EVENT_NETIF_LINK_UP, (void*)_lwip_prepare_netif_status_msg(n));
|
||||
} else {
|
||||
_enqueueEvent(ZTS_EVENT_NETIF_LINK_DOWN, (void*)_lwip_prepare_netif_status_msg(n));
|
||||
}
|
||||
#if LWIP_NETIF_STATUS_CALLBACK
|
||||
// Not currently used
|
||||
netif_set_status_callback(n, netif_status_callback);
|
||||
#endif
|
||||
#if LWIP_NETIF_REMOVE_CALLBACK
|
||||
netif_set_remove_callback(n, netif_remove_callback);
|
||||
#endif
|
||||
#if LWIP_NETIF_LINK_CALLBACK
|
||||
netif_set_link_callback(n, netif_link_callback);
|
||||
#endif
|
||||
}
|
||||
|
||||
static struct zts_netif_details *_lwip_prepare_netif_status_msg(struct netif *n)
|
||||
{
|
||||
if (!n || !n->state) {
|
||||
return NULL;
|
||||
}
|
||||
VirtualTap *tap = (VirtualTap*)(n->state);
|
||||
struct zts_netif_details *ifd = new zts_netif_details;
|
||||
ifd->nwid = tap->_nwid;
|
||||
ifd->mtu = n->mtu;
|
||||
memcpy(&(ifd->mac), n->hwaddr, n->hwaddr_len);
|
||||
ifd->mac = htonll(ifd->mac) >> 16;
|
||||
return ifd;
|
||||
}
|
||||
|
||||
static err_t _netif_init4(struct netif *n)
|
||||
@@ -652,7 +562,7 @@ static err_t _netif_init4(struct netif *n)
|
||||
if (!n || !n->state) {
|
||||
return ERR_IF;
|
||||
}
|
||||
// Called from netif code, no need to lock
|
||||
// Called from core, no need to lock
|
||||
VirtualTap *tap = (VirtualTap*)(n->state);
|
||||
n->hwaddr_len = 6;
|
||||
n->name[0] = '4';
|
||||
@@ -680,7 +590,7 @@ static err_t _netif_init6(struct netif *n)
|
||||
n->hwaddr_len = sizeof(n->hwaddr);
|
||||
VirtualTap *tap = (VirtualTap*)(n->state);
|
||||
tap->_mac.copyTo(n->hwaddr, n->hwaddr_len);
|
||||
// Called from netif code, no need to lock
|
||||
// Called from core, no need to lock
|
||||
n->hwaddr_len = 6;
|
||||
n->name[0] = '6';
|
||||
n->name[1] = 'a'+netifCount;
|
||||
@@ -715,6 +625,11 @@ void _lwip_init_interface(void *tapref, const InetAddress &ip)
|
||||
isNewNetif = true;
|
||||
netifCount++;
|
||||
}
|
||||
/*
|
||||
netif_set_status_callback(n, _netif_status_callback);
|
||||
netif_set_remove_callback(n, _netif_remove_callback);
|
||||
netif_set_link_callback(n, _netif_link_callback);
|
||||
*/
|
||||
char nmbuf[INET6_ADDRSTRLEN];
|
||||
static ip4_addr_t ip4, netmask, gw;
|
||||
IP4_ADDR(&gw,127,0,0,1);
|
||||
@@ -723,13 +638,12 @@ void _lwip_init_interface(void *tapref, const InetAddress &ip)
|
||||
LOCK_TCPIP_CORE();
|
||||
netif_add(n, &ip4, &netmask, &gw, (void*)vtap, _netif_init4, tcpip_input);
|
||||
vtap->netif4 = (void*)n;
|
||||
_enqueueEvent(ZTS_EVENT_NETIF_UP, (void*)_lwip_prepare_netif_status_msg(n));
|
||||
UNLOCK_TCPIP_CORE();
|
||||
snprintf(macbuf, ZTS_MAC_ADDRSTRLEN, "%02x:%02x:%02x:%02x:%02x:%02x",
|
||||
n->hwaddr[0], n->hwaddr[1], n->hwaddr[2],
|
||||
n->hwaddr[3], n->hwaddr[4], n->hwaddr[5]);
|
||||
DEBUG_INFO("initialized netif=%p as [mac=%s, addr=%s, nm=%s, tap=%p]",n,
|
||||
macbuf, ip.toString(ipbuf), ip.netmask().toString(nmbuf), vtap);
|
||||
//DEBUG_INFO("initialized netif=%p as [mac=%s, addr=%s, nm=%s, tap=%p]",n,
|
||||
// macbuf, ip.toString(ipbuf), ip.netmask().toString(nmbuf), vtap);
|
||||
}
|
||||
if (ip.isV6()) {
|
||||
if (vtap->netif6) {
|
||||
@@ -739,7 +653,11 @@ void _lwip_init_interface(void *tapref, const InetAddress &ip)
|
||||
n = new struct netif;
|
||||
isNewNetif = true;
|
||||
netifCount++;
|
||||
}
|
||||
}/*
|
||||
netif_set_status_callback(n, _netif_status_callback);
|
||||
netif_set_remove_callback(n, _netif_remove_callback);
|
||||
netif_set_link_callback(n, _netif_link_callback);
|
||||
*/
|
||||
static ip6_addr_t ip6;
|
||||
memcpy(&(ip6.addr), ip.rawIpData(), sizeof(ip6.addr));
|
||||
LOCK_TCPIP_CORE();
|
||||
@@ -756,13 +674,37 @@ void _lwip_init_interface(void *tapref, const InetAddress &ip)
|
||||
netif_add_ip6_address(n,&ip6,NULL);
|
||||
n->output_ip6 = ethip6_output;
|
||||
UNLOCK_TCPIP_CORE();
|
||||
_enqueueEvent(ZTS_EVENT_NETIF_UP, (void*)_lwip_prepare_netif_status_msg(n));
|
||||
snprintf(macbuf, ZTS_MAC_ADDRSTRLEN, "%02x:%02x:%02x:%02x:%02x:%02x",
|
||||
n->hwaddr[0], n->hwaddr[1], n->hwaddr[2],
|
||||
n->hwaddr[3], n->hwaddr[4], n->hwaddr[5]);
|
||||
DEBUG_INFO("initialized netif=%p as [mac=%s, addr=%s, tap=%p]", n,
|
||||
macbuf, ip.toString(ipbuf), vtap);
|
||||
//DEBUG_INFO("initialized netif=%p as [mac=%s, addr=%s, tap=%p]", n,
|
||||
// macbuf, ip.toString(ipbuf), vtap);
|
||||
}
|
||||
}
|
||||
|
||||
void _lwip_remove_address_from_netif(void *tapref, const InetAddress &ip)
|
||||
{
|
||||
if (!tapref) {
|
||||
return;
|
||||
}
|
||||
VirtualTap *vtap = (VirtualTap*)tapref;
|
||||
struct netif *n = NULL;
|
||||
/* When true multi-homing is implemented this will need to
|
||||
be a bit more sophisticated */
|
||||
if (ip.isV4()) {
|
||||
if (vtap->netif4) {
|
||||
n = (struct netif*)vtap->netif4;
|
||||
}
|
||||
}
|
||||
if (ip.isV6()) {
|
||||
if (vtap->netif6) {
|
||||
n = (struct netif*)vtap->netif6;
|
||||
}
|
||||
}
|
||||
if (!n) {
|
||||
return;
|
||||
}
|
||||
_lwip_remove_netif(n);
|
||||
}
|
||||
|
||||
} // namespace ZeroTier
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
|
||||
#include "lwip/err.h"
|
||||
|
||||
#define ZTS_LWIP_DRIVER_THREAD_NAME "NetworkStackThread"
|
||||
#define ZTS_LWIP_DRIVER_THREAD_NAME "ZTNetworkStackThread"
|
||||
|
||||
#include "MAC.hpp"
|
||||
#include "Phy.hpp"
|
||||
@@ -119,20 +119,6 @@ public:
|
||||
void threadMain()
|
||||
throw();
|
||||
|
||||
#if defined(__MINGW32__)
|
||||
/* The following is merely to make ZeroTier's OneService happy while building on Windows.
|
||||
we won't use these in libzt */
|
||||
NET_LUID _deviceLuid;
|
||||
std::string _deviceInstanceId;
|
||||
|
||||
/**
|
||||
* Returns whether the VirtualTap interface has been initialized
|
||||
*/
|
||||
bool isInitialized() const { return _initialized; };
|
||||
|
||||
inline const NET_LUID &luid() const { return _deviceLuid; }
|
||||
inline const std::string &instanceId() const { return _deviceInstanceId; }
|
||||
#endif
|
||||
/**
|
||||
* For moving data onto the ZeroTier virtual wire
|
||||
*/
|
||||
@@ -151,8 +137,6 @@ public:
|
||||
|
||||
int _networkStatus = 0;
|
||||
|
||||
std::vector<std::pair<InetAddress, InetAddress> > routes;
|
||||
|
||||
char vtap_full_name[64];
|
||||
|
||||
std::vector<InetAddress> ips() const;
|
||||
@@ -223,7 +207,6 @@ bool _lwip_is_up();
|
||||
* @brief Initialize network stack semaphores, threads, and timers.
|
||||
*
|
||||
* @usage This is called during the initial setup of each VirtualTap but is only allowed to execute once
|
||||
* @return
|
||||
*/
|
||||
void _lwip_driver_init();
|
||||
|
||||
@@ -233,30 +216,21 @@ void _lwip_driver_init();
|
||||
* @usage This is to be called after it is determined that no further network activity will take place.
|
||||
* The tcpip thread will be stopped, all interfaces will be brought down and all resources will
|
||||
* be deallocated. A full application restart will be required to bring the stack back online.
|
||||
* @return
|
||||
*/
|
||||
void _lwip_driver_shutdown();
|
||||
|
||||
/**
|
||||
* @brief Requests that a netif be brought down and removed.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
void _lwip_remove_netif(void *netif);
|
||||
|
||||
/**
|
||||
* @brief Initialize and start the DNS client
|
||||
*
|
||||
* @usage Called after lwip_driver_init()
|
||||
* @return
|
||||
*/
|
||||
void _lwip_dns_init();
|
||||
|
||||
/**
|
||||
* @brief Starts DHCP timers
|
||||
*
|
||||
* @usage lwip_driver_init()
|
||||
* @return
|
||||
*/
|
||||
void _lwip_start_dhcp(void *netif);
|
||||
|
||||
@@ -286,13 +260,19 @@ static void _netif_link_callback(struct netif *netif);
|
||||
/**
|
||||
* @brief Set up an interface in the network stack for the VirtualTap.
|
||||
*
|
||||
* @param
|
||||
* @param tapref Reference to VirtualTap that will be responsible for sending and receiving data
|
||||
* @param ip Virtual IP address for this ZeroTier VirtualTap interface
|
||||
* @return
|
||||
*/
|
||||
void _lwip_init_interface(void *tapref, const InetAddress &ip);
|
||||
|
||||
/**
|
||||
* @brief Remove an assigned address from an lwIP netif
|
||||
*
|
||||
* @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);
|
||||
|
||||
/**
|
||||
* @brief Called from the stack, outbound ethernet frames from the network stack enter the ZeroTier virtual wire here.
|
||||
*
|
||||
@@ -313,7 +293,6 @@ err_t _lwip_eth_tx(struct netif *netif, struct pbuf *p);
|
||||
* @param etherType Protocol type
|
||||
* @param data Pointer to Ethernet frame
|
||||
* @param len Length of Ethernet frame
|
||||
* @return
|
||||
*/
|
||||
void _lwip_eth_rx(VirtualTap *tap, const MAC &from, const MAC &to, unsigned int etherType,
|
||||
const void *data, unsigned int len);
|
||||
|
||||
Reference in New Issue
Block a user