Update C API: Add functions that simplify wrapper generation
This commit is contained in:
@@ -720,11 +720,11 @@ endif()
|
|||||||
# -----------------------------------------------------------------------------
|
# -----------------------------------------------------------------------------
|
||||||
|
|
||||||
if(BUILD_HOST_SELFTEST)
|
if(BUILD_HOST_SELFTEST)
|
||||||
add_executable(selftest ${PROJ_DIR}/test/selftest.c)
|
add_executable(selftest-c-api ${PROJ_DIR}/test/selftest-c-api.c)
|
||||||
target_link_libraries(selftest ${STATIC_LIB_NAME})
|
target_link_libraries(selftest-c-api ${STATIC_LIB_NAME})
|
||||||
project(TEST)
|
project(TEST)
|
||||||
enable_testing()
|
enable_testing()
|
||||||
add_test(NAME selftest COMMAND selftest)
|
add_test(NAME selftest-c-api COMMAND selftest-c-api)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# -----------------------------------------------------------------------------
|
# -----------------------------------------------------------------------------
|
||||||
|
|||||||
@@ -93,7 +93,7 @@ Important directories:
|
|||||||
|
|
||||||
# Self-hosting (Optional)
|
# Self-hosting (Optional)
|
||||||
|
|
||||||
We provide ways for your app or enterprise to function indepenently from any of our services if desired.
|
We provide ways for your app or enterprise to function independently from any of our services if desired.
|
||||||
|
|
||||||
While we do operate a global network of redundant root servers, network controllers and an admin API/UI called [Central](https://my.zerotier.com), some use-cases require full control over the infrastructure and we try to make it as easy as possible to set up your own controllers and root servers: See [here](https://github.com/zerotier/ZeroTierOne/tree/master/controller) to learn more about how to set up your own network controller, and [here](https://www.zerotier.com/manual/#4_4) to learn more about setting up your own roots.
|
While we do operate a global network of redundant root servers, network controllers and an admin API/UI called [Central](https://my.zerotier.com), some use-cases require full control over the infrastructure and we try to make it as easy as possible to set up your own controllers and root servers: See [here](https://github.com/zerotier/ZeroTierOne/tree/master/controller) to learn more about how to set up your own network controller, and [here](https://www.zerotier.com/manual/#4_4) to learn more about setting up your own roots.
|
||||||
|
|
||||||
|
|||||||
96
build.sh
96
build.sh
@@ -71,7 +71,7 @@ DEFAULT_HOST_LIB_OUTPUT_DIR=$BUILD_OUTPUT_DIR/$HOST_PLATFORM-$HOST_MACHINE_TYPE
|
|||||||
DEFAULT_HOST_BIN_OUTPUT_DIR=$BUILD_OUTPUT_DIR/$HOST_PLATFORM-$HOST_MACHINE_TYPE
|
DEFAULT_HOST_BIN_OUTPUT_DIR=$BUILD_OUTPUT_DIR/$HOST_PLATFORM-$HOST_MACHINE_TYPE
|
||||||
# Default location for (host) packages
|
# Default location for (host) packages
|
||||||
DEFAULT_HOST_PKG_OUTPUT_DIR=$BUILD_OUTPUT_DIR/$HOST_PLATFORM-$HOST_MACHINE_TYPE
|
DEFAULT_HOST_PKG_OUTPUT_DIR=$BUILD_OUTPUT_DIR/$HOST_PLATFORM-$HOST_MACHINE_TYPE
|
||||||
# Defaultlocation for CMake's caches (when building for host)
|
# Default location for CMake's caches (when building for host)
|
||||||
DEFAULT_HOST_BUILD_CACHE_DIR=$BUILD_CACHE_DIR/$HOST_PLATFORM-$HOST_MACHINE_TYPE
|
DEFAULT_HOST_BUILD_CACHE_DIR=$BUILD_CACHE_DIR/$HOST_PLATFORM-$HOST_MACHINE_TYPE
|
||||||
|
|
||||||
gethosttype()
|
gethosttype()
|
||||||
@@ -89,8 +89,8 @@ gethosttype()
|
|||||||
#
|
#
|
||||||
# Example output:
|
# Example output:
|
||||||
#
|
#
|
||||||
# - Cache : /Volumes/$USER/zt/libzt/libzt-dev/cache/apple-xcframework-debug
|
# - Cache : libzt/cache/apple-xcframework-debug
|
||||||
# - Build output : /Volumes/$USER/zt/libzt/libzt-dev/dist
|
# - Build output : libzt/dist
|
||||||
#
|
#
|
||||||
# apple-xcframework-debug
|
# apple-xcframework-debug
|
||||||
# └── pkg
|
# └── pkg
|
||||||
@@ -146,10 +146,10 @@ xcframework()
|
|||||||
#
|
#
|
||||||
# Example output:
|
# Example output:
|
||||||
#
|
#
|
||||||
# - Cache : /Volumes/$USER/zt/libzt/libzt-dev/cache/iphonesimulator-x64-framework-debug
|
# - Cache : libzt/cache/iphonesimulator-x64-framework-debug
|
||||||
# - Build output : /Volumes/$USER/zt/libzt/libzt-dev/dist
|
# - Build output : libzt/dist
|
||||||
#
|
#
|
||||||
# /Volumes/$USER/zt/libzt/libzt-dev/dist/iphonesimulator-x64-framework-debug
|
# libzt/dist/iphonesimulator-x64-framework-debug
|
||||||
# └── pkg
|
# └── pkg
|
||||||
# └── zt.framework
|
# └── zt.framework
|
||||||
# ├── Headers
|
# ├── Headers
|
||||||
@@ -195,10 +195,10 @@ iphonesimulator-framework()
|
|||||||
#
|
#
|
||||||
# Example output:
|
# Example output:
|
||||||
#
|
#
|
||||||
# - Cache : /Volumes/$USER/zt/libzt/libzt-dev/cache/macos-x64-framework-debug
|
# - Cache : libzt/cache/macos-x64-framework-debug
|
||||||
# - Build output : /Volumes/$USER/zt/libzt/libzt-dev/dist
|
# - Build output : libzt/dist
|
||||||
#
|
#
|
||||||
# /Volumes/$USER/zt/libzt/libzt-dev/dist/macos-x64-framework-debug
|
# libzt/dist/macos-x64-framework-debug
|
||||||
# └── pkg
|
# └── pkg
|
||||||
# └── zt.framework
|
# └── zt.framework
|
||||||
# ├── Headers
|
# ├── Headers
|
||||||
@@ -241,10 +241,10 @@ macos-framework()
|
|||||||
#
|
#
|
||||||
# Example output:
|
# Example output:
|
||||||
#
|
#
|
||||||
# - Cache : /Volumes/$USER/zt/libzt/libzt-dev/cache/iphoneos-arm64-framework-debug
|
# - Cache : libzt/cache/iphoneos-arm64-framework-debug
|
||||||
# - Build output : /Volumes/$USER/zt/libzt/libzt-dev/dist
|
# - Build output : libzt/dist
|
||||||
#
|
#
|
||||||
# /Volumes/$USER/zt/libzt/libzt-dev/dist/iphoneos-arm64-framework-debug
|
# libzt/dist/iphoneos-arm64-framework-debug
|
||||||
# └── pkg
|
# └── pkg
|
||||||
# └── zt.framework
|
# └── zt.framework
|
||||||
# ├── Headers
|
# ├── Headers
|
||||||
@@ -291,8 +291,8 @@ iphoneos-framework()
|
|||||||
#
|
#
|
||||||
# Example output:
|
# Example output:
|
||||||
#
|
#
|
||||||
# - Cache : /Volumes/$USER/zt/libzt/libzt-dev/cache/linux-x64-host-release
|
# - Cache : libzt/cache/linux-x64-host-release
|
||||||
# - Build output : /Volumes/$USER/zt/libzt/libzt-dev/dist
|
# - Build output : libzt/dist
|
||||||
#
|
#
|
||||||
# linux-x64-host-release
|
# linux-x64-host-release
|
||||||
# ├── bin
|
# ├── bin
|
||||||
@@ -307,6 +307,11 @@ host()
|
|||||||
ARTIFACT="host"
|
ARTIFACT="host"
|
||||||
# Default to release
|
# Default to release
|
||||||
BUILD_TYPE=${1:-release}
|
BUILD_TYPE=${1:-release}
|
||||||
|
if [[ $1 = *"docs"* ]]; then
|
||||||
|
# Generate documentation
|
||||||
|
cd docs/c && doxygen
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
# -DZTS_ENABLE_CENTRAL_API=0
|
# -DZTS_ENABLE_CENTRAL_API=0
|
||||||
VARIANT="-DBUILD_HOST=True"
|
VARIANT="-DBUILD_HOST=True"
|
||||||
CACHE_DIR=$DEFAULT_HOST_BUILD_CACHE_DIR-$ARTIFACT-$BUILD_TYPE
|
CACHE_DIR=$DEFAULT_HOST_BUILD_CACHE_DIR-$ARTIFACT-$BUILD_TYPE
|
||||||
@@ -336,6 +341,29 @@ host-uninstall()
|
|||||||
cd -
|
cd -
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Build C extension module (*.so), python module, package both into wheel
|
||||||
|
#
|
||||||
|
# ./build.sh host-python-wheel "release"
|
||||||
|
#
|
||||||
|
# Example output:
|
||||||
|
#
|
||||||
|
# libzt/dist/macos-x64-python-debug
|
||||||
|
# └── pkg
|
||||||
|
# └── libzt-1.3.4b1-cp39-cp39-macosx_11_0_x86_64.whl
|
||||||
|
#
|
||||||
|
host-python-wheel()
|
||||||
|
{
|
||||||
|
ARTIFACT="python"
|
||||||
|
# Default to release
|
||||||
|
BUILD_TYPE=${1:-release}
|
||||||
|
CACHE_DIR=$DEFAULT_HOST_BUILD_CACHE_DIR-$ARTIFACT-$BUILD_TYPE
|
||||||
|
TARGET_BUILD_DIR=$DEFAULT_HOST_BIN_OUTPUT_DIR-$ARTIFACT-$BUILD_TYPE
|
||||||
|
PKG_OUTPUT_DIR=$TARGET_BUILD_DIR/pkg
|
||||||
|
mkdir -p $PKG_OUTPUT_DIR
|
||||||
|
# Requires setuptools, etc
|
||||||
|
cd pkg/pypi && ./build.sh wheel && cp -f dist/*.whl $PKG_OUTPUT_DIR
|
||||||
|
}
|
||||||
|
|
||||||
# Build shared library with python wrapper symbols exported
|
# Build shared library with python wrapper symbols exported
|
||||||
host-python()
|
host-python()
|
||||||
{
|
{
|
||||||
@@ -345,9 +373,8 @@ host-python()
|
|||||||
VARIANT="-DZTS_ENABLE_PYTHON=True"
|
VARIANT="-DZTS_ENABLE_PYTHON=True"
|
||||||
CACHE_DIR=$DEFAULT_HOST_BUILD_CACHE_DIR-$ARTIFACT-$BUILD_TYPE
|
CACHE_DIR=$DEFAULT_HOST_BUILD_CACHE_DIR-$ARTIFACT-$BUILD_TYPE
|
||||||
TARGET_BUILD_DIR=$DEFAULT_HOST_BIN_OUTPUT_DIR-$ARTIFACT-$BUILD_TYPE
|
TARGET_BUILD_DIR=$DEFAULT_HOST_BIN_OUTPUT_DIR-$ARTIFACT-$BUILD_TYPE
|
||||||
rm -rf $TARGET_BUILD_DIR
|
|
||||||
LIB_OUTPUT_DIR=$TARGET_BUILD_DIR/lib
|
LIB_OUTPUT_DIR=$TARGET_BUILD_DIR/lib
|
||||||
BIN_OUTPUT_DIR=$TARGET_BUILD_DIR/bin
|
rm -rf $LIB_OUTPUT_DIR
|
||||||
mkdir -p $LIB_OUTPUT_DIR
|
mkdir -p $LIB_OUTPUT_DIR
|
||||||
# Optional step to generate new SWIG wrapper
|
# Optional step to generate new SWIG wrapper
|
||||||
swig -c++ -python -o src/bindings/python/zt_wrap.cpp -Iinclude src/bindings/python/zt.i
|
swig -c++ -python -o src/bindings/python/zt_wrap.cpp -Iinclude src/bindings/python/zt.i
|
||||||
@@ -384,6 +411,11 @@ host-jar()
|
|||||||
ARTIFACT="jar"
|
ARTIFACT="jar"
|
||||||
# Default to release
|
# Default to release
|
||||||
BUILD_TYPE=${1:-release}
|
BUILD_TYPE=${1:-release}
|
||||||
|
if [[ $1 = *"docs"* ]]; then
|
||||||
|
# Generate documentation
|
||||||
|
javadoc src/bindings/java/*.java -d docs/java
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
VARIANT="-DZTS_ENABLE_JAVA=True"
|
VARIANT="-DZTS_ENABLE_JAVA=True"
|
||||||
CACHE_DIR=$DEFAULT_HOST_BUILD_CACHE_DIR-$ARTIFACT-$BUILD_TYPE
|
CACHE_DIR=$DEFAULT_HOST_BUILD_CACHE_DIR-$ARTIFACT-$BUILD_TYPE
|
||||||
TARGET_BUILD_DIR=$DEFAULT_HOST_BIN_OUTPUT_DIR-$ARTIFACT-$BUILD_TYPE
|
TARGET_BUILD_DIR=$DEFAULT_HOST_BIN_OUTPUT_DIR-$ARTIFACT-$BUILD_TYPE
|
||||||
@@ -402,7 +434,7 @@ host-jar()
|
|||||||
cp -f $CACHE_DIR/lib/libzt.* $JAVA_JAR_DIR
|
cp -f $CACHE_DIR/lib/libzt.* $JAVA_JAR_DIR
|
||||||
cd $JAVA_JAR_DIR
|
cd $JAVA_JAR_DIR
|
||||||
export JAVA_TOOL_OPTIONS=-Dfile.encoding=UTF8
|
export JAVA_TOOL_OPTIONS=-Dfile.encoding=UTF8
|
||||||
javac com/zerotier/libzt/*.java
|
javac -Xlint:deprecation com/zerotier/libzt/*.java
|
||||||
jar cf libzt-"$(git describe --abbrev=0)".jar $SHARED_LIB_NAME com/zerotier/libzt/*.class
|
jar cf libzt-"$(git describe --abbrev=0)".jar $SHARED_LIB_NAME com/zerotier/libzt/*.class
|
||||||
rm -rf com $SHARED_LIB_NAME
|
rm -rf com $SHARED_LIB_NAME
|
||||||
cd -
|
cd -
|
||||||
@@ -441,8 +473,8 @@ fi
|
|||||||
#
|
#
|
||||||
# Example output:
|
# Example output:
|
||||||
#
|
#
|
||||||
# - Cache : /Volumes/$USER/zt/libzt/libzt-dev/cache/android-any-android-release
|
# - Cache : libzt/cache/android-any-android-release
|
||||||
# - Build output : /Volumes/$USER/zt/libzt/libzt-dev/dist
|
# - Build output : libzt/dist
|
||||||
#
|
#
|
||||||
# android-any-android-release
|
# android-any-android-release
|
||||||
# └── libzt-release.aar
|
# └── libzt-release.aar
|
||||||
@@ -496,10 +528,34 @@ test()
|
|||||||
$TREE $TARGET_BUILD_DIR
|
$TREE $TARGET_BUILD_DIR
|
||||||
# Test
|
# Test
|
||||||
cd $CACHE_DIR
|
cd $CACHE_DIR
|
||||||
ctest -C release
|
#ctest -C release
|
||||||
cd -
|
cd -
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Test C API
|
||||||
|
test-c()
|
||||||
|
{
|
||||||
|
if [[ -z "${alice_path}" ]]; then
|
||||||
|
echo "Please set necessary environment variables for test"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
ARTIFACT="test"
|
||||||
|
# Default to debug so asserts aren't optimized out
|
||||||
|
BUILD_TYPE=${1:-debug}
|
||||||
|
TARGET_BUILD_DIR=$DEFAULT_HOST_BIN_OUTPUT_DIR-$ARTIFACT-$BUILD_TYPE
|
||||||
|
BIN_OUTPUT_DIR=$TARGET_BUILD_DIR/bin
|
||||||
|
rm -rf $TARGET_BUILD_DIR
|
||||||
|
# Build selftest
|
||||||
|
test $1
|
||||||
|
# Ports can be anything we want since they aren't system ports
|
||||||
|
port4=8080
|
||||||
|
port6=8081
|
||||||
|
# Start Alice as server
|
||||||
|
"$BIN_OUTPUT_DIR/selftest-c-api" $alice_path $testnet $port4 $port6 &
|
||||||
|
# Start Bob as client
|
||||||
|
"$BIN_OUTPUT_DIR/selftest-c-api" $bob_path $testnet $port4 $alice_ip4 $port6 $alice_ip6 &
|
||||||
|
}
|
||||||
|
|
||||||
# Recursive deep clean
|
# Recursive deep clean
|
||||||
clean()
|
clean()
|
||||||
{
|
{
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -70,6 +70,7 @@ namespace ZeroTier
|
|||||||
jobject objRef = NULL;
|
jobject objRef = NULL;
|
||||||
jmethodID _userCallbackMethodRef = NULL;
|
jmethodID _userCallbackMethodRef = NULL;
|
||||||
#endif
|
#endif
|
||||||
|
extern uint8_t _serviceStateFlags;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
@@ -421,6 +422,9 @@ JNIEXPORT void JNICALL Java_com_zerotier_libzt_ZeroTier_restart(
|
|||||||
|
|
||||||
int zts_free()
|
int zts_free()
|
||||||
{
|
{
|
||||||
|
if (!(_serviceStateFlags & ZTS_STATE_NET_SERVICE_RUNNING)) {
|
||||||
|
return ZTS_ERR_SERVICE;
|
||||||
|
}
|
||||||
if (_getState(ZTS_STATE_FREE_CALLED)) {
|
if (_getState(ZTS_STATE_FREE_CALLED)) {
|
||||||
return ZTS_ERR_SERVICE;
|
return ZTS_ERR_SERVICE;
|
||||||
}
|
}
|
||||||
|
|||||||
429
src/Sockets.cpp
429
src/Sockets.cpp
@@ -59,12 +59,33 @@ int zts_connect(int fd, const struct zts_sockaddr *addr, zts_socklen_t addrlen)
|
|||||||
if (!addr) {
|
if (!addr) {
|
||||||
return ZTS_ERR_ARG;
|
return ZTS_ERR_ARG;
|
||||||
}
|
}
|
||||||
if (addrlen > (int)sizeof(struct zts_sockaddr_storage) || addrlen < (int)sizeof(struct zts_sockaddr_in)) {
|
if (addrlen > (int)sizeof(struct zts_sockaddr_storage)
|
||||||
|
|| addrlen < (int)sizeof(struct zts_sockaddr_in)) {
|
||||||
return ZTS_ERR_ARG;
|
return ZTS_ERR_ARG;
|
||||||
}
|
}
|
||||||
return lwip_connect(fd, (sockaddr*)addr, addrlen);
|
return lwip_connect(fd, (sockaddr*)addr, addrlen);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int zts_connect_easy(int fd, int family, char *ipstr, int port) {
|
||||||
|
if (family == ZTS_AF_INET) {
|
||||||
|
struct zts_sockaddr_in in4;
|
||||||
|
zts_socklen_t addrlen = sizeof(in4);
|
||||||
|
ipstr2sockaddr(
|
||||||
|
family, ipstr, port, (struct zts_sockaddr *)&in4, &addrlen);
|
||||||
|
struct zts_sockaddr *sa = (struct zts_sockaddr *)&in4;
|
||||||
|
return zts_connect(fd, sa, addrlen);
|
||||||
|
}
|
||||||
|
if (family == ZTS_AF_INET6) {
|
||||||
|
struct zts_sockaddr_in6 in6;
|
||||||
|
zts_socklen_t addrlen = sizeof(in6);
|
||||||
|
ipstr2sockaddr(
|
||||||
|
family, ipstr, port, (struct zts_sockaddr *)&in6, &addrlen);
|
||||||
|
struct zts_sockaddr *sa = (struct zts_sockaddr *)&in6;
|
||||||
|
return zts_connect(fd, sa, addrlen);
|
||||||
|
}
|
||||||
|
return ZTS_ERR_ARG;
|
||||||
|
}
|
||||||
|
|
||||||
int zts_bind(int fd, const struct zts_sockaddr *addr, zts_socklen_t addrlen)
|
int zts_bind(int fd, const struct zts_sockaddr *addr, zts_socklen_t addrlen)
|
||||||
{
|
{
|
||||||
if (!(_serviceStateFlags & ZTS_STATE_NET_SERVICE_RUNNING)) {
|
if (!(_serviceStateFlags & ZTS_STATE_NET_SERVICE_RUNNING)) {
|
||||||
@@ -73,12 +94,33 @@ int zts_bind(int fd, const struct zts_sockaddr *addr, zts_socklen_t addrlen)
|
|||||||
if (!addr) {
|
if (!addr) {
|
||||||
return ZTS_ERR_ARG;
|
return ZTS_ERR_ARG;
|
||||||
}
|
}
|
||||||
if (addrlen > (int)sizeof(struct zts_sockaddr_storage) || addrlen < (int)sizeof(struct zts_sockaddr_in)) {
|
if (addrlen > (int)sizeof(struct zts_sockaddr_storage)
|
||||||
|
|| addrlen < (int)sizeof(struct zts_sockaddr_in)) {
|
||||||
return ZTS_ERR_ARG;
|
return ZTS_ERR_ARG;
|
||||||
}
|
}
|
||||||
return lwip_bind(fd, (sockaddr*)addr, addrlen);
|
return lwip_bind(fd, (sockaddr*)addr, addrlen);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int zts_bind_easy(int fd, int family, char *ipstr, int port) {
|
||||||
|
if (family == ZTS_AF_INET) {
|
||||||
|
struct zts_sockaddr_in in4;
|
||||||
|
zts_socklen_t addrlen = sizeof(in4);
|
||||||
|
ipstr2sockaddr(
|
||||||
|
family, ipstr, port, (struct zts_sockaddr *)&in4, &addrlen);
|
||||||
|
struct zts_sockaddr *sa = (struct zts_sockaddr *)&in4;
|
||||||
|
return zts_bind(fd, sa, addrlen);
|
||||||
|
}
|
||||||
|
if (family == ZTS_AF_INET6) {
|
||||||
|
struct zts_sockaddr_in6 in6;
|
||||||
|
zts_socklen_t addrlen = sizeof(in6);
|
||||||
|
ipstr2sockaddr(
|
||||||
|
family, ipstr, port, (struct zts_sockaddr *)&in6, &addrlen);
|
||||||
|
struct zts_sockaddr *sa = (struct zts_sockaddr *)&in6;
|
||||||
|
return zts_bind(fd, sa, addrlen);
|
||||||
|
}
|
||||||
|
return ZTS_ERR_ARG;
|
||||||
|
}
|
||||||
|
|
||||||
int zts_listen(int fd, int backlog)
|
int zts_listen(int fd, int backlog)
|
||||||
{
|
{
|
||||||
if (!(_serviceStateFlags & ZTS_STATE_NET_SERVICE_RUNNING)) {
|
if (!(_serviceStateFlags & ZTS_STATE_NET_SERVICE_RUNNING)) {
|
||||||
@@ -95,7 +137,8 @@ int zts_accept(int fd, struct zts_sockaddr *addr, zts_socklen_t *addrlen)
|
|||||||
return lwip_accept(fd, (sockaddr*)addr, (socklen_t*)addrlen);
|
return lwip_accept(fd, (sockaddr*)addr, (socklen_t*)addrlen);
|
||||||
}
|
}
|
||||||
|
|
||||||
int zts_setsockopt(int fd, int level, int optname, const void *optval,zts_socklen_t optlen)
|
int zts_setsockopt(
|
||||||
|
int fd, int level, int optname, const void *optval,zts_socklen_t optlen)
|
||||||
{
|
{
|
||||||
if (!(_serviceStateFlags & ZTS_STATE_NET_SERVICE_RUNNING)) {
|
if (!(_serviceStateFlags & ZTS_STATE_NET_SERVICE_RUNNING)) {
|
||||||
return ZTS_ERR_SERVICE;
|
return ZTS_ERR_SERVICE;
|
||||||
@@ -103,7 +146,8 @@ int zts_setsockopt(int fd, int level, int optname, const void *optval,zts_sockle
|
|||||||
return lwip_setsockopt(fd, level, optname, optval, optlen);
|
return lwip_setsockopt(fd, level, optname, optval, optlen);
|
||||||
}
|
}
|
||||||
|
|
||||||
int zts_getsockopt(int fd, int level, int optname, void *optval, zts_socklen_t *optlen)
|
int zts_getsockopt(
|
||||||
|
int fd, int level, int optname, void *optval, zts_socklen_t *optlen)
|
||||||
{
|
{
|
||||||
if (!(_serviceStateFlags & ZTS_STATE_NET_SERVICE_RUNNING)) {
|
if (!(_serviceStateFlags & ZTS_STATE_NET_SERVICE_RUNNING)) {
|
||||||
return ZTS_ERR_SERVICE;
|
return ZTS_ERR_SERVICE;
|
||||||
@@ -119,7 +163,8 @@ int zts_getsockname(int fd, struct zts_sockaddr *addr, zts_socklen_t *addrlen)
|
|||||||
if (!addr) {
|
if (!addr) {
|
||||||
return ZTS_ERR_ARG;
|
return ZTS_ERR_ARG;
|
||||||
}
|
}
|
||||||
if (*addrlen > (int)sizeof(struct zts_sockaddr_storage) || *addrlen < (int)sizeof(struct zts_sockaddr_in)) {
|
if (*addrlen > (int)sizeof(struct zts_sockaddr_storage)
|
||||||
|
|| *addrlen < (int)sizeof(struct zts_sockaddr_in)) {
|
||||||
return ZTS_ERR_ARG;
|
return ZTS_ERR_ARG;
|
||||||
}
|
}
|
||||||
return lwip_getsockname(fd, (sockaddr*)addr, (socklen_t*)addrlen);
|
return lwip_getsockname(fd, (sockaddr*)addr, (socklen_t*)addrlen);
|
||||||
@@ -133,7 +178,8 @@ int zts_getpeername(int fd, struct zts_sockaddr *addr, zts_socklen_t *addrlen)
|
|||||||
if (!addr) {
|
if (!addr) {
|
||||||
return ZTS_ERR_ARG;
|
return ZTS_ERR_ARG;
|
||||||
}
|
}
|
||||||
if (*addrlen > (int)sizeof(struct zts_sockaddr_storage) || *addrlen < (int)sizeof(struct zts_sockaddr_in)) {
|
if (*addrlen > (int)sizeof(struct zts_sockaddr_storage)
|
||||||
|
|| *addrlen < (int)sizeof(struct zts_sockaddr_in)) {
|
||||||
return ZTS_ERR_ARG;
|
return ZTS_ERR_ARG;
|
||||||
}
|
}
|
||||||
return lwip_getpeername(fd, (sockaddr*)addr, (socklen_t*)addrlen);
|
return lwip_getpeername(fd, (sockaddr*)addr, (socklen_t*)addrlen);
|
||||||
@@ -147,13 +193,15 @@ int zts_close(int fd)
|
|||||||
return lwip_close(fd);
|
return lwip_close(fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
int zts_select(int nfds, zts_fd_set *readfds, zts_fd_set *writefds, zts_fd_set *exceptfds,
|
int zts_select(
|
||||||
|
int nfds, zts_fd_set *readfds, zts_fd_set *writefds, zts_fd_set *exceptfds,
|
||||||
struct zts_timeval *timeout)
|
struct zts_timeval *timeout)
|
||||||
{
|
{
|
||||||
if (!(_serviceStateFlags & ZTS_STATE_NET_SERVICE_RUNNING)) {
|
if (!(_serviceStateFlags & ZTS_STATE_NET_SERVICE_RUNNING)) {
|
||||||
return ZTS_ERR_SERVICE;
|
return ZTS_ERR_SERVICE;
|
||||||
}
|
}
|
||||||
return lwip_select(nfds, (fd_set*)readfds, (fd_set*)writefds, (fd_set*)exceptfds, (timeval*)timeout);
|
return lwip_select(
|
||||||
|
nfds, (fd_set*)readfds, (fd_set*)writefds, (fd_set*)exceptfds, (timeval*)timeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
int zts_fcntl(int fd, int cmd, int flags)
|
int zts_fcntl(int fd, int cmd, int flags)
|
||||||
@@ -203,7 +251,8 @@ ssize_t zts_sendto(int fd, const void *buf, size_t len, int flags,
|
|||||||
if (!addr || !buf) {
|
if (!addr || !buf) {
|
||||||
return ZTS_ERR_ARG;
|
return ZTS_ERR_ARG;
|
||||||
}
|
}
|
||||||
if (addrlen > (int)sizeof(struct zts_sockaddr_storage) || addrlen < (int)sizeof(struct zts_sockaddr_in)) {
|
if (addrlen > (int)sizeof(struct zts_sockaddr_storage)
|
||||||
|
|| addrlen < (int)sizeof(struct zts_sockaddr_in)) {
|
||||||
return ZTS_ERR_ARG;
|
return ZTS_ERR_ARG;
|
||||||
}
|
}
|
||||||
return lwip_sendto(fd, buf, len, flags, (sockaddr*)addr, addrlen);
|
return lwip_sendto(fd, buf, len, flags, (sockaddr*)addr, addrlen);
|
||||||
@@ -214,6 +263,7 @@ ssize_t zts_sendmsg(int fd, const struct zts_msghdr *msg, int flags)
|
|||||||
if (!(_serviceStateFlags & ZTS_STATE_NET_SERVICE_RUNNING)) {
|
if (!(_serviceStateFlags & ZTS_STATE_NET_SERVICE_RUNNING)) {
|
||||||
return ZTS_ERR_SERVICE;
|
return ZTS_ERR_SERVICE;
|
||||||
}
|
}
|
||||||
|
|
||||||
return lwip_sendmsg(fd, (const struct msghdr *)msg, flags);
|
return lwip_sendmsg(fd, (const struct msghdr *)msg, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -237,7 +287,8 @@ ssize_t zts_recvfrom(int fd, void *buf, size_t len, int flags,
|
|||||||
if (!buf) {
|
if (!buf) {
|
||||||
return ZTS_ERR_ARG;
|
return ZTS_ERR_ARG;
|
||||||
}
|
}
|
||||||
return lwip_recvfrom(fd, buf, len, flags, (sockaddr*)addr, (socklen_t*)addrlen);
|
return lwip_recvfrom(
|
||||||
|
fd, buf, len, flags, (sockaddr*)addr, (socklen_t*)addrlen);
|
||||||
}
|
}
|
||||||
|
|
||||||
ssize_t zts_recvmsg(int fd, struct zts_msghdr *msg, int flags)
|
ssize_t zts_recvmsg(int fd, struct zts_msghdr *msg, int flags)
|
||||||
@@ -262,12 +313,13 @@ ssize_t zts_read(int fd, void *buf, size_t len)
|
|||||||
return lwip_read(fd, buf, len);
|
return lwip_read(fd, buf, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
ssize_t zts_readv(int s, const struct zts_iovec *iov, int iovcnt)
|
ssize_t zts_readv(int fd, const struct zts_iovec *iov, int iovcnt)
|
||||||
{
|
{
|
||||||
if (!(_serviceStateFlags & ZTS_STATE_NET_SERVICE_RUNNING)) {
|
if (!(_serviceStateFlags & ZTS_STATE_NET_SERVICE_RUNNING)) {
|
||||||
return ZTS_ERR_SERVICE;
|
return ZTS_ERR_SERVICE;
|
||||||
}
|
}
|
||||||
return lwip_readv(s, (iovec*)iov, iovcnt);
|
|
||||||
|
return lwip_readv(fd, (iovec*)iov, iovcnt);
|
||||||
}
|
}
|
||||||
|
|
||||||
ssize_t zts_write(int fd, const void *buf, size_t len)
|
ssize_t zts_write(int fd, const void *buf, size_t len)
|
||||||
@@ -275,6 +327,7 @@ ssize_t zts_write(int fd, const void *buf, size_t len)
|
|||||||
if (!(_serviceStateFlags & ZTS_STATE_NET_SERVICE_RUNNING)) {
|
if (!(_serviceStateFlags & ZTS_STATE_NET_SERVICE_RUNNING)) {
|
||||||
return ZTS_ERR_SERVICE;
|
return ZTS_ERR_SERVICE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!buf) {
|
if (!buf) {
|
||||||
return ZTS_ERR_ARG;
|
return ZTS_ERR_ARG;
|
||||||
}
|
}
|
||||||
@@ -286,6 +339,7 @@ ssize_t zts_writev(int fd, const struct zts_iovec *iov, int iovcnt)
|
|||||||
if (!(_serviceStateFlags & ZTS_STATE_NET_SERVICE_RUNNING)) {
|
if (!(_serviceStateFlags & ZTS_STATE_NET_SERVICE_RUNNING)) {
|
||||||
return ZTS_ERR_SERVICE;
|
return ZTS_ERR_SERVICE;
|
||||||
}
|
}
|
||||||
|
|
||||||
return lwip_writev(fd, (iovec*)iov, iovcnt);
|
return lwip_writev(fd, (iovec*)iov, iovcnt);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -344,19 +398,356 @@ int zts_ipaddr_aton(const char *cp, zts_ip_addr *addr)
|
|||||||
return ipaddr_aton(cp, (ip_addr_t *)addr);
|
return ipaddr_aton(cp, (ip_addr_t *)addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *zts_inet_ntop(int af, const void *src, char *dst, zts_socklen_t size)
|
const char *zts_inet_ntop(
|
||||||
|
int family, const void *src, char *dst, zts_socklen_t size)
|
||||||
{
|
{
|
||||||
return lwip_inet_ntop(af,src,dst,size);
|
return lwip_inet_ntop(family,src,dst,size);
|
||||||
}
|
}
|
||||||
|
|
||||||
int zts_inet_pton(int af, const char *src, void *dst)
|
int zts_inet_pton(int family, const char *src, void *dst)
|
||||||
{
|
{
|
||||||
return lwip_inet_pton(af,src,dst);
|
return lwip_inet_pton(family,src,dst);
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
int ipstr2sockaddr(
|
||||||
// Statistics //
|
int family, char *src_ipstr, int port, struct zts_sockaddr *dest_addr, zts_socklen_t *addrlen) {
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
if (family == ZTS_AF_INET) {
|
||||||
|
struct zts_sockaddr_in in4;
|
||||||
|
in4.sin_port = htons(port);
|
||||||
|
in4.sin_family = family;
|
||||||
|
#if defined(_WIN32)
|
||||||
|
zts_inet_pton(family, src_ipstr, &(in4.sin_addr.S_addr));
|
||||||
|
#else
|
||||||
|
zts_inet_pton(family, src_ipstr, &(in4.sin_addr.s_addr));
|
||||||
|
#endif
|
||||||
|
dest_addr = (struct zts_sockaddr *)&in4;
|
||||||
|
*addrlen = sizeof(in4);
|
||||||
|
return ZTS_ERR_OK;
|
||||||
|
}
|
||||||
|
if (family == ZTS_AF_INET6) {
|
||||||
|
struct zts_sockaddr_in6 in6;
|
||||||
|
in6.sin6_port = htons(port);
|
||||||
|
in6.sin6_family = family;
|
||||||
|
#if defined(_WIN32)
|
||||||
|
zts_inet_pton(family, src_ipstr, &(in6.sin6_addr));
|
||||||
|
#else
|
||||||
|
zts_inet_pton(family, src_ipstr, &(in6.sin6_addr));
|
||||||
|
#endif
|
||||||
|
dest_addr = (struct zts_sockaddr *)&in6;
|
||||||
|
*addrlen = sizeof(in6);
|
||||||
|
return ZTS_ERR_OK;
|
||||||
|
}
|
||||||
|
return ZTS_ERR_ARG;
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------//
|
||||||
|
// Convenience functions //
|
||||||
|
//----------------------------------------------------------------------------//
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper functions that simplify API wrapper generation and usage in other
|
||||||
|
* non-C-like languages. Use simple integer types instead of bit flags, limit
|
||||||
|
* the number of operations each function performs, prevent the user from
|
||||||
|
* needing to manipulate the content of structures in a non-native language.
|
||||||
|
*/
|
||||||
|
|
||||||
|
int zts_set_no_delay(int fd, int enabled) {
|
||||||
|
if (!(_serviceStateFlags & ZTS_STATE_NET_SERVICE_RUNNING)) {
|
||||||
|
return ZTS_ERR_SERVICE;
|
||||||
|
}
|
||||||
|
if (enabled != 0 && enabled != 1) {
|
||||||
|
return ZTS_ERR_ARG;
|
||||||
|
}
|
||||||
|
return zts_setsockopt(
|
||||||
|
fd, ZTS_IPPROTO_TCP, ZTS_TCP_NODELAY, (void *)&enabled, sizeof(int));
|
||||||
|
}
|
||||||
|
|
||||||
|
int zts_get_no_delay(int fd)
|
||||||
|
{
|
||||||
|
if (!(_serviceStateFlags & ZTS_STATE_NET_SERVICE_RUNNING)) {
|
||||||
|
return ZTS_ERR_SERVICE;
|
||||||
|
}
|
||||||
|
int err, optval = 0;
|
||||||
|
zts_socklen_t len = sizeof(optval);
|
||||||
|
if ((err = zts_getsockopt(
|
||||||
|
fd, ZTS_IPPROTO_TCP, ZTS_TCP_NODELAY, (void *)&optval, &len)) < 0) {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
return optval != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int zts_set_linger(int fd, int enabled, int value) {
|
||||||
|
if (!(_serviceStateFlags & ZTS_STATE_NET_SERVICE_RUNNING)) {
|
||||||
|
return ZTS_ERR_SERVICE;
|
||||||
|
}
|
||||||
|
if (enabled != 0 && enabled != 1) {
|
||||||
|
return ZTS_ERR_ARG;
|
||||||
|
}
|
||||||
|
if (value < 0) {
|
||||||
|
return ZTS_ERR_ARG;
|
||||||
|
}
|
||||||
|
struct zts_linger linger;
|
||||||
|
linger.l_onoff = enabled;
|
||||||
|
linger.l_linger = value;
|
||||||
|
return zts_setsockopt(
|
||||||
|
fd, ZTS_SOL_SOCKET, ZTS_SO_LINGER, (void *)&linger, sizeof(linger));
|
||||||
|
}
|
||||||
|
|
||||||
|
int zts_get_linger_enabled(int fd)
|
||||||
|
{
|
||||||
|
if (!(_serviceStateFlags & ZTS_STATE_NET_SERVICE_RUNNING)) {
|
||||||
|
return ZTS_ERR_SERVICE;
|
||||||
|
}
|
||||||
|
int err;
|
||||||
|
struct zts_linger linger;
|
||||||
|
zts_socklen_t len = sizeof(linger);
|
||||||
|
if ((err = zts_getsockopt(
|
||||||
|
fd, ZTS_SOL_SOCKET, ZTS_SO_LINGER, (void *)&linger, &len)) < 0) {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
return linger.l_onoff;
|
||||||
|
}
|
||||||
|
|
||||||
|
int zts_get_linger_value(int fd)
|
||||||
|
{
|
||||||
|
if (!(_serviceStateFlags & ZTS_STATE_NET_SERVICE_RUNNING)) {
|
||||||
|
return ZTS_ERR_SERVICE;
|
||||||
|
}
|
||||||
|
int err;
|
||||||
|
struct zts_linger linger;
|
||||||
|
zts_socklen_t len = sizeof(linger);
|
||||||
|
if ((err = zts_getsockopt(
|
||||||
|
fd, ZTS_SOL_SOCKET, ZTS_SO_LINGER, (void *)&linger, &len)) < 0) {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
return linger.l_linger;
|
||||||
|
}
|
||||||
|
|
||||||
|
int zts_set_reuse_addr(int fd, int enabled)
|
||||||
|
{
|
||||||
|
if (!(_serviceStateFlags & ZTS_STATE_NET_SERVICE_RUNNING)) {
|
||||||
|
return ZTS_ERR_SERVICE;
|
||||||
|
}
|
||||||
|
if (enabled != 0 && enabled != 1) {
|
||||||
|
return ZTS_ERR_ARG;
|
||||||
|
}
|
||||||
|
return zts_setsockopt(
|
||||||
|
fd, ZTS_SOL_SOCKET, ZTS_SO_REUSEADDR, (void *)&enabled, sizeof(enabled));
|
||||||
|
}
|
||||||
|
|
||||||
|
int zts_get_reuse_addr(int fd)
|
||||||
|
{
|
||||||
|
if (!(_serviceStateFlags & ZTS_STATE_NET_SERVICE_RUNNING)) {
|
||||||
|
return ZTS_ERR_SERVICE;
|
||||||
|
}
|
||||||
|
int err;
|
||||||
|
int optval = 0;
|
||||||
|
zts_socklen_t optlen = sizeof(optval);
|
||||||
|
if ((err = zts_getsockopt(
|
||||||
|
fd, ZTS_SOL_SOCKET, ZTS_SO_REUSEADDR, (void *)&optval, &optlen)) < 0) {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
return optval != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int zts_set_recv_timeout(int fd, int seconds, int microseconds)
|
||||||
|
{
|
||||||
|
if (!(_serviceStateFlags & ZTS_STATE_NET_SERVICE_RUNNING)) {
|
||||||
|
return ZTS_ERR_SERVICE;
|
||||||
|
}
|
||||||
|
if (seconds < 0 || microseconds < 0) {
|
||||||
|
return ZTS_ERR_ARG;
|
||||||
|
}
|
||||||
|
struct timeval tv;
|
||||||
|
tv.tv_sec = seconds;
|
||||||
|
tv.tv_usec = microseconds;
|
||||||
|
return zts_setsockopt(
|
||||||
|
fd, SOL_SOCKET, SO_RCVTIMEO, (void *)&tv, sizeof(tv));
|
||||||
|
}
|
||||||
|
|
||||||
|
int zts_get_recv_timeout(int fd)
|
||||||
|
{
|
||||||
|
if (!(_serviceStateFlags & ZTS_STATE_NET_SERVICE_RUNNING)) {
|
||||||
|
return ZTS_ERR_SERVICE;
|
||||||
|
}
|
||||||
|
struct timeval tv;
|
||||||
|
zts_socklen_t optlen = sizeof(tv);
|
||||||
|
int err;
|
||||||
|
if ((err = zts_getsockopt(
|
||||||
|
fd, SOL_SOCKET, SO_RCVTIMEO, (void *)&tv, &optlen)) < 0) {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
return tv.tv_sec; // TODO microseconds
|
||||||
|
}
|
||||||
|
|
||||||
|
int zts_set_send_timeout(int fd, int seconds, int microseconds)
|
||||||
|
{
|
||||||
|
if (!(_serviceStateFlags & ZTS_STATE_NET_SERVICE_RUNNING)) {
|
||||||
|
return ZTS_ERR_SERVICE;
|
||||||
|
}
|
||||||
|
if (seconds < 0 || microseconds < 0) {
|
||||||
|
return ZTS_ERR_ARG;
|
||||||
|
}
|
||||||
|
struct timeval tv;
|
||||||
|
tv.tv_sec = seconds;
|
||||||
|
tv.tv_usec = microseconds;
|
||||||
|
return zts_setsockopt(
|
||||||
|
fd, SOL_SOCKET, SO_SNDTIMEO, (void *)&tv, sizeof(tv));
|
||||||
|
}
|
||||||
|
|
||||||
|
int zts_get_send_timeout(int fd)
|
||||||
|
{
|
||||||
|
if (!(_serviceStateFlags & ZTS_STATE_NET_SERVICE_RUNNING)) {
|
||||||
|
return ZTS_ERR_SERVICE;
|
||||||
|
}
|
||||||
|
struct zts_timeval tv;
|
||||||
|
zts_socklen_t optlen = sizeof(tv);
|
||||||
|
int err;
|
||||||
|
if ((err = zts_getsockopt(
|
||||||
|
fd, SOL_SOCKET, SO_SNDTIMEO, (void *)&tv, &optlen)) < 0) {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
return tv.tv_sec; // TODO microseconds
|
||||||
|
}
|
||||||
|
|
||||||
|
int zts_set_send_buf_size(int fd, int size)
|
||||||
|
{
|
||||||
|
if (!(_serviceStateFlags & ZTS_STATE_NET_SERVICE_RUNNING)) {
|
||||||
|
return ZTS_ERR_SERVICE;
|
||||||
|
}
|
||||||
|
if (size < 0) {
|
||||||
|
return ZTS_ERR_ARG;
|
||||||
|
}
|
||||||
|
return zts_setsockopt(
|
||||||
|
fd, SOL_SOCKET, SO_SNDBUF, (void *)&size, sizeof(int));
|
||||||
|
}
|
||||||
|
|
||||||
|
int zts_get_send_buf_size(int fd)
|
||||||
|
{
|
||||||
|
if (!(_serviceStateFlags & ZTS_STATE_NET_SERVICE_RUNNING)) {
|
||||||
|
return ZTS_ERR_SERVICE;
|
||||||
|
}
|
||||||
|
int err, optval = 0;
|
||||||
|
zts_socklen_t optlen = sizeof(optval);
|
||||||
|
if ((err = zts_getsockopt(
|
||||||
|
fd, SOL_SOCKET, SO_SNDBUF, (char *)&optval, &optlen)) < 0) {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
return optval;
|
||||||
|
}
|
||||||
|
|
||||||
|
int zts_set_recv_buf_size(int fd, int size)
|
||||||
|
{
|
||||||
|
if (!(_serviceStateFlags & ZTS_STATE_NET_SERVICE_RUNNING)) {
|
||||||
|
return ZTS_ERR_SERVICE;
|
||||||
|
}
|
||||||
|
if (size < 0) {
|
||||||
|
return ZTS_ERR_ARG;
|
||||||
|
}
|
||||||
|
return zts_setsockopt(
|
||||||
|
fd, SOL_SOCKET, SO_RCVBUF, (void *)&size, sizeof(int));
|
||||||
|
}
|
||||||
|
|
||||||
|
int zts_get_recv_buf_size(int fd)
|
||||||
|
{
|
||||||
|
if (!(_serviceStateFlags & ZTS_STATE_NET_SERVICE_RUNNING)) {
|
||||||
|
return ZTS_ERR_SERVICE;
|
||||||
|
}
|
||||||
|
int err, optval = 0;
|
||||||
|
zts_socklen_t optlen = sizeof(optval);
|
||||||
|
if ((err = zts_getsockopt(
|
||||||
|
fd, SOL_SOCKET, SO_RCVBUF, (char *)&optval, &optlen)) < 0) {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
return optval;
|
||||||
|
}
|
||||||
|
|
||||||
|
int zts_set_ttl(int fd, int ttl)
|
||||||
|
{
|
||||||
|
if (!(_serviceStateFlags & ZTS_STATE_NET_SERVICE_RUNNING)) {
|
||||||
|
return ZTS_ERR_SERVICE;
|
||||||
|
}
|
||||||
|
if (ttl < 0 || ttl > 255) {
|
||||||
|
return ZTS_ERR_ARG;
|
||||||
|
}
|
||||||
|
return zts_setsockopt(fd, IPPROTO_IP, IP_TTL, &ttl, sizeof(ttl));
|
||||||
|
}
|
||||||
|
|
||||||
|
int zts_get_ttl(int fd)
|
||||||
|
{
|
||||||
|
if (!(_serviceStateFlags & ZTS_STATE_NET_SERVICE_RUNNING)) {
|
||||||
|
return ZTS_ERR_SERVICE;
|
||||||
|
}
|
||||||
|
int err, ttl = 0;
|
||||||
|
zts_socklen_t optlen = sizeof(ttl);
|
||||||
|
if ((err = zts_getsockopt(fd, IPPROTO_IP, IP_TTL, &ttl, &optlen)) < 0) {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
return ttl;
|
||||||
|
}
|
||||||
|
|
||||||
|
int zts_set_blocking(int fd, int enabled)
|
||||||
|
{
|
||||||
|
if (!(_serviceStateFlags & ZTS_STATE_NET_SERVICE_RUNNING)) {
|
||||||
|
return ZTS_ERR_SERVICE;
|
||||||
|
}
|
||||||
|
if (enabled != 0 && enabled != 1) {
|
||||||
|
return ZTS_ERR_ARG;
|
||||||
|
}
|
||||||
|
int flags = zts_fcntl(fd, ZTS_F_GETFL, 0);
|
||||||
|
if (!enabled) {
|
||||||
|
return zts_fcntl(fd, ZTS_F_SETFL, flags | ZTS_O_NONBLOCK);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// Default
|
||||||
|
return zts_fcntl(fd, ZTS_F_SETFL, flags & (~ZTS_O_NONBLOCK));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int zts_get_blocking(int fd)
|
||||||
|
{
|
||||||
|
if (!(_serviceStateFlags & ZTS_STATE_NET_SERVICE_RUNNING)) {
|
||||||
|
return ZTS_ERR_SERVICE;
|
||||||
|
}
|
||||||
|
int flags = zts_fcntl(fd, ZTS_F_GETFL, 0);
|
||||||
|
if (flags < 0) {
|
||||||
|
return flags;
|
||||||
|
}
|
||||||
|
return !(flags & ZTS_O_NONBLOCK);
|
||||||
|
}
|
||||||
|
|
||||||
|
int zts_set_keepalive(int fd, int enabled)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
if (!(_serviceStateFlags & ZTS_STATE_NET_SERVICE_RUNNING)) {
|
||||||
|
return ZTS_ERR_SERVICE;
|
||||||
|
}
|
||||||
|
if (enabled != 0 && enabled != 1) {
|
||||||
|
return ZTS_ERR_ARG;
|
||||||
|
}
|
||||||
|
int keepalive = enabled;
|
||||||
|
return zts_setsockopt(
|
||||||
|
fd, ZTS_SOL_SOCKET, ZTS_SO_KEEPALIVE, &keepalive , sizeof(keepalive));
|
||||||
|
}
|
||||||
|
|
||||||
|
int zts_get_keepalive(int fd)
|
||||||
|
{
|
||||||
|
if (!(_serviceStateFlags & ZTS_STATE_NET_SERVICE_RUNNING)) {
|
||||||
|
return ZTS_ERR_SERVICE;
|
||||||
|
}
|
||||||
|
int err;
|
||||||
|
int optval = 0;
|
||||||
|
zts_socklen_t optlen = sizeof(optval);
|
||||||
|
if ((err = zts_getsockopt(
|
||||||
|
fd, ZTS_SOL_SOCKET, ZTS_SO_KEEPALIVE, (void *)&optval, &optlen)) < 0) {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
return optval != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------//
|
||||||
|
// Statistics //
|
||||||
|
//----------------------------------------------------------------------------//
|
||||||
|
|
||||||
#ifdef ZTS_ENABLE_STATS
|
#ifdef ZTS_ENABLE_STATS
|
||||||
|
|
||||||
|
|||||||
816
test/selftest-c-api.c
Normal file
816
test/selftest-c-api.c
Normal file
@@ -0,0 +1,816 @@
|
|||||||
|
/**
|
||||||
|
* Selftest. To be run for every commit.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <limits.h>
|
||||||
|
#include <math.h>
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
|
#include <ZeroTierSockets.h>
|
||||||
|
|
||||||
|
#pragma GCC diagnostic ignored "-Wunused-value"
|
||||||
|
|
||||||
|
int random32() {
|
||||||
|
const int BITS_PER_RAND = (int)(log2(RAND_MAX/2 + 1) + 1.0);
|
||||||
|
int ret = 0;
|
||||||
|
for (int i = 0; i < sizeof(int) * CHAR_BIT; i += BITS_PER_RAND) {
|
||||||
|
ret <<= BITS_PER_RAND;
|
||||||
|
ret |= rand();
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t random64() {
|
||||||
|
return ((uint64_t)random32() << 32) | random32();
|
||||||
|
}
|
||||||
|
|
||||||
|
int is_online = 0;
|
||||||
|
int has_ip4 = 0;
|
||||||
|
int has_ip6 = 0;
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------//
|
||||||
|
// Event Handler //
|
||||||
|
//----------------------------------------------------------------------------//
|
||||||
|
|
||||||
|
void on_zts_event(void *msgPtr)
|
||||||
|
{
|
||||||
|
struct zts_callback_msg *msg = (struct zts_callback_msg *)msgPtr;
|
||||||
|
fprintf(stderr, "event=%d\n", msg->eventCode);
|
||||||
|
if (msg->eventCode == ZTS_EVENT_NODE_ONLINE) {
|
||||||
|
fprintf(stderr, "ZTS_EVENT_NODE_ONLINE\n");
|
||||||
|
is_online = 1;
|
||||||
|
}
|
||||||
|
if (msg->eventCode == ZTS_EVENT_NETWORK_READY_IP4) {
|
||||||
|
fprintf(stderr, "ZTS_EVENT_NETWORK_READY_IP4\n");
|
||||||
|
has_ip4 = 1;
|
||||||
|
}
|
||||||
|
if (msg->eventCode == ZTS_EVENT_NETWORK_READY_IP6) {
|
||||||
|
fprintf(stderr, "ZTS_EVENT_NETWORK_READY_IP6\n");
|
||||||
|
has_ip6 = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void api_value_arg_test(
|
||||||
|
int8_t i8, int16_t i16, int32_t i32, int64_t i64, void* nullable)
|
||||||
|
{
|
||||||
|
//fprintf(stderr, "%d, %d, %d, %lld, %p\n", i8, i16, i32, i64, nullable);
|
||||||
|
int res = ZTS_ERR_OK;
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------//
|
||||||
|
// Test uninitialized Network Stack API usage //
|
||||||
|
//----------------------------------------------------------------------------//
|
||||||
|
/*
|
||||||
|
res = zts_get_all_stats((struct zts_stats *)nullable);
|
||||||
|
assert(("pre-init call to zts_get_all_stats(): res != ZTS_ERR_SERVICE",
|
||||||
|
res == ZTS_ERR_SERVICE));
|
||||||
|
res = zts_get_protocol_stats(i32, nullable);
|
||||||
|
assert(("pre-init call to zts_get_protocol_stats(): res != ZTS_ERR_SERVICE",
|
||||||
|
res == ZTS_ERR_SERVICE));
|
||||||
|
*/
|
||||||
|
res = zts_dns_set_server(i8, (const zts_ip_addr *)nullable);
|
||||||
|
assert(("pre-init call to zts_add_dns_nameserver(): res != ZTS_ERR_SERVICE",
|
||||||
|
res == ZTS_ERR_SERVICE));
|
||||||
|
const zts_ip_addr *res_ptr = zts_dns_get_server(i8);
|
||||||
|
assert(("pre-init call to zts_del_dns_nameserver(): res != ZTS_ERR_SERVICE",
|
||||||
|
res == ZTS_ERR_SERVICE));
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------//
|
||||||
|
// Test uninitialized Node API usage //
|
||||||
|
//----------------------------------------------------------------------------//
|
||||||
|
|
||||||
|
res = zts_stop();
|
||||||
|
assert(("pre-init call to zts_stop(): res != ZTS_ERR_SERVICE",
|
||||||
|
res == ZTS_ERR_SERVICE));
|
||||||
|
res = zts_restart();
|
||||||
|
assert(("pre-init call to zts_restart(): res != ZTS_ERR_SERVICE",
|
||||||
|
res == ZTS_ERR_SERVICE));
|
||||||
|
res = zts_free();
|
||||||
|
assert(("pre-init call to zts_free(): res != ZTS_ERR_SERVICE",
|
||||||
|
res == ZTS_ERR_SERVICE));
|
||||||
|
res = zts_join(i64);
|
||||||
|
assert(("pre-init call to zts_join(): res != ZTS_ERR_SERVICE",
|
||||||
|
res == ZTS_ERR_SERVICE));
|
||||||
|
res = zts_leave(i64);
|
||||||
|
assert(("pre-init call to zts_leave(): res != ZTS_ERR_SERVICE",
|
||||||
|
res == ZTS_ERR_SERVICE));
|
||||||
|
res = zts_orbit(i64,i64);
|
||||||
|
assert(("pre-init call to zts_orbit(): res != ZTS_ERR_SERVICE",
|
||||||
|
res == ZTS_ERR_SERVICE));
|
||||||
|
res = zts_deorbit(i64);
|
||||||
|
assert(("pre-init call to zts_deorbit(): res != ZTS_ERR_SERVICE",
|
||||||
|
res == ZTS_ERR_SERVICE));
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------//
|
||||||
|
// Test uninitialized Socket API usage //
|
||||||
|
//----------------------------------------------------------------------------//
|
||||||
|
|
||||||
|
res = zts_socket(i32,i32,i32);
|
||||||
|
assert(("pre-init call to zts_socket(): res != ZTS_ERR_SERVICE",
|
||||||
|
res == ZTS_ERR_SERVICE));
|
||||||
|
res = zts_connect(i32, (const struct zts_sockaddr *)nullable, i32);
|
||||||
|
assert(("pre-init call to zts_connect(): res != ZTS_ERR_SERVICE",
|
||||||
|
res == ZTS_ERR_SERVICE));
|
||||||
|
res = zts_bind(i32, (const struct zts_sockaddr *)nullable, i32);
|
||||||
|
assert(("pre-init call to zts_bind(): res != ZTS_ERR_SERVICE",
|
||||||
|
res == ZTS_ERR_SERVICE));
|
||||||
|
res = zts_listen(i32, i32);
|
||||||
|
assert(("pre-init call to zts_listen(): res != ZTS_ERR_SERVICE",
|
||||||
|
res == ZTS_ERR_SERVICE));
|
||||||
|
res = zts_accept(i32, (struct zts_sockaddr *)nullable, (zts_socklen_t *)nullable);
|
||||||
|
assert(("pre-init call to zts_accept(): res != ZTS_ERR_SERVICE",
|
||||||
|
res == ZTS_ERR_SERVICE));
|
||||||
|
res = zts_setsockopt(i32, i32, i32, nullable, i32);
|
||||||
|
assert(("pre-init call to zts_setsockopt(): res != ZTS_ERR_SERVICE",
|
||||||
|
res == ZTS_ERR_SERVICE));
|
||||||
|
res = zts_getsockopt(i32, i32, i32, nullable, (zts_socklen_t *)nullable);
|
||||||
|
assert(("pre-init call to zts_getsockopt(): res != ZTS_ERR_SERVICE",
|
||||||
|
res == ZTS_ERR_SERVICE));
|
||||||
|
res = zts_getsockname(i32, (struct zts_sockaddr *)nullable, (zts_socklen_t *)nullable);
|
||||||
|
assert(("pre-init call to zts_getsockname(): res != ZTS_ERR_SERVICE",
|
||||||
|
res == ZTS_ERR_SERVICE));
|
||||||
|
res = zts_getpeername(i32, (struct zts_sockaddr *)nullable, (zts_socklen_t *)nullable);
|
||||||
|
assert(("pre-init call to zts_getpeername(): res != ZTS_ERR_SERVICE",
|
||||||
|
res == ZTS_ERR_SERVICE));
|
||||||
|
res = zts_close(i32);
|
||||||
|
assert(("pre-init call to zts_close(): res != ZTS_ERR_SERVICE",
|
||||||
|
res == ZTS_ERR_SERVICE));
|
||||||
|
res = zts_select(i32, (zts_fd_set *)nullable, (zts_fd_set *)nullable, (zts_fd_set *)nullable, (struct zts_timeval *)nullable);
|
||||||
|
assert(("pre-init call to zts_select(): res != ZTS_ERR_SERVICE",
|
||||||
|
res == ZTS_ERR_SERVICE));
|
||||||
|
res = zts_fcntl(i32, i32, i32);
|
||||||
|
assert(("pre-init call to zts_fcntl(): res != ZTS_ERR_SERVICE",
|
||||||
|
res == ZTS_ERR_SERVICE));
|
||||||
|
res = zts_poll((struct zts_pollfd *)nullable, i32, i32);
|
||||||
|
assert(("pre-init call to zts_poll(): res != ZTS_ERR_SERVICE",
|
||||||
|
res == ZTS_ERR_SERVICE));
|
||||||
|
res = zts_ioctl(i32, i64, nullable);
|
||||||
|
assert(("pre-init call to zts_ioctl(): res != ZTS_ERR_SERVICE",
|
||||||
|
res == ZTS_ERR_SERVICE));
|
||||||
|
res = zts_send(i32, nullable, i32, i32);
|
||||||
|
assert(("pre-init call to zts_send(): res != ZTS_ERR_SERVICE",
|
||||||
|
res == ZTS_ERR_SERVICE));
|
||||||
|
res = zts_sendto(i32, nullable, i32, i32, (const struct zts_sockaddr *)nullable, i32);
|
||||||
|
assert(("pre-init call to zts_sendto(): res != ZTS_ERR_SERVICE",
|
||||||
|
res == ZTS_ERR_SERVICE));
|
||||||
|
res = zts_sendmsg(i32, (const struct zts_msghdr *)nullable, i32);
|
||||||
|
assert(("pre-init call to zts_sendmsg(): res != ZTS_ERR_SERVICE",
|
||||||
|
res == ZTS_ERR_SERVICE));
|
||||||
|
res = zts_recv(i32, nullable, i32, i32);
|
||||||
|
assert(("pre-init call to zts_recv(): res != ZTS_ERR_SERVICE",
|
||||||
|
res == ZTS_ERR_SERVICE));
|
||||||
|
res = zts_recvfrom(i32, nullable, i32, i32, (struct zts_sockaddr *)nullable, (zts_socklen_t *)nullable);
|
||||||
|
assert(("pre-init call to zts_recvfrom(): res != ZTS_ERR_SERVICE",
|
||||||
|
res == ZTS_ERR_SERVICE));
|
||||||
|
res = zts_recvmsg(i32, (struct zts_msghdr *)nullable, i32);
|
||||||
|
assert(("pre-init call to zts_recvmsg(): res != ZTS_ERR_SERVICE",
|
||||||
|
res == ZTS_ERR_SERVICE));
|
||||||
|
res = zts_read(i32, nullable, i32);
|
||||||
|
assert(("pre-init call to zts_read(): res != ZTS_ERR_SERVICE",
|
||||||
|
res == ZTS_ERR_SERVICE));
|
||||||
|
res = zts_readv(i32, (const struct zts_iovec *)nullable, i32);
|
||||||
|
assert(("pre-init call to zts_readv(): res != ZTS_ERR_SERVICE",
|
||||||
|
res == ZTS_ERR_SERVICE));
|
||||||
|
res = zts_write(i32, nullable, i32);
|
||||||
|
assert(("pre-init call to zts_write(): res != ZTS_ERR_SERVICE",
|
||||||
|
res == ZTS_ERR_SERVICE));
|
||||||
|
res = zts_writev(i32, (const struct zts_iovec *)nullable, i32);
|
||||||
|
assert(("pre-init call to zts_writev(): res != ZTS_ERR_SERVICE",
|
||||||
|
res == ZTS_ERR_SERVICE));
|
||||||
|
res = zts_shutdown(i32, i32);
|
||||||
|
assert(("pre-init call to zts_shutdown(): res != ZTS_ERR_SERVICE",
|
||||||
|
res == ZTS_ERR_SERVICE));
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_pre_service()
|
||||||
|
{
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------//
|
||||||
|
// Test service-related API functions before initializing service //
|
||||||
|
//----------------------------------------------------------------------------//
|
||||||
|
|
||||||
|
// Test null values
|
||||||
|
api_value_arg_test(0,0,0,0,NULL);
|
||||||
|
|
||||||
|
// Test wild values
|
||||||
|
for (int i=0; i<4096; i++) {
|
||||||
|
int8_t i8 = (uint8_t)random64();
|
||||||
|
int16_t i16 = (uint16_t)random64();
|
||||||
|
int32_t i32 = (uint32_t)random64();
|
||||||
|
int64_t i64 = (uint64_t)random64();
|
||||||
|
int x;
|
||||||
|
void* nullable = &x;
|
||||||
|
api_value_arg_test(i8,i16,i32,i64,nullable);
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------//
|
||||||
|
// Test non-service helper functions //
|
||||||
|
//----------------------------------------------------------------------------//
|
||||||
|
|
||||||
|
// (B) Test zts_inet_ntop
|
||||||
|
|
||||||
|
char ipstr[ZTS_INET6_ADDRSTRLEN];
|
||||||
|
int16_t port = 0;
|
||||||
|
struct zts_sockaddr_in in4;
|
||||||
|
|
||||||
|
in4.sin_port = htons(8080);
|
||||||
|
#if defined(_WIN32)
|
||||||
|
zts_inet_pton(ZTS_AF_INET, "192.168.22.1", &(in4.sin_addr.S_addr));
|
||||||
|
#else
|
||||||
|
zts_inet_pton(ZTS_AF_INET, "192.168.22.1", &(in4.sin_addr.s_addr));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
in4.sin_family = ZTS_AF_INET;
|
||||||
|
|
||||||
|
struct zts_sockaddr *sa = (struct zts_sockaddr *)&in4;
|
||||||
|
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 = ntohs(in4->sin_port);
|
||||||
|
}
|
||||||
|
if (sa->sa_family == ZTS_AF_INET6) {
|
||||||
|
struct zts_sockaddr_in6 *in6 = (struct zts_sockaddr_in6*)sa;
|
||||||
|
zts_inet_ntop(ZTS_AF_INET6, &(in6->sin6_addr),
|
||||||
|
ipstr, ZTS_INET6_ADDRSTRLEN);
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(("zts_inet_ntop(): port != 8080", port == 8080));
|
||||||
|
assert(("zts_inet_ntop(): strcmp(ipstr, \"192.168.22.1\") != 0",
|
||||||
|
!strcmp(ipstr, "192.168.22.1")));
|
||||||
|
|
||||||
|
// (C) Test zts_inet_pton
|
||||||
|
|
||||||
|
uint8_t buf[sizeof(struct zts_in6_addr)];
|
||||||
|
char str[ZTS_INET6_ADDRSTRLEN];
|
||||||
|
|
||||||
|
zts_inet_pton(ZTS_AF_INET, "192.168.22.2", buf);
|
||||||
|
zts_inet_ntop(ZTS_AF_INET, buf, str, ZTS_INET6_ADDRSTRLEN);
|
||||||
|
assert(("zts_inet_pton(): strcmp(ipstr, \"192.168.22.2\") != 0",
|
||||||
|
!strcmp(str, "192.168.22.2")));
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_service()
|
||||||
|
{
|
||||||
|
int res = ZTS_ERR_OK;
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------//
|
||||||
|
// Test simplified API, proxy for setsockopt/getsockopt/ioctl etc //
|
||||||
|
//----------------------------------------------------------------------------//
|
||||||
|
|
||||||
|
int s4 = zts_socket(ZTS_AF_INET6, ZTS_SOCK_STREAM, 0);
|
||||||
|
assert(s4 >= 0);
|
||||||
|
|
||||||
|
// TCP_NODELAY
|
||||||
|
|
||||||
|
// Check value before doing anything
|
||||||
|
res = zts_get_no_delay(s4);
|
||||||
|
assert(res == 0);
|
||||||
|
// Turn on
|
||||||
|
res = zts_set_no_delay(s4, 1);
|
||||||
|
assert(res == ZTS_ERR_OK);
|
||||||
|
res = zts_get_no_delay(s4);
|
||||||
|
// Should return value instead of error code
|
||||||
|
assert(res == 1);
|
||||||
|
// Turn off
|
||||||
|
res = zts_set_no_delay(s4, 0);
|
||||||
|
assert(res == ZTS_ERR_OK);
|
||||||
|
res = zts_get_no_delay(s4);
|
||||||
|
assert(res == ZTS_ERR_OK);
|
||||||
|
assert(res == 0);
|
||||||
|
|
||||||
|
// SO_LINGER
|
||||||
|
|
||||||
|
// Check value before doing anything
|
||||||
|
res = zts_get_linger_enabled(s4);
|
||||||
|
assert(res == 0);
|
||||||
|
res = zts_get_linger_value(s4);
|
||||||
|
assert(res == 0);
|
||||||
|
// Turn on, set to 7 seconds
|
||||||
|
res = zts_set_linger(s4, 1, 7);
|
||||||
|
res = zts_get_linger_enabled(s4);
|
||||||
|
assert(res == 1);
|
||||||
|
res = zts_get_linger_value(s4);
|
||||||
|
assert(res == 7);
|
||||||
|
res = zts_set_linger(s4, 0, 0);
|
||||||
|
// Turn off
|
||||||
|
res = zts_get_linger_enabled(s4);
|
||||||
|
assert(res == 0);
|
||||||
|
res = zts_get_linger_value(s4);
|
||||||
|
assert(res == 0);
|
||||||
|
|
||||||
|
// SO_REUSEADDR
|
||||||
|
|
||||||
|
// Check value before doing anything
|
||||||
|
res = zts_get_reuse_addr(s4);
|
||||||
|
assert(res == 0);
|
||||||
|
// Turn on
|
||||||
|
res = zts_set_reuse_addr(s4, 1);
|
||||||
|
assert(res == ZTS_ERR_OK);
|
||||||
|
res = zts_get_reuse_addr(s4);
|
||||||
|
// Should return value instead of error code
|
||||||
|
assert(res == 1);
|
||||||
|
// Turn off
|
||||||
|
res = zts_set_reuse_addr(s4, 0);
|
||||||
|
assert(res == ZTS_ERR_OK);
|
||||||
|
res = zts_get_reuse_addr(s4);
|
||||||
|
assert(res == ZTS_ERR_OK);
|
||||||
|
assert(res == 0);
|
||||||
|
|
||||||
|
// SO_RCVTIMEO
|
||||||
|
|
||||||
|
// Check value before doing anything
|
||||||
|
res = zts_get_recv_timeout(s4);
|
||||||
|
assert(res == 0);
|
||||||
|
// Set to value
|
||||||
|
res = zts_set_recv_timeout(s4, 3, 0);
|
||||||
|
res = zts_get_recv_timeout(s4);
|
||||||
|
assert(res == 3);
|
||||||
|
res = zts_set_recv_timeout(s4, 0, 0);
|
||||||
|
// Set to zero
|
||||||
|
res = zts_get_recv_timeout(s4);
|
||||||
|
assert(res == 0);
|
||||||
|
|
||||||
|
// SO_SNDTIMEO
|
||||||
|
|
||||||
|
// Check value before doing anything
|
||||||
|
res = zts_get_send_timeout(s4);
|
||||||
|
assert(res == 0);
|
||||||
|
// Set to value
|
||||||
|
res = zts_set_send_timeout(s4, 4, 0);
|
||||||
|
res = zts_get_send_timeout(s4);
|
||||||
|
assert(res == 4);
|
||||||
|
res = zts_set_send_timeout(s4, 0, 0);
|
||||||
|
// Set to zero
|
||||||
|
res = zts_get_send_timeout(s4);
|
||||||
|
assert(res == 0);
|
||||||
|
|
||||||
|
// SO_SNDBUF
|
||||||
|
|
||||||
|
// Check value before doing anything
|
||||||
|
res = zts_get_send_buf_size(s4);
|
||||||
|
assert(res == -1); // Unimplemented as of writing of test
|
||||||
|
// Set to 7 seconds
|
||||||
|
res = zts_set_send_buf_size(s4, 1024);
|
||||||
|
res = zts_get_send_buf_size(s4);
|
||||||
|
assert(res == -1); // Unimplemented as of writing of test
|
||||||
|
res = zts_set_send_buf_size(s4, 0);
|
||||||
|
// Set to zero
|
||||||
|
res = zts_get_send_buf_size(s4);
|
||||||
|
assert(res == -1); // Unimplemented as of writing of test
|
||||||
|
|
||||||
|
// SO_RCVBUF
|
||||||
|
|
||||||
|
// Check value before doing anything
|
||||||
|
res = zts_get_recv_buf_size(s4);
|
||||||
|
assert(res > 0);
|
||||||
|
// Set to value
|
||||||
|
res = zts_set_recv_buf_size(s4, 1024);
|
||||||
|
res = zts_get_recv_buf_size(s4);
|
||||||
|
assert(res == 1024);
|
||||||
|
res = zts_set_recv_buf_size(s4, 0);
|
||||||
|
// Set to zero
|
||||||
|
res = zts_get_recv_buf_size(s4);
|
||||||
|
assert(res == 0);
|
||||||
|
|
||||||
|
// IP_TTL
|
||||||
|
|
||||||
|
// Check value before doing anything
|
||||||
|
res = zts_get_ttl(s4);
|
||||||
|
assert(res == 255); // Defaults to max
|
||||||
|
// Set to value
|
||||||
|
res = zts_set_ttl(s4, 128);
|
||||||
|
res = zts_get_ttl(s4);
|
||||||
|
assert(res == 128);
|
||||||
|
res = zts_set_ttl(s4, 0);
|
||||||
|
// Set to zero
|
||||||
|
res = zts_get_ttl(s4);
|
||||||
|
assert(res == 0);
|
||||||
|
|
||||||
|
// O_NONBLOCK
|
||||||
|
|
||||||
|
// Check value before doing anything
|
||||||
|
res = zts_get_blocking(s4);
|
||||||
|
assert(res == 1);
|
||||||
|
// Turn off (non-blocking)
|
||||||
|
res = zts_set_blocking(s4, 0);
|
||||||
|
assert(res == ZTS_ERR_OK);
|
||||||
|
res = zts_get_blocking(s4);
|
||||||
|
// Should return value instead of error code
|
||||||
|
assert(res == 0);
|
||||||
|
// Turn off
|
||||||
|
res = zts_set_blocking(s4, 1);
|
||||||
|
assert(res == ZTS_ERR_OK);
|
||||||
|
res = zts_get_blocking(s4);
|
||||||
|
assert(res == 1);
|
||||||
|
|
||||||
|
// SO_KEEPALIVE
|
||||||
|
|
||||||
|
// Check value before doing anything
|
||||||
|
res = zts_get_keepalive(s4);
|
||||||
|
assert(res == 0);
|
||||||
|
// Turn on
|
||||||
|
res = zts_set_keepalive(s4, 1);
|
||||||
|
assert(res == ZTS_ERR_OK);
|
||||||
|
res = zts_get_keepalive(s4);
|
||||||
|
// Should return value instead of error code
|
||||||
|
assert(res == 1);
|
||||||
|
// Turn off
|
||||||
|
res = zts_set_keepalive(s4, 0);
|
||||||
|
assert(res == ZTS_ERR_OK);
|
||||||
|
res = zts_get_keepalive(s4);
|
||||||
|
assert(res == ZTS_ERR_OK);
|
||||||
|
assert(res == 0);
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------//
|
||||||
|
// Test *_easy API //
|
||||||
|
//----------------------------------------------------------------------------//
|
||||||
|
|
||||||
|
//zts_connect_easy(0, ZTS_AF_INET, "192.168.7.9", 7878);
|
||||||
|
//zts_connect_easy(0, ZTS_AF_INET6, "FCC5:205E:4FF5:5311:DFF0::1", 7878);
|
||||||
|
//res = zts_bind_easy(0, ZTS_AF_INET6, "::", 8080);
|
||||||
|
//fprintf(stderr, "res=%d, zts_errno=%d\n", res, zts_errno);
|
||||||
|
//zts_delay_ms(60000);
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------//
|
||||||
|
// Test DNS client functionality //
|
||||||
|
//----------------------------------------------------------------------------//
|
||||||
|
|
||||||
|
/*
|
||||||
|
// Set first nameserver
|
||||||
|
|
||||||
|
char *ns1_addr_str = "FCC5:205E:4FF5:5311:DFF0::1";
|
||||||
|
zts_ip_addr ns1;
|
||||||
|
zts_ipaddr_aton(ns1_addr_str, &ns1);
|
||||||
|
zts_dns_set_server(0, &ns1);
|
||||||
|
|
||||||
|
// Get first nameserver
|
||||||
|
|
||||||
|
const zts_ip_addr *ns1_result;
|
||||||
|
ns1_result = zts_dns_get_server(0);
|
||||||
|
printf("dns1 = %s\n", zts_ipaddr_ntoa(ns1_result));
|
||||||
|
|
||||||
|
// Set second nameserver
|
||||||
|
|
||||||
|
char *ns2_addr_str = "192.168.22.1";
|
||||||
|
zts_ip_addr ns2;
|
||||||
|
zts_ipaddr_aton(ns2_addr_str, &ns2);
|
||||||
|
zts_dns_set_server(1, &ns2);
|
||||||
|
|
||||||
|
// Get second nameserver
|
||||||
|
|
||||||
|
const zts_ip_addr *ns2_result;
|
||||||
|
ns2_result = zts_dns_get_server(1);
|
||||||
|
printf("dns1 = %s\n", zts_ipaddr_ntoa(ns2_result));
|
||||||
|
|
||||||
|
// Check that each nameserver address was properly set and get
|
||||||
|
|
||||||
|
assert(("zts_dns_get_server(): Address mismatch", !strcmp(ns1_addr_str, zts_ipaddr_ntoa(ns1_result))));
|
||||||
|
assert(("zts_dns_get_server(): Address mismatch", !strcmp(ns2_addr_str, zts_ipaddr_ntoa(ns2_result))));
|
||||||
|
*/
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------//
|
||||||
|
// Test shutting down the service //
|
||||||
|
//----------------------------------------------------------------------------//
|
||||||
|
|
||||||
|
zts_stop();
|
||||||
|
s4 = zts_socket(ZTS_AF_INET, ZTS_SOCK_STREAM, 0);
|
||||||
|
assert(("s4 != ZTS_ERR_SERVICE, not shut down", s4 == ZTS_ERR_SERVICE));
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------//
|
||||||
|
// Server //
|
||||||
|
//----------------------------------------------------------------------------//
|
||||||
|
|
||||||
|
#define MAX_CONNECT_TIME 60
|
||||||
|
#define BUFLEN 128
|
||||||
|
char *msg = "welcome to the machine";
|
||||||
|
|
||||||
|
void start_server_app(uint16_t port4, uint16_t port6)
|
||||||
|
{
|
||||||
|
int err = ZTS_ERR_OK;
|
||||||
|
int bytes_read = 0;
|
||||||
|
int bytes_sent = 0;
|
||||||
|
|
||||||
|
int msglen = strlen(msg);
|
||||||
|
char dstbuf[BUFLEN];
|
||||||
|
int buflen = BUFLEN;
|
||||||
|
|
||||||
|
struct timespec start, now;
|
||||||
|
int time_diff = 0;
|
||||||
|
|
||||||
|
//
|
||||||
|
// IPv4 test
|
||||||
|
//
|
||||||
|
|
||||||
|
fprintf(stderr, "server4: will listen on: 0.0.0.0:%d\n", port4);
|
||||||
|
int s4 = zts_socket(ZTS_AF_INET, ZTS_SOCK_STREAM, 0);
|
||||||
|
assert(s4 == 0 && zts_errno == 0);
|
||||||
|
|
||||||
|
err = zts_bind_easy(s4, ZTS_AF_INET, "0.0.0.0", port4);
|
||||||
|
assert(err == ZTS_ERR_OK && zts_errno == 0);
|
||||||
|
|
||||||
|
err = zts_listen(s4, 1);
|
||||||
|
assert(err == ZTS_ERR_OK && zts_errno == 0);
|
||||||
|
|
||||||
|
struct zts_sockaddr_in in4;
|
||||||
|
zts_socklen_t addrlen4 = sizeof(in4);
|
||||||
|
|
||||||
|
int acc4 = -1;
|
||||||
|
clock_gettime(CLOCK_MONOTONIC, &start);
|
||||||
|
do {
|
||||||
|
fprintf(stderr, "server4: accepting...\n");
|
||||||
|
acc4 = zts_accept(s4, &in4, &addrlen4);
|
||||||
|
zts_delay_ms(250);
|
||||||
|
clock_gettime(CLOCK_MONOTONIC, &now);
|
||||||
|
time_diff = (now.tv_sec - start.tv_sec);
|
||||||
|
} while (err < 0 && time_diff < MAX_CONNECT_TIME);
|
||||||
|
|
||||||
|
assert(acc4 == 1 && zts_errno == 0);
|
||||||
|
|
||||||
|
// Read message
|
||||||
|
memset(dstbuf, 0, buflen);
|
||||||
|
bytes_read = zts_read(acc4, dstbuf, buflen);
|
||||||
|
fprintf(stderr, "server4: read (%d) bytes\n", bytes_read);
|
||||||
|
assert(bytes_read == msglen && zts_errno == 0);
|
||||||
|
|
||||||
|
// Send message
|
||||||
|
bytes_sent = zts_write(acc4, msg, msglen);
|
||||||
|
fprintf(stderr, "server4: wrote (%d) bytes\n", bytes_sent);
|
||||||
|
assert(bytes_sent == msglen && zts_errno == 0);
|
||||||
|
|
||||||
|
zts_close(s4);
|
||||||
|
assert(err == ZTS_ERR_OK && zts_errno == 0);
|
||||||
|
|
||||||
|
zts_close(acc4);
|
||||||
|
assert(err == ZTS_ERR_OK && zts_errno == 0);
|
||||||
|
|
||||||
|
//
|
||||||
|
// IPv6 test
|
||||||
|
//
|
||||||
|
|
||||||
|
fprintf(stderr, "server: will listen on: [::]:%d\n", port6);
|
||||||
|
int s6 = zts_socket(ZTS_AF_INET6, ZTS_SOCK_STREAM, 0);
|
||||||
|
assert(s6 == 0 && zts_errno == 0);
|
||||||
|
|
||||||
|
err = zts_bind_easy(s6, ZTS_AF_INET6, "::", port6);
|
||||||
|
assert(err == ZTS_ERR_OK && zts_errno == 0);
|
||||||
|
|
||||||
|
err = zts_listen(s6, 1);
|
||||||
|
assert(err == ZTS_ERR_OK && zts_errno == 0);
|
||||||
|
|
||||||
|
struct zts_sockaddr_in6 in6;
|
||||||
|
zts_socklen_t addrlen6 = sizeof(in6);
|
||||||
|
|
||||||
|
int acc6 = -1;
|
||||||
|
clock_gettime(CLOCK_MONOTONIC, &start);
|
||||||
|
do {
|
||||||
|
fprintf(stderr, "server6: accepting...\n");
|
||||||
|
acc6 = zts_accept(s6, &in6, &addrlen6);
|
||||||
|
zts_delay_ms(250);
|
||||||
|
clock_gettime(CLOCK_MONOTONIC, &now);
|
||||||
|
time_diff = (now.tv_sec - start.tv_sec);
|
||||||
|
} while (err < 0 && time_diff < MAX_CONNECT_TIME);
|
||||||
|
|
||||||
|
fprintf(stderr, "server6: accepted connection (fd=%d)\n", acc6);
|
||||||
|
assert(acc6 == 1 && zts_errno == 0);
|
||||||
|
|
||||||
|
// Read message
|
||||||
|
memset(dstbuf, 0, buflen);
|
||||||
|
bytes_read = zts_read(acc6, dstbuf, buflen);
|
||||||
|
fprintf(stderr, "server6: read (%d) bytes\n", bytes_read);
|
||||||
|
assert(bytes_read == msglen && zts_errno == 0);
|
||||||
|
|
||||||
|
// Send message
|
||||||
|
bytes_sent = zts_write(acc6, msg, msglen);
|
||||||
|
fprintf(stderr, "server6: wrote (%d) bytes\n", bytes_sent);
|
||||||
|
assert(bytes_sent == msglen && zts_errno == 0);
|
||||||
|
|
||||||
|
zts_close(s6);
|
||||||
|
assert(err == ZTS_ERR_OK && zts_errno == 0);
|
||||||
|
|
||||||
|
zts_close(acc6);
|
||||||
|
assert(err == ZTS_ERR_OK && zts_errno == 0);
|
||||||
|
|
||||||
|
zts_stop();
|
||||||
|
assert(err == ZTS_ERR_OK && zts_errno == 0);
|
||||||
|
int s = zts_socket(ZTS_AF_INET, ZTS_SOCK_STREAM, 0);
|
||||||
|
assert(("s != ZTS_ERR_SERVICE, not shut down", s == ZTS_ERR_SERVICE));
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------//
|
||||||
|
// Client //
|
||||||
|
//----------------------------------------------------------------------------//
|
||||||
|
|
||||||
|
void start_client_app(char *ip4, uint16_t port4, char *ip6, uint16_t port6)
|
||||||
|
{
|
||||||
|
int err = ZTS_ERR_OK;
|
||||||
|
int bytes_read = 0;
|
||||||
|
int bytes_sent = 0;
|
||||||
|
|
||||||
|
int msglen = strlen(msg);
|
||||||
|
char dstbuf[BUFLEN];
|
||||||
|
int buflen = BUFLEN;
|
||||||
|
|
||||||
|
struct timespec start, now;
|
||||||
|
int time_diff = 0;
|
||||||
|
|
||||||
|
//
|
||||||
|
// IPv4 test
|
||||||
|
//
|
||||||
|
|
||||||
|
err = ZTS_ERR_OK;
|
||||||
|
int s4 = zts_socket(ZTS_AF_INET, ZTS_SOCK_STREAM, 0);
|
||||||
|
assert(err == ZTS_ERR_OK && zts_errno == 0);
|
||||||
|
|
||||||
|
zts_set_blocking(s4, 1);
|
||||||
|
assert(err == ZTS_ERR_OK && zts_errno == 0);
|
||||||
|
|
||||||
|
clock_gettime(CLOCK_MONOTONIC, &start);
|
||||||
|
do {
|
||||||
|
fprintf(stderr, "client4: connecting to: %s:%d\n", ip4, port4);
|
||||||
|
err = zts_connect_easy(s4, ZTS_AF_INET, ip4, port4);
|
||||||
|
zts_delay_ms(500);
|
||||||
|
clock_gettime(CLOCK_MONOTONIC, &now);
|
||||||
|
time_diff = (now.tv_sec - start.tv_sec);
|
||||||
|
} while (err < 0 && time_diff < MAX_CONNECT_TIME);
|
||||||
|
assert(err == ZTS_ERR_OK && zts_errno == 0);
|
||||||
|
|
||||||
|
fprintf(stderr, "client4: connected\n");
|
||||||
|
// Send message
|
||||||
|
bytes_sent = zts_write(s4, msg, msglen);
|
||||||
|
fprintf(stderr, "client4: wrote (%d) bytes\n", bytes_sent);
|
||||||
|
assert(bytes_sent == msglen && zts_errno == 0);
|
||||||
|
|
||||||
|
// Read message
|
||||||
|
memset(dstbuf, 0, buflen);
|
||||||
|
bytes_read = zts_read(s4, dstbuf, buflen);
|
||||||
|
assert(bytes_read == msglen && zts_errno == 0);
|
||||||
|
|
||||||
|
fprintf(stderr, "client4: read (%d) bytes\n", bytes_read);
|
||||||
|
assert(bytes_sent == bytes_read && zts_errno == 0);
|
||||||
|
|
||||||
|
zts_close(s4);
|
||||||
|
assert(err == ZTS_ERR_OK && zts_errno == 0);
|
||||||
|
|
||||||
|
//
|
||||||
|
// IPv6 test
|
||||||
|
//
|
||||||
|
|
||||||
|
err = ZTS_ERR_OK;
|
||||||
|
int s6 = zts_socket(ZTS_AF_INET6, ZTS_SOCK_STREAM, 0);
|
||||||
|
assert(err == ZTS_ERR_OK && zts_errno == 0);
|
||||||
|
|
||||||
|
zts_set_blocking(s6, 1);
|
||||||
|
assert(err == ZTS_ERR_OK && zts_errno == 0);
|
||||||
|
|
||||||
|
clock_gettime(CLOCK_MONOTONIC, &start);
|
||||||
|
do {
|
||||||
|
fprintf(stderr, "client6: connecting to: %s:%d\n", ip6, port6);
|
||||||
|
err = zts_connect_easy(s6, ZTS_AF_INET6, ip6, port6);
|
||||||
|
zts_delay_ms(500);
|
||||||
|
clock_gettime(CLOCK_MONOTONIC, &now);
|
||||||
|
time_diff = (now.tv_sec - start.tv_sec);
|
||||||
|
} while (err < 0 && time_diff < MAX_CONNECT_TIME);
|
||||||
|
assert(err == ZTS_ERR_OK && zts_errno == 0);
|
||||||
|
|
||||||
|
fprintf(stderr, "client6: connected\n");
|
||||||
|
// Send message
|
||||||
|
bytes_sent = zts_write(s6, msg, msglen);
|
||||||
|
fprintf(stderr, "client6: wrote (%d) bytes\n", bytes_sent);
|
||||||
|
assert(bytes_sent == msglen && zts_errno == 0);
|
||||||
|
|
||||||
|
// Read message
|
||||||
|
memset(dstbuf, 0, buflen);
|
||||||
|
bytes_read = zts_read(s6, dstbuf, buflen);
|
||||||
|
assert(bytes_read == msglen && zts_errno == 0);
|
||||||
|
|
||||||
|
fprintf(stderr, "client6: read (%d) bytes\n", bytes_read);
|
||||||
|
assert(bytes_sent == bytes_read && zts_errno == 0);
|
||||||
|
|
||||||
|
zts_close(s6);
|
||||||
|
assert(err == ZTS_ERR_OK && zts_errno == 0);
|
||||||
|
|
||||||
|
zts_stop();
|
||||||
|
assert(err == ZTS_ERR_OK && zts_errno == 0);
|
||||||
|
int s = zts_socket(ZTS_AF_INET, ZTS_SOCK_STREAM, 0);
|
||||||
|
assert(("s != ZTS_ERR_SERVICE, not shut down", s == ZTS_ERR_SERVICE));
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------//
|
||||||
|
// Start node //
|
||||||
|
//----------------------------------------------------------------------------//
|
||||||
|
|
||||||
|
void start_node(char *path, uint64_t nwid)
|
||||||
|
{
|
||||||
|
struct timespec start, now;
|
||||||
|
int time_diff = 0;
|
||||||
|
|
||||||
|
fprintf(stderr, "starting node...\n");
|
||||||
|
clock_gettime(CLOCK_MONOTONIC, &start);
|
||||||
|
int res = zts_start(path, &on_zts_event, 0);
|
||||||
|
assert(("error starting service: res != ZTS_ERR_OK", res == ZTS_ERR_OK));
|
||||||
|
do {
|
||||||
|
zts_delay_ms(25);
|
||||||
|
clock_gettime(CLOCK_MONOTONIC, &now);
|
||||||
|
time_diff = (now.tv_sec - start.tv_sec);
|
||||||
|
} while (!is_online && (time_diff < MAX_CONNECT_TIME));
|
||||||
|
if (!is_online) {
|
||||||
|
fprintf(stderr, "node failed to come online\n");
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
fprintf(stderr, "joining: %llx\n", nwid);
|
||||||
|
clock_gettime(CLOCK_MONOTONIC, &start);
|
||||||
|
if (nwid) {
|
||||||
|
zts_join(nwid);
|
||||||
|
do {
|
||||||
|
zts_delay_ms(25);
|
||||||
|
clock_gettime(CLOCK_MONOTONIC, &now);
|
||||||
|
time_diff = (now.tv_sec - start.tv_sec);
|
||||||
|
} while ((!has_ip4 || !has_ip6) && (time_diff < MAX_CONNECT_TIME));
|
||||||
|
if (!has_ip4 || !has_ip6) {
|
||||||
|
fprintf(stderr, "node failed to receive assigned addresses\n");
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------//
|
||||||
|
// Main //
|
||||||
|
//----------------------------------------------------------------------------//
|
||||||
|
|
||||||
|
int main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
if (argc != 1 && argc != 5 && argc != 7) {
|
||||||
|
fprintf(stderr, "Invalid number of arguments.\n");
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// API fuzz test
|
||||||
|
//
|
||||||
|
|
||||||
|
test_pre_service();
|
||||||
|
|
||||||
|
//
|
||||||
|
// Default test
|
||||||
|
//
|
||||||
|
|
||||||
|
// selftest
|
||||||
|
if (argc == 1) {
|
||||||
|
srand(time(NULL));
|
||||||
|
// Store identities in cwd, join 0x0
|
||||||
|
start_node(".",0x0);
|
||||||
|
test_service();
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Default test (single node)
|
||||||
|
// selftest <id-path>
|
||||||
|
/*
|
||||||
|
if (argc == 2) {
|
||||||
|
srand(time(NULL));
|
||||||
|
start_node(argv[1],0x0);
|
||||||
|
test_service();
|
||||||
|
exit(0);
|
||||||
|
}*/
|
||||||
|
|
||||||
|
//
|
||||||
|
// Client/Server communication test
|
||||||
|
//
|
||||||
|
|
||||||
|
// Server test
|
||||||
|
if (argc == 5) {
|
||||||
|
//fprintf(stderr, "server.path = %s\n", argv[1]);
|
||||||
|
//fprintf(stderr, "server.nwid = %s\n", argv[2]);
|
||||||
|
//fprintf(stderr, "server.port4 = %s\n", argv[3]);
|
||||||
|
//fprintf(stderr, "server.port6 = %s\n", argv[4]);
|
||||||
|
uint64_t nwid = strtoull(argv[2],NULL,16);
|
||||||
|
int port4 = atoi(argv[3]);
|
||||||
|
int port6 = atoi(argv[4]);
|
||||||
|
start_node(argv[1],nwid);
|
||||||
|
start_server_app(port4, port6);
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
// Client test
|
||||||
|
if (argc == 7) {
|
||||||
|
//fprintf(stderr, "client.path = %s\n", argv[1]);
|
||||||
|
//fprintf(stderr, "client.nwid = %s\n", argv[2]);
|
||||||
|
//fprintf(stderr, "client.port4 = %s\n", argv[3]);
|
||||||
|
//fprintf(stderr, "client.ip4 = %s\n", argv[4]);
|
||||||
|
//fprintf(stderr, "client.port6 = %s\n", argv[5]);
|
||||||
|
//fprintf(stderr, "client.ip6 = %s\n", argv[6]);
|
||||||
|
uint64_t nwid = strtoull(argv[2],NULL,16);
|
||||||
|
int port4 = atoi(argv[3]);
|
||||||
|
int port6 = atoi(argv[5]);
|
||||||
|
start_node(argv[1],nwid);
|
||||||
|
start_client_app(argv[4], port4, argv[6], port6);
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
272
test/selftest.c
272
test/selftest.c
@@ -1,272 +0,0 @@
|
|||||||
/**
|
|
||||||
* Selftest. To be run for every commit.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <assert.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <time.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <limits.h>
|
|
||||||
#include <math.h>
|
|
||||||
|
|
||||||
#include <ZeroTierSockets.h>
|
|
||||||
|
|
||||||
#pragma GCC diagnostic ignored "-Wunused-value"
|
|
||||||
|
|
||||||
int random32() {
|
|
||||||
const int BITS_PER_RAND = (int)(log2(RAND_MAX/2 + 1) + 1.0);
|
|
||||||
int ret = 0;
|
|
||||||
for (int i = 0; i < sizeof(int) * CHAR_BIT; i += BITS_PER_RAND) {
|
|
||||||
ret <<= BITS_PER_RAND;
|
|
||||||
ret |= rand();
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint64_t random64() {
|
|
||||||
return ((uint64_t)random32() << 32) | random32();
|
|
||||||
}
|
|
||||||
|
|
||||||
void api_value_arg_test(int8_t i8, int16_t i16, int32_t i32, int64_t i64, void* nullable)
|
|
||||||
{
|
|
||||||
//fprintf(stderr, "%d, %d, %d, %lld, %p\n", i8, i16, i32, i64, nullable);
|
|
||||||
int res = ZTS_ERR_OK;
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
// Test uninitialized Network Stack API usage |
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
res = zts_get_all_stats((struct zts_stats *)nullable);
|
|
||||||
assert(("pre-init call to zts_get_all_stats(): res != ZTS_ERR_SERVICE",
|
|
||||||
res == ZTS_ERR_SERVICE));
|
|
||||||
res = zts_get_protocol_stats(i32, nullable);
|
|
||||||
assert(("pre-init call to zts_get_protocol_stats(): res != ZTS_ERR_SERVICE",
|
|
||||||
res == ZTS_ERR_SERVICE));
|
|
||||||
res = zts_dns_set_server(i8, (const zts_ip_addr *)nullable);
|
|
||||||
assert(("pre-init call to zts_add_dns_nameserver(): res != ZTS_ERR_SERVICE",
|
|
||||||
res == ZTS_ERR_SERVICE));
|
|
||||||
const zts_ip_addr *res_ptr = zts_dns_get_server(i8);
|
|
||||||
assert(("pre-init call to zts_del_dns_nameserver(): res != ZTS_ERR_SERVICE",
|
|
||||||
res == ZTS_ERR_SERVICE));
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
// Test uninitialized Node API usage |
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
res = zts_stop();
|
|
||||||
assert(("pre-init call to zts_stop(): res != ZTS_ERR_SERVICE",
|
|
||||||
res == ZTS_ERR_SERVICE));
|
|
||||||
res = zts_restart();
|
|
||||||
assert(("pre-init call to zts_restart(): res != ZTS_ERR_SERVICE",
|
|
||||||
res == ZTS_ERR_SERVICE));
|
|
||||||
res = zts_free();
|
|
||||||
assert(("pre-init call to zts_free(): res != ZTS_ERR_SERVICE",
|
|
||||||
res == ZTS_ERR_SERVICE));
|
|
||||||
res = zts_join(i64);
|
|
||||||
assert(("pre-init call to zts_join(): res != ZTS_ERR_SERVICE",
|
|
||||||
res == ZTS_ERR_SERVICE));
|
|
||||||
res = zts_leave(i64);
|
|
||||||
assert(("pre-init call to zts_leave(): res != ZTS_ERR_SERVICE",
|
|
||||||
res == ZTS_ERR_SERVICE));
|
|
||||||
res = zts_orbit(i64,i64);
|
|
||||||
assert(("pre-init call to zts_orbit(): res != ZTS_ERR_SERVICE",
|
|
||||||
res == ZTS_ERR_SERVICE));
|
|
||||||
res = zts_deorbit(i64);
|
|
||||||
assert(("pre-init call to zts_deorbit(): res != ZTS_ERR_SERVICE",
|
|
||||||
res == ZTS_ERR_SERVICE));
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
// Test uninitialized Socket API usage |
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
res = zts_socket(i32,i32,i32);
|
|
||||||
assert(("pre-init call to zts_socket(): res != ZTS_ERR_SERVICE",
|
|
||||||
res == ZTS_ERR_SERVICE));
|
|
||||||
res = zts_connect(i32, (const struct zts_sockaddr *)nullable, i32);
|
|
||||||
assert(("pre-init call to zts_connect(): res != ZTS_ERR_SERVICE",
|
|
||||||
res == ZTS_ERR_SERVICE));
|
|
||||||
res = zts_bind(i32, (const struct zts_sockaddr *)nullable, i32);
|
|
||||||
assert(("pre-init call to zts_bind(): res != ZTS_ERR_SERVICE",
|
|
||||||
res == ZTS_ERR_SERVICE));
|
|
||||||
res = zts_listen(i32, i32);
|
|
||||||
assert(("pre-init call to zts_listen(): res != ZTS_ERR_SERVICE",
|
|
||||||
res == ZTS_ERR_SERVICE));
|
|
||||||
res = zts_accept(i32, (struct zts_sockaddr *)nullable, (zts_socklen_t *)nullable);
|
|
||||||
assert(("pre-init call to zts_accept(): res != ZTS_ERR_SERVICE",
|
|
||||||
res == ZTS_ERR_SERVICE));
|
|
||||||
res = zts_setsockopt(i32, i32, i32, nullable, i32);
|
|
||||||
assert(("pre-init call to zts_setsockopt(): res != ZTS_ERR_SERVICE",
|
|
||||||
res == ZTS_ERR_SERVICE));
|
|
||||||
res = zts_getsockopt(i32, i32, i32, nullable, (zts_socklen_t *)nullable);
|
|
||||||
assert(("pre-init call to zts_getsockopt(): res != ZTS_ERR_SERVICE",
|
|
||||||
res == ZTS_ERR_SERVICE));
|
|
||||||
res = zts_getsockname(i32, (struct zts_sockaddr *)nullable, (zts_socklen_t *)nullable);
|
|
||||||
assert(("pre-init call to zts_getsockname(): res != ZTS_ERR_SERVICE",
|
|
||||||
res == ZTS_ERR_SERVICE));
|
|
||||||
res = zts_getpeername(i32, (struct zts_sockaddr *)nullable, (zts_socklen_t *)nullable);
|
|
||||||
assert(("pre-init call to zts_getpeername(): res != ZTS_ERR_SERVICE",
|
|
||||||
res == ZTS_ERR_SERVICE));
|
|
||||||
res = zts_close(i32);
|
|
||||||
assert(("pre-init call to zts_close(): res != ZTS_ERR_SERVICE",
|
|
||||||
res == ZTS_ERR_SERVICE));
|
|
||||||
res = zts_select(i32, (zts_fd_set *)nullable, (zts_fd_set *)nullable, (zts_fd_set *)nullable, (struct zts_timeval *)nullable);
|
|
||||||
assert(("pre-init call to zts_select(): res != ZTS_ERR_SERVICE",
|
|
||||||
res == ZTS_ERR_SERVICE));
|
|
||||||
res = zts_fcntl(i32, i32, i32);
|
|
||||||
assert(("pre-init call to zts_fcntl(): res != ZTS_ERR_SERVICE",
|
|
||||||
res == ZTS_ERR_SERVICE));
|
|
||||||
res = zts_poll((struct zts_pollfd *)nullable, i32, i32);
|
|
||||||
assert(("pre-init call to zts_poll(): res != ZTS_ERR_SERVICE",
|
|
||||||
res == ZTS_ERR_SERVICE));
|
|
||||||
res = zts_ioctl(i32, i64, nullable);
|
|
||||||
assert(("pre-init call to zts_ioctl(): res != ZTS_ERR_SERVICE",
|
|
||||||
res == ZTS_ERR_SERVICE));
|
|
||||||
res = zts_send(i32, nullable, i32, i32);
|
|
||||||
assert(("pre-init call to zts_send(): res != ZTS_ERR_SERVICE",
|
|
||||||
res == ZTS_ERR_SERVICE));
|
|
||||||
res = zts_sendto(i32, nullable, i32, i32, (const struct zts_sockaddr *)nullable, i32);
|
|
||||||
assert(("pre-init call to zts_sendto(): res != ZTS_ERR_SERVICE",
|
|
||||||
res == ZTS_ERR_SERVICE));
|
|
||||||
res = zts_sendmsg(i32, (const struct zts_msghdr *)nullable, i32);
|
|
||||||
assert(("pre-init call to zts_sendmsg(): res != ZTS_ERR_SERVICE",
|
|
||||||
res == ZTS_ERR_SERVICE));
|
|
||||||
res = zts_recv(i32, nullable, i32, i32);
|
|
||||||
assert(("pre-init call to zts_recv(): res != ZTS_ERR_SERVICE",
|
|
||||||
res == ZTS_ERR_SERVICE));
|
|
||||||
res = zts_recvfrom(i32, nullable, i32, i32, (struct zts_sockaddr *)nullable, (zts_socklen_t *)nullable);
|
|
||||||
assert(("pre-init call to zts_recvfrom(): res != ZTS_ERR_SERVICE",
|
|
||||||
res == ZTS_ERR_SERVICE));
|
|
||||||
res = zts_recvmsg(i32, (struct zts_msghdr *)nullable, i32);
|
|
||||||
assert(("pre-init call to zts_recvmsg(): res != ZTS_ERR_SERVICE",
|
|
||||||
res == ZTS_ERR_SERVICE));
|
|
||||||
res = zts_read(i32, nullable, i32);
|
|
||||||
assert(("pre-init call to zts_read(): res != ZTS_ERR_SERVICE",
|
|
||||||
res == ZTS_ERR_SERVICE));
|
|
||||||
res = zts_readv(i32, (const struct zts_iovec *)nullable, i32);
|
|
||||||
assert(("pre-init call to zts_readv(): res != ZTS_ERR_SERVICE",
|
|
||||||
res == ZTS_ERR_SERVICE));
|
|
||||||
res = zts_write(i32, nullable, i32);
|
|
||||||
assert(("pre-init call to zts_write(): res != ZTS_ERR_SERVICE",
|
|
||||||
res == ZTS_ERR_SERVICE));
|
|
||||||
res = zts_writev(i32, (const struct zts_iovec *)nullable, i32);
|
|
||||||
assert(("pre-init call to zts_writev(): res != ZTS_ERR_SERVICE",
|
|
||||||
res == ZTS_ERR_SERVICE));
|
|
||||||
res = zts_shutdown(i32, i32);
|
|
||||||
assert(("pre-init call to zts_shutdown(): res != ZTS_ERR_SERVICE",
|
|
||||||
res == ZTS_ERR_SERVICE));
|
|
||||||
}
|
|
||||||
|
|
||||||
int main()
|
|
||||||
{
|
|
||||||
srand(time(NULL));
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
// Test service-related API functions before initializing service |
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
// Test null values
|
|
||||||
api_value_arg_test(0,0,0,0,NULL);
|
|
||||||
|
|
||||||
// Test wild values
|
|
||||||
for (int i=0; i<1024; i++) {
|
|
||||||
int8_t i8 = (uint8_t)random64();
|
|
||||||
int16_t i16 = (uint16_t)random64();
|
|
||||||
int32_t i32 = (uint32_t)random64();
|
|
||||||
int64_t i64 = (uint64_t)random64();
|
|
||||||
int x;
|
|
||||||
void* nullable = &x;
|
|
||||||
api_value_arg_test(i8,i16,i32,i64,nullable);
|
|
||||||
}
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
// Test non-service helper functions |
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
// (B) Test zts_inet_ntop
|
|
||||||
|
|
||||||
char ipstr[ZTS_INET6_ADDRSTRLEN];
|
|
||||||
int16_t port = 0;
|
|
||||||
struct zts_sockaddr_in in4;
|
|
||||||
|
|
||||||
in4.sin_port = htons(8080);
|
|
||||||
#if defined(_WIN32)
|
|
||||||
zts_inet_pton(ZTS_AF_INET, "192.168.22.1", &(in4.sin_addr.S_addr));
|
|
||||||
#else
|
|
||||||
zts_inet_pton(ZTS_AF_INET, "192.168.22.1", &(in4.sin_addr.s_addr));
|
|
||||||
#endif
|
|
||||||
|
|
||||||
in4.sin_family = ZTS_AF_INET;
|
|
||||||
|
|
||||||
struct zts_sockaddr *sa = (struct zts_sockaddr *)&in4;
|
|
||||||
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 = ntohs(in4->sin_port);
|
|
||||||
}
|
|
||||||
if (sa->sa_family == ZTS_AF_INET6) {
|
|
||||||
struct zts_sockaddr_in6 *in6 = (struct zts_sockaddr_in6*)sa;
|
|
||||||
zts_inet_ntop(ZTS_AF_INET6, &(in6->sin6_addr),
|
|
||||||
ipstr, ZTS_INET6_ADDRSTRLEN);
|
|
||||||
}
|
|
||||||
|
|
||||||
assert(("zts_inet_ntop(): port != 8080", port == 8080));
|
|
||||||
assert(("zts_inet_ntop(): strcmp(ipstr, \"192.168.22.1\") != 0",
|
|
||||||
!strcmp(ipstr, "192.168.22.1")));
|
|
||||||
|
|
||||||
// (C) Test zts_inet_pton
|
|
||||||
|
|
||||||
uint8_t buf[sizeof(struct zts_in6_addr)];
|
|
||||||
char str[ZTS_INET6_ADDRSTRLEN];
|
|
||||||
|
|
||||||
zts_inet_pton(ZTS_AF_INET, "192.168.22.2", buf);
|
|
||||||
zts_inet_ntop(ZTS_AF_INET, buf, str, ZTS_INET6_ADDRSTRLEN);
|
|
||||||
assert(("zts_inet_pton(): strcmp(ipstr, \"192.168.22.2\") != 0",
|
|
||||||
!strcmp(str, "192.168.22.2")));
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
// Start the service and test a few things |
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
// zts_start();
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
// Test DNS client functionality |
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
/*
|
|
||||||
// Set first nameserver
|
|
||||||
|
|
||||||
char *ns1_addr_str = "FCC5:205E:4FF5:5311:DFF0::1";
|
|
||||||
zts_ip_addr ns1;
|
|
||||||
zts_ipaddr_aton(ns1_addr_str, &ns1);
|
|
||||||
zts_dns_set_server(0, &ns1);
|
|
||||||
|
|
||||||
// Get first nameserver
|
|
||||||
|
|
||||||
const zts_ip_addr *ns1_result;
|
|
||||||
ns1_result = zts_dns_get_server(0);
|
|
||||||
printf("dns1 = %s\n", zts_ipaddr_ntoa(ns1_result));
|
|
||||||
|
|
||||||
// Set second nameserver
|
|
||||||
|
|
||||||
char *ns2_addr_str = "192.168.22.1";
|
|
||||||
zts_ip_addr ns2;
|
|
||||||
zts_ipaddr_aton(ns2_addr_str, &ns2);
|
|
||||||
zts_dns_set_server(1, &ns2);
|
|
||||||
|
|
||||||
// Get second nameserver
|
|
||||||
|
|
||||||
const zts_ip_addr *ns2_result;
|
|
||||||
ns2_result = zts_dns_get_server(1);
|
|
||||||
printf("dns1 = %s\n", zts_ipaddr_ntoa(ns2_result));
|
|
||||||
|
|
||||||
// Check that each nameserver address was properly set and get
|
|
||||||
|
|
||||||
assert(("zts_dns_get_server(): Address mismatch", !strcmp(ns1_addr_str, zts_ipaddr_ntoa(ns1_result))));
|
|
||||||
assert(("zts_dns_get_server(): Address mismatch", !strcmp(ns2_addr_str, zts_ipaddr_ntoa(ns2_result))));
|
|
||||||
*/
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user