Added zts_get_protocol_stats(), zts_restart(), updated API documentation
This commit is contained in:
73
API.md
73
API.md
@@ -2,19 +2,19 @@
|
||||
|
||||
<a href="https://www.zerotier.com/?pk_campaign=github_libzt"><img src="https://raw.githubusercontent.com/zerotier/ZeroTierOne/master/artwork/ZeroTierIcon.png" width="128" height="128" align="left" hspace="20"></a>
|
||||
|
||||
The ZeroTier SDK is composed of two libraries: `libztcore` which is the platform-agnostic network hypervisor, and `libzt` which is the network hypervisor paired with a userspace network stack. `libzt` is a superset of `libztcore` and is distinguished by the fact that it exposes a standard [socket API](https://en.wikipedia.org/wiki/Berkeley_sockets) and simple network control API. The full source for these products can be found at [github.com/zerotier/libzt](https://github.com/zerotier/libzt) for the SDK and [github.com/zerotier/ZeroTierOne](https://github.com/zerotier/ZeroTierOne) for the desktop client. With these libraries the stack and virtual link are exclusive to your app and traffic is fully encrypted via the [Salsa20](https://en.wikipedia.org/wiki/Salsa20) cipher. For a more in-depth discussion on the technical side of ZeroTier, check out our [Manual](https://www.zerotier.com/manual.shtml?pk_campaign=github_libzt)
|
||||
The ZeroTier SDK is composed of two libraries: `libztcore` which is the platform-agnostic network hypervisor, and `libzt` which is the network hypervisor paired with a userspace network stack. `libzt` is a superset of `libztcore` and is distinguished by the fact that it exposes a standard [socket API](https://en.wikipedia.org/wiki/Berkeley_sockets) and simple network control API. The full source for these products can be found at [github.com/zerotier/libzt](https://github.com/zerotier/libzt) for the SDK and [github.com/zerotier/ZeroTierOne](https://github.com/zerotier/ZeroTierOne) for the desktop client. With these libraries the network stack and virtual link are exclusive to your app and traffic is fully encrypted via the [Salsa20](https://en.wikipedia.org/wiki/Salsa20) cipher. For a more in-depth discussion on the technical side of ZeroTier, check out our [Manual](https://www.zerotier.com/manual.shtml?pk_campaign=github_libzt)
|
||||
|
||||
<br>
|
||||
|
||||
# Getting started
|
||||
|
||||
Before we dive into the technicals, the first thing to understand is that there are two API families to choose from and each is intended for very different purposes, they are briefly explained below:
|
||||
Before we dive into the technicals, the first thing to understand is that there are two API families to choose from and each is intended for a very different purpose:
|
||||
|
||||
`libzt` Intended for convenience and simplicity, derives from [Berkley Sockets](https://en.wikipedia.org/wiki/Berkeley_sockets).
|
||||
- socket API: `zts_socket(), zts_connect(), zts_bind(), ...`
|
||||
- control API: `zts_start(), zts_join(), zts_leave(), ....`
|
||||
|
||||
`libztcore` Intended for raw performance. If your goal is simply moving frames as quickly as possible and you're willing to put in some extra work, this API exposed in `include/ZeroTierOne.h` is what you're looking for. For an example of how this API is used, see the living documentation that is `src/Service.cpp`.
|
||||
`libztcore` Intended for raw performance. If your goal is simply moving frames as quickly as possible and you're willing to put in some extra work, is what you're looking. The API is described in `include/ZeroTierOne.h`. For an example of how this API is used, see the living documentation that is `src/Service.cpp`.
|
||||
- core API: `ZT_VirtualNetworkFrameFunction(), ZT_WirePacketSendFunction(), ...`
|
||||
|
||||
*NOTE: The remainder of this document will focus on the usage of the socket and control C API exposed in `include/ZeroTier.h` for `libzt`. For more information on the `libztcore` API see `include/ZeroTierOne.h`. We also provide bindings, frameworks, and packages for other languages and platforms in the `ports` directory and example applications using them in the `examples` directory.*
|
||||
@@ -29,7 +29,7 @@ To start the service, simply call:
|
||||
|
||||
`zts_start(char *path, void (*userCallbackFunc)(struct zts_callback_msg*), int port)`
|
||||
|
||||
At this stage if a cryptograph identity doesn't already exist, it will generate a new one and store it on disk, the node's address (commonly referred to as `nodeId`) will be derived from this identity and will be presented to you upon receiving the `ZTS_EVENT_NODE_ONLINE` shown below.
|
||||
At this stage, if a cryptographic identity for this node does not already exist, it will generate a new one and store it on disk, the node's address (commonly referred to as `nodeId`) will be derived from this identity and will be presented to you upon receiving the `ZTS_EVENT_NODE_ONLINE` shown below.
|
||||
|
||||
*NOTE: The first argument `path` is a path where you will allow ZeroTier to store its automatically-generated cryptographic identity files (`identity.public` and `identity.secret`), these files are your keys to communicating on the network. Keep them safe and keep them unique. If any two nodes are online using the same identities you will have a bad time. The second argument `userCallbackFunc` is a function that you specify to handle all generated events for the life of your program (see below):*
|
||||
|
||||
@@ -40,6 +40,7 @@ void myZeroTierEventCallback(struct zts_callback_msg *msg)
|
||||
printf("ZTS_EVENT_NODE_ONLINE, nodeId=%llx\n", msg->node->address);
|
||||
// You can join networks now!
|
||||
}
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
@@ -58,9 +59,9 @@ After receiving `ZTS_EVENT_NODE_ONLINE` you will be allowed to join or leave net
|
||||
|
||||
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, the userspace 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.
|
||||
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.
|
||||
|
||||
Lastly, 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>
|
||||
|
||||
@@ -85,9 +86,9 @@ ZTS_EVENT_NETWORK_DOWN
|
||||
|
||||
# Communicating with peers
|
||||
|
||||
After successfully starting the service and joining a network, communicating with other nodes (peers) on that network is as easy as it would ordinarily be without ZeroTier. However, one thing to be aware of is the difference between relay and P2P modes. In the event that a direct connection cannot be established between your nodes, ZeroTier offers a free relaying service, this means that your nodes are reachable almost instantaneously but at a temporary performance cost. One should wait to send large amounts of traffic until a `ZTS_EVENT_PEER_P2P` is received for the node that you're interested in talking to. This event usually only takes a few seconds to appear after your node comes online. Similarly if after some time ZeroTier determines that a previously known path to one of your nodes is no longer available you will see a `ZTS_EVENT_PEER_RELAY` event.
|
||||
After successfully starting the service and joining a network, communicating with other nodes (peers) on that network is as easy as it would ordinarily be without ZeroTier. However, one thing to be aware of is the difference between relay and P2P modes. In the event that a direct connection cannot be established between your nodes, ZeroTier offers a free relaying service, this means that your nodes are reachable almost instantaneously but at a temporary performance cost. One should wait to send large amounts of traffic until a `ZTS_EVENT_PEER_P2P` is received for the node that you're interested in talking to. This event usually only takes a few seconds to appear after data has initially been sent. Similarly if after some time ZeroTier determines that a previously known path to one of your nodes is no longer available you will see a `ZTS_EVENT_PEER_RELAY` event.
|
||||
|
||||
If one wants to query the current reachability state of another node `zts_get_peer_status(uint64_t peerId)` can be used. This function will actually **return** the previously mentioned event values, plus an additional one called `ZTS_EVENT_PEER_UNREACHABLE` if no known direct path exists between the calling node and the remote node.
|
||||
One can use `zts_get_peer_status(uint64_t peerId)` to query the current reachability state of another node. This function will actually **return** the previously mentioned event values, plus an additional one called `ZTS_EVENT_PEER_UNREACHABLE` if no known direct path exists between the calling node and the remote node.
|
||||
|
||||
<div style="page-break-after: always;"></div>
|
||||
|
||||
@@ -141,7 +142,7 @@ ZTS_EVENT_PEER_P2P --- node=a09acf0233
|
||||
|
||||
## Node Events
|
||||
|
||||
These events pertain to the state of the current node. Additionally, one can query the status of the node with `zts_get_node_status()`. This message type will arrive with a `zts_node_details` object accessible via `msg->node`.
|
||||
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.
|
||||
|
||||
```
|
||||
ZTS_EVENT_NODE_OFFLINE
|
||||
@@ -155,7 +156,7 @@ ZTS_EVENT_NODE_NORMAL_TERMINATION
|
||||
|
||||
## Network Events
|
||||
|
||||
These events pertain to the state of the indicated network. Additionally, one can query the status of the network with `zts_get_network_status(uint64_t networkId)`. 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`.
|
||||
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.
|
||||
|
||||
```
|
||||
ZTS_EVENT_NETWORK_NOT_FOUND
|
||||
@@ -170,7 +171,7 @@ ZTS_EVENT_NETWORK_DOWN
|
||||
|
||||
## 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.
|
||||
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.
|
||||
|
||||
```
|
||||
ZTS_EVENT_PEER_P2P
|
||||
@@ -244,14 +245,52 @@ The socket API error codes are defined in `doc/errno.h`
|
||||
|
||||
*NOTE: For Android/Java (or similar) which use JNI, the socket API's error codes are negative values*
|
||||
|
||||
*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>
|
||||
|
||||
# Threading
|
||||
# Thread model
|
||||
|
||||
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 manner. 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.
|
||||
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.
|
||||
|
||||
*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.*
|
||||
|
||||
# Statistics
|
||||
|
||||
Protocol and service statistics are available in debug builds of `libzt`. These statistics are detailed fully in the section of `include/ZeroTier.h` that is guarded by `LWIP_STATS`. The protocol constants are defined in `include/ZeroTierConstants.h`. An example usage is as follows:
|
||||
|
||||
C++ example:
|
||||
```
|
||||
struct zts_stats_proto stats;
|
||||
|
||||
// Get received pings
|
||||
if (zts_get_protocol_stats(ZTS_STATS_PROTOCOL_ICMP, &stats) == ZTS_ERR_OK) {
|
||||
printf("icmp.recv=%d\n", stats.recv);
|
||||
}
|
||||
|
||||
// Get dropped TCP packets
|
||||
if (zts_get_protocol_stats(ZTS_STATS_PROTOCOL_TCP, &stats) == ZTS_ERR_OK) {
|
||||
printf("tcp.drop=%d\n", stats.drop);
|
||||
}
|
||||
```
|
||||
|
||||
Java Example:
|
||||
|
||||
```
|
||||
import com.zerotier.libzt.ZeroTierProtoStats;
|
||||
|
||||
...
|
||||
|
||||
// Get received pings
|
||||
ZeroTierProtoStats stats = new ZeroTierProtoStats();
|
||||
ZeroTier.get_protocol_stats(ZeroTier.STATS_PROTOCOL_ICMP, stats);
|
||||
System.out.println("icmp.recv="+stats.recv);
|
||||
```
|
||||
|
||||
# Network Controller Mode (Coming soon)
|
||||
|
||||
The library form of ZeroTier can act as a network controller and is controlled via the `zts_controller_*` API calls specified in `include/ZeroTier.h`.
|
||||
|
||||
# C Example
|
||||
|
||||
```
|
||||
@@ -270,7 +309,7 @@ void myZeroTierEventCallback(struct zts_callback_msg *msg)
|
||||
switch (msg->eventCode)
|
||||
{
|
||||
case ZTS_EVENT_NODE_ONLINE:
|
||||
printf("ZTS_EVENT_NODE_ONLINE, node=%llx\n", msg->node->address);
|
||||
printf("ZTS_EVENT_NODE_ONLINE, nodeId=%llx\n", msg->node->address);
|
||||
node_ready = true;
|
||||
break;
|
||||
case ZTS_EVENT_NODE_OFFLINE:
|
||||
@@ -278,14 +317,14 @@ void myZeroTierEventCallback(struct zts_callback_msg *msg)
|
||||
node_ready = false;
|
||||
break;
|
||||
case ZTS_EVENT_NETWORK_READY_IP4:
|
||||
printf("ZTS_EVENT_NETWORK_READY_IP4 --- network=%llx\n", msg->network->nwid);
|
||||
printf("ZTS_EVENT_NETWORK_READY_IP4, networkId=%llx\n", msg->network->nwid);
|
||||
network_ready = true;
|
||||
break;
|
||||
case ZTS_EVENT_PEER_P2P:
|
||||
printf("ZTS_EVENT_PEER_P2P --- node=%llx\n", msg->peer->address);
|
||||
printf("ZTS_EVENT_PEER_P2P, nodeId=%llx\n", msg->peer->address);
|
||||
break;
|
||||
case ZTS_EVENT_PEER_RELAY:
|
||||
printf("ZTS_EVENT_PEER_RELAY --- node=%llx\n", msg->peer->address);
|
||||
printf("ZTS_EVENT_PEER_RELAY, nodeId=%llx\n", msg->peer->address);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
||||
@@ -107,6 +107,22 @@ set (ZT_FLAGS "${ZT_FLAGS} -DZT_SDK=1")
|
||||
if (DEBUG_BUILD)
|
||||
set (LWIP_FLAGS "${LWIP_FLAGS} -DLWIP_DBG_TYPES_ON=128")
|
||||
set (LWIP_FLAGS "${LWIP_FLAGS} -DSOCKETS_DEBUG=128")
|
||||
set (LWIP_FLAGS "${LWIP_FLAGS} -DLWIP_STATS_LARGE=1")
|
||||
set (LWIP_FLAGS "${LWIP_FLAGS} -DLWIP_STATS=1")
|
||||
set (LWIP_FLAGS "${LWIP_FLAGS} -DLINK_STATS=1")
|
||||
set (LWIP_FLAGS "${LWIP_FLAGS} -DETHARP_STATS=1")
|
||||
set (LWIP_FLAGS "${LWIP_FLAGS} -DIPFRAG_STATS=1")
|
||||
set (LWIP_FLAGS "${LWIP_FLAGS} -DIP_STATS=1")
|
||||
set (LWIP_FLAGS "${LWIP_FLAGS} -DICMP_STATS=1")
|
||||
set (LWIP_FLAGS "${LWIP_FLAGS} -DIGMP_STATS=1")
|
||||
set (LWIP_FLAGS "${LWIP_FLAGS} -DUDP_STATS=1")
|
||||
set (LWIP_FLAGS "${LWIP_FLAGS} -DTCP_STATS=1")
|
||||
set (LWIP_FLAGS "${LWIP_FLAGS} -DSYS_STATS=1")
|
||||
set (LWIP_FLAGS "${LWIP_FLAGS} -DIP6_STATS=1")
|
||||
set (LWIP_FLAGS "${LWIP_FLAGS} -DICMP6_STATS=1")
|
||||
set (LWIP_FLAGS "${LWIP_FLAGS} -DIP6_FRAG_STATS=1")
|
||||
set (LWIP_FLAGS "${LWIP_FLAGS} -DMLD6_STATS=1")
|
||||
set (LWIP_FLAGS "${LWIP_FLAGS} -DND6_STATS=1")
|
||||
else ()
|
||||
set (LWIP_FLAGS "${LWIP_FLAGS} -DLWIP_DBG_TYPES_ON=0")
|
||||
endif ()
|
||||
@@ -277,6 +293,9 @@ include_directories (${PROJ_DIR}/ext/concurrentqueue)
|
||||
# TODO: Should separate this into its own ios.cmake file
|
||||
|
||||
if (IOS_FRAMEWORK)
|
||||
# Controllers probably won't be run from iPhones, so we can omit JSON support
|
||||
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DOMIT_JSON_SUPPORT=1")
|
||||
set (CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DOMIT_JSON_SUPPORT=1")
|
||||
set(DEVROOT
|
||||
"/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer")
|
||||
if (IOS_ARM64)
|
||||
@@ -298,6 +317,8 @@ if (IOS_FRAMEWORK)
|
||||
endif ()
|
||||
|
||||
if (MACOS_FRAMEWORK)
|
||||
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DOMIT_JSON_SUPPORT=1")
|
||||
set (CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DOMIT_JSON_SUPPORT=1")
|
||||
include_directories ("/Library/Developer/CommandLineTools/SDKs/MacOSX10.14.sdk/usr/include/")
|
||||
endif ()
|
||||
|
||||
|
||||
7
dist.sh
7
dist.sh
@@ -148,6 +148,7 @@ host_jar()
|
||||
fi
|
||||
LIB_OUTPUT_DIR=$(pwd)/lib/$1/${NORMALIZED_OSNAME}-$(uname -m)
|
||||
mkdir -p $LIB_OUTPUT_DIR
|
||||
rm -rf $LIB_OUTPUT_DIR/zt.jar
|
||||
# Build dynamic library
|
||||
BUILD_DIR=$(pwd)/tmp/${NORMALIZED_OSNAME}-$(uname -m)-jni-$1
|
||||
UPPERCASE_CONFIG="$(tr '[:lower:]' '[:upper:]' <<< ${1:0:1})${1:1}"
|
||||
@@ -184,16 +185,22 @@ host()
|
||||
echo "Executing task: " ${FUNCNAME[ 0 ]} "(" $1 ")"
|
||||
NORMALIZED_OSNAME=$OSNAME
|
||||
if [[ $OSNAME = *"darwin"* ]]; then
|
||||
DYNAMIC_LIB_NAME="libzt.dylib"
|
||||
NORMALIZED_OSNAME="macos"
|
||||
fi
|
||||
if [[ $OSNAME = *"linux"* ]]; then
|
||||
DYNAMIC_LIB_NAME="libzt.so"
|
||||
fi
|
||||
# CMake build files
|
||||
BUILD_DIR=$(pwd)/tmp/${NORMALIZED_OSNAME}-$(uname -m)-$1
|
||||
mkdir -p $BUILD_DIR
|
||||
# Where to place results
|
||||
BIN_OUTPUT_DIR=$(pwd)/bin/$1/${NORMALIZED_OSNAME}-$(uname -m)
|
||||
mkdir -p $BIN_OUTPUT_DIR
|
||||
rm -rf $BIN_OUTPUT_DIR/*
|
||||
LIB_OUTPUT_DIR=$(pwd)/lib/$1/${NORMALIZED_OSNAME}-$(uname -m)
|
||||
mkdir -p $LIB_OUTPUT_DIR
|
||||
rm -rf $LIB_OUTPUT_DIR/libzt.a $LIB_OUTPUT_DIR/$DYNAMIC_LIB_NAME $LIB_OUTPUT_DIR/libztcore.a
|
||||
# Build
|
||||
cmake -H. -B$BUILD_DIR -DCMAKE_BUILD_TYPE=$1
|
||||
cmake --build $BUILD_DIR $BUILD_CONCURRENCY
|
||||
|
||||
@@ -71,55 +71,53 @@ index 74c22d33..3e4f53b4 100644
|
||||
if (nqcb->oldQueues[i]->byteLength > maxQueueLength) {
|
||||
maxQueueLength = nqcb->oldQueues[i]->byteLength;
|
||||
diff --git a/osdep/OSUtils.cpp b/osdep/OSUtils.cpp
|
||||
index 676f6335..c1a2a73d 100644
|
||||
index 676f6335..2834fd22 100644
|
||||
--- a/osdep/OSUtils.cpp
|
||||
+++ b/osdep/OSUtils.cpp
|
||||
@@ -451,7 +451,7 @@ std::string OSUtils::platformDefaultHomePath()
|
||||
|
||||
@@ -452,6 +452,7 @@ std::string OSUtils::platformDefaultHomePath()
|
||||
#endif // __UNIX_LIKE__ or not...
|
||||
}
|
||||
-
|
||||
+/*
|
||||
|
||||
+#ifndef OMIT_JSON_SUPPORT
|
||||
// Inline these massive JSON operations in one place only to reduce binary footprint and compile time
|
||||
nlohmann::json OSUtils::jsonParse(const std::string &buf) { return nlohmann::json::parse(buf.c_str()); }
|
||||
std::string OSUtils::jsonDump(const nlohmann::json &j,int indentation) { return j.dump(indentation); }
|
||||
@@ -542,7 +542,7 @@ std::string OSUtils::jsonBinFromHex(const nlohmann::json &jv)
|
||||
}
|
||||
@@ -543,6 +544,8 @@ std::string OSUtils::jsonBinFromHex(const nlohmann::json &jv)
|
||||
return std::string();
|
||||
}
|
||||
-
|
||||
+*/
|
||||
|
||||
+#endif // OMIT_JSON_SUPPORT
|
||||
+
|
||||
// Used to convert HTTP header names to ASCII lower case
|
||||
const unsigned char OSUtils::TOLOWER_TABLE[256] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, ' ', '!', '"', '#', '$', '%', '&', 0x27, '(', ')', '*', '+', ',', '-', '.', '/', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ':', ';', '<', '=', '>', '?', '@', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '{', '|', '}', '~', '_', '`', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '{', '|', '}', '~', 0x7f, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff };
|
||||
|
||||
diff --git a/osdep/OSUtils.hpp b/osdep/OSUtils.hpp
|
||||
index 2c4283b0..64489bfa 100644
|
||||
index 2c4283b0..afdb1bf1 100644
|
||||
--- a/osdep/OSUtils.hpp
|
||||
+++ b/osdep/OSUtils.hpp
|
||||
@@ -55,7 +55,7 @@
|
||||
@@ -55,7 +55,9 @@
|
||||
#endif
|
||||
#endif
|
||||
|
||||
-#include "../ext/json/json.hpp"
|
||||
+//#include "../ext/json/json.hpp"
|
||||
+#ifndef OMIT_JSON_SUPPORT
|
||||
#include "../ext/json/json.hpp"
|
||||
+#endif
|
||||
|
||||
namespace ZeroTier {
|
||||
|
||||
@@ -283,7 +283,7 @@ public:
|
||||
* @return Platform default ZeroTier One home path
|
||||
@@ -284,6 +286,7 @@ public:
|
||||
*/
|
||||
static std::string platformDefaultHomePath();
|
||||
-
|
||||
+/*
|
||||
|
||||
+#ifndef OMIT_JSON_SUPPORT
|
||||
static nlohmann::json jsonParse(const std::string &buf);
|
||||
static std::string jsonDump(const nlohmann::json &j,int indentation = 1);
|
||||
static uint64_t jsonInt(const nlohmann::json &jv,const uint64_t dfl);
|
||||
@@ -291,7 +291,7 @@ public:
|
||||
@@ -291,6 +294,7 @@ public:
|
||||
static bool jsonBool(const nlohmann::json &jv,const bool dfl);
|
||||
static std::string jsonString(const nlohmann::json &jv,const char *dfl);
|
||||
static std::string jsonBinFromHex(const nlohmann::json &jv);
|
||||
-
|
||||
+*/
|
||||
+#endif // OMIT_JSON_SUPPORT
|
||||
|
||||
private:
|
||||
static const unsigned char TOLOWER_TABLE[256];
|
||||
};
|
||||
|
||||
@@ -30,8 +30,8 @@
|
||||
* ZeroTier socket API
|
||||
*/
|
||||
|
||||
#ifndef LIBZT_H
|
||||
#define LIBZT_H
|
||||
#ifndef ZEROTIER_H
|
||||
#define ZEROTIER_H
|
||||
|
||||
#include "ZeroTierConstants.h"
|
||||
|
||||
@@ -87,17 +87,9 @@ extern "C" {
|
||||
// Custom errno to prevent conflicts with platform's own errno
|
||||
extern int zts_errno;
|
||||
|
||||
typedef uint8_t u8_t;
|
||||
typedef int8_t s8_t;
|
||||
typedef uint16_t u16_t;
|
||||
typedef int16_t s16_t;
|
||||
typedef uint32_t u32_t;
|
||||
typedef int32_t s32_t;
|
||||
typedef uintptr_t mem_ptr_t;
|
||||
|
||||
typedef u32_t zts_in_addr_t;
|
||||
typedef u16_t zts_in_port_t;
|
||||
typedef u8_t zts_sa_family_t;
|
||||
typedef uint32_t zts_in_addr_t;
|
||||
typedef uint16_t zts_in_port_t;
|
||||
typedef uint8_t zts_sa_family_t;
|
||||
|
||||
struct zts_in_addr {
|
||||
zts_in_addr_t s_addr;
|
||||
@@ -105,14 +97,14 @@ struct zts_in_addr {
|
||||
|
||||
struct zts_in6_addr {
|
||||
union un {
|
||||
u32_t u32_addr[4];
|
||||
u8_t u8_addr[16];
|
||||
uint32_t u32_addr[4];
|
||||
uint8_t u8_addr[16];
|
||||
} un;
|
||||
//#define s6_addr un.u8_addr
|
||||
};
|
||||
|
||||
struct zts_sockaddr_in {
|
||||
u8_t sin_len;
|
||||
uint8_t sin_len;
|
||||
zts_sa_family_t sin_family;
|
||||
zts_in_port_t sin_port;
|
||||
struct zts_in_addr sin_addr;
|
||||
@@ -121,26 +113,26 @@ struct zts_sockaddr_in {
|
||||
};
|
||||
|
||||
struct zts_sockaddr_in6 {
|
||||
u8_t sin6_len; /* length of this structure */
|
||||
uint8_t sin6_len; /* length of this structure */
|
||||
zts_sa_family_t sin6_family; /* AF_INET6 */
|
||||
zts_in_port_t sin6_port; /* Transport layer port # */
|
||||
u32_t sin6_flowinfo; /* IPv6 flow information */
|
||||
uint32_t sin6_flowinfo; /* IPv6 flow information */
|
||||
struct zts_in6_addr sin6_addr; /* IPv6 address */
|
||||
u32_t sin6_scope_id; /* Set of interfaces for scope */
|
||||
uint32_t sin6_scope_id; /* Set of interfaces for scope */
|
||||
};
|
||||
|
||||
struct zts_sockaddr {
|
||||
u8_t sa_len;
|
||||
uint8_t sa_len;
|
||||
zts_sa_family_t sa_family;
|
||||
char sa_data[14];
|
||||
};
|
||||
|
||||
struct zts_sockaddr_storage {
|
||||
u8_t s2_len;
|
||||
uint8_t s2_len;
|
||||
zts_sa_family_t ss_family;
|
||||
char s2_data1[2];
|
||||
u32_t s2_data2[3];
|
||||
u32_t s2_data3[3];
|
||||
uint32_t s2_data2[3];
|
||||
uint32_t s2_data3[3];
|
||||
};
|
||||
|
||||
#if !defined(zts_iovec)
|
||||
@@ -516,6 +508,16 @@ ZT_SOCKET_API int ZTCALL zts_start(const char *path, void (*userCallbackFunc)(st
|
||||
*/
|
||||
ZT_SOCKET_API int ZTCALL zts_stop();
|
||||
|
||||
/**
|
||||
* @brief Stops and re-starts the ZeroTier service.
|
||||
*
|
||||
* @usage This call will block until the service has been brought offline. Then
|
||||
* it will return and the user application can then watch for the appropriate
|
||||
* startup callback events.
|
||||
* @return Returns ZTS_ERR_OK on success, -1 on failure
|
||||
*/
|
||||
ZT_SOCKET_API int ZTCALL zts_restart();
|
||||
|
||||
/**
|
||||
* @brief Stops all background services, brings down all interfaces, frees all resources. After calling this function
|
||||
* an application restart will be required before the library can be used again. This is a blocking call.
|
||||
@@ -580,7 +582,6 @@ ZT_SOCKET_API int ZTCALL zts_join(const uint64_t nwid);
|
||||
*/
|
||||
ZT_SOCKET_API int ZTCALL zts_leave(const uint64_t nwid);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Leaves all networks
|
||||
*
|
||||
@@ -743,6 +744,114 @@ void *_zts_start_service(void *thread_id);
|
||||
*/
|
||||
int _zts_can_perform_service_operation();
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// Statistics //
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef LWIP_STATS
|
||||
|
||||
/** Protocol related stats */
|
||||
struct zts_stats_proto {
|
||||
uint32_t xmit; /* Transmitted packets. */
|
||||
uint32_t recv; /* Received packets. */
|
||||
uint32_t fw; /* Forwarded packets. */
|
||||
uint32_t drop; /* Dropped packets. */
|
||||
uint32_t chkerr; /* Checksum error. */
|
||||
uint32_t lenerr; /* Invalid length error. */
|
||||
uint32_t memerr; /* Out of memory error. */
|
||||
uint32_t rterr; /* Routing error. */
|
||||
uint32_t proterr; /* Protocol error. */
|
||||
uint32_t opterr; /* Error in options. */
|
||||
uint32_t err; /* Misc error. */
|
||||
uint32_t cachehit;
|
||||
};
|
||||
|
||||
/** IGMP stats */
|
||||
struct zts_stats_igmp {
|
||||
uint32_t xmit; /* Transmitted packets. */
|
||||
uint32_t recv; /* Received packets. */
|
||||
uint32_t drop; /* Dropped packets. */
|
||||
uint32_t chkerr; /* Checksum error. */
|
||||
uint32_t lenerr; /* Invalid length error. */
|
||||
uint32_t memerr; /* Out of memory error. */
|
||||
uint32_t proterr; /* Protocol error. */
|
||||
uint32_t rx_v1; /* Received v1 frames. */
|
||||
uint32_t rx_group; /* Received group-specific queries. */
|
||||
uint32_t rx_general; /* Received general queries. */
|
||||
uint32_t rx_report; /* Received reports. */
|
||||
uint32_t tx_join; /* Sent joins. */
|
||||
uint32_t tx_leave; /* Sent leaves. */
|
||||
uint32_t tx_report; /* Sent reports. */
|
||||
};
|
||||
|
||||
/** System element stats */
|
||||
struct zts_stats_syselem {
|
||||
uint32_t used;
|
||||
uint32_t max;
|
||||
uint32_t err;
|
||||
};
|
||||
|
||||
/** System stats */
|
||||
struct zts_stats_sys {
|
||||
struct zts_stats_syselem sem;
|
||||
struct zts_stats_syselem mutex;
|
||||
struct zts_stats_syselem mbox;
|
||||
};
|
||||
|
||||
/** lwIP stats container */
|
||||
struct zts_stats {
|
||||
/** Link level */
|
||||
struct zts_stats_proto link;
|
||||
/** ARP */
|
||||
struct zts_stats_proto etharp;
|
||||
/** Fragmentation */
|
||||
struct zts_stats_proto ip_frag;
|
||||
/** IP */
|
||||
struct zts_stats_proto ip;
|
||||
/** ICMP */
|
||||
struct zts_stats_proto icmp;
|
||||
/** IGMP */
|
||||
struct zts_stats_igmp igmp;
|
||||
/** UDP */
|
||||
struct zts_stats_proto udp;
|
||||
/** TCP */
|
||||
struct zts_stats_proto tcp;
|
||||
/** System */
|
||||
struct zts_stats_sys sys;
|
||||
/** IPv6 */
|
||||
struct zts_stats_proto ip6;
|
||||
/** ICMP6 */
|
||||
struct zts_stats_proto icmp6;
|
||||
/** IPv6 fragmentation */
|
||||
struct zts_stats_proto ip6_frag;
|
||||
/** Multicast listener discovery */
|
||||
struct zts_stats_igmp mld6;
|
||||
/** Neighbor discovery */
|
||||
struct zts_stats_proto nd6;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Returns all statistical counters for all protocols (inefficient)
|
||||
*
|
||||
* @usage This function can only be used in debug builds. It can be called at
|
||||
* any time after the node has come online
|
||||
* @return ZTS_ERR_OK if successful, ZTS_ERR_* otherwise
|
||||
*/
|
||||
int zts_get_all_stats(struct zts_stats *statsDest);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Populates the given structure with the requested protocol's
|
||||
* statistical counters (from lwIP)
|
||||
*
|
||||
* @usage This function can only be used in debug builds. It can be called at
|
||||
* any time after the node has come online
|
||||
* @return ZTS_ERR_OK if successful, ZTS_ERR_* otherwise
|
||||
*/
|
||||
int zts_get_protocol_stats(int protocolType, void *protoStatsDest);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// Status getters //
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -30,6 +30,9 @@
|
||||
* Common constants used throughout the SDK
|
||||
*/
|
||||
|
||||
#ifndef ZEROTIER_CONSTANTS_H
|
||||
#define ZEROTIER_CONSTANTS_H
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// Control API error codes //
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
@@ -228,4 +231,21 @@
|
||||
#error "external ZTS_FD_SETSIZE too small for number of sockets"
|
||||
#endif // FD_SET
|
||||
|
||||
//#if defined(_USING_LWIP_DEFINITIONS_)
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// Statistics //
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define ZTS_STATS_PROTOCOL_LINK 0
|
||||
#define ZTS_STATS_PROTOCOL_ETHARP 1
|
||||
#define ZTS_STATS_PROTOCOL_IP 2
|
||||
#define ZTS_STATS_PROTOCOL_UDP 3
|
||||
#define ZTS_STATS_PROTOCOL_TCP 4
|
||||
#define ZTS_STATS_PROTOCOL_ICMP 5
|
||||
#define ZTS_STATS_PROTOCOL_IP_FRAG 6
|
||||
#define ZTS_STATS_PROTOCOL_IP6 7
|
||||
#define ZTS_STATS_PROTOCOL_ICMP6 8
|
||||
#define ZTS_STATS_PROTOCOL_IP6_FRAG 9
|
||||
|
||||
//#if defined(_USING_LWIP_DEFINITIONS_)
|
||||
|
||||
#endif // ZEROTIER_CONSTANTS_H
|
||||
169
src/Controls.cpp
169
src/Controls.cpp
@@ -621,11 +621,9 @@ JNIEXPORT int JNICALL Java_com_zerotier_libzt_ZeroTier_start(
|
||||
int zts_stop()
|
||||
{
|
||||
Mutex::Lock _l(_service_lock);
|
||||
bool didStop = false;
|
||||
if (__zts_can_perform_service_operation()) {
|
||||
_run_service = false;
|
||||
service->terminate();
|
||||
didStop = true;
|
||||
#if defined(_WIN32)
|
||||
WSACleanup();
|
||||
#endif
|
||||
@@ -641,6 +639,41 @@ JNIEXPORT void JNICALL Java_com_zerotier_libzt_ZeroTier_stop(
|
||||
}
|
||||
#endif
|
||||
|
||||
int zts_restart()
|
||||
{
|
||||
_service_lock.lock();
|
||||
// Store callback references
|
||||
void (*_tmpUserEventCallbackFunc)(struct zts_callback_msg *);
|
||||
_tmpUserEventCallbackFunc = _userEventCallbackFunc;
|
||||
int tmpPort = _port;
|
||||
std::string tmpPath = _path;
|
||||
// Stop the service
|
||||
if (__zts_can_perform_service_operation()) {
|
||||
_run_service = false;
|
||||
service->terminate();
|
||||
#if defined(_WIN32)
|
||||
WSACleanup();
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
_service_lock.unlock();
|
||||
return ZTS_ERR_SERVICE;
|
||||
}
|
||||
// Start again with same parameters as initial call
|
||||
_service_lock.unlock();
|
||||
while (service) {
|
||||
_api_sleep(ZTS_CALLBACK_PROCESSING_INTERVAL);
|
||||
}
|
||||
return zts_start(tmpPath.c_str(), _tmpUserEventCallbackFunc, tmpPort);
|
||||
}
|
||||
#ifdef SDK_JNI
|
||||
JNIEXPORT void JNICALL Java_com_zerotier_libzt_ZeroTier_restart(
|
||||
JNIEnv *env, jobject thisObj)
|
||||
{
|
||||
zts_restart();
|
||||
}
|
||||
#endif
|
||||
|
||||
int zts_free()
|
||||
{
|
||||
Mutex::Lock _l(_service_lock);
|
||||
@@ -868,6 +901,138 @@ int zts_get_all_network_details(struct zts_network_details *nds, int *num)
|
||||
#ifdef SDK_JNI
|
||||
#endif
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// Statistics //
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "lwip/stats.h"
|
||||
|
||||
extern struct stats_ lwip_stats;
|
||||
|
||||
int zts_get_all_stats(struct zts_stats *statsDest)
|
||||
{
|
||||
#if LWIP_STATS
|
||||
if (!statsDest) {
|
||||
return ZTS_ERR_INVALID_ARG;
|
||||
}
|
||||
memset(statsDest, 0, sizeof(struct zts_stats));
|
||||
// Copy lwIP stats
|
||||
memcpy(&(statsDest->link), &(lwip_stats.link), sizeof(struct stats_proto));
|
||||
memcpy(&(statsDest->etharp), &(lwip_stats.etharp), sizeof(struct stats_proto));
|
||||
memcpy(&(statsDest->ip_frag), &(lwip_stats.ip_frag), sizeof(struct stats_proto));
|
||||
memcpy(&(statsDest->ip), &(lwip_stats.ip), sizeof(struct stats_proto));
|
||||
memcpy(&(statsDest->icmp), &(lwip_stats.icmp), sizeof(struct stats_proto));
|
||||
//memcpy(&(statsDest->igmp), &(lwip_stats.igmp), sizeof(struct stats_igmp));
|
||||
memcpy(&(statsDest->udp), &(lwip_stats.udp), sizeof(struct stats_proto));
|
||||
memcpy(&(statsDest->tcp), &(lwip_stats.tcp), sizeof(struct stats_proto));
|
||||
// mem omitted
|
||||
// memp omitted
|
||||
memcpy(&(statsDest->sys), &(lwip_stats.sys), sizeof(struct stats_sys));
|
||||
memcpy(&(statsDest->ip6), &(lwip_stats.ip6), sizeof(struct stats_proto));
|
||||
memcpy(&(statsDest->icmp6), &(lwip_stats.icmp6), sizeof(struct stats_proto));
|
||||
memcpy(&(statsDest->ip6_frag), &(lwip_stats.ip6_frag), sizeof(struct stats_proto));
|
||||
memcpy(&(statsDest->mld6), &(lwip_stats.mld6), sizeof(struct stats_igmp));
|
||||
memcpy(&(statsDest->nd6), &(lwip_stats.nd6), sizeof(struct stats_proto));
|
||||
memcpy(&(statsDest->ip_frag), &(lwip_stats.ip_frag), sizeof(struct stats_proto));
|
||||
// mib2 omitted
|
||||
// Copy ZT stats
|
||||
// ...
|
||||
return ZTS_ERR_OK;
|
||||
#else
|
||||
return ZTS_ERR_NO_RESULT;
|
||||
#endif
|
||||
}
|
||||
#ifdef SDK_JNI
|
||||
// No implementation for JNI
|
||||
#endif
|
||||
|
||||
int zts_get_protocol_stats(int protocolType, void *protoStatsDest)
|
||||
{
|
||||
#if LWIP_STATS
|
||||
if (!protoStatsDest) {
|
||||
return ZTS_ERR_INVALID_ARG;
|
||||
}
|
||||
memset(protoStatsDest, 0, sizeof(struct stats_proto));
|
||||
switch (protocolType)
|
||||
{
|
||||
case ZTS_STATS_PROTOCOL_LINK:
|
||||
memcpy(protoStatsDest, &(lwip_stats.link), sizeof(struct stats_proto));
|
||||
break;
|
||||
case ZTS_STATS_PROTOCOL_ETHARP:
|
||||
memcpy(protoStatsDest, &(lwip_stats.etharp), sizeof(struct stats_proto));
|
||||
break;
|
||||
case ZTS_STATS_PROTOCOL_IP:
|
||||
memcpy(protoStatsDest, &(lwip_stats.ip), sizeof(struct stats_proto));
|
||||
break;
|
||||
case ZTS_STATS_PROTOCOL_UDP:
|
||||
memcpy(protoStatsDest, &(lwip_stats.udp), sizeof(struct stats_proto));
|
||||
break;
|
||||
case ZTS_STATS_PROTOCOL_TCP:
|
||||
memcpy(protoStatsDest, &(lwip_stats.tcp), sizeof(struct stats_proto));
|
||||
break;
|
||||
case ZTS_STATS_PROTOCOL_ICMP:
|
||||
memcpy(protoStatsDest, &(lwip_stats.icmp), sizeof(struct stats_proto));
|
||||
break;
|
||||
case ZTS_STATS_PROTOCOL_IP_FRAG:
|
||||
memcpy(protoStatsDest, &(lwip_stats.ip_frag), sizeof(struct stats_proto));
|
||||
break;
|
||||
case ZTS_STATS_PROTOCOL_IP6:
|
||||
memcpy(protoStatsDest, &(lwip_stats.ip6), sizeof(struct stats_proto));
|
||||
break;
|
||||
case ZTS_STATS_PROTOCOL_ICMP6:
|
||||
memcpy(protoStatsDest, &(lwip_stats.icmp6), sizeof(struct stats_proto));
|
||||
break;
|
||||
case ZTS_STATS_PROTOCOL_IP6_FRAG:
|
||||
memcpy(protoStatsDest, &(lwip_stats.ip6_frag), sizeof(struct stats_proto));
|
||||
break;
|
||||
default:
|
||||
return ZTS_ERR_INVALID_ARG;
|
||||
}
|
||||
return ZTS_ERR_OK;
|
||||
#else
|
||||
return ZTS_ERR_NO_RESULT;
|
||||
#endif
|
||||
}
|
||||
#ifdef SDK_JNI
|
||||
JNIEXPORT jint JNICALL Java_com_zerotier_libzt_ZeroTier_get_1protocol_1stats(
|
||||
JNIEnv *env, jobject thisObj, jint protocolType, jobject protoStatsObj)
|
||||
{
|
||||
struct stats_proto stats;
|
||||
int retval = zts_get_protocol_stats(protocolType, &stats);
|
||||
// Copy stats into Java object
|
||||
jclass c = env->GetObjectClass(protoStatsObj);
|
||||
if (!c) {
|
||||
return ZTS_ERR_INVALID_ARG;
|
||||
}
|
||||
jfieldID fid;
|
||||
fid = env->GetFieldID(c, "xmit", "I");
|
||||
env->SetIntField(protoStatsObj, fid, stats.xmit);
|
||||
fid = env->GetFieldID(c, "recv", "I");
|
||||
env->SetIntField(protoStatsObj, fid, stats.recv);
|
||||
fid = env->GetFieldID(c, "fw", "I");
|
||||
env->SetIntField(protoStatsObj, fid, stats.fw);
|
||||
fid = env->GetFieldID(c, "drop", "I");
|
||||
env->SetIntField(protoStatsObj, fid, stats.drop);
|
||||
fid = env->GetFieldID(c, "chkerr", "I");
|
||||
env->SetIntField(protoStatsObj, fid, stats.chkerr);
|
||||
fid = env->GetFieldID(c, "lenerr", "I");
|
||||
env->SetIntField(protoStatsObj, fid, stats.lenerr);
|
||||
fid = env->GetFieldID(c, "memerr", "I");
|
||||
env->SetIntField(protoStatsObj, fid, stats.memerr);
|
||||
fid = env->GetFieldID(c, "rterr", "I");
|
||||
env->SetIntField(protoStatsObj, fid, stats.rterr);
|
||||
fid = env->GetFieldID(c, "proterr", "I");
|
||||
env->SetIntField(protoStatsObj, fid, stats.proterr);
|
||||
fid = env->GetFieldID(c, "opterr", "I");
|
||||
env->SetIntField(protoStatsObj, fid, stats.opterr);
|
||||
fid = env->GetFieldID(c, "err", "I");
|
||||
env->SetIntField(protoStatsObj, fid, stats.err);
|
||||
fid = env->GetFieldID(c, "cachehit", "I");
|
||||
env->SetIntField(protoStatsObj, fid, stats.cachehit);
|
||||
return retval;
|
||||
}
|
||||
#endif
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// Multipath/QoS //
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -181,12 +181,30 @@ public class ZeroTier
|
||||
public static int TCP_KEEPINTVL = 0x00000004;
|
||||
public static int TCP_KEEPCNT = 0x00000005;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// Statistics //
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
public static int STATS_PROTOCOL_LINK = 0;
|
||||
public static int STATS_PROTOCOL_ETHARP = 1;
|
||||
public static int STATS_PROTOCOL_IP = 2;
|
||||
public static int STATS_PROTOCOL_UDP = 3;
|
||||
public static int STATS_PROTOCOL_TCP = 4;
|
||||
public static int STATS_PROTOCOL_ICMP = 5;
|
||||
public static int STATS_PROTOCOL_IP_FRAG = 6;
|
||||
public static int STATS_PROTOCOL_IP6 = 7;
|
||||
public static int STATS_PROTOCOL_ICMP6 = 8;
|
||||
public static int STATS_PROTOCOL_IP6_FRAG = 9;
|
||||
|
||||
public static native int get_protocol_stats(int protocolNum, ZeroTierProtoStats stats);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// ZeroTier Service Controls //
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
public static native int start(String path, ZeroTierEventListener callbackClass, int port);
|
||||
public static native int stop();
|
||||
public static native int restart();
|
||||
public static native int join(long nwid);
|
||||
public static native int leave(long nwid);
|
||||
public static native long get_node_id();
|
||||
|
||||
19
src/java/ZeroTierProtoStats.java
Normal file
19
src/java/ZeroTierProtoStats.java
Normal file
@@ -0,0 +1,19 @@
|
||||
package com.zerotier.libzt;
|
||||
|
||||
import com.zerotier.libzt.ZeroTier;
|
||||
|
||||
public class ZeroTierProtoStats
|
||||
{
|
||||
public int xmit; /* Transmitted packets. */
|
||||
public int recv; /* Received packets. */
|
||||
public int fw; /* Forwarded packets. */
|
||||
public int drop; /* Dropped packets. */
|
||||
public int chkerr; /* Checksum error. */
|
||||
public int lenerr; /* Invalid length error. */
|
||||
public int memerr; /* Out of memory error. */
|
||||
public int rterr; /* Routing error. */
|
||||
public int proterr; /* Protocol error. */
|
||||
public int opterr; /* Error in options. */
|
||||
public int err; /* Misc error. */
|
||||
public int cachehit;
|
||||
}
|
||||
361
src/lwipopts.h
361
src/lwipopts.h
@@ -49,6 +49,7 @@
|
||||
------------------------------------------------------------------------------*/
|
||||
|
||||
// Misc
|
||||
#define LWIP_STATS_LARGE 1
|
||||
#define LWIP_NOASSERT 1
|
||||
#if __ANDROID__
|
||||
#define LWIP_DONT_PROVIDE_BYTEORDER_FUNCTIONS 0
|
||||
@@ -82,149 +83,49 @@
|
||||
------------------------------------ Presets -----------------------------------
|
||||
------------------------------------------------------------------------------*/
|
||||
|
||||
// Embedded applications (lwIP out-of-the-box defaults)
|
||||
#if 0
|
||||
#define TCP_TMR_INTERVAL 250
|
||||
#endif
|
||||
|
||||
// Desktop-class applications
|
||||
#if 1
|
||||
#define LWIP_MTU 1500
|
||||
#define LWIP_CHKSUM_ALGORITHM 2
|
||||
// memory
|
||||
#define MEMP_NUM_NETCONN 1024
|
||||
#define MEMP_NUM_NETBUF 2
|
||||
#define MEMP_NUM_TCPIP_MSG_API 1024
|
||||
#define MEMP_NUM_TCPIP_MSG_INPKT 1024
|
||||
#define PBUF_POOL_SIZE 1024
|
||||
#define TCP_DEFAULT_LISTEN_BACKLOG 0xff
|
||||
// arp
|
||||
#define ARP_TABLE_SIZE 64
|
||||
#define ARP_MAXAGE 300
|
||||
#define ARP_QUEUEING 1
|
||||
#define ARP_QUEUE_LEN 3
|
||||
// ip
|
||||
#define IP_REASS_MAXAGE 15
|
||||
#define IP_REASS_MAX_PBUFS 32
|
||||
// tcp
|
||||
#define TCP_TMR_INTERVAL 250
|
||||
#define TCP_WND 0xffff0
|
||||
#define TCP_MAXRTX 12
|
||||
#define TCP_SYNMAXRTX 12
|
||||
#define LWIP_TCP_SACK_OUT 1
|
||||
#define LWIP_TCP_MAX_SACK_NUM 4
|
||||
#define TCP_MSS (LWIP_MTU - 40)
|
||||
#define TCP_SND_BUF (64 * TCP_MSS)
|
||||
#define TCP_SND_QUEUELEN (64 * (2 * (TCP_SND_BUF/TCP_MSS)))
|
||||
#define TCP_SNDLOWAT (0xffff - (4*TCP_MSS) - 1)
|
||||
#define TCP_SNDQUEUELOWAT LWIP_MAX(((TCP_SND_QUEUELEN)/2), 5)
|
||||
#define TCP_WND_UPDATE_THRESHOLD LWIP_MIN((TCP_WND / 4), (TCP_MSS * 4))
|
||||
#define LWIP_WND_SCALE 1
|
||||
#define TCP_RCV_SCALE 4
|
||||
// tcpip
|
||||
#define TCPIP_MBOX_SIZE 0
|
||||
#define LWIP_TCPIP_CORE_LOCKING 1
|
||||
#define LWIP_TCPIP_CORE_LOCKING_INPUT 1
|
||||
// netconn
|
||||
#define LWIP_NETCONN_FULLDUPLEX 0
|
||||
// netif
|
||||
#define LWIP_SINGLE_NETIF 0
|
||||
#define LWIP_NETIF_HWADDRHINT 1
|
||||
#define LWIP_NETIF_TX_SINGLE_PBUF 0
|
||||
#define TCPIP_THREAD_PRIO 1
|
||||
#endif
|
||||
|
||||
// Desktop-class applications
|
||||
#if 0
|
||||
#define MTU 2800
|
||||
#define LWIP_CHKSUM_ALGORITHM 2
|
||||
// memory
|
||||
#define MEMP_NUM_NETCONN 1024
|
||||
#define MEMP_NUM_NETBUF 2
|
||||
#define MEMP_NUM_TCPIP_MSG_API 64
|
||||
#define MEMP_NUM_TCPIP_MSG_INPKT 64
|
||||
#define PBUF_POOL_SIZE 128
|
||||
// arp
|
||||
#define ARP_TABLE_SIZE 64
|
||||
#define ARP_MAXAGE 300
|
||||
#define ARP_QUEUEING 1
|
||||
#define ARP_QUEUE_LEN 3
|
||||
// ip
|
||||
#define IP_REASS_MAXAGE 15
|
||||
#define IP_REASS_MAX_PBUFS 32
|
||||
// tcp
|
||||
#define TCP_TMR_INTERVAL 25
|
||||
#define TCP_WND 0xffff
|
||||
#define TCP_MAXRTX 12
|
||||
#define TCP_SYNMAXRTX 12
|
||||
#define LWIP_TCP_SACK_OUT 1
|
||||
#define LWIP_TCP_MAX_SACK_NUM 4
|
||||
#define TCP_MSS (MTU - 40)
|
||||
#define TCP_SND_BUF (32 * TCP_MSS)
|
||||
#define TCP_SND_QUEUELEN (64 * (2 * (TCP_SND_BUF/TCP_MSS)))
|
||||
#define TCP_SNDLOWAT (0xffff - (4*TCP_MSS) - 1)
|
||||
#define TCP_SNDQUEUELOWAT LWIP_MAX(((TCP_SND_QUEUELEN)/2), 5)
|
||||
#define TCP_WND_UPDATE_THRESHOLD LWIP_MIN((TCP_WND / 4), (TCP_MSS * 4))
|
||||
#define LWIP_WND_SCALE 1
|
||||
#define TCP_RCV_SCALE 0
|
||||
// tcpip
|
||||
#define TCPIP_MBOX_SIZE 0
|
||||
#define LWIP_TCPIP_CORE_LOCKING 1
|
||||
#define LWIP_TCPIP_CORE_LOCKING_INPUT 1
|
||||
// netconn
|
||||
#define LWIP_NETCONN_FULLDUPLEX 0
|
||||
// netif
|
||||
#define LWIP_SINGLE_NETIF 0
|
||||
#define LWIP_NETIF_HWADDRHINT 1
|
||||
#define LWIP_NETIF_TX_SINGLE_PBUF 0
|
||||
#define TCPIP_THREAD_PRIO 1
|
||||
#endif
|
||||
|
||||
// Stable
|
||||
#if 0
|
||||
#define MTU 2800
|
||||
#define LWIP_CHKSUM_ALGORITHM 2
|
||||
// memory
|
||||
#define MEMP_NUM_NETCONN 1024
|
||||
#define MEMP_NUM_NETBUF 2
|
||||
#define MEMP_NUM_TCPIP_MSG_API 64
|
||||
#define MEMP_NUM_TCPIP_MSG_INPKT 64
|
||||
#define PBUF_POOL_SIZE 128
|
||||
// arp
|
||||
#define ARP_TABLE_SIZE 64
|
||||
#define ARP_MAXAGE 300
|
||||
#define ARP_QUEUEING 1
|
||||
#define ARP_QUEUE_LEN 3
|
||||
// ip
|
||||
#define IP_REASS_MAXAGE 15
|
||||
#define IP_REASS_MAX_PBUFS 32
|
||||
// tcp
|
||||
#define TCP_TMR_INTERVAL 25
|
||||
#define TCP_WND 0xffff
|
||||
#define TCP_MAXRTX 12
|
||||
#define TCP_SYNMAXRTX 12
|
||||
#define LWIP_TCP_SACK_OUT 0
|
||||
#define LWIP_TCP_MAX_SACK_NUM 4
|
||||
#define TCP_MSS (MTU - 40)
|
||||
#define TCP_SND_BUF (32 * TCP_MSS)
|
||||
#define TCP_SND_QUEUELEN (64 * (2 * (TCP_SND_BUF/TCP_MSS)))
|
||||
#define TCP_SNDLOWAT (0xffff - (4*TCP_MSS) - 1)
|
||||
#define TCP_SNDLOWAT LWIP_MIN(LWIP_MAX(((TCP_SND_BUF)/2), (2 * TCP_MSS) + 1), (TCP_SND_BUF) - 1)
|
||||
#define TCP_WND_UPDATE_THRESHOLD LWIP_MIN((TCP_WND / 4), (TCP_MSS * 4))
|
||||
#define LWIP_WND_SCALE 1
|
||||
#define TCP_RCV_SCALE 0
|
||||
// tcpip
|
||||
#define TCPIP_MBOX_SIZE 0
|
||||
#define LWIP_TCPIP_CORE_LOCKING 1
|
||||
#define LWIP_TCPIP_CORE_LOCKING_INPUT 1
|
||||
// netconn
|
||||
#define LWIP_NETCONN_FULLDUPLEX 0
|
||||
// netif
|
||||
#define LWIP_SINGLE_NETIF 0
|
||||
#define LWIP_NETIF_HWADDRHINT 1
|
||||
#define LWIP_NETIF_TX_SINGLE_PBUF 0
|
||||
#define TCPIP_THREAD_PRIO 1
|
||||
#endif
|
||||
#define LWIP_MTU 1500
|
||||
#define LWIP_CHKSUM_ALGORITHM 2
|
||||
// memory
|
||||
#define MEMP_NUM_NETCONN 1024
|
||||
#define MEMP_NUM_NETBUF 2
|
||||
#define MEMP_NUM_TCPIP_MSG_API 1024
|
||||
#define MEMP_NUM_TCPIP_MSG_INPKT 1024
|
||||
#define PBUF_POOL_SIZE 1024
|
||||
#define TCP_DEFAULT_LISTEN_BACKLOG 0xff
|
||||
// arp
|
||||
#define ARP_TABLE_SIZE 64
|
||||
#define ARP_MAXAGE 300
|
||||
#define ARP_QUEUEING 1
|
||||
#define ARP_QUEUE_LEN 3
|
||||
// ip
|
||||
#define IP_REASS_MAXAGE 15
|
||||
#define IP_REASS_MAX_PBUFS 32
|
||||
// tcp
|
||||
#define TCP_TMR_INTERVAL 250
|
||||
#define TCP_WND 0xffff0
|
||||
#define TCP_MAXRTX 12
|
||||
#define TCP_SYNMAXRTX 12
|
||||
#define LWIP_TCP_SACK_OUT 1
|
||||
#define LWIP_TCP_MAX_SACK_NUM 4
|
||||
#define TCP_MSS (LWIP_MTU - 40)
|
||||
#define TCP_SND_BUF (64 * TCP_MSS)
|
||||
#define TCP_SND_QUEUELEN (64 * (2 * (TCP_SND_BUF/TCP_MSS)))
|
||||
#define TCP_SNDLOWAT (0xffff - (4*TCP_MSS) - 1)
|
||||
#define TCP_SNDQUEUELOWAT LWIP_MAX(((TCP_SND_QUEUELEN)/2), 5)
|
||||
#define TCP_WND_UPDATE_THRESHOLD LWIP_MIN((TCP_WND / 4), (TCP_MSS * 4))
|
||||
#define LWIP_WND_SCALE 1
|
||||
#define TCP_RCV_SCALE 4
|
||||
// tcpip
|
||||
#define TCPIP_MBOX_SIZE 0
|
||||
#define LWIP_TCPIP_CORE_LOCKING 1
|
||||
#define LWIP_TCPIP_CORE_LOCKING_INPUT 1
|
||||
// netconn
|
||||
#define LWIP_NETCONN_FULLDUPLEX 0
|
||||
// netif
|
||||
#define LWIP_SINGLE_NETIF 0
|
||||
#define LWIP_NETIF_HWADDRHINT 1
|
||||
#define LWIP_NETIF_TX_SINGLE_PBUF 0
|
||||
#define TCPIP_THREAD_PRIO 1
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
------------------------------------ Timers ------------------------------------
|
||||
@@ -2290,180 +2191,6 @@ happening sooner than they should.
|
||||
* @}
|
||||
*/
|
||||
|
||||
/*
|
||||
----------------------------------------
|
||||
---------- Statistics options ----------
|
||||
----------------------------------------
|
||||
*/
|
||||
/**
|
||||
* @defgroup lwip_opts_stats Statistics
|
||||
* @ingroup lwip_opts_debug
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* LWIP_STATS==1: Enable statistics collection in lwip_stats.
|
||||
*/
|
||||
#if !defined LWIP_STATS || defined __DOXYGEN__
|
||||
#define LWIP_STATS 0
|
||||
#endif
|
||||
|
||||
#if LWIP_STATS
|
||||
|
||||
/**
|
||||
* LWIP_STATS_DISPLAY==1: Compile in the statistics output functions.
|
||||
*/
|
||||
#if !defined LWIP_STATS_DISPLAY || defined __DOXYGEN__
|
||||
#define LWIP_STATS_DISPLAY 0
|
||||
#endif
|
||||
|
||||
/**
|
||||
* LINK_STATS==1: Enable link stats.
|
||||
*/
|
||||
#if !defined LINK_STATS || defined __DOXYGEN__
|
||||
#define LINK_STATS 0
|
||||
#endif
|
||||
|
||||
/**
|
||||
* ETHARP_STATS==1: Enable etharp stats.
|
||||
*/
|
||||
#if !defined ETHARP_STATS || defined __DOXYGEN__
|
||||
#define ETHARP_STATS (LWIP_ARP)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* IP_STATS==1: Enable IP stats.
|
||||
*/
|
||||
#if !defined IP_STATS || defined __DOXYGEN__
|
||||
#define IP_STATS 0
|
||||
#endif
|
||||
|
||||
/**
|
||||
* IPFRAG_STATS==1: Enable IP fragmentation stats. Default is
|
||||
* on if using either frag or reass.
|
||||
*/
|
||||
#if !defined IPFRAG_STATS || defined __DOXYGEN__
|
||||
#define IPFRAG_STATS (IP_REASSEMBLY || IP_FRAG)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* ICMP_STATS==1: Enable ICMP stats.
|
||||
*/
|
||||
#if !defined ICMP_STATS || defined __DOXYGEN__
|
||||
#define ICMP_STATS 0
|
||||
#endif
|
||||
|
||||
/**
|
||||
* IGMP_STATS==1: Enable IGMP stats.
|
||||
*/
|
||||
#if !defined IGMP_STATS || defined __DOXYGEN__
|
||||
#define IGMP_STATS (LWIP_IGMP)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* UDP_STATS==1: Enable UDP stats. Default is on if
|
||||
* UDP enabled, otherwise off.
|
||||
*/
|
||||
#if !defined UDP_STATS || defined __DOXYGEN__
|
||||
#define UDP_STATS (LWIP_UDP)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* TCP_STATS==1: Enable TCP stats. Default is on if TCP
|
||||
* enabled, otherwise off.
|
||||
*/
|
||||
#if !defined TCP_STATS || defined __DOXYGEN__
|
||||
#define TCP_STATS (LWIP_TCP)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* MEM_STATS==1: Enable mem.c stats.
|
||||
*/
|
||||
#if !defined MEM_STATS || defined __DOXYGEN__
|
||||
#define MEM_STATS ((MEM_LIBC_MALLOC == 0) && (MEM_USE_POOLS == 0))
|
||||
#endif
|
||||
|
||||
/**
|
||||
* MEMP_STATS==1: Enable memp.c pool stats.
|
||||
*/
|
||||
#if !defined MEMP_STATS || defined __DOXYGEN__
|
||||
#define MEMP_STATS (MEMP_MEM_MALLOC == 0)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* SYS_STATS==1: Enable system stats (sem and mbox counts, etc).
|
||||
*/
|
||||
#if !defined SYS_STATS || defined __DOXYGEN__
|
||||
#define SYS_STATS (NO_SYS == 0)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* IP6_STATS==1: Enable IPv6 stats.
|
||||
*/
|
||||
#if !defined IP6_STATS || defined __DOXYGEN__
|
||||
#define IP6_STATS (LWIP_IPV6)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* ICMP6_STATS==1: Enable ICMP for IPv6 stats.
|
||||
*/
|
||||
#if !defined ICMP6_STATS || defined __DOXYGEN__
|
||||
#define ICMP6_STATS (LWIP_IPV6 && LWIP_ICMP6)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* IP6_FRAG_STATS==1: Enable IPv6 fragmentation stats.
|
||||
*/
|
||||
#if !defined IP6_FRAG_STATS || defined __DOXYGEN__
|
||||
#define IP6_FRAG_STATS (LWIP_IPV6 && (LWIP_IPV6_FRAG || LWIP_IPV6_REASS))
|
||||
#endif
|
||||
|
||||
/**
|
||||
* MLD6_STATS==1: Enable MLD for IPv6 stats.
|
||||
*/
|
||||
#if !defined MLD6_STATS || defined __DOXYGEN__
|
||||
#define MLD6_STATS (LWIP_IPV6 && LWIP_IPV6_MLD)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* ND6_STATS==1: Enable Neighbor discovery for IPv6 stats.
|
||||
*/
|
||||
#if !defined ND6_STATS || defined __DOXYGEN__
|
||||
#define ND6_STATS (LWIP_IPV6)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* MIB2_STATS==1: Stats for SNMP MIB2.
|
||||
*/
|
||||
#if !defined MIB2_STATS || defined __DOXYGEN__
|
||||
#define MIB2_STATS 0
|
||||
#endif
|
||||
|
||||
#else
|
||||
|
||||
#define LINK_STATS 0
|
||||
#define ETHARP_STATS 0
|
||||
#define IP_STATS 0
|
||||
#define IPFRAG_STATS 0
|
||||
#define ICMP_STATS 0
|
||||
#define IGMP_STATS 0
|
||||
#define UDP_STATS 0
|
||||
#define TCP_STATS 0
|
||||
#define MEM_STATS 0
|
||||
#define MEMP_STATS 0
|
||||
#define SYS_STATS 0
|
||||
#define LWIP_STATS_DISPLAY 0
|
||||
#define IP6_STATS 0
|
||||
#define ICMP6_STATS 0
|
||||
#define IP6_FRAG_STATS 0
|
||||
#define MLD6_STATS 0
|
||||
#define ND6_STATS 0
|
||||
#define MIB2_STATS 0
|
||||
|
||||
#endif /* LWIP_STATS */
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/*
|
||||
--------------------------------------
|
||||
---------- Checksum options ----------
|
||||
|
||||
Reference in New Issue
Block a user