Add WIP Java language bindings
This commit is contained in:
757
build.sh
757
build.sh
@@ -8,47 +8,47 @@
|
||||
CMAKE=cmake3
|
||||
if [[ $(which $CMAKE) = "" ]];
|
||||
then
|
||||
CMAKE=cmake # try this next
|
||||
CMAKE=cmake # try this next
|
||||
fi
|
||||
if [[ $(which $CMAKE) = "" ]];
|
||||
then
|
||||
echo "CMake (cmake) not found. Please install before continuing."
|
||||
exit
|
||||
echo "CMake (cmake) not found. Please install before continuing."
|
||||
exit
|
||||
fi
|
||||
|
||||
#
|
||||
if [[ ! $(which tree) = "" ]];
|
||||
then
|
||||
TREE=tree
|
||||
TREE=tree
|
||||
else
|
||||
TREE="du -a "
|
||||
TREE="du -a "
|
||||
fi
|
||||
|
||||
# Determine operating system
|
||||
OSNAME=$(uname | tr '[A-Z]' '[a-z]')
|
||||
if [[ $OSNAME = *"darwin"* ]]; then
|
||||
SHARED_LIB_NAME="libzt.dylib"
|
||||
STATIC_LIB_NAME="libzt.a"
|
||||
HOST_PLATFORM="macos"
|
||||
SHARED_LIB_NAME="libzt.dylib"
|
||||
STATIC_LIB_NAME="libzt.a"
|
||||
HOST_PLATFORM="macos"
|
||||
fi
|
||||
if [[ $OSNAME = *"linux"* ]]; then
|
||||
SHARED_LIB_NAME="libzt.so"
|
||||
STATIC_LIB_NAME="libzt.a"
|
||||
HOST_PLATFORM="linux"
|
||||
SHARED_LIB_NAME="libzt.so"
|
||||
STATIC_LIB_NAME="libzt.a"
|
||||
HOST_PLATFORM="linux"
|
||||
fi
|
||||
|
||||
# Determine and normalize machine type
|
||||
HOST_MACHINE_TYPE=$(uname -m)
|
||||
if [[ $HOST_MACHINE_TYPE = *"x86_64"* ]]; then
|
||||
HOST_MACHINE_TYPE="x64"
|
||||
HOST_MACHINE_TYPE="x64"
|
||||
fi
|
||||
|
||||
# Determine number of cores. We'll tell CMake to use them all
|
||||
if [[ $OSNAME = *"darwin"* ]]; then
|
||||
N_PROCESSORS=$(sysctl -n hw.ncpu)
|
||||
N_PROCESSORS=$(sysctl -n hw.ncpu)
|
||||
fi
|
||||
if [[ $OSNAME = *"linux"* ]]; then
|
||||
N_PROCESSORS=$(nproc --all)
|
||||
N_PROCESSORS=$(nproc --all)
|
||||
fi
|
||||
|
||||
# How many processor cores CMake should use during builds,
|
||||
@@ -63,7 +63,7 @@ function ver()
|
||||
printf "%02d%02d%02d%02d" ${1//./ }
|
||||
}
|
||||
if [[ (( $(ver $CMAKE_VERSION) > $(ver "3.12") )) ]]; then
|
||||
BUILD_CONCURRENCY="-j $N_PROCESSORS"
|
||||
BUILD_CONCURRENCY="-j $N_PROCESSORS"
|
||||
fi
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
@@ -87,7 +87,7 @@ DEFAULT_HOST_BUILD_CACHE_DIR=$BUILD_CACHE_DIR/$HOST_PLATFORM-$HOST_MACHINE_TYPE
|
||||
|
||||
gethosttype()
|
||||
{
|
||||
echo $HOST_PLATFORM-$HOST_MACHINE_TYPE
|
||||
echo $HOST_PLATFORM-$HOST_MACHINE_TYPE
|
||||
}
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
@@ -100,8 +100,8 @@ gethosttype()
|
||||
#
|
||||
# Example output:
|
||||
#
|
||||
# - Cache : libzt/cache/apple-xcframework-debug
|
||||
# - Build output : libzt/dist
|
||||
# - Cache : libzt/cache/apple-xcframework-debug
|
||||
# - Build output : libzt/dist
|
||||
#
|
||||
# apple-xcframework-debug
|
||||
# └── pkg
|
||||
@@ -119,36 +119,36 @@ gethosttype()
|
||||
#
|
||||
xcframework()
|
||||
{
|
||||
if [[ ! $OSNAME = *"darwin"* ]]; then
|
||||
echo "Can only build this on a Mac"
|
||||
exit 0
|
||||
fi
|
||||
BUILD_TYPE=${1:-release}
|
||||
UPPERCASE_BUILD_TYPE="$(tr '[:lower:]' '[:upper:]' <<< ${BUILD_TYPE:0:1})${BUILD_TYPE:1}"
|
||||
if [[ ! $OSNAME = *"darwin"* ]]; then
|
||||
echo "Can only build this on a Mac"
|
||||
exit 0
|
||||
fi
|
||||
BUILD_TYPE=${1:-release}
|
||||
UPPERCASE_BUILD_TYPE="$(tr '[:lower:]' '[:upper:]' <<< ${BUILD_TYPE:0:1})${BUILD_TYPE:1}"
|
||||
|
||||
# Build all frameworks
|
||||
macos-framework $BUILD_TYPE
|
||||
iphoneos-framework $BUILD_TYPE
|
||||
iphonesimulator-framework $BUILD_TYPE
|
||||
# Build all frameworks
|
||||
macos-framework $BUILD_TYPE
|
||||
iphoneos-framework $BUILD_TYPE
|
||||
iphonesimulator-framework $BUILD_TYPE
|
||||
|
||||
ARTIFACT="xcframework"
|
||||
TARGET_PLATFORM="apple"
|
||||
TARGET_BUILD_DIR=$BUILD_OUTPUT_DIR/$TARGET_PLATFORM-$ARTIFACT-$BUILD_TYPE
|
||||
rm -rf $TARGET_BUILD_DIR
|
||||
PKG_OUTPUT_DIR=$TARGET_BUILD_DIR/pkg
|
||||
mkdir -p $PKG_OUTPUT_DIR
|
||||
ARTIFACT="xcframework"
|
||||
TARGET_PLATFORM="apple"
|
||||
TARGET_BUILD_DIR=$BUILD_OUTPUT_DIR/$TARGET_PLATFORM-$ARTIFACT-$BUILD_TYPE
|
||||
rm -rf $TARGET_BUILD_DIR
|
||||
PKG_OUTPUT_DIR=$TARGET_BUILD_DIR/pkg
|
||||
mkdir -p $PKG_OUTPUT_DIR
|
||||
|
||||
MACOS_FRAMEWORK_DIR=macos-x64-framework-$BUILD_TYPE
|
||||
IOS_FRAMEWORK_DIR=iphoneos-arm64-framework-$BUILD_TYPE
|
||||
IOS_SIM_FRAMEWORK_DIR=iphonesimulator-x64-framework-$BUILD_TYPE
|
||||
MACOS_FRAMEWORK_DIR=macos-x64-framework-$BUILD_TYPE
|
||||
IOS_FRAMEWORK_DIR=iphoneos-arm64-framework-$BUILD_TYPE
|
||||
IOS_SIM_FRAMEWORK_DIR=iphonesimulator-x64-framework-$BUILD_TYPE
|
||||
|
||||
# Pack everything
|
||||
rm -rf $PKG_OUTPUT_DIR/zt.xcframework # Remove prior to move to prevent error
|
||||
xcodebuild -create-xcframework \
|
||||
-framework $BUILD_CACHE_DIR/$MACOS_FRAMEWORK_DIR/lib/$UPPERCASE_BUILD_TYPE/zt.framework \
|
||||
-framework $BUILD_CACHE_DIR/$IOS_FRAMEWORK_DIR/lib/$UPPERCASE_BUILD_TYPE/zt.framework \
|
||||
-framework $BUILD_CACHE_DIR/$IOS_SIM_FRAMEWORK_DIR/lib/$UPPERCASE_BUILD_TYPE/zt.framework \
|
||||
-output $PKG_OUTPUT_DIR/zt.xcframework
|
||||
# Pack everything
|
||||
rm -rf $PKG_OUTPUT_DIR/zt.xcframework # Remove prior to move to prevent error
|
||||
xcodebuild -create-xcframework \
|
||||
-framework $BUILD_CACHE_DIR/$MACOS_FRAMEWORK_DIR/lib/$UPPERCASE_BUILD_TYPE/zt.framework \
|
||||
-framework $BUILD_CACHE_DIR/$IOS_FRAMEWORK_DIR/lib/$UPPERCASE_BUILD_TYPE/zt.framework \
|
||||
-framework $BUILD_CACHE_DIR/$IOS_SIM_FRAMEWORK_DIR/lib/$UPPERCASE_BUILD_TYPE/zt.framework \
|
||||
-output $PKG_OUTPUT_DIR/zt.xcframework
|
||||
}
|
||||
|
||||
# Build iOS framework
|
||||
@@ -157,8 +157,8 @@ xcframework()
|
||||
#
|
||||
# Example output:
|
||||
#
|
||||
# - Cache : libzt/cache/iphonesimulator-x64-framework-debug
|
||||
# - Build output : libzt/dist
|
||||
# - Cache : libzt/cache/iphonesimulator-x64-framework-debug
|
||||
# - Build output : libzt/dist
|
||||
#
|
||||
# libzt/dist/iphonesimulator-x64-framework-debug
|
||||
# └── pkg
|
||||
@@ -172,32 +172,32 @@ xcframework()
|
||||
#
|
||||
iphonesimulator-framework()
|
||||
{
|
||||
if [[ ! $OSNAME = *"darwin"* ]]; then
|
||||
echo "Can only build this on a Mac"
|
||||
exit 0
|
||||
fi
|
||||
ARTIFACT="framework"
|
||||
BUILD_TYPE=${1:-Release}
|
||||
UPPERCASE_BUILD_TYPE="$(tr '[:lower:]' '[:upper:]' <<< ${BUILD_TYPE:0:1})${BUILD_TYPE:1}"
|
||||
VARIANT="-DBUILD_IOS_FRAMEWORK=True"
|
||||
TARGET_PLATFORM="iphonesimulator"
|
||||
TARGET_MACHINE_TYPE="x64" # presumably
|
||||
CACHE_DIR=$BUILD_CACHE_DIR/$TARGET_PLATFORM-$TARGET_MACHINE_TYPE-$ARTIFACT-$BUILD_TYPE
|
||||
TARGET_BUILD_DIR=$BUILD_OUTPUT_DIR/$TARGET_PLATFORM-$TARGET_MACHINE_TYPE-$ARTIFACT-$BUILD_TYPE
|
||||
rm -rf $TARGET_BUILD_DIR
|
||||
PKG_OUTPUT_DIR=$TARGET_BUILD_DIR/pkg
|
||||
mkdir -p $PKG_OUTPUT_DIR
|
||||
# Generate project
|
||||
mkdir -p $CACHE_DIR
|
||||
cd $CACHE_DIR
|
||||
# iOS (SDK 11+, 64-bit only, arm64)
|
||||
$CMAKE -G Xcode ../../ $VARIANT
|
||||
# Build framework
|
||||
xcodebuild -target zt -configuration "$UPPERCASE_BUILD_TYPE" -sdk "iphonesimulator"
|
||||
cd -
|
||||
cp -rf $CACHE_DIR/lib/$UPPERCASE_BUILD_TYPE/*.framework $PKG_OUTPUT_DIR
|
||||
echo -e "\n - Build cache : $CACHE_DIR\n - Build output : $BUILD_OUTPUT_DIR\n"
|
||||
$TREE $TARGET_BUILD_DIR
|
||||
if [[ ! $OSNAME = *"darwin"* ]]; then
|
||||
echo "Can only build this on a Mac"
|
||||
exit 0
|
||||
fi
|
||||
ARTIFACT="framework"
|
||||
BUILD_TYPE=${1:-Release}
|
||||
UPPERCASE_BUILD_TYPE="$(tr '[:lower:]' '[:upper:]' <<< ${BUILD_TYPE:0:1})${BUILD_TYPE:1}"
|
||||
VARIANT="-DBUILD_IOS_FRAMEWORK=True"
|
||||
TARGET_PLATFORM="iphonesimulator"
|
||||
TARGET_MACHINE_TYPE="x64" # presumably
|
||||
CACHE_DIR=$BUILD_CACHE_DIR/$TARGET_PLATFORM-$TARGET_MACHINE_TYPE-$ARTIFACT-$BUILD_TYPE
|
||||
TARGET_BUILD_DIR=$BUILD_OUTPUT_DIR/$TARGET_PLATFORM-$TARGET_MACHINE_TYPE-$ARTIFACT-$BUILD_TYPE
|
||||
rm -rf $TARGET_BUILD_DIR
|
||||
PKG_OUTPUT_DIR=$TARGET_BUILD_DIR/pkg
|
||||
mkdir -p $PKG_OUTPUT_DIR
|
||||
# Generate project
|
||||
mkdir -p $CACHE_DIR
|
||||
cd $CACHE_DIR
|
||||
# iOS (SDK 11+, 64-bit only, arm64)
|
||||
$CMAKE -G Xcode ../../ $VARIANT
|
||||
# Build framework
|
||||
xcodebuild -target zt -configuration "$UPPERCASE_BUILD_TYPE" -sdk "iphonesimulator"
|
||||
cd -
|
||||
cp -rf $CACHE_DIR/lib/$UPPERCASE_BUILD_TYPE/*.framework $PKG_OUTPUT_DIR
|
||||
echo -e "\n - Build cache : $CACHE_DIR\n - Build output : $BUILD_OUTPUT_DIR\n"
|
||||
$TREE $TARGET_BUILD_DIR
|
||||
}
|
||||
|
||||
# Build macOS framework
|
||||
@@ -206,8 +206,8 @@ iphonesimulator-framework()
|
||||
#
|
||||
# Example output:
|
||||
#
|
||||
# - Cache : libzt/cache/macos-x64-framework-debug
|
||||
# - Build output : libzt/dist
|
||||
# - Cache : libzt/cache/macos-x64-framework-debug
|
||||
# - Build output : libzt/dist
|
||||
#
|
||||
# libzt/dist/macos-x64-framework-debug
|
||||
# └── pkg
|
||||
@@ -221,29 +221,29 @@ iphonesimulator-framework()
|
||||
#
|
||||
macos-framework()
|
||||
{
|
||||
if [[ ! $OSNAME = *"darwin"* ]]; then
|
||||
echo "Can only build this on a Mac"
|
||||
exit 0
|
||||
fi
|
||||
ARTIFACT="framework"
|
||||
BUILD_TYPE=${1:-Release}
|
||||
UPPERCASE_BUILD_TYPE="$(tr '[:lower:]' '[:upper:]' <<< ${BUILD_TYPE:0:1})${BUILD_TYPE:1}"
|
||||
VARIANT="-DBUILD_MACOS_FRAMEWORK=True"
|
||||
CACHE_DIR=$DEFAULT_HOST_BUILD_CACHE_DIR-$ARTIFACT-$BUILD_TYPE
|
||||
TARGET_BUILD_DIR=$DEFAULT_HOST_BIN_OUTPUT_DIR-$ARTIFACT-$BUILD_TYPE
|
||||
rm -rf $TARGET_BUILD_DIR
|
||||
PKG_OUTPUT_DIR=$TARGET_BUILD_DIR/pkg
|
||||
mkdir -p $PKG_OUTPUT_DIR
|
||||
# Generate project
|
||||
mkdir -p $CACHE_DIR
|
||||
cd $CACHE_DIR
|
||||
$CMAKE -G Xcode ../../ $VARIANT
|
||||
# Build framework
|
||||
xcodebuild -target zt -configuration $UPPERCASE_BUILD_TYPE -sdk "macosx"
|
||||
cd -
|
||||
cp -rf $CACHE_DIR/lib/$UPPERCASE_BUILD_TYPE/*.framework $PKG_OUTPUT_DIR
|
||||
echo -e "\n - Build cache : $CACHE_DIR\n - Build output : $BUILD_OUTPUT_DIR\n"
|
||||
$TREE $TARGET_BUILD_DIR
|
||||
if [[ ! $OSNAME = *"darwin"* ]]; then
|
||||
echo "Can only build this on a Mac"
|
||||
exit 0
|
||||
fi
|
||||
ARTIFACT="framework"
|
||||
BUILD_TYPE=${1:-Release}
|
||||
UPPERCASE_BUILD_TYPE="$(tr '[:lower:]' '[:upper:]' <<< ${BUILD_TYPE:0:1})${BUILD_TYPE:1}"
|
||||
VARIANT="-DBUILD_MACOS_FRAMEWORK=True"
|
||||
CACHE_DIR=$DEFAULT_HOST_BUILD_CACHE_DIR-$ARTIFACT-$BUILD_TYPE
|
||||
TARGET_BUILD_DIR=$DEFAULT_HOST_BIN_OUTPUT_DIR-$ARTIFACT-$BUILD_TYPE
|
||||
rm -rf $TARGET_BUILD_DIR
|
||||
PKG_OUTPUT_DIR=$TARGET_BUILD_DIR/pkg
|
||||
mkdir -p $PKG_OUTPUT_DIR
|
||||
# Generate project
|
||||
mkdir -p $CACHE_DIR
|
||||
cd $CACHE_DIR
|
||||
$CMAKE -G Xcode ../../ $VARIANT
|
||||
# Build framework
|
||||
xcodebuild -target zt -configuration $UPPERCASE_BUILD_TYPE -sdk "macosx"
|
||||
cd -
|
||||
cp -rf $CACHE_DIR/lib/$UPPERCASE_BUILD_TYPE/*.framework $PKG_OUTPUT_DIR
|
||||
echo -e "\n - Build cache : $CACHE_DIR\n - Build output : $BUILD_OUTPUT_DIR\n"
|
||||
$TREE $TARGET_BUILD_DIR
|
||||
}
|
||||
|
||||
# Build iOS framework
|
||||
@@ -252,8 +252,8 @@ macos-framework()
|
||||
#
|
||||
# Example output:
|
||||
#
|
||||
# - Cache : libzt/cache/iphoneos-arm64-framework-debug
|
||||
# - Build output : libzt/dist
|
||||
# - Cache : libzt/cache/iphoneos-arm64-framework-debug
|
||||
# - Build output : libzt/dist
|
||||
#
|
||||
# libzt/dist/iphoneos-arm64-framework-debug
|
||||
# └── pkg
|
||||
@@ -267,33 +267,33 @@ macos-framework()
|
||||
#
|
||||
iphoneos-framework()
|
||||
{
|
||||
if [[ ! $OSNAME = *"darwin"* ]]; then
|
||||
echo "Can only build this on a Mac"
|
||||
exit 0
|
||||
fi
|
||||
ARTIFACT="framework"
|
||||
BUILD_TYPE=${1:-Release}
|
||||
UPPERCASE_BUILD_TYPE="$(tr '[:lower:]' '[:upper:]' <<< ${BUILD_TYPE:0:1})${BUILD_TYPE:1}"
|
||||
VARIANT="-DBUILD_IOS_FRAMEWORK=True -DIOS_ARM64=True"
|
||||
TARGET_PLATFORM="iphoneos"
|
||||
TARGET_MACHINE_TYPE=arm64
|
||||
CACHE_DIR=$BUILD_CACHE_DIR/$TARGET_PLATFORM-$TARGET_MACHINE_TYPE-$ARTIFACT-$BUILD_TYPE
|
||||
TARGET_BUILD_DIR=$BUILD_OUTPUT_DIR/$TARGET_PLATFORM-$TARGET_MACHINE_TYPE-$ARTIFACT-$BUILD_TYPE
|
||||
rm -rf $TARGET_BUILD_DIR
|
||||
PKG_OUTPUT_DIR=$TARGET_BUILD_DIR/pkg
|
||||
mkdir -p $PKG_OUTPUT_DIR
|
||||
# Generate project
|
||||
mkdir -p $CACHE_DIR
|
||||
cd $CACHE_DIR
|
||||
# iOS (SDK 11+, 64-bit only, arm64)
|
||||
$CMAKE -G Xcode ../../ $VARIANT
|
||||
sed -i '' 's/x86_64/$(CURRENT_ARCH)/g' zt.xcodeproj/project.pbxproj
|
||||
# Build framework
|
||||
xcodebuild -arch $TARGET_MACHINE_TYPE -target zt -configuration "$UPPERCASE_BUILD_TYPE" -sdk "iphoneos"
|
||||
cd -
|
||||
cp -rvf $CACHE_DIR/lib/$UPPERCASE_BUILD_TYPE/*.framework $PKG_OUTPUT_DIR
|
||||
echo -e "\n - Build cache : $CACHE_DIR\n - Build output : $BUILD_OUTPUT_DIR\n"
|
||||
$TREE $TARGET_BUILD_DIR
|
||||
if [[ ! $OSNAME = *"darwin"* ]]; then
|
||||
echo "Can only build this on a Mac"
|
||||
exit 0
|
||||
fi
|
||||
ARTIFACT="framework"
|
||||
BUILD_TYPE=${1:-Release}
|
||||
UPPERCASE_BUILD_TYPE="$(tr '[:lower:]' '[:upper:]' <<< ${BUILD_TYPE:0:1})${BUILD_TYPE:1}"
|
||||
VARIANT="-DBUILD_IOS_FRAMEWORK=True -DIOS_ARM64=True"
|
||||
TARGET_PLATFORM="iphoneos"
|
||||
TARGET_MACHINE_TYPE=arm64
|
||||
CACHE_DIR=$BUILD_CACHE_DIR/$TARGET_PLATFORM-$TARGET_MACHINE_TYPE-$ARTIFACT-$BUILD_TYPE
|
||||
TARGET_BUILD_DIR=$BUILD_OUTPUT_DIR/$TARGET_PLATFORM-$TARGET_MACHINE_TYPE-$ARTIFACT-$BUILD_TYPE
|
||||
rm -rf $TARGET_BUILD_DIR
|
||||
PKG_OUTPUT_DIR=$TARGET_BUILD_DIR/pkg
|
||||
mkdir -p $PKG_OUTPUT_DIR
|
||||
# Generate project
|
||||
mkdir -p $CACHE_DIR
|
||||
cd $CACHE_DIR
|
||||
# iOS (SDK 11+, 64-bit only, arm64)
|
||||
$CMAKE -G Xcode ../../ $VARIANT
|
||||
sed -i '' 's/x86_64/$(CURRENT_ARCH)/g' zt.xcodeproj/project.pbxproj
|
||||
# Build framework
|
||||
xcodebuild -arch $TARGET_MACHINE_TYPE -target zt -configuration "$UPPERCASE_BUILD_TYPE" -sdk "iphoneos"
|
||||
cd -
|
||||
cp -rvf $CACHE_DIR/lib/$UPPERCASE_BUILD_TYPE/*.framework $PKG_OUTPUT_DIR
|
||||
echo -e "\n - Build cache : $CACHE_DIR\n - Build output : $BUILD_OUTPUT_DIR\n"
|
||||
$TREE $TARGET_BUILD_DIR
|
||||
}
|
||||
|
||||
# Build standard libraries, examples, and selftest
|
||||
@@ -302,8 +302,8 @@ iphoneos-framework()
|
||||
#
|
||||
# Example output:
|
||||
#
|
||||
# - Cache : libzt/cache/linux-x64-host-release
|
||||
# - Build output : libzt/dist
|
||||
# - Cache : libzt/cache/linux-x64-host-release
|
||||
# - Build output : libzt/dist
|
||||
#
|
||||
# linux-x64-host-release
|
||||
# ├── bin
|
||||
@@ -315,35 +315,35 @@ iphoneos-framework()
|
||||
#
|
||||
host()
|
||||
{
|
||||
ARTIFACT="host"
|
||||
# Default to release
|
||||
BUILD_TYPE=${1:-release}
|
||||
VARIANT="-DBUILD_HOST=True"
|
||||
CACHE_DIR=$DEFAULT_HOST_BUILD_CACHE_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
|
||||
BIN_OUTPUT_DIR=$TARGET_BUILD_DIR/bin
|
||||
mkdir -p $LIB_OUTPUT_DIR
|
||||
mkdir -p $BIN_OUTPUT_DIR
|
||||
$CMAKE $VARIANT -H. -B$CACHE_DIR -DCMAKE_BUILD_TYPE=$BUILD_TYPE
|
||||
$CMAKE --build $CACHE_DIR $BUILD_CONCURRENCY
|
||||
cp -f $CACHE_DIR/lib/libzt.* $LIB_OUTPUT_DIR
|
||||
cp -f $CACHE_DIR/bin/* $BIN_OUTPUT_DIR
|
||||
echo -e "\n - Build cache : $CACHE_DIR\n - Build output : $BUILD_OUTPUT_DIR\n"
|
||||
$TREE $TARGET_BUILD_DIR
|
||||
ARTIFACT="host"
|
||||
# Default to release
|
||||
BUILD_TYPE=${1:-release}
|
||||
VARIANT="-DBUILD_HOST=True"
|
||||
CACHE_DIR=$DEFAULT_HOST_BUILD_CACHE_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
|
||||
BIN_OUTPUT_DIR=$TARGET_BUILD_DIR/bin
|
||||
mkdir -p $LIB_OUTPUT_DIR
|
||||
mkdir -p $BIN_OUTPUT_DIR
|
||||
$CMAKE $VARIANT -H. -B$CACHE_DIR -DCMAKE_BUILD_TYPE=$BUILD_TYPE
|
||||
$CMAKE --build $CACHE_DIR $BUILD_CONCURRENCY
|
||||
cp -f $CACHE_DIR/lib/libzt.* $LIB_OUTPUT_DIR
|
||||
cp -f $CACHE_DIR/bin/* $BIN_OUTPUT_DIR
|
||||
echo -e "\n - Build cache : $CACHE_DIR\n - Build output : $BUILD_OUTPUT_DIR\n"
|
||||
$TREE $TARGET_BUILD_DIR
|
||||
}
|
||||
host-install()
|
||||
{
|
||||
cd cache/$HOST_PLATFORM-$HOST_MACHINE_TYPE-host-$1/
|
||||
make install
|
||||
cd -
|
||||
cd cache/$HOST_PLATFORM-$HOST_MACHINE_TYPE-host-$1/
|
||||
make install
|
||||
cd -
|
||||
}
|
||||
host-uninstall()
|
||||
{
|
||||
cd cache/$HOST_PLATFORM-$HOST_MACHINE_TYPE-host-$1/
|
||||
xargs rm < install_manifest.txt
|
||||
cd -
|
||||
cd cache/$HOST_PLATFORM-$HOST_MACHINE_TYPE-host-$1/
|
||||
xargs rm < install_manifest.txt
|
||||
cd -
|
||||
}
|
||||
|
||||
# Build C extension module (*.so), python module, package both into wheel
|
||||
@@ -358,98 +358,117 @@ host-uninstall()
|
||||
#
|
||||
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
|
||||
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
|
||||
host-python()
|
||||
{
|
||||
ARTIFACT="python"
|
||||
# Default to release
|
||||
BUILD_TYPE=${1:-release}
|
||||
VARIANT="-DZTS_ENABLE_PYTHON=True"
|
||||
CACHE_DIR=$DEFAULT_HOST_BUILD_CACHE_DIR-$ARTIFACT-$BUILD_TYPE
|
||||
TARGET_BUILD_DIR=$DEFAULT_HOST_BIN_OUTPUT_DIR-$ARTIFACT-$BUILD_TYPE
|
||||
LIB_OUTPUT_DIR=$TARGET_BUILD_DIR/lib
|
||||
rm -rf $LIB_OUTPUT_DIR
|
||||
mkdir -p $LIB_OUTPUT_DIR
|
||||
# Optional step to generate new SWIG wrapper
|
||||
swig -c++ -python -o src/bindings/python/zt_wrap.cxx -Iinclude src/bindings/python/zt.i
|
||||
$CMAKE $VARIANT -H. -B$CACHE_DIR -DCMAKE_BUILD_TYPE=$BUILD_TYPE
|
||||
$CMAKE --build $CACHE_DIR $BUILD_CONCURRENCY
|
||||
cp -f $CACHE_DIR/lib/$SHARED_LIB_NAME $LIB_OUTPUT_DIR/_libzt.so
|
||||
echo -e "\n - Build cache : $CACHE_DIR\n - Build output : $BUILD_OUTPUT_DIR\n"
|
||||
$TREE $TARGET_BUILD_DIR
|
||||
ARTIFACT="python"
|
||||
# Default to release
|
||||
BUILD_TYPE=${1:-release}
|
||||
VARIANT="-DZTS_ENABLE_PYTHON=True"
|
||||
CACHE_DIR=$DEFAULT_HOST_BUILD_CACHE_DIR-$ARTIFACT-$BUILD_TYPE
|
||||
TARGET_BUILD_DIR=$DEFAULT_HOST_BIN_OUTPUT_DIR-$ARTIFACT-$BUILD_TYPE
|
||||
LIB_OUTPUT_DIR=$TARGET_BUILD_DIR/lib
|
||||
rm -rf $LIB_OUTPUT_DIR
|
||||
mkdir -p $LIB_OUTPUT_DIR
|
||||
# Optional step to generate new SWIG wrapper
|
||||
swig -c++ -python -o src/bindings/python/zt_wrap.cxx -Iinclude src/bindings/python/zt.i
|
||||
$CMAKE $VARIANT -H. -B$CACHE_DIR -DCMAKE_BUILD_TYPE=$BUILD_TYPE
|
||||
$CMAKE --build $CACHE_DIR $BUILD_CONCURRENCY
|
||||
cp -f $CACHE_DIR/lib/$SHARED_LIB_NAME $LIB_OUTPUT_DIR/_libzt.so
|
||||
echo -e "\n - Build cache : $CACHE_DIR\n - Build output : $BUILD_OUTPUT_DIR\n"
|
||||
$TREE $TARGET_BUILD_DIR
|
||||
}
|
||||
|
||||
# Build shared library with P/INVOKE wrapper symbols exported
|
||||
host-pinvoke()
|
||||
{
|
||||
ARTIFACT="pinvoke"
|
||||
# Default to release
|
||||
BUILD_TYPE=${1:-release}
|
||||
VARIANT="-DZTS_ENABLE_PINVOKE=True"
|
||||
CACHE_DIR=$DEFAULT_HOST_BUILD_CACHE_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
|
||||
BIN_OUTPUT_DIR=$TARGET_BUILD_DIR/bin
|
||||
mkdir -p $LIB_OUTPUT_DIR
|
||||
$CMAKE $VARIANT -H. -B$CACHE_DIR -DCMAKE_BUILD_TYPE=$BUILD_TYPE
|
||||
$CMAKE --build $CACHE_DIR $BUILD_CONCURRENCY
|
||||
cp -f $CACHE_DIR/lib/libzt.* $LIB_OUTPUT_DIR
|
||||
echo -e "\n - Build cache : $CACHE_DIR\n - Build output : $BUILD_OUTPUT_DIR\n"
|
||||
$TREE $TARGET_BUILD_DIR
|
||||
ARTIFACT="pinvoke"
|
||||
# Default to release
|
||||
BUILD_TYPE=${1:-release}
|
||||
VARIANT="-DZTS_ENABLE_PINVOKE=True"
|
||||
CACHE_DIR=$DEFAULT_HOST_BUILD_CACHE_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
|
||||
BIN_OUTPUT_DIR=$TARGET_BUILD_DIR/bin
|
||||
mkdir -p $LIB_OUTPUT_DIR
|
||||
$CMAKE $VARIANT -H. -B$CACHE_DIR -DCMAKE_BUILD_TYPE=$BUILD_TYPE
|
||||
$CMAKE --build $CACHE_DIR $BUILD_CONCURRENCY
|
||||
cp -f $CACHE_DIR/lib/libzt.* $LIB_OUTPUT_DIR
|
||||
echo -e "\n - Build cache : $CACHE_DIR\n - Build output : $BUILD_OUTPUT_DIR\n"
|
||||
$TREE $TARGET_BUILD_DIR
|
||||
}
|
||||
|
||||
# Build shared library with Java JNI wrapper symbols exported (.jar)
|
||||
host-jar()
|
||||
{
|
||||
ARTIFACT="jar"
|
||||
# Default to 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"
|
||||
CACHE_DIR=$DEFAULT_HOST_BUILD_CACHE_DIR-$ARTIFACT-$BUILD_TYPE
|
||||
TARGET_BUILD_DIR=$DEFAULT_HOST_BIN_OUTPUT_DIR-$ARTIFACT-$BUILD_TYPE
|
||||
rm -rf $TARGET_BUILD_DIR
|
||||
PKG_OUTPUT_DIR=$TARGET_BUILD_DIR/pkg
|
||||
mkdir -p $PKG_OUTPUT_DIR
|
||||
# Share same cache dir with CMake
|
||||
JAVA_JAR_DIR=$CACHE_DIR/pkg/jar
|
||||
JAVA_JAR_SOURCE_TREE_DIR=$JAVA_JAR_DIR/com/zerotier/libzt/
|
||||
mkdir -p $JAVA_JAR_SOURCE_TREE_DIR
|
||||
cp -f src/bindings/java/*.java $JAVA_JAR_SOURCE_TREE_DIR
|
||||
# Build
|
||||
$CMAKE $VARIANT -H. -B$CACHE_DIR -DCMAKE_BUILD_TYPE=$BUILD_TYPE
|
||||
$CMAKE --build $CACHE_DIR $BUILD_CONCURRENCY
|
||||
# Package everything
|
||||
cp -f $CACHE_DIR/lib/libzt.* $JAVA_JAR_DIR
|
||||
cd $JAVA_JAR_DIR
|
||||
export JAVA_TOOL_OPTIONS=-Dfile.encoding=UTF8
|
||||
javac -Xlint:deprecation com/zerotier/libzt/*.java
|
||||
jar cf libzt-"$(git describe --abbrev=0)".jar $SHARED_LIB_NAME com/zerotier/libzt/*.class
|
||||
rm -rf com $SHARED_LIB_NAME
|
||||
cd -
|
||||
# Copy JAR to dist/
|
||||
echo -e "\nContents of JAR:\n"
|
||||
jar tf $JAVA_JAR_DIR/*.jar
|
||||
echo -e
|
||||
mv $JAVA_JAR_DIR/*.jar $PKG_OUTPUT_DIR
|
||||
echo -e "\n - Build cache : $CACHE_DIR\n - Build output : $BUILD_OUTPUT_DIR\n"
|
||||
$TREE $TARGET_BUILD_DIR
|
||||
ARTIFACT="jar"
|
||||
# Default to 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"
|
||||
CACHE_DIR=$DEFAULT_HOST_BUILD_CACHE_DIR-$ARTIFACT-$BUILD_TYPE
|
||||
TARGET_BUILD_DIR=$DEFAULT_HOST_BIN_OUTPUT_DIR-$ARTIFACT-$BUILD_TYPE
|
||||
rm -rf $TARGET_BUILD_DIR
|
||||
PKG_OUTPUT_DIR=$TARGET_BUILD_DIR/pkg
|
||||
mkdir -p $PKG_OUTPUT_DIR
|
||||
# Share same cache dir with CMake
|
||||
JAVA_JAR_DIR=$CACHE_DIR/pkg/jar
|
||||
JAVA_JAR_SOURCE_TREE_DIR=$JAVA_JAR_DIR/com/zerotier/sdk/
|
||||
mkdir -p $JAVA_JAR_SOURCE_TREE_DIR
|
||||
cp -f src/bindings/java/*.java $JAVA_JAR_SOURCE_TREE_DIR
|
||||
# Build
|
||||
$CMAKE $VARIANT -H. -B$CACHE_DIR -DCMAKE_BUILD_TYPE=$BUILD_TYPE
|
||||
$CMAKE --build $CACHE_DIR $BUILD_CONCURRENCY
|
||||
# Package everything
|
||||
cp -f $CACHE_DIR/lib/libzt.* $JAVA_JAR_DIR
|
||||
cd $JAVA_JAR_DIR
|
||||
export JAVA_TOOL_OPTIONS=-Dfile.encoding=UTF8
|
||||
javac -Xlint:deprecation com/zerotier/sdk/*.java
|
||||
jar cf libzt-"$(git describe --abbrev=0)".jar $SHARED_LIB_NAME com/zerotier/sdk/*.class
|
||||
rm -rf com $SHARED_LIB_NAME
|
||||
cd -
|
||||
# Copy JAR to dist/
|
||||
echo -e "\nContents of JAR:\n"
|
||||
jar tf $JAVA_JAR_DIR/*.jar
|
||||
echo -e
|
||||
mv $JAVA_JAR_DIR/*.jar $PKG_OUTPUT_DIR
|
||||
echo -e "\n - Build cache : $CACHE_DIR\n - Build output : $BUILD_OUTPUT_DIR\n"
|
||||
$TREE $TARGET_BUILD_DIR
|
||||
|
||||
# Test JAR
|
||||
if [[ $2 = *"test"* ]]; then
|
||||
if [[ -z "${alice_path}" ]]; then
|
||||
echo "Please set necessary environment variables for test"
|
||||
exit 0
|
||||
fi
|
||||
cd test
|
||||
rm -rf *.dylib
|
||||
rm -rf *.jar
|
||||
cp -f $PKG_OUTPUT_DIR/*.jar .
|
||||
# Unpack JAR to get access to shared library
|
||||
jar xf *.jar libzt.dylib
|
||||
javac -cp *.jar selftest.java
|
||||
# Start Alice as server
|
||||
java -cp ".:libzt-"$(git describe --abbrev=0)".jar" selftest server $alice_path $testnet $port4 &
|
||||
# Start Bob as client
|
||||
java -cp ".:libzt-"$(git describe --abbrev=0)".jar" selftest client $bob_path $testnet $alice_ip4 $port4 &
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
@@ -463,13 +482,12 @@ ANDROID_PKG_PROJ_DIR=$(pwd)/pkg/android
|
||||
#export PATH=/Library/Java/JavaVirtualMachines/$JDK/Contents/Home/bin/:${PATH}
|
||||
#export PATH=/Users/$USER/Library/Android/sdk/platform-tools/:${PATH}
|
||||
GRADLE_ARGS=--stacktrace
|
||||
#ANDROID_APP_NAME=com.example.mynewestapplication
|
||||
# for our purposes we limit this to execution on macOS
|
||||
if [[ $OSNAME = *"linux"* ]]; then
|
||||
export ANDROID_HOME=/usr/lib/android-sdk/
|
||||
export ANDROID_HOME=/usr/lib/android-sdk/
|
||||
fi
|
||||
if [[ $OSNAME = *"darwin"* ]]; then
|
||||
export ANDROID_HOME=/Users/$USER/Library/Android/sdk
|
||||
export ANDROID_HOME=/Users/$USER/Library/Android/sdk
|
||||
fi
|
||||
|
||||
# Build shared library with Java JNI wrapper symbols exported (.aar)
|
||||
@@ -478,179 +496,182 @@ fi
|
||||
#
|
||||
# Example output:
|
||||
#
|
||||
# - Cache : libzt/cache/android-any-android-release
|
||||
# - Build output : libzt/dist
|
||||
# - Cache : libzt/cache/android-any-android-release
|
||||
# - Build output : libzt/dist
|
||||
#
|
||||
# android-any-android-release
|
||||
# └── libzt-release.aar
|
||||
#
|
||||
android-aar()
|
||||
{
|
||||
ARTIFACT="android"
|
||||
BUILD_TYPE=${1:-release} # Default to release
|
||||
CMAKE_SWITCH="ZTS_ENABLE_JAVA"
|
||||
TARGET_PLATFORM="android"
|
||||
TARGET_MACHINE_TYPE=any
|
||||
CACHE_DIR=$BUILD_CACHE_DIR/$TARGET_PLATFORM-$TARGET_MACHINE_TYPE-$ARTIFACT-$BUILD_TYPE
|
||||
PKG_OUTPUT_DIR=$BUILD_OUTPUT_DIR/$TARGET_PLATFORM-$TARGET_MACHINE_TYPE-$ARTIFACT-$BUILD_TYPE
|
||||
mkdir -p $CACHE_DIR
|
||||
mkdir -p $PKG_OUTPUT_DIR
|
||||
# Unsure why, but Gradle's build script chokes on this non-source file now
|
||||
rm -rf ext/ZeroTierOne/ext/miniupnpc/VERSION
|
||||
export PATH=$ANDROID_HOME/cmdline-tools/tools/bin:$PATH
|
||||
# Copy source files into project
|
||||
cp -f src/bindings/java/*.java ${ANDROID_PKG_PROJ_DIR}/app/src/main/java/com/zerotier/libzt
|
||||
# Build
|
||||
UPPERCASE_BUILD_TYPE="$(tr '[:lower:]' '[:upper:]' <<< ${BUILD_TYPE:0:1})${BUILD_TYPE:1}"
|
||||
CMAKE_FLAGS="-D${CMAKE_SWITCH}=1 -D${CMAKE_SWITCH}=ON"
|
||||
cd $ANDROID_PKG_PROJ_DIR
|
||||
./gradlew $GRADLE_ARGS assemble$UPPERCASE_BUILD_TYPE # assembleRelease / assembleDebug
|
||||
mv $ANDROID_PKG_PROJ_DIR/app/build/outputs/aar/*.aar \
|
||||
$PKG_OUTPUT_DIR/libzt-$BUILD_TYPE.aar
|
||||
cd -
|
||||
echo -e "\n - Build cache : $CACHE_DIR\n - Build output : $BUILD_OUTPUT_DIR\n"
|
||||
$TREE $PKG_OUTPUT_DIR
|
||||
ARTIFACT="android"
|
||||
BUILD_TYPE=${1:-release} # Default to release
|
||||
CMAKE_SWITCH="ZTS_ENABLE_JAVA"
|
||||
TARGET_PLATFORM="android"
|
||||
TARGET_MACHINE_TYPE=any
|
||||
CACHE_DIR=$BUILD_CACHE_DIR/$TARGET_PLATFORM-$TARGET_MACHINE_TYPE-$ARTIFACT-$BUILD_TYPE
|
||||
PKG_OUTPUT_DIR=$BUILD_OUTPUT_DIR/$TARGET_PLATFORM-$TARGET_MACHINE_TYPE-$ARTIFACT-$BUILD_TYPE
|
||||
mkdir -p $CACHE_DIR
|
||||
mkdir -p $PKG_OUTPUT_DIR
|
||||
# Unsure why, but Gradle's build script chokes on this non-source file now
|
||||
rm -rf ext/ZeroTierOne/ext/miniupnpc/VERSION
|
||||
export PATH=$ANDROID_HOME/cmdline-tools/tools/bin:$PATH
|
||||
# Copy source files into project
|
||||
cp -f src/bindings/java/*.java ${ANDROID_PKG_PROJ_DIR}/app/src/main/java/com/zerotier/libzt
|
||||
# Build
|
||||
UPPERCASE_BUILD_TYPE="$(tr '[:lower:]' '[:upper:]' <<< ${BUILD_TYPE:0:1})${BUILD_TYPE:1}"
|
||||
CMAKE_FLAGS="-D${CMAKE_SWITCH}=1 -D${CMAKE_SWITCH}=ON"
|
||||
cd $ANDROID_PKG_PROJ_DIR
|
||||
./gradlew $GRADLE_ARGS assemble$UPPERCASE_BUILD_TYPE # assembleRelease / assembleDebug
|
||||
mv $ANDROID_PKG_PROJ_DIR/app/build/outputs/aar/*.aar \
|
||||
$PKG_OUTPUT_DIR/libzt-$BUILD_TYPE.aar
|
||||
cd -
|
||||
echo -e "\n - Build cache : $CACHE_DIR\n - Build output : $BUILD_OUTPUT_DIR\n"
|
||||
$TREE $PKG_OUTPUT_DIR
|
||||
}
|
||||
|
||||
# Build static library and selftest. Currently this only tests
|
||||
# the core C API, not any of the language bindings.
|
||||
test()
|
||||
{
|
||||
ARTIFACT="test"
|
||||
# Default to release
|
||||
BUILD_TYPE=${1:-release}
|
||||
VARIANT="-DBUILD_HOST_SELFTEST_ONLY=True"
|
||||
CACHE_DIR=$DEFAULT_HOST_BUILD_CACHE_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
|
||||
BIN_OUTPUT_DIR=$TARGET_BUILD_DIR/bin
|
||||
mkdir -p $BIN_OUTPUT_DIR
|
||||
$CMAKE $VARIANT -H. -B$CACHE_DIR -DCMAKE_BUILD_TYPE=$BUILD_TYPE
|
||||
$CMAKE --build $CACHE_DIR $BUILD_CONCURRENCY
|
||||
cp -f $CACHE_DIR/bin/* $BIN_OUTPUT_DIR
|
||||
echo -e "\n - Build cache : $CACHE_DIR\n - Build output : $BUILD_OUTPUT_DIR\n"
|
||||
$TREE $TARGET_BUILD_DIR
|
||||
# Test
|
||||
cd $CACHE_DIR
|
||||
#ctest -C release
|
||||
cd -
|
||||
ARTIFACT="test"
|
||||
# Default to release
|
||||
BUILD_TYPE=${1:-release}
|
||||
VARIANT="-DBUILD_HOST_SELFTEST_ONLY=True"
|
||||
CACHE_DIR=$DEFAULT_HOST_BUILD_CACHE_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
|
||||
BIN_OUTPUT_DIR=$TARGET_BUILD_DIR/bin
|
||||
mkdir -p $BIN_OUTPUT_DIR
|
||||
$CMAKE $VARIANT -H. -B$CACHE_DIR -DCMAKE_BUILD_TYPE=$BUILD_TYPE
|
||||
$CMAKE --build $CACHE_DIR $BUILD_CONCURRENCY
|
||||
cp -f $CACHE_DIR/bin/* $BIN_OUTPUT_DIR
|
||||
echo -e "\n - Build cache : $CACHE_DIR\n - Build output : $BUILD_OUTPUT_DIR\n"
|
||||
$TREE $TARGET_BUILD_DIR
|
||||
# Test
|
||||
cd $CACHE_DIR
|
||||
#ctest -C release
|
||||
cd -
|
||||
}
|
||||
|
||||
format-code()
|
||||
{
|
||||
if [[ ! $(which clang-format) = "" ]];
|
||||
then
|
||||
# Eventually: find . -path ./ext -prune -false -o -type f \( -iname \*.c -o -iname \*.h -o -iname \*.cpp -o -iname \*.hpp \) -exec clang-format -i {} \;
|
||||
clang-format -i include/*.h \
|
||||
src/*.c \
|
||||
src/*.cpp \
|
||||
src/*.hpp \
|
||||
examples/c/*.c \
|
||||
test/*.c \
|
||||
src/bindings/csharp/*.cs \
|
||||
src/bindings/csharp/*.cxx \
|
||||
examples/csharp/*.cs
|
||||
return 0
|
||||
else
|
||||
echo "Please install clang-format."
|
||||
fi
|
||||
if [[ ! $(which clang-format) = "" ]];
|
||||
then
|
||||
# Eventually: find . -path ./ext -prune -false -o -type f \( -iname \*.c -o -iname \*.h -o -iname \*.cpp -o -iname \*.hpp \) -exec clang-format -i {} \;
|
||||
clang-format -i include/*.h \
|
||||
src/*.c \
|
||||
src/*.cpp \
|
||||
src/*.hpp \
|
||||
examples/c/*.c \
|
||||
examples/csharp/*.cs \
|
||||
examples/java/*.java \
|
||||
test/*.c \
|
||||
test/*.cs \
|
||||
src/bindings/csharp/*.cs \
|
||||
src/bindings/csharp/*.cxx \
|
||||
src/bindings/java/*.java \
|
||||
src/bindings/java/*.cxx \
|
||||
examples/csharp/*.cs
|
||||
return 0
|
||||
else
|
||||
echo "Please install clang-format."
|
||||
fi
|
||||
}
|
||||
|
||||
# Test C API
|
||||
test-c()
|
||||
{
|
||||
if [[ -z "${alice_path}" ]]; then
|
||||
echo "Please set necessary environment variables for test"
|
||||
#exit 0
|
||||
fi
|
||||
BUILD_TYPE=${1:-debug}
|
||||
test $BUILD_TYPE
|
||||
# Build selftest
|
||||
#test $BUILD_TYPE
|
||||
# Clear logs
|
||||
rm -rf test/*.txt
|
||||
# Start Alice as server
|
||||
echo "$BIN_OUTPUT_DIR/selftest-c" $alice_path $testnet $port4 $port6 &
|
||||
# Start Bob as client
|
||||
echo "$BIN_OUTPUT_DIR/selftest-c" $bob_path $testnet $port4 $alice_ip4 $port6 $alice_ip6 &
|
||||
if [[ -z "${alice_path}" ]]; then
|
||||
echo "Please set necessary environment variables for test"
|
||||
#exit 0
|
||||
fi
|
||||
BUILD_TYPE=${1:-debug}
|
||||
#BUILD_TYPE="ASAN"
|
||||
# Build selftest
|
||||
test $BUILD_TYPE
|
||||
# Start Alice as server
|
||||
"$BIN_OUTPUT_DIR/selftest-c" $alice_path $testnet $port4 $port6 &
|
||||
# Start Bob as client
|
||||
"$BIN_OUTPUT_DIR/selftest-c" $bob_path $testnet $port4 $alice_ip4 $port6 $alice_ip6 &
|
||||
}
|
||||
|
||||
# Test C# API
|
||||
test-cs()
|
||||
{
|
||||
if [[ -z "${alice_path}" ]]; then
|
||||
echo "Please set necessary environment variables for test"
|
||||
exit 0
|
||||
fi
|
||||
ARTIFACT="pinvoke"
|
||||
# Default to debug so asserts aren't optimized out
|
||||
BUILD_TYPE=${1:-debug}
|
||||
TARGET_BUILD_DIR=$DEFAULT_HOST_BIN_OUTPUT_DIR-$ARTIFACT-$BUILD_TYPE
|
||||
LIB_OUTPUT_DIR=$TARGET_BUILD_DIR/lib
|
||||
BIN_OUTPUT_DIR=$TARGET_BUILD_DIR/bin
|
||||
rm -rf $TARGET_BUILD_DIR
|
||||
# Build C shared library exporting C# symbols
|
||||
host-pinvoke $1
|
||||
# TODO: This should eventually be converted to a proper dotnet project
|
||||
# Build C# managed API library
|
||||
csc -target:library -doc:$LIB_OUTPUT_DIR/ZeroTier.Sockets.xml -out:$LIB_OUTPUT_DIR/ZeroTier.Sockets.dll src/bindings/csharp/*.cs
|
||||
# Build selftest
|
||||
mkdir -p $BIN_OUTPUT_DIR
|
||||
csc -out:$BIN_OUTPUT_DIR/selftest.exe -reference:$LIB_OUTPUT_DIR/ZeroTier.Sockets.dll test/selftest.cs
|
||||
# Copy shared libraries into bin directory so they can be discovered by dlopen
|
||||
cp $LIB_OUTPUT_DIR/* $BIN_OUTPUT_DIR
|
||||
# Start Alice as server
|
||||
mono --debug "$BIN_OUTPUT_DIR/selftest.exe" $alice_path $testnet $port4 $port6 &
|
||||
sleep 10
|
||||
# Start Bob as client
|
||||
mono --debug "$BIN_OUTPUT_DIR/selftest.exe" $bob_path $testnet $port4 $alice_ip4 $port6 $alice_ip6 &
|
||||
if [[ -z "${alice_path}" ]]; then
|
||||
echo "Please set necessary environment variables for test"
|
||||
exit 0
|
||||
fi
|
||||
ARTIFACT="pinvoke"
|
||||
# Default to debug so asserts aren't optimized out
|
||||
BUILD_TYPE=${1:-debug}
|
||||
TARGET_BUILD_DIR=$DEFAULT_HOST_BIN_OUTPUT_DIR-$ARTIFACT-$BUILD_TYPE
|
||||
LIB_OUTPUT_DIR=$TARGET_BUILD_DIR/lib
|
||||
BIN_OUTPUT_DIR=$TARGET_BUILD_DIR/bin
|
||||
rm -rf $TARGET_BUILD_DIR
|
||||
# Build C shared library exporting C# symbols
|
||||
host-pinvoke $1
|
||||
# TODO: This should eventually be converted to a proper dotnet project
|
||||
# Build C# managed API library
|
||||
csc -target:library -doc:$LIB_OUTPUT_DIR/ZeroTier.Sockets.xml -out:$LIB_OUTPUT_DIR/ZeroTier.Sockets.dll src/bindings/csharp/*.cs
|
||||
# Build selftest
|
||||
mkdir -p $BIN_OUTPUT_DIR
|
||||
csc -out:$BIN_OUTPUT_DIR/selftest.exe -reference:$LIB_OUTPUT_DIR/ZeroTier.Sockets.dll test/selftest.cs
|
||||
# Copy shared libraries into bin directory so they can be discovered by dlopen
|
||||
cp $LIB_OUTPUT_DIR/* $BIN_OUTPUT_DIR
|
||||
# Start Alice as server
|
||||
mono --debug "$BIN_OUTPUT_DIR/selftest.exe" $alice_path $testnet $port4 $port6 &
|
||||
sleep 10
|
||||
# Start Bob as client
|
||||
mono --debug "$BIN_OUTPUT_DIR/selftest.exe" $bob_path $testnet $port4 $alice_ip4 $port6 $alice_ip6 &
|
||||
}
|
||||
|
||||
# Recursive deep clean
|
||||
clean()
|
||||
{
|
||||
# Finished artifacts
|
||||
rm -rf $BUILD_OUTPUT_DIR
|
||||
# CMake's build system cache
|
||||
rm -rf $BUILD_CACHE_DIR
|
||||
# CMake test output
|
||||
rm -rf bin
|
||||
rm -rf Testing
|
||||
rm -rf CMakeFiles
|
||||
rm -rf *.cmake
|
||||
rm -rf CMakeCache.txt
|
||||
rm -rf Makefile
|
||||
# Android AAR project binaries and sources (copied from src/bindings/java)
|
||||
rm -rf $ANDROID_PKG_PROJ_DIR/app/build
|
||||
rm -rf $ANDROID_PKG_PROJ_DIR/app/src/main/java/com/zerotier/libzt/*.java
|
||||
rm -rf $ANDROID_PKG_PROJ_DIR/app/.externalNativeBuild
|
||||
# Remove whatever remains
|
||||
find . \
|
||||
\( -name '*.dylib' \
|
||||
-o -name '*.dll' \
|
||||
-o -name '*.aar' \
|
||||
-o -name '*.jar' \
|
||||
-o -name '*.so' \
|
||||
-o -name '*.a' \
|
||||
-o -name '*.o' \
|
||||
-o -name '*.exe' \
|
||||
-o -name '*.o.d' \
|
||||
-o -name '*.out' \
|
||||
-o -name '*.log' \
|
||||
-o -name '*.dSYM' \
|
||||
-o -name '*.class' \
|
||||
\) -exec rm -rf {} +
|
||||
# Finished artifacts
|
||||
rm -rf $BUILD_OUTPUT_DIR
|
||||
# CMake's build system cache
|
||||
rm -rf $BUILD_CACHE_DIR
|
||||
# CMake test output
|
||||
rm -rf bin
|
||||
rm -rf Testing
|
||||
rm -rf CMakeFiles
|
||||
rm -rf *.cmake
|
||||
rm -rf CMakeCache.txt
|
||||
rm -rf Makefile
|
||||
# Android AAR project binaries and sources (copied from src/bindings/java)
|
||||
rm -rf $ANDROID_PKG_PROJ_DIR/app/build
|
||||
rm -rf $ANDROID_PKG_PROJ_DIR/app/src/main/java/com/zerotier/libzt/*.java
|
||||
rm -rf $ANDROID_PKG_PROJ_DIR/app/.externalNativeBuild
|
||||
# Remove whatever remains
|
||||
find . \
|
||||
\( -name '*.dylib' \
|
||||
-o -name '*.dll' \
|
||||
-o -name '*.aar' \
|
||||
-o -name '*.jar' \
|
||||
-o -name '*.so' \
|
||||
-o -name '*.a' \
|
||||
-o -name '*.o' \
|
||||
-o -name '*.exe' \
|
||||
-o -name '*.o.d' \
|
||||
-o -name '*.out' \
|
||||
-o -name '*.log' \
|
||||
-o -name '*.dSYM' \
|
||||
-o -name '*.class' \
|
||||
\) -exec rm -rf {} +
|
||||
|
||||
find . -type d -name "__pycache__" -exec rm -rf {} +
|
||||
find . -type d -name "__pycache__" -exec rm -rf {} +
|
||||
}
|
||||
|
||||
list()
|
||||
{
|
||||
IFS=$'\n'
|
||||
for f in $(declare -F); do
|
||||
echo "${f:11}"
|
||||
done
|
||||
IFS=$'\n'
|
||||
for f in $(declare -F); do
|
||||
echo "${f:11}"
|
||||
done
|
||||
}
|
||||
|
||||
"$@"
|
||||
|
||||
@@ -1,161 +1,138 @@
|
||||
//package com.zerotier.libzt.javasimpleexample;
|
||||
|
||||
import com.zerotier.libzt.ZeroTier;
|
||||
import com.zerotier.libzt.ZeroTierEventListener;
|
||||
import com.zerotier.sdk.*;
|
||||
import java.io.DataInputStream;
|
||||
import java.io.DataOutputStream;
|
||||
import java.math.BigInteger;
|
||||
|
||||
public class Example {
|
||||
public class selftest {
|
||||
public static void main(String[] args)
|
||||
{
|
||||
System.err.println(args.length);
|
||||
if (args.length < 4 || args.length > 5) {
|
||||
System.err.println("Invalid arguments");
|
||||
System.err.println(" Usage: <server|client> <id_path> <network> <addr> <port>");
|
||||
System.err.println(" example server ./ 0123456789abcdef 8080");
|
||||
System.err.println(" example client ./ 0123456789abcdef 192.168.22.1 8080\n");
|
||||
System.exit(1);
|
||||
}
|
||||
|
||||
static void sleep(int ms) {
|
||||
try {
|
||||
Thread.sleep(ms);
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
String storagePath = "";
|
||||
String remoteAddr = "";
|
||||
int port = 0;
|
||||
String mode = args[0];
|
||||
storagePath = args[1];
|
||||
BigInteger networkId = new BigInteger(args[2], 16);
|
||||
if (args.length == 4) {
|
||||
port = Integer.parseInt(args[3]);
|
||||
}
|
||||
if (args.length == 5) {
|
||||
remoteAddr = args[3];
|
||||
port = Integer.parseInt(args[4]);
|
||||
}
|
||||
System.out.println("mode = " + mode);
|
||||
System.out.println("networkId = " + Long.toHexString(networkId.longValue()));
|
||||
System.out.println("storagePath = " + storagePath);
|
||||
System.out.println("remoteAddr = " + remoteAddr);
|
||||
System.out.println("port = " + port);
|
||||
|
||||
public static void main(String[] args) {
|
||||
String keyPath="."; // Default to current directory
|
||||
BigInteger networkId;
|
||||
Integer servicePort=0;
|
||||
if (args.length != 3) {
|
||||
System.err.println(" Invalid arguments");
|
||||
System.err.println(" Usage: example <path_to_write_keys> <nwid> <ztServicePort>");
|
||||
System.exit(1);
|
||||
}
|
||||
keyPath = args[0];
|
||||
networkId = new BigInteger(args[1], 16);
|
||||
servicePort = Integer.parseInt(args[2]);
|
||||
System.out.println("networkId = " + Long.toHexString(networkId.longValue()));
|
||||
System.out.println("keyPath = " + keyPath);
|
||||
System.out.println("servicePort = " + servicePort);
|
||||
// ZeroTier setup
|
||||
|
||||
//
|
||||
// BEGIN SETUP
|
||||
//
|
||||
ZeroTierNode node = new ZeroTierNode();
|
||||
|
||||
// Set up event listener and start service
|
||||
MyZeroTierEventListener listener = new MyZeroTierEventListener();
|
||||
ZeroTier.start(keyPath, (ZeroTierEventListener)listener, servicePort);
|
||||
// Wait for EVENT_NODE_ONLINE
|
||||
System.out.println("waiting for node to come online...");
|
||||
while (listener.isOnline == false) { sleep(50); }
|
||||
System.out.println("joining network");
|
||||
ZeroTier.join(networkId.longValue());
|
||||
// Wait for EVENT_NETWORK_READY_IP4/6
|
||||
System.out.println("waiting for network config...");
|
||||
while (listener.isNetworkReady == false) { sleep(50); }
|
||||
System.out.println("joined");
|
||||
node.initFromStorage(storagePath);
|
||||
// node.initSetEventHandler(new MyZeroTierEventListener());
|
||||
// node.initSetPort(9994);
|
||||
node.start();
|
||||
|
||||
//
|
||||
// END SETUP
|
||||
//
|
||||
System.out.println("Waiting for node to come online...");
|
||||
while (! node.isOnline()) {
|
||||
ZeroTierNative.zts_util_delay(50);
|
||||
}
|
||||
System.out.println("Node ID: " + Long.toHexString(node.getId()));
|
||||
System.out.println("Joining network...");
|
||||
node.join(networkId.longValue());
|
||||
System.out.println("Waiting for network...");
|
||||
while (! node.isNetworkTransportReady(networkId.longValue())) {
|
||||
ZeroTierNative.zts_util_delay(50);
|
||||
}
|
||||
System.out.println("joined");
|
||||
|
||||
sleep(120000);
|
||||
// Socket logic
|
||||
|
||||
/**
|
||||
*
|
||||
* Begin using socket API after this point:
|
||||
*
|
||||
* ZeroTier.ZeroTierSocket, ZeroTier.ZeroTierSocketFactory, etc
|
||||
*
|
||||
* (or)
|
||||
*
|
||||
* ZeroTier.socket(), ZeroTier.connect(), etc
|
||||
*/
|
||||
}
|
||||
if (mode.equals("server")) {
|
||||
System.out.println("Starting server...");
|
||||
try {
|
||||
ZeroTierSocket socket =
|
||||
new ZeroTierSocket(ZeroTierNative.ZTS_AF_INET, ZeroTierNative.ZTS_SOCK_STREAM, 0);
|
||||
socket.bind("0.0.0.0", port);
|
||||
socket.listen(100);
|
||||
ZeroTierSocket newConnection = socket.accept();
|
||||
ZeroTierInputStream inputStream = newConnection.getInputStream();
|
||||
DataInputStream dataInputStream = new DataInputStream(inputStream);
|
||||
String message = dataInputStream.readUTF();
|
||||
System.out.println("recv: " + message);
|
||||
socket.close();
|
||||
newConnection.close();
|
||||
}
|
||||
catch (Exception ex) {
|
||||
System.out.println(ex);
|
||||
}
|
||||
}
|
||||
|
||||
if (mode.equals("client")) {
|
||||
System.out.println("Starting client...");
|
||||
try {
|
||||
ZeroTierSocket socket =
|
||||
new ZeroTierSocket(ZeroTierNative.ZTS_AF_INET, ZeroTierNative.ZTS_SOCK_STREAM, 0);
|
||||
socket.connect(remoteAddr, port);
|
||||
ZeroTierOutputStream outputStream = socket.getOutputStream();
|
||||
DataOutputStream dataOutputStream = new DataOutputStream(outputStream);
|
||||
dataOutputStream.writeUTF("Hello from java!");
|
||||
socket.close();
|
||||
}
|
||||
catch (Exception ex) {
|
||||
System.out.println(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Example event handling
|
||||
* (OPTIONAL) event handler
|
||||
*/
|
||||
class MyZeroTierEventListener implements ZeroTierEventListener {
|
||||
|
||||
public boolean isNetworkReady = false;
|
||||
public boolean isOnline = false;
|
||||
|
||||
public void onZeroTierEvent(long id, int eventCode) {
|
||||
if (eventCode == ZeroTier.EVENT_NODE_UP) {
|
||||
System.out.println("EVENT_NODE_UP: nodeId=" + Long.toHexString(id));
|
||||
}
|
||||
if (eventCode == ZeroTier.EVENT_NODE_ONLINE) {
|
||||
// The core service is running properly and can join networks now
|
||||
System.out.println("EVENT_NODE_ONLINE: nodeId=" + Long.toHexString(id));
|
||||
isOnline = true;
|
||||
}
|
||||
if (eventCode == ZeroTier.EVENT_NODE_OFFLINE) {
|
||||
// Network does not seem to be reachable by any available strategy
|
||||
System.out.println("EVENT_NODE_OFFLINE");
|
||||
}
|
||||
if (eventCode == ZeroTier.EVENT_NODE_DOWN) {
|
||||
// Called when the node is shutting down
|
||||
System.out.println("EVENT_NODE_DOWN");
|
||||
}
|
||||
if (eventCode == ZeroTier.EVENT_NODE_IDENTITY_COLLISION) {
|
||||
// Another node with this identity already exists
|
||||
System.out.println("EVENT_NODE_IDENTITY_COLLISION");
|
||||
}
|
||||
if (eventCode == ZeroTier.EVENT_NODE_UNRECOVERABLE_ERROR) {
|
||||
// Try again
|
||||
System.out.println("EVENT_NODE_UNRECOVERABLE_ERROR");
|
||||
}
|
||||
if (eventCode == ZeroTier.EVENT_NODE_NORMAL_TERMINATION) {
|
||||
// Normal closure
|
||||
System.out.println("EVENT_NODE_NORMAL_TERMINATION");
|
||||
}
|
||||
if (eventCode == ZeroTier.EVENT_NETWORK_READY_IP4) {
|
||||
// We have at least one assigned address and we've received a network configuration
|
||||
System.out.println("ZTS_EVENT_NETWORK_READY_IP4: nwid=" + Long.toHexString(id));
|
||||
isNetworkReady = true;
|
||||
}
|
||||
if (eventCode == ZeroTier.EVENT_NETWORK_READY_IP6) {
|
||||
// We have at least one assigned address and we've received a network configuration
|
||||
System.out.println("ZTS_EVENT_NETWORK_READY_IP6: nwid=" + Long.toHexString(id));
|
||||
//isNetworkReady = true;
|
||||
}
|
||||
if (eventCode == ZeroTier.EVENT_NETWORK_DOWN) {
|
||||
// Someone called leave(), we have no assigned addresses, or otherwise cannot use this interface
|
||||
System.out.println("EVENT_NETWORK_DOWN: nwid=" + Long.toHexString(id));
|
||||
}
|
||||
if (eventCode == ZeroTier.EVENT_NETWORK_REQ_CONFIG) {
|
||||
// Waiting for network configuration
|
||||
System.out.println("EVENT_NETWORK_REQ_CONFIG: nwid=" + Long.toHexString(id));
|
||||
}
|
||||
if (eventCode == ZeroTier.EVENT_NETWORK_OK) {
|
||||
// Config received and this node is authorized for this network
|
||||
System.out.println("EVENT_NETWORK_OK: nwid=" + Long.toHexString(id));
|
||||
}
|
||||
if (eventCode == ZeroTier.EVENT_NETWORK_ACCESS_DENIED) {
|
||||
// You are not authorized to join this network
|
||||
System.out.println("EVENT_NETWORK_ACCESS_DENIED: nwid=" + Long.toHexString(id));
|
||||
}
|
||||
if (eventCode == ZeroTier.EVENT_NETWORK_NOT_FOUND) {
|
||||
// The virtual network does not exist
|
||||
System.out.println("EVENT_NETWORK_NOT_FOUND: nwid=" + Long.toHexString(id));
|
||||
}
|
||||
if (eventCode == ZeroTier.EVENT_NETWORK_CLIENT_TOO_OLD) {
|
||||
// The core version is too old
|
||||
System.out.println("EVENT_NETWORK_CLIENT_TOO_OLD: nwid=" + Long.toHexString(id));
|
||||
}
|
||||
if (eventCode == ZeroTier.EVENT_PEER_DIRECT) {
|
||||
System.out.println("EVENT_PEER_DIRECT: id=" + Long.toHexString(id));
|
||||
/*
|
||||
ZeroTierPeerDetails details = new ZeroTierPeerDetails();
|
||||
ZeroTier.get_peer(id, details);
|
||||
System.out.println("address="+Long.toHexString(details.address));
|
||||
System.out.println("pathCount="+details.pathCount);
|
||||
System.out.println("version="+details.versionMajor+"."+details.versionMinor+"."+details.versionRev);
|
||||
System.out.println("latency="+details.latency); // Not relevant
|
||||
System.out.println("role="+details.role); // Not relevent
|
||||
// Print all known paths
|
||||
for (int i=0; i<details.pathCount; i++) {
|
||||
System.out.println("addr="+details.paths[i].toString());
|
||||
}
|
||||
*/
|
||||
}
|
||||
if (eventCode == ZeroTier.EVENT_PEER_RELAY) {
|
||||
System.out.println("EVENT_PEER_RELAY: id=" + Long.toHexString(id));
|
||||
}
|
||||
}
|
||||
class MyZeroTierEventListener implements ZeroTierEventListener {
|
||||
public void onZeroTierEvent(long id, int event_code)
|
||||
{
|
||||
if (event_code == ZeroTierNative.ZTS_EVENT_NODE_UP) {
|
||||
System.out.println("EVENT_NODE_UP");
|
||||
}
|
||||
if (event_code == ZeroTierNative.ZTS_EVENT_NODE_ONLINE) {
|
||||
System.out.println("EVENT_NODE_ONLINE: " + Long.toHexString(id));
|
||||
}
|
||||
if (event_code == ZeroTierNative.ZTS_EVENT_NODE_OFFLINE) {
|
||||
System.out.println("EVENT_NODE_OFFLINE");
|
||||
}
|
||||
if (event_code == ZeroTierNative.ZTS_EVENT_NODE_DOWN) {
|
||||
System.out.println("EVENT_NODE_DOWN");
|
||||
}
|
||||
if (event_code == ZeroTierNative.ZTS_EVENT_NETWORK_READY_IP4) {
|
||||
System.out.println("ZTS_EVENT_NETWORK_READY_IP4: " + Long.toHexString(id));
|
||||
}
|
||||
if (event_code == ZeroTierNative.ZTS_EVENT_NETWORK_READY_IP6) {
|
||||
System.out.println("ZTS_EVENT_NETWORK_READY_IP6: " + Long.toHexString(id));
|
||||
}
|
||||
if (event_code == ZeroTierNative.ZTS_EVENT_NETWORK_DOWN) {
|
||||
System.out.println("EVENT_NETWORK_DOWN: " + Long.toHexString(id));
|
||||
}
|
||||
if (event_code == ZeroTierNative.ZTS_EVENT_NETWORK_OK) {
|
||||
System.out.println("EVENT_NETWORK_OK: " + Long.toHexString(id));
|
||||
}
|
||||
if (event_code == ZeroTierNative.ZTS_EVENT_NETWORK_ACCESS_DENIED) {
|
||||
System.out.println("EVENT_NETWORK_ACCESS_DENIED: " + Long.toHexString(id));
|
||||
}
|
||||
if (event_code == ZeroTierNative.ZTS_EVENT_NETWORK_NOT_FOUND) {
|
||||
System.out.println("EVENT_NETWORK_NOT_FOUND: " + Long.toHexString(id));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
# Java example
|
||||
|
||||
1). Build or download the `zt-1.3.3.jar`, copy it to this directory
|
||||
1). Build or download the `libzt-1.3.3.jar`, copy it to this directory
|
||||
|
||||
2). Run `make`
|
||||
|
||||
3). `java -cp ".:zt-1.3.3.jar" Example id_path 0123456789abcdef 9997`
|
||||
3). `java -cp ".:libzt-1.3.3.jar" Example id_path 0123456789abcdef 9997`
|
||||
|
||||
See [src/bindings/java](../../src/bindings/java) for wrapper implementation code.
|
||||
See [src/bindings/java](../../src/bindings/java) for wrapper implementation code.
|
||||
|
||||
@@ -1,557 +0,0 @@
|
||||
/*
|
||||
* Copyright (c)2013-2021 ZeroTier, Inc.
|
||||
*
|
||||
* Use of this software is governed by the Business Source License included
|
||||
* in the LICENSE.TXT file in the project's root directory.
|
||||
*
|
||||
* Change Date: 2025-01-01
|
||||
*
|
||||
* On the date above, in accordance with the Business Source License, use
|
||||
* of this software will be governed by version 2.0 of the Apache License.
|
||||
*/
|
||||
/****/
|
||||
|
||||
/**
|
||||
* @file
|
||||
*
|
||||
* ZeroTier Socket API
|
||||
*/
|
||||
|
||||
#ifdef ZTS_ENABLE_JAVA
|
||||
|
||||
#include "lwip/sockets.h"
|
||||
#include "lwip/def.h"
|
||||
#include "lwip/inet.h"
|
||||
#include "lwip/stats.h"
|
||||
|
||||
#include "ZeroTierSockets.h"
|
||||
|
||||
#define ZTS_STATE_NODE_RUNNING 0x01
|
||||
#define ZTS_STATE_STACK_RUNNING 0x02
|
||||
#define ZTS_STATE_NET_SERVICE_RUNNING 0x04
|
||||
#define ZTS_STATE_CALLBACKS_RUNNING 0x08
|
||||
#define ZTS_STATE_FREE_CALLED 0x10
|
||||
|
||||
#include <jni.h>
|
||||
|
||||
extern int zts_errno;
|
||||
|
||||
namespace ZeroTier {
|
||||
|
||||
extern uint8_t _serviceStateFlags;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void ss2zta(JNIEnv *env, struct zts_sockaddr_storage *ss, jobject addr);
|
||||
void zta2ss(JNIEnv *env, struct zts_sockaddr_storage *ss, jobject addr);
|
||||
void ztfdset2fdset(JNIEnv *env, int nfds, jobject src_ztfd_set, zts_fd_set *dest_fd_set);
|
||||
void fdset2ztfdset(JNIEnv *env, int nfds, zts_fd_set *src_fd_set, jobject dest_ztfd_set);
|
||||
|
||||
JNIEXPORT jint JNICALL Java_com_zerotier_libzt_ZeroTier_socket(
|
||||
JNIEnv *env, jobject thisObj, jint family, jint type, jint protocol)
|
||||
{
|
||||
int retval = zts_socket(family, type, protocol);
|
||||
return retval > -1 ? retval : -(zts_errno); // Encode lwIP errno into return value for JNI functions only
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL Java_com_zerotier_libzt_ZeroTier_connect(
|
||||
JNIEnv *env, jobject thisObj, jint fd, jobject addr)
|
||||
{
|
||||
struct zts_sockaddr_storage ss;
|
||||
zta2ss(env, &ss, addr);
|
||||
socklen_t addrlen = ss.ss_family == ZTS_AF_INET ? sizeof(struct zts_sockaddr_in) : sizeof(struct zts_sockaddr_in6);
|
||||
int retval = zts_connect(fd, (struct zts_sockaddr *)&ss, addrlen);
|
||||
return retval > -1 ? retval : -(zts_errno);
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL Java_com_zerotier_libzt_ZeroTier_bind(
|
||||
JNIEnv *env, jobject thisObj, jint fd, jobject addr)
|
||||
{
|
||||
struct zts_sockaddr_storage ss;
|
||||
zta2ss(env, &ss, addr);
|
||||
zts_socklen_t addrlen = ss.ss_family == ZTS_AF_INET ? sizeof(struct zts_sockaddr_in) : sizeof(struct zts_sockaddr_in6);
|
||||
int retval = zts_bind(fd, (struct zts_sockaddr*)&ss, addrlen);
|
||||
return retval > -1 ? retval : -(zts_errno);
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL Java_com_zerotier_libzt_ZeroTier_listen(
|
||||
JNIEnv *env, jobject thisObj, jint fd, int backlog)
|
||||
{
|
||||
int retval = zts_listen(fd, backlog);
|
||||
return retval > -1 ? retval : -(zts_errno);
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL Java_com_zerotier_libzt_ZeroTier_accept(
|
||||
JNIEnv *env, jobject thisObj, jint fd, jobject addr, jint port)
|
||||
{
|
||||
struct zts_sockaddr_storage ss;
|
||||
zts_socklen_t addrlen = sizeof(struct zts_sockaddr_storage);
|
||||
int retval = zts_accept(fd, (zts_sockaddr*)&ss, &addrlen);
|
||||
ss2zta(env, &ss, addr);
|
||||
return retval > -1 ? retval : -(zts_errno);
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL Java_com_zerotier_libzt_ZeroTier_setsockopt(
|
||||
JNIEnv *env, jobject thisObj, jint fd, jint level, jint optname, jobject optval)
|
||||
{
|
||||
jclass c = env->GetObjectClass(optval);
|
||||
if (!c) {
|
||||
return ZTS_ERR_SERVICE;
|
||||
}
|
||||
int optval_int = -1;
|
||||
|
||||
if (optname == SO_BROADCAST
|
||||
|| optname == SO_KEEPALIVE
|
||||
|| optname == SO_REUSEADDR
|
||||
|| optname == SO_REUSEPORT
|
||||
|| optname == TCP_NODELAY)
|
||||
{
|
||||
jfieldID fid = env->GetFieldID(c, "booleanValue", "Z");
|
||||
optval_int = (int)(env->GetBooleanField(optval, fid));
|
||||
}
|
||||
if (optname == IP_TTL
|
||||
|| optname == SO_RCVTIMEO
|
||||
|| optname == IP_TOS
|
||||
|| optname == SO_LINGER
|
||||
|| optname == SO_RCVBUF
|
||||
|| optname == SO_SNDBUF)
|
||||
{
|
||||
jfieldID fid = env->GetFieldID(c, "integerValue", "I");
|
||||
optval_int = env->GetIntField(optval, fid);
|
||||
}
|
||||
|
||||
int retval = ZTS_ERR_OK;
|
||||
|
||||
if (optname == SO_RCVTIMEO) {
|
||||
struct timeval tv;
|
||||
// Convert milliseconds from setSoTimeout() call to seconds and microseconds
|
||||
tv.tv_usec = optval_int * 1000;
|
||||
tv.tv_sec = optval_int / 1000000;
|
||||
retval = zts_setsockopt(fd, level, optname, &tv, sizeof(tv));
|
||||
}
|
||||
else {
|
||||
retval = zts_setsockopt(fd, level, optname, &optval_int, sizeof(optval_int));
|
||||
}
|
||||
return retval > -1 ? retval : -(zts_errno);
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL Java_com_zerotier_libzt_ZeroTier_getsockopt(
|
||||
JNIEnv *env, jobject thisObj, jint fd, jint level, jint optname, jobject optval)
|
||||
{
|
||||
jclass c = env->GetObjectClass(optval);
|
||||
if (!c) {
|
||||
return ZTS_ERR_SERVICE;
|
||||
}
|
||||
int optval_int = 0;
|
||||
zts_socklen_t optlen; // Intentionally not used
|
||||
|
||||
int retval;
|
||||
|
||||
if (optname == SO_RCVTIMEO) {
|
||||
struct zts_timeval tv;
|
||||
optlen = sizeof(tv);
|
||||
retval = zts_getsockopt(fd, level, optname, &tv, &optlen);
|
||||
// Convert seconds and microseconds back to milliseconds
|
||||
optval_int = (tv.tv_sec * 1000) + (tv.tv_usec / 1000);
|
||||
}
|
||||
else {
|
||||
retval = zts_getsockopt(fd, level, optname, &optval_int, &optlen);
|
||||
}
|
||||
|
||||
if (optname == SO_BROADCAST
|
||||
|| optname == SO_KEEPALIVE
|
||||
|| optname == SO_REUSEADDR
|
||||
|| optname == SO_REUSEPORT
|
||||
|| optname == TCP_NODELAY)
|
||||
{
|
||||
jfieldID fid = env->GetFieldID(c, "isBoolean", "Z");
|
||||
env->SetBooleanField(optval, fid, true);
|
||||
fid = env->GetFieldID(c, "booleanValue", "Z");
|
||||
env->SetBooleanField(optval, fid, (bool)optval_int);
|
||||
}
|
||||
if (optname == IP_TTL
|
||||
|| optname == SO_RCVTIMEO
|
||||
|| optname == IP_TOS
|
||||
|| optname == SO_LINGER
|
||||
|| optname == SO_RCVBUF
|
||||
|| optname == SO_SNDBUF)
|
||||
{
|
||||
jfieldID fid = env->GetFieldID(c, "isInteger", "Z");
|
||||
env->SetBooleanField(optval, fid, true);
|
||||
fid = env->GetFieldID(c, "integerValue", "I");
|
||||
env->SetIntField(optval, fid, optval_int);
|
||||
}
|
||||
return retval > -1 ? retval : -(zts_errno);
|
||||
}
|
||||
|
||||
JNIEXPORT jboolean JNICALL Java_com_zerotier_libzt_ZeroTier_getsockname(JNIEnv *env, jobject thisObj,
|
||||
jint fd, jobject addr)
|
||||
{
|
||||
struct zts_sockaddr_storage ss;
|
||||
zts_socklen_t addrlen = sizeof(struct zts_sockaddr_storage);
|
||||
int retval = zts_getsockname(fd, (struct zts_sockaddr *)&ss, &addrlen);
|
||||
ss2zta(env, &ss, addr);
|
||||
return retval > -1 ? retval : -(zts_errno);
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL Java_com_zerotier_libzt_ZeroTier_getpeername(JNIEnv *env, jobject thisObj,
|
||||
jint fd, jobject addr)
|
||||
{
|
||||
struct zts_sockaddr_storage ss;
|
||||
int retval = zts_getpeername(fd, (struct zts_sockaddr *)&ss, (zts_socklen_t*)sizeof(struct zts_sockaddr_storage));
|
||||
ss2zta(env, &ss, addr);
|
||||
return retval > -1 ? retval : -(zts_errno);
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL Java_com_zerotier_libzt_ZeroTier_close(
|
||||
JNIEnv *env, jobject thisObj, jint fd)
|
||||
{
|
||||
return zts_close(fd);
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL Java_com_zerotier_libzt_ZeroTier_select(JNIEnv *env, jobject thisObj,
|
||||
jint nfds, jobject readfds, jobject writefds, jobject exceptfds, jint timeout_sec, jint timeout_usec)
|
||||
{
|
||||
struct zts_timeval _timeout;
|
||||
_timeout.tv_sec = timeout_sec;
|
||||
_timeout.tv_usec = timeout_usec;
|
||||
zts_fd_set _readfds, _writefds, _exceptfds;
|
||||
zts_fd_set *r = NULL;
|
||||
zts_fd_set *w = NULL;
|
||||
zts_fd_set *e = NULL;
|
||||
if (readfds) {
|
||||
r = &_readfds;
|
||||
ztfdset2fdset(env, nfds, readfds, &_readfds);
|
||||
}
|
||||
if (writefds) {
|
||||
w = &_writefds;
|
||||
ztfdset2fdset(env, nfds, writefds, &_writefds);
|
||||
}
|
||||
if (exceptfds) {
|
||||
e = &_exceptfds;
|
||||
ztfdset2fdset(env, nfds, exceptfds, &_exceptfds);
|
||||
}
|
||||
int retval = zts_select(nfds, r, w, e, &_timeout);
|
||||
if (readfds) {
|
||||
fdset2ztfdset(env, nfds, &_readfds, readfds);
|
||||
}
|
||||
if (writefds) {
|
||||
fdset2ztfdset(env, nfds, &_writefds, writefds);
|
||||
}
|
||||
if (exceptfds) {
|
||||
fdset2ztfdset(env, nfds, &_exceptfds, exceptfds);
|
||||
}
|
||||
return retval > -1 ? retval : -(zts_errno);
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL Java_com_zerotier_libzt_ZeroTier_fcntl(
|
||||
JNIEnv *env, jobject thisObj, jint fd, jint cmd, jint flags)
|
||||
{
|
||||
int retval = zts_fcntl(fd, cmd, flags);
|
||||
return retval > -1 ? retval : -(zts_errno);
|
||||
}
|
||||
|
||||
JNIEXPORT int JNICALL Java_com_zerotier_libzt_ZeroTier_ioctl(
|
||||
JNIEnv *env, jobject thisObj, jint fd, jlong request, jobject argp)
|
||||
{
|
||||
int retval = ZTS_ERR_OK;
|
||||
if (request == FIONREAD) {
|
||||
int bytesRemaining = 0;
|
||||
retval = zts_ioctl(fd, request, &bytesRemaining);
|
||||
// set value in general object
|
||||
jclass c = env->GetObjectClass(argp);
|
||||
if (!c) {
|
||||
return ZTS_ERR_ARG;
|
||||
}
|
||||
jfieldID fid = env->GetFieldID(c, "integer", "I");
|
||||
env->SetIntField(argp, fid, bytesRemaining);
|
||||
}
|
||||
if (request == FIONBIO) {
|
||||
// TODO: double check
|
||||
int meaninglessVariable = 0;
|
||||
retval = zts_ioctl(fd, request, &meaninglessVariable);
|
||||
}
|
||||
return retval > -1 ? retval : -(zts_errno);
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL Java_com_zerotier_libzt_ZeroTier_send(
|
||||
JNIEnv *env, jobject thisObj, jint fd, jbyteArray buf, int flags)
|
||||
{
|
||||
void *data = env->GetPrimitiveArrayCritical(buf, NULL);
|
||||
int retval = zts_send(fd, data, env->GetArrayLength(buf), flags);
|
||||
env->ReleasePrimitiveArrayCritical(buf, data, 0);
|
||||
return retval > -1 ? retval : -(zts_errno);
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL Java_com_zerotier_libzt_ZeroTier_sendto(
|
||||
JNIEnv *env, jobject thisObj, jint fd, jbyteArray buf, jint flags, jobject addr)
|
||||
{
|
||||
void *data = env->GetPrimitiveArrayCritical(buf, NULL);
|
||||
struct zts_sockaddr_storage ss;
|
||||
zta2ss(env, &ss, addr);
|
||||
zts_socklen_t addrlen = ss.ss_family == ZTS_AF_INET ? sizeof(struct zts_sockaddr_in) : sizeof(struct zts_sockaddr_in6);
|
||||
int retval = zts_sendto(fd, data, env->GetArrayLength(buf), flags, (struct zts_sockaddr *)&ss, addrlen);
|
||||
env->ReleasePrimitiveArrayCritical(buf, data, 0);
|
||||
return retval > -1 ? retval : -(zts_errno);
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL Java_com_zerotier_libzt_ZeroTier_recv(JNIEnv *env, jobject thisObj,
|
||||
jint fd, jbyteArray buf, jint flags)
|
||||
{
|
||||
void *data = env->GetPrimitiveArrayCritical(buf, NULL);
|
||||
int retval = zts_recv(fd, data, env->GetArrayLength(buf), flags);
|
||||
env->ReleasePrimitiveArrayCritical(buf, data, 0);
|
||||
return retval > -1 ? retval : -(zts_errno);
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL Java_com_zerotier_libzt_ZeroTier_recvfrom(
|
||||
JNIEnv *env, jobject thisObj, jint fd, jbyteArray buf, jint flags, jobject addr)
|
||||
{
|
||||
zts_socklen_t addrlen = sizeof(struct zts_sockaddr_storage);
|
||||
struct zts_sockaddr_storage ss;
|
||||
void *data = env->GetPrimitiveArrayCritical(buf, NULL);
|
||||
int retval = zts_recvfrom(fd, data, env->GetArrayLength(buf), flags, (struct zts_sockaddr *)&ss, &addrlen);
|
||||
env->ReleasePrimitiveArrayCritical(buf, data, 0);
|
||||
ss2zta(env, &ss, addr);
|
||||
return retval > -1 ? retval : -(zts_errno);
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL Java_com_zerotier_libzt_ZeroTier_read(JNIEnv *env, jobject thisObj,
|
||||
jint fd, jbyteArray buf)
|
||||
{
|
||||
void *data = env->GetPrimitiveArrayCritical(buf, NULL);
|
||||
int retval = zts_read(fd, data, env->GetArrayLength(buf));
|
||||
env->ReleasePrimitiveArrayCritical(buf, data, 0);
|
||||
return retval > -1 ? retval : -(zts_errno);
|
||||
}
|
||||
|
||||
ssize_t zts_read_offset(int fd, void *buf, size_t offset, size_t len)
|
||||
{
|
||||
if (!(_serviceStateFlags & ZTS_STATE_NET_SERVICE_RUNNING)) {
|
||||
return ZTS_ERR_SERVICE;
|
||||
}
|
||||
if (!buf) {
|
||||
return ZTS_ERR_ARG;
|
||||
}
|
||||
char *cbuf = (char*)buf;
|
||||
return lwip_read(fd, &(cbuf[offset]), len);
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL Java_com_zerotier_libzt_ZeroTier_read_1offset(JNIEnv *env, jobject thisObj,
|
||||
jint fd, jbyteArray buf, jint offset, jint len)
|
||||
{
|
||||
void *data = env->GetPrimitiveArrayCritical(buf, NULL);
|
||||
int retval = zts_read_offset(fd, data, offset, len);
|
||||
env->ReleasePrimitiveArrayCritical(buf, data, 0);
|
||||
return retval > -1 ? retval : -(zts_errno);
|
||||
}
|
||||
JNIEXPORT jint JNICALL Java_com_zerotier_libzt_ZeroTier_read_1length(JNIEnv *env, jobject thisObj,
|
||||
jint fd, jbyteArray buf, jint len)
|
||||
{
|
||||
void *data = env->GetPrimitiveArrayCritical(buf, NULL);
|
||||
int retval = zts_read(fd, data, len);
|
||||
env->ReleasePrimitiveArrayCritical(buf, data, 0);
|
||||
return retval > -1 ? retval : -(zts_errno);
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL Java_com_zerotier_libzt_ZeroTier_write__IB(JNIEnv *env, jobject thisObj,
|
||||
jint fd, jbyteArray buf)
|
||||
{
|
||||
void *data = env->GetPrimitiveArrayCritical(buf, NULL);
|
||||
int retval = zts_write(fd, data, env->GetArrayLength(buf));
|
||||
env->ReleasePrimitiveArrayCritical(buf, data, 0);
|
||||
return retval > -1 ? retval : -(zts_errno);
|
||||
}
|
||||
JNIEXPORT jint JNICALL Java_com_zerotier_libzt_ZeroTier_write_1offset(JNIEnv *env, jobject thisObj,
|
||||
jint fd, jbyteArray buf, jint offset, jint len)
|
||||
{
|
||||
void *data = env->GetPrimitiveArrayCritical(&(buf[offset]), NULL); // PENDING: check?
|
||||
int retval = zts_write(fd, data, len);
|
||||
env->ReleasePrimitiveArrayCritical(buf, data, 0);
|
||||
return retval > -1 ? retval : -(zts_errno);
|
||||
}
|
||||
JNIEXPORT jint JNICALL Java_com_zerotier_libzt_ZeroTier_write_1byte(JNIEnv *env, jobject thisObj,
|
||||
jint fd, jbyte buf)
|
||||
{
|
||||
int retval = zts_write(fd, &buf, 1);
|
||||
return retval > -1 ? retval : -(zts_errno);
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL Java_com_zerotier_libzt_ZeroTier_shutdown(
|
||||
JNIEnv *env, jobject thisObj, int fd, int how)
|
||||
{
|
||||
return zts_shutdown(fd, how);
|
||||
}
|
||||
|
||||
#ifdef ZTS_ENABLE_STATS
|
||||
|
||||
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_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 // ZTS_ENABLE_STATS
|
||||
|
||||
void ztfdset2fdset(JNIEnv *env, int nfds, jobject src_ztfd_set, zts_fd_set *dest_fd_set)
|
||||
{
|
||||
jclass c = env->GetObjectClass(src_ztfd_set);
|
||||
if (!c) {
|
||||
return;
|
||||
}
|
||||
ZTS_FD_ZERO(dest_fd_set);
|
||||
jfieldID fid = env->GetFieldID(c, "fds_bits", "[B");
|
||||
jobject fdData = env->GetObjectField (src_ztfd_set, fid);
|
||||
jbyteArray * arr = reinterpret_cast<jbyteArray*>(&fdData);
|
||||
char *data = (char*)env->GetByteArrayElements(*arr, NULL);
|
||||
for (int i=0; i<nfds; i++) {
|
||||
if (data[i] == 0x01) {
|
||||
ZTS_FD_SET(i, dest_fd_set);
|
||||
}
|
||||
}
|
||||
env->ReleaseByteArrayElements(*arr, (jbyte*)data, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
void fdset2ztfdset(JNIEnv *env, int nfds, zts_fd_set *src_fd_set, jobject dest_ztfd_set)
|
||||
{
|
||||
jclass c = env->GetObjectClass(dest_ztfd_set);
|
||||
if (!c) {
|
||||
return;
|
||||
}
|
||||
jfieldID fid = env->GetFieldID(c, "fds_bits", "[B");
|
||||
jobject fdData = env->GetObjectField (dest_ztfd_set, fid);
|
||||
jbyteArray * arr = reinterpret_cast<jbyteArray*>(&fdData);
|
||||
char *data = (char*)env->GetByteArrayElements(*arr, NULL);
|
||||
for (int i=0; i<nfds; i++) {
|
||||
if (ZTS_FD_ISSET(i, src_fd_set)) {
|
||||
data[i] = 0x01;
|
||||
}
|
||||
}
|
||||
env->ReleaseByteArrayElements(*arr, (jbyte*)data, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// Helpers (for moving data across the JNI barrier) //
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void ss2zta(JNIEnv *env, struct zts_sockaddr_storage *ss, jobject addr)
|
||||
{
|
||||
jclass c = env->GetObjectClass(addr);
|
||||
if (!c) {
|
||||
return;
|
||||
}
|
||||
if(ss->ss_family == ZTS_AF_INET)
|
||||
{
|
||||
struct zts_sockaddr_in *in4 = (struct zts_sockaddr_in*)ss;
|
||||
jfieldID fid = env->GetFieldID(c, "_port", "I");
|
||||
env->SetIntField(addr, fid, lwip_ntohs(in4->sin_port));
|
||||
fid = env->GetFieldID(c,"_family", "I");
|
||||
env->SetIntField(addr, fid, (in4->sin_family));
|
||||
fid = env->GetFieldID(c, "_ip4", "[B");
|
||||
jobject ipData = env->GetObjectField (addr, fid);
|
||||
jbyteArray * arr = reinterpret_cast<jbyteArray*>(&ipData);
|
||||
char *data = (char*)env->GetByteArrayElements(*arr, NULL);
|
||||
memcpy(data, &(in4->sin_addr.s_addr), 4);
|
||||
env->ReleaseByteArrayElements(*arr, (jbyte*)data, 0);
|
||||
|
||||
return;
|
||||
}
|
||||
if(ss->ss_family == ZTS_AF_INET6)
|
||||
{
|
||||
struct zts_sockaddr_in6 *in6 = (struct zts_sockaddr_in6*)ss;
|
||||
jfieldID fid = env->GetFieldID(c, "_port", "I");
|
||||
env->SetIntField(addr, fid, lwip_ntohs(in6->sin6_port));
|
||||
fid = env->GetFieldID(c,"_family", "I");
|
||||
env->SetIntField(addr, fid, (in6->sin6_family));
|
||||
fid = env->GetFieldID(c, "_ip6", "[B");
|
||||
jobject ipData = env->GetObjectField (addr, fid);
|
||||
jbyteArray * arr = reinterpret_cast<jbyteArray*>(&ipData);
|
||||
char *data = (char*)env->GetByteArrayElements(*arr, NULL);
|
||||
memcpy(data, &(in6->sin6_addr.s6_addr), 16);
|
||||
env->ReleaseByteArrayElements(*arr, (jbyte*)data, 0);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void zta2ss(JNIEnv *env, struct zts_sockaddr_storage *ss, jobject addr)
|
||||
{
|
||||
jclass c = env->GetObjectClass(addr);
|
||||
if (!c) {
|
||||
return;
|
||||
}
|
||||
jfieldID fid = env->GetFieldID(c, "_family", "I");
|
||||
int family = env->GetIntField(addr, fid);
|
||||
if (family == ZTS_AF_INET)
|
||||
{
|
||||
struct zts_sockaddr_in *in4 = (struct zts_sockaddr_in*)ss;
|
||||
fid = env->GetFieldID(c, "_port", "I");
|
||||
in4->sin_port = lwip_htons(env->GetIntField(addr, fid));
|
||||
in4->sin_family = ZTS_AF_INET;
|
||||
fid = env->GetFieldID(c, "_ip4", "[B");
|
||||
jobject ipData = env->GetObjectField (addr, fid);
|
||||
jbyteArray * arr = reinterpret_cast<jbyteArray*>(&ipData);
|
||||
char *data = (char*)env->GetByteArrayElements(*arr, NULL);
|
||||
memcpy(&(in4->sin_addr.s_addr), data, 4);
|
||||
env->ReleaseByteArrayElements(*arr, (jbyte*)data, 0);
|
||||
return;
|
||||
}
|
||||
if (family == ZTS_AF_INET6)
|
||||
{
|
||||
struct zts_sockaddr_in6 *in6 = (struct zts_sockaddr_in6*)ss;
|
||||
jfieldID fid = env->GetFieldID(c, "_port", "I");
|
||||
in6->sin6_port = lwip_htons(env->GetIntField(addr, fid));
|
||||
fid = env->GetFieldID(c,"_family", "I");
|
||||
in6->sin6_family = ZTS_AF_INET6;
|
||||
fid = env->GetFieldID(c, "_ip6", "[B");
|
||||
jobject ipData = env->GetObjectField (addr, fid);
|
||||
jbyteArray * arr = reinterpret_cast<jbyteArray*>(&ipData);
|
||||
char *data = (char*)env->GetByteArrayElements(*arr, NULL);
|
||||
memcpy(&(in6->sin6_addr.s6_addr), data, 16);
|
||||
env->ReleaseByteArrayElements(*arr, (jbyte*)data, 0);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
} // namespace ZeroTier
|
||||
|
||||
#endif // ZTS_ENABLE_JAVA
|
||||
|
||||
1192
src/bindings/java/JavaSockets.cxx
Normal file
1192
src/bindings/java/JavaSockets.cxx
Normal file
File diff suppressed because it is too large
Load Diff
4
src/bindings/java/README.md
Normal file
4
src/bindings/java/README.md
Normal file
@@ -0,0 +1,4 @@
|
||||
Java Language Bindings
|
||||
=====
|
||||
|
||||
See [examples/java](./../../../examples/java/) for usage.
|
||||
24
src/bindings/java/ZeroTierEventListener.java
Normal file
24
src/bindings/java/ZeroTierEventListener.java
Normal file
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
* Copyright (c)2013-2021 ZeroTier, Inc.
|
||||
*
|
||||
* Use of this software is governed by the Business Source License included
|
||||
* in the LICENSE.TXT file in the project's root directory.
|
||||
*
|
||||
* Change Date: 2026-01-01
|
||||
*
|
||||
* On the date above, in accordance with the Business Source License, use
|
||||
* of this software will be governed by version 2.0 of the Apache License.
|
||||
*/
|
||||
/****/
|
||||
|
||||
package com.zerotier.sdk;
|
||||
|
||||
/**
|
||||
* Class that must be implemented to receive ZeroTier event notifications.
|
||||
*/
|
||||
interface ZeroTierEventListener {
|
||||
/*
|
||||
* Called when an even occurs within ZeroTier
|
||||
*/
|
||||
public void onZeroTierEvent(long nwid, int event_code);
|
||||
}
|
||||
55
src/bindings/java/ZeroTierFileDescriptorSet.java
Normal file
55
src/bindings/java/ZeroTierFileDescriptorSet.java
Normal file
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright (c)2013-2021 ZeroTier, Inc.
|
||||
*
|
||||
* Use of this software is governed by the Business Source License included
|
||||
* in the LICENSE.TXT file in the project's root directory.
|
||||
*
|
||||
* Change Date: 2026-01-01
|
||||
*
|
||||
* On the date above, in accordance with the Business Source License, use
|
||||
* of this software will be governed by version 2.0 of the Apache License.
|
||||
*/
|
||||
/****/
|
||||
|
||||
package com.zerotier.sdk;
|
||||
|
||||
/**
|
||||
* This class provides an fdset-like behavior to ZeroTierSocket
|
||||
*/
|
||||
class ZeroTierFileDescriptorSet {
|
||||
byte[] fds_bits = new byte[1024];
|
||||
|
||||
/**
|
||||
* Clear bit
|
||||
*/
|
||||
public void CLR(int fd)
|
||||
{
|
||||
fds_bits[fd] = 0x00;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if bit is set
|
||||
*/
|
||||
public boolean ISSET(int fd)
|
||||
{
|
||||
return fds_bits[fd] == 0x01;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set bit
|
||||
*/
|
||||
public void SET(int fd)
|
||||
{
|
||||
fds_bits[fd] = 0x01;
|
||||
}
|
||||
|
||||
/**
|
||||
* Zero-out all bits
|
||||
*/
|
||||
public void ZERO()
|
||||
{
|
||||
for (int i = 0; i < 1024; i++) {
|
||||
fds_bits[i] = 0x00;
|
||||
}
|
||||
}
|
||||
}
|
||||
209
src/bindings/java/ZeroTierInputStream.java
Normal file
209
src/bindings/java/ZeroTierInputStream.java
Normal file
@@ -0,0 +1,209 @@
|
||||
/*
|
||||
* Copyright (c)2013-2021 ZeroTier, Inc.
|
||||
*
|
||||
* Use of this software is governed by the Business Source License included
|
||||
* in the LICENSE.TXT file in the project's root directory.
|
||||
*
|
||||
* Change Date: 2026-01-01
|
||||
*
|
||||
* On the date above, in accordance with the Business Source License, use
|
||||
* of this software will be governed by version 2.0 of the Apache License.
|
||||
*/
|
||||
/****/
|
||||
|
||||
package com.zerotier.sdk;
|
||||
|
||||
import com.zerotier.sdk.ZeroTierNative;
|
||||
import java.io.*;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* Extends InputStream using ZeroTier as a transport
|
||||
*/
|
||||
public class ZeroTierInputStream extends InputStream {
|
||||
/**
|
||||
* File descriptor used by lower native layer
|
||||
*/
|
||||
public int zfd = -1;
|
||||
|
||||
/**
|
||||
* Close the ZeroTierInputStream
|
||||
* @exception IOException when an I/O error occurs
|
||||
*/
|
||||
public void close() throws IOException
|
||||
{
|
||||
/* Note: this operation currently only stops RX on a socket that is shared
|
||||
between both I/OStreams. This means that closing this stream will only shutdown
|
||||
that aspect of the socket but not actually close it and free resources. Resources
|
||||
will be properly freed when the socket implementation's close() is called or if
|
||||
both I/OStreams are closed separately */
|
||||
ZeroTierNative.zts_shutdown(zfd, ZeroTierNative.ZTS_SHUT_RD);
|
||||
zfd = -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Transfer bytes from this stream to another
|
||||
* @param destStream Unused
|
||||
* @return Number of bytes transferred
|
||||
* @exception IOException when an I/O error occurs
|
||||
*/
|
||||
public long transferTo(OutputStream destStream) throws IOException
|
||||
{
|
||||
Objects.requireNonNull(destStream, "destStream must not be null");
|
||||
int bytesTransferred = 0, bytesRead;
|
||||
byte[] buf = new byte[8192];
|
||||
while (((bytesRead = ZeroTierNative.zts_read(zfd, buf)) >= 0)) {
|
||||
destStream.write(buf, 0, bytesRead);
|
||||
bytesTransferred += bytesRead;
|
||||
}
|
||||
return bytesTransferred;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read a single byte from the stream
|
||||
* @return Single byte read
|
||||
* @exception IOException when an I/O error occurs
|
||||
*/
|
||||
public int read() throws IOException
|
||||
{
|
||||
byte[] buf = new byte[1];
|
||||
// Unlike a native read(), if nothing is read we should return -1
|
||||
int retval = ZeroTierNative.zts_read(zfd, buf);
|
||||
if ((retval == 0) | (retval == -104) /* EINTR, from SO_RCVTIMEO */) {
|
||||
return -1;
|
||||
}
|
||||
if (retval < 0) {
|
||||
throw new IOException("read(), errno=" + retval);
|
||||
}
|
||||
return buf[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Read from stream into buffer
|
||||
* @param destBuffer Destination buffer
|
||||
* @return Number of bytes read
|
||||
* @exception IOException when an I/O error occurs
|
||||
*/
|
||||
public int read(byte[] destBuffer) throws IOException
|
||||
{
|
||||
Objects.requireNonNull(destBuffer, "input byte array must not be null");
|
||||
// Unlike a native read(), if nothing is read we should return -1
|
||||
int retval = ZeroTierNative.zts_read(zfd, destBuffer);
|
||||
if ((retval == 0) | (retval == -104) /* EINTR, from SO_RCVTIMEO */) {
|
||||
return -1;
|
||||
}
|
||||
if (retval < 0) {
|
||||
throw new IOException("read(destBuffer), errno=" + retval);
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read from stream into buffer at offset
|
||||
* @param destBuffer Destination buffer
|
||||
* @param offset Where in the destination buffer bytes should be written
|
||||
* @param numBytes Number of bytes to read
|
||||
* @return Number of bytes read.
|
||||
* @exception IOException when an I/O error occurs
|
||||
*/
|
||||
public int read(byte[] destBuffer, int offset, int numBytes) throws IOException
|
||||
{
|
||||
Objects.requireNonNull(destBuffer, "input byte array must not be null");
|
||||
if (offset < 0) {
|
||||
throw new IndexOutOfBoundsException("offset < 0");
|
||||
}
|
||||
if (numBytes < 0) {
|
||||
throw new IndexOutOfBoundsException("numBytes < 0");
|
||||
}
|
||||
if (numBytes > (destBuffer.length - offset)) {
|
||||
throw new IndexOutOfBoundsException("numBytes > (destBuffer.length - offset");
|
||||
}
|
||||
if (numBytes == 0) {
|
||||
return 0;
|
||||
}
|
||||
// Unlike a native read(), if nothing is read we should return -1
|
||||
int retval = ZeroTierNative.zts_read_offset(zfd, destBuffer, offset, numBytes);
|
||||
if ((retval == 0) | (retval == -104) /* EINTR, from SO_RCVTIMEO */) {
|
||||
return -1;
|
||||
}
|
||||
if (retval < 0) {
|
||||
throw new IOException("read(destBuffer, offset, numBytes), errno=" + retval);
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read all available data from stream
|
||||
* @return Array of bytes
|
||||
* @exception IOException when an I/O error occurs
|
||||
*/
|
||||
public byte[] readAllBytes() throws IOException
|
||||
{
|
||||
int pendingDataSize = ZeroTierNative.zts_simple_get_pending_data_size(zfd);
|
||||
byte[] buf = new byte[pendingDataSize];
|
||||
int retval = ZeroTierNative.zts_read(zfd, buf);
|
||||
if ((retval == 0) | (retval == -104) /* EINTR, from SO_RCVTIMEO */) {
|
||||
// No action needed
|
||||
}
|
||||
if (retval < 0) {
|
||||
throw new IOException("readAllBytes(), errno=" + retval);
|
||||
}
|
||||
return buf;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read a given number of bytes from the stream into a buffer
|
||||
* @param destBuffer Destination buffer
|
||||
* @param offset Where in the destination buffer bytes should be written
|
||||
* @param numBytes Number of bytes to read
|
||||
* @return Nothing.
|
||||
* @exception IOException when an I/O error occurs
|
||||
*/
|
||||
public int readNBytes(byte[] destBuffer, int offset, int numBytes) throws IOException
|
||||
{
|
||||
Objects.requireNonNull(destBuffer, "input byte array must not be null");
|
||||
if (offset < 0) {
|
||||
throw new IndexOutOfBoundsException("offset < 0");
|
||||
}
|
||||
if (numBytes < 0) {
|
||||
throw new IndexOutOfBoundsException("numBytes < 0");
|
||||
}
|
||||
if (numBytes > (destBuffer.length - offset)) {
|
||||
throw new IndexOutOfBoundsException("numBytes > destBuffer.length - offset");
|
||||
}
|
||||
if (numBytes == 0) {
|
||||
return 0;
|
||||
}
|
||||
int retval = ZeroTierNative.zts_read_offset(zfd, destBuffer, offset, numBytes);
|
||||
if ((retval == 0) | (retval == -104) /* EINTR, from SO_RCVTIMEO */) {
|
||||
// No action needed
|
||||
}
|
||||
if (retval < 0) {
|
||||
throw new IOException("readNBytes(destBuffer, offset, numBytes), errno=" + retval);
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
/**
|
||||
* Skip a certain number of bytes
|
||||
* @param numBytes Unused
|
||||
* @return Nothing.
|
||||
* @exception IOException when an I/O error occurs
|
||||
*/
|
||||
public long skip(long numBytes) throws IOException
|
||||
{
|
||||
if (numBytes <= 0) {
|
||||
return 0;
|
||||
}
|
||||
long bytesRemaining = numBytes, bytesRead;
|
||||
int bufSize = (int)Math.min(2048, bytesRemaining);
|
||||
byte[] buf = new byte[bufSize];
|
||||
while (bytesRemaining > 0) {
|
||||
if ((bytesRead = ZeroTierNative.zts_read_length(zfd, buf, (int)Math.min(bufSize, bytesRemaining))) < 0) {
|
||||
break;
|
||||
}
|
||||
bytesRemaining -= bytesRead;
|
||||
}
|
||||
return numBytes - bytesRemaining;
|
||||
}
|
||||
}
|
||||
603
src/bindings/java/ZeroTierNative.java
Normal file
603
src/bindings/java/ZeroTierNative.java
Normal file
@@ -0,0 +1,603 @@
|
||||
/*
|
||||
* Copyright (c)2013-2021 ZeroTier, Inc.
|
||||
*
|
||||
* Use of this software is governed by the Business Source License included
|
||||
* in the LICENSE.TXT file in the project's root directory.
|
||||
*
|
||||
* Change Date: 2026-01-01
|
||||
*
|
||||
* On the date above, in accordance with the Business Source License, use
|
||||
* of this software will be governed by version 2.0 of the Apache License.
|
||||
*/
|
||||
/****/
|
||||
|
||||
package com.zerotier.sdk;
|
||||
|
||||
/**
|
||||
* Class that exposes the low-level C socket interface provided by libzt. This
|
||||
* can be used instead of the higher-level ZeroTierSocket API.
|
||||
*/
|
||||
public class ZeroTierNative {
|
||||
// Only to be called by static initializer of this class
|
||||
public static native int zts_init();
|
||||
|
||||
static
|
||||
{
|
||||
// Loads dynamic library at initialization time
|
||||
System.loadLibrary("zt");
|
||||
if (zts_init() != ZeroTierNative.ZTS_ERR_OK) {
|
||||
throw new ExceptionInInitializerError("JNI init() failed (see GetJavaVM())");
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------//
|
||||
// Event codes //
|
||||
//----------------------------------------------------------------------------//
|
||||
|
||||
/**
|
||||
* Node has been initialized
|
||||
*
|
||||
* This is the first event generated; and is always sent. It may occur
|
||||
* before node's constructor returns.
|
||||
*
|
||||
*/
|
||||
public static int ZTS_EVENT_NODE_UP = 200;
|
||||
|
||||
/**
|
||||
* Node is online -- at least one upstream node appears reachable
|
||||
*
|
||||
*/
|
||||
public static int ZTS_EVENT_NODE_ONLINE = 201;
|
||||
|
||||
/**
|
||||
* Node is offline -- network does not seem to be reachable by any available
|
||||
* strategy
|
||||
*
|
||||
*/
|
||||
public static int ZTS_EVENT_NODE_OFFLINE = 202;
|
||||
|
||||
/**
|
||||
* Node is shutting down
|
||||
*
|
||||
* This is generated within Node's destructor when it is being shut down.
|
||||
* It's done for convenience; since cleaning up other state in the event
|
||||
* handler may appear more idiomatic.
|
||||
*
|
||||
*/
|
||||
public static int ZTS_EVENT_NODE_DOWN = 203;
|
||||
|
||||
/**
|
||||
* A fatal error has occurred. One possible reason is:
|
||||
*
|
||||
* Your identity has collided with another node's ZeroTier address
|
||||
*
|
||||
* This happens if two different public keys both hash (via the algorithm
|
||||
* in Identity::generate()) to the same 40-bit ZeroTier address.
|
||||
*
|
||||
* This is something you should "never" see; where "never" is defined as
|
||||
* once per 2^39 new node initializations / identity creations. If you do
|
||||
* see it; you're going to see it very soon after a node is first
|
||||
* initialized.
|
||||
*
|
||||
* This is reported as an event rather than a return code since it's
|
||||
* detected asynchronously via error messages from authoritative nodes.
|
||||
*
|
||||
* If this occurs; you must shut down and delete the node; delete the
|
||||
* identity.secret record/file from the data store; and restart to generate
|
||||
* a new identity. If you don't do this; you will not be able to communicate
|
||||
* with other nodes.
|
||||
*
|
||||
* We'd automate this process; but we don't think silently deleting
|
||||
* private keys or changing our address without telling the calling code
|
||||
* is good form. It violates the principle of least surprise.
|
||||
*
|
||||
* You can technically get away with not handling this; but we recommend
|
||||
* doing so in a mature reliable application. Besides; handling this
|
||||
* condition is a good way to make sure it never arises. It's like how
|
||||
* umbrellas prevent rain and smoke detectors prevent fires. They do; right?
|
||||
*
|
||||
* Meta-data: none
|
||||
*/
|
||||
public static int ZTS_EVENT_NODE_FATAL_ERROR = 204;
|
||||
|
||||
/** Network ID does not correspond to a known network */
|
||||
public static int ZTS_EVENT_NETWORK_NOT_FOUND = 210;
|
||||
/** The version of ZeroTier inside libzt is too old */
|
||||
public static int ZTS_EVENT_NETWORK_CLIENT_TOO_OLD = 211;
|
||||
/** The configuration for a network has been requested (no action needed) */
|
||||
public static int ZTS_EVENT_NETWORK_REQ_CONFIG = 212;
|
||||
/** The node joined the network successfully (no action needed) */
|
||||
public static int ZTS_EVENT_NETWORK_OK = 213;
|
||||
/** The node is not allowed to join the network (you must authorize node) */
|
||||
public static int ZTS_EVENT_NETWORK_ACCESS_DENIED = 214;
|
||||
/** The node has received an IPv4 address from the network controller */
|
||||
public static int ZTS_EVENT_NETWORK_READY_IP4 = 215;
|
||||
/** The node has received an IPv6 address from the network controller */
|
||||
public static int ZTS_EVENT_NETWORK_READY_IP6 = 216;
|
||||
/** Deprecated */
|
||||
public static int ZTS_EVENT_NETWORK_READY_IP4_IP6 = 217;
|
||||
/** Network controller is unreachable */
|
||||
public static int ZTS_EVENT_NETWORK_DOWN = 218;
|
||||
/** Network change received from controller */
|
||||
public static int ZTS_EVENT_NETWORK_UPDATE = 219;
|
||||
|
||||
/** TCP/IP stack (lwIP) is up (for debug purposes) */
|
||||
public static int ZTS_EVENT_STACK_UP = 220;
|
||||
/** TCP/IP stack (lwIP) id down (for debug purposes) */
|
||||
public static int ZTS_EVENT_STACK_DOWN = 221;
|
||||
|
||||
/** lwIP netif up (for debug purposes) */
|
||||
public static int ZTS_EVENT_NETIF_UP = 230;
|
||||
/** lwIP netif down (for debug purposes) */
|
||||
public static int ZTS_EVENT_NETIF_DOWN = 231;
|
||||
/** lwIP netif removed (for debug purposes) */
|
||||
public static int ZTS_EVENT_NETIF_REMOVED = 232;
|
||||
/** lwIP netif link up (for debug purposes) */
|
||||
public static int ZTS_EVENT_NETIF_LINK_UP = 233;
|
||||
/** lwIP netif link down (for debug purposes) */
|
||||
public static int ZTS_EVENT_NETIF_LINK_DOWN = 234;
|
||||
|
||||
/** A direct P2P path to peer is known */
|
||||
public static int ZTS_EVENT_PEER_DIRECT = 240;
|
||||
/** A direct P2P path to peer is NOT known. Traffic is now relayed */
|
||||
public static int ZTS_EVENT_PEER_RELAY = 241;
|
||||
/** A peer is unreachable. Check NAT/Firewall settings */
|
||||
public static int ZTS_EVENT_PEER_UNREACHABLE = 242;
|
||||
/** A new path to a peer was discovered */
|
||||
public static int ZTS_EVENT_PEER_PATH_DISCOVERED = 243;
|
||||
/** A known path to a peer is now considered dead */
|
||||
public static int ZTS_EVENT_PEER_PATH_DEAD = 244;
|
||||
|
||||
/** A new managed network route was added */
|
||||
public static int ZTS_EVENT_ROUTE_ADDED = 250;
|
||||
/** A managed network route was removed */
|
||||
public static int ZTS_EVENT_ROUTE_REMOVED = 251;
|
||||
|
||||
/** A new managed IPv4 address was assigned to this peer */
|
||||
public static int ZTS_EVENT_ADDR_ADDED_IP4 = 260;
|
||||
/** A managed IPv4 address assignment was removed from this peer */
|
||||
public static int ZTS_EVENT_ADDR_REMOVED_IP4 = 261;
|
||||
/** A new managed IPv4 address was assigned to this peer */
|
||||
public static int ZTS_EVENT_ADDR_ADDED_IP6 = 262;
|
||||
/** A managed IPv6 address assignment was removed from this peer */
|
||||
public static int ZTS_EVENT_ADDR_REMOVED_IP6 = 263;
|
||||
|
||||
/** The node's secret key (identity) */
|
||||
public static int ZTS_EVENT_STORE_IDENTITY_SECRET = 270;
|
||||
/** The node's public key (identity) */
|
||||
public static int ZTS_EVENT_STORE_IDENTITY_PUBLIC = 271;
|
||||
/** The node has received an updated planet config */
|
||||
public static int ZTS_EVENT_STORE_PLANET = 272;
|
||||
/** New reachability hints and peer configuration */
|
||||
public static int ZTS_EVENT_STORE_PEER = 273;
|
||||
/** New network config */
|
||||
public static int ZTS_EVENT_STORE_NETWORK = 274;
|
||||
|
||||
// Socket protocol types
|
||||
/** Stream socket */
|
||||
public static int ZTS_SOCK_STREAM = 0x00000001;
|
||||
/** Datagram socket */
|
||||
public static int ZTS_SOCK_DGRAM = 0x00000002;
|
||||
public static int ZTS_SOCK_RAW = 0x00000003;
|
||||
// Socket family types
|
||||
/** IPv4 address family */
|
||||
public static int ZTS_AF_INET = 0x00000002;
|
||||
// another test comment
|
||||
/** IPv6 address family */
|
||||
public static int ZTS_AF_INET6 = 0x0000000a;
|
||||
/* yet one more */
|
||||
public static int ZTS_PF_INET = ZTS_AF_INET;
|
||||
public static int ZTS_PF_INET6 = ZTS_AF_INET6;
|
||||
// Used as level numbers for setsockopt() and getsockopt()
|
||||
public static int ZTS_IPPROTO_IP = 0x00000000;
|
||||
public static int ZTS_IPPROTO_ICMP = 0x00000001;
|
||||
public static int ZTS_IPPROTO_TCP = 0x00000006;
|
||||
public static int ZTS_IPPROTO_UDP = 0x00000011;
|
||||
public static int ZTS_IPPROTO_IPV6 = 0x00000029;
|
||||
public static int ZTS_IPPROTO_ICMPV6 = 0x0000003a;
|
||||
public static int ZTS_IPPROTO_UDPLITE = 0x00000088;
|
||||
public static int ZTS_IPPROTO_RAW = 0x000000ff;
|
||||
// send() and recv() flags
|
||||
public static int ZTS_MSG_PEEK = 0x00000001;
|
||||
public static int ZTS_MSG_WAITALL = 0x00000002;
|
||||
public static int ZTS_MSG_OOB = 0x00000004;
|
||||
public static int ZTS_MSG_DONTWAIT = 0x00000008;
|
||||
public static int ZTS_MSG_MORE = 0x00000010;
|
||||
// fnctl() commands
|
||||
public static int ZTS_F_GETFL = 0x00000003;
|
||||
public static int ZTS_F_SETFL = 0x00000004;
|
||||
// fnctl() flags
|
||||
public static int ZTS_O_NONBLOCK = 0x00000001;
|
||||
public static int ZTS_O_NDELAY = 0x00000001;
|
||||
// Shutdown commands
|
||||
public static int ZTS_SHUT_RD = 0x00000000;
|
||||
public static int ZTS_SHUT_WR = 0x00000001;
|
||||
public static int ZTS_SHUT_RDWR = 0x00000002;
|
||||
// ioctl() commands
|
||||
public static int ZTS_FIONREAD = 0x4008667F;
|
||||
public static int ZTS_FIONBIO = 0x8008667E;
|
||||
// Socket level option number
|
||||
public static int ZTS_SOL_SOCKET = 0x00000FFF;
|
||||
// Socket options
|
||||
public static int ZTS_SO_REUSEADDR = 0x00000004;
|
||||
public static int ZTS_SO_KEEPALIVE = 0x00000008;
|
||||
public static int ZTS_SO_BROADCAST = 0x00000020;
|
||||
// Socket options
|
||||
public static int ZTS_SO_DEBUG = 0x00000001; // NOT YET SUPPORTED
|
||||
public static int ZTS_SO_ACCEPTCONN = 0x00000002;
|
||||
public static int ZTS_SO_DONTROUTE = 0x00000010; // NOT YET SUPPORTED
|
||||
public static int ZTS_SO_USELOOPBACK = 0x00000040; // NOT YET SUPPORTED
|
||||
public static int ZTS_SO_LINGER = 0x00000080;
|
||||
public static int ZTS_SO_DONTLINGER = ((int)(~ZTS_SO_LINGER));
|
||||
public static int ZTS_SO_OOBINLINE = 0x00000100; // NOT YET SUPPORTED
|
||||
public static int ZTS_SO_REUSEPORT = 0x00000200; // NOT YET SUPPORTED
|
||||
public static int ZTS_SO_SNDBUF = 0x00001001; // NOT YET SUPPORTED
|
||||
public static int ZTS_SO_RCVBUF = 0x00001002;
|
||||
public static int ZTS_SO_SNDLOWAT = 0x00001003; // NOT YET SUPPORTED
|
||||
public static int ZTS_SO_RCVLOWAT = 0x00001004; // NOT YET SUPPORTED
|
||||
public static int ZTS_SO_SNDTIMEO = 0x00001005;
|
||||
public static int ZTS_SO_RCVTIMEO = 0x00001006;
|
||||
public static int ZTS_SO_ERROR = 0x00001007;
|
||||
public static int ZTS_SO_TYPE = 0x00001008;
|
||||
public static int ZTS_SO_CONTIMEO = 0x00001009; // NOT YET SUPPORTED
|
||||
public static int ZTS_SO_NO_CHECK = 0x0000100a;
|
||||
// IPPROTO_IP options
|
||||
public static int ZTS_IP_TOS = 0x00000001;
|
||||
public static int ZTS_IP_TTL = 0x00000002;
|
||||
// IPPROTO_TCP options
|
||||
public static int ZTS_TCP_NODELAY = 0x00000001;
|
||||
public static int ZTS_TCP_KEEPALIVE = 0x00000002;
|
||||
public static int ZTS_TCP_KEEPIDLE = 0x00000003;
|
||||
public static int ZTS_TCP_KEEPINTVL = 0x00000004;
|
||||
public static int ZTS_TCP_KEEPCNT = 0x00000005;
|
||||
|
||||
//----------------------------------------------------------------------------//
|
||||
// ZeroTier Service Controls //
|
||||
//----------------------------------------------------------------------------//
|
||||
|
||||
//----------------------------------------------------------------------------//
|
||||
// Error codes //
|
||||
//----------------------------------------------------------------------------//
|
||||
|
||||
/** (0) No error */
|
||||
public static int ZTS_ERR_OK = 0;
|
||||
/** (-1) Socket error, see zts_errno */
|
||||
public static int ZTS_ERR_SOCKET = -1;
|
||||
/** (-2) You probably did something at the wrong time */
|
||||
public static int ZTS_ERR_SERVICE = -2;
|
||||
/** (-3) Invalid argument */
|
||||
public static int ZTS_ERR_ARG = -3;
|
||||
/** (-4) No result (not necessarily an error) */
|
||||
public static int ZTS_ERR_RESULT = -4;
|
||||
/** (-5) Consider filing a bug report */
|
||||
public static int ZTS_ERR_GENERAL = -5;
|
||||
|
||||
//----------------------------------------------------------------------------//
|
||||
// zts_errno Error codes //
|
||||
//----------------------------------------------------------------------------//
|
||||
|
||||
/** Operation not permitted (`zts_errno` value) */
|
||||
public static int ZTS_EPERM = 1;
|
||||
/** No such file or directory */
|
||||
public static int ZTS_ENOENT = 2;
|
||||
/** No such process */
|
||||
public static int ZTS_ESRCH = 3;
|
||||
/** Interrupted system call */
|
||||
public static int ZTS_EINTR = 4;
|
||||
/** I/O error */
|
||||
public static int ZTS_EIO = 5;
|
||||
/** No such device or address */
|
||||
public static int ZTS_ENXIO = 6;
|
||||
/** Bad file number */
|
||||
public static int ZTS_EBADF = 9;
|
||||
/** Try again */
|
||||
public static int ZTS_EAGAIN = 11;
|
||||
/** Operation would block */
|
||||
public static int ZTS_EWOULDBLOCK = 11;
|
||||
/** Out of memory */
|
||||
public static int ZTS_ENOMEM = 12;
|
||||
/** Permission denied */
|
||||
public static int ZTS_EACCES = 13;
|
||||
/** Bad address */
|
||||
public static int ZTS_EFAULT = 14;
|
||||
/** Device or resource busy */
|
||||
public static int ZTS_EBUSY = 16;
|
||||
/** File exists */
|
||||
public static int ZTS_EEXIST = 17;
|
||||
/** No such device */
|
||||
public static int ZTS_ENODEV = 19;
|
||||
/** Invalid argument */
|
||||
public static int ZTS_EINVAL = 22;
|
||||
/** File table overflow */
|
||||
public static int ZTS_ENFILE = 23;
|
||||
/** Too many open files */
|
||||
public static int ZTS_EMFILE = 24;
|
||||
/** Function not implemented */
|
||||
public static int ZTS_ENOSYS = 38;
|
||||
/** Socket operation on non-socket */
|
||||
public static int ZTS_ENOTSOCK = 88;
|
||||
/** Destination address required */
|
||||
public static int ZTS_EDESTADDRREQ = 89;
|
||||
/** Message too long */
|
||||
public static int ZTS_EMSGSIZE = 90;
|
||||
/** Protocol wrong type for socket */
|
||||
public static int ZTS_EPROTOTYPE = 91;
|
||||
/** Protocol not available */
|
||||
public static int ZTS_ENOPROTOOPT = 92;
|
||||
/** Protocol not supported */
|
||||
public static int ZTS_EPROTONOSUPPORT = 93;
|
||||
/** Socket type not supported */
|
||||
public static int ZTS_ESOCKTNOSUPPORT = 94;
|
||||
/** Operation not supported on transport endpoint */
|
||||
public static int ZTS_EOPNOTSUPP = 95;
|
||||
/** Protocol family not supported */
|
||||
public static int ZTS_EPFNOSUPPORT = 96;
|
||||
/** Address family not supported by protocol */
|
||||
public static int ZTS_EAFNOSUPPORT = 97;
|
||||
/** Address already in use */
|
||||
public static int ZTS_EADDRINUSE = 98;
|
||||
/** Cannot assign requested address */
|
||||
public static int ZTS_EADDRNOTAVAIL = 99;
|
||||
/** Network is down */
|
||||
public static int ZTS_ENETDOWN = 100;
|
||||
/** Network is unreachable */
|
||||
public static int ZTS_ENETUNREACH = 101;
|
||||
/** Software caused connection abort */
|
||||
public static int ZTS_ECONNABORTED = 103;
|
||||
/** Connection reset by peer */
|
||||
public static int ZTS_ECONNRESET = 104;
|
||||
/** No buffer space available */
|
||||
public static int ZTS_ENOBUFS = 105;
|
||||
/** Transport endpoint is already connected */
|
||||
public static int ZTS_EISCONN = 106;
|
||||
/** Transport endpoint is not connected */
|
||||
public static int ZTS_ENOTCONN = 107;
|
||||
/** Connection timed out */
|
||||
public static int ZTS_ETIMEDOUT = 110;
|
||||
/** No route to host */
|
||||
public static int ZTS_EHOSTUNREACH = 113;
|
||||
/** Operation already in progress */
|
||||
public static int ZTS_EALREADY = 114;
|
||||
/** Operation now in progress */
|
||||
public static int ZTS_EINPROGRESS = 115;
|
||||
|
||||
//----------------------------------------------------------------------------//
|
||||
// Misc definitions //
|
||||
//----------------------------------------------------------------------------//
|
||||
|
||||
/**
|
||||
* Length of human-readable MAC address string
|
||||
*/
|
||||
public static int ZTS_MAC_ADDRSTRLEN = 18;
|
||||
|
||||
/**
|
||||
* Max length of human-readable IPv4 string
|
||||
*/
|
||||
public static int ZTS_INET_ADDRSTRLEN = 16;
|
||||
|
||||
/**
|
||||
* Max length of human-readable IPv6 string
|
||||
*/
|
||||
public static int ZTS_INET6_ADDRSTRLEN = 46;
|
||||
|
||||
/**
|
||||
* Maximum (and required) length of string buffers used to receive
|
||||
* string-format IP addresses from the API. This is set to `ZTS_INET6_ADDRSTRLEN`
|
||||
* to handle all cases: `ZTS_AF_INET` and `ZTS_AF_INET6`
|
||||
*/
|
||||
public static int ZTS_IP_MAX_STR_LEN = 46;
|
||||
|
||||
/**
|
||||
* Required buffer length to safely receive data store items
|
||||
*/
|
||||
public static int ZTS_STORE_DATA_LEN = 4096;
|
||||
|
||||
/**
|
||||
* Maximum length of network short name
|
||||
*/
|
||||
public static int ZTS_MAX_NETWORK_SHORT_NAME_LENGTH = 127;
|
||||
|
||||
/**
|
||||
* Maximum number of pushed routes on a network
|
||||
*/
|
||||
public static int ZTS_MAX_NETWORK_ROUTES = 32;
|
||||
|
||||
/**
|
||||
* Maximum number of statically assigned IP addresses per network endpoint
|
||||
* using ZT address management (not DHCP)
|
||||
*/
|
||||
public static int ZTS_MAX_ASSIGNED_ADDRESSES = 16;
|
||||
|
||||
/**
|
||||
* Maximum number of direct network paths to a given peer
|
||||
*/
|
||||
public static int ZTS_MAX_PEER_NETWORK_PATHS = 16;
|
||||
|
||||
/**
|
||||
* Maximum number of multicast groups a device / network interface can be
|
||||
* subscribed to at once
|
||||
*/
|
||||
public static int ZTS_MAX_MULTICAST_SUBSCRIPTIONS = 1024;
|
||||
|
||||
/**
|
||||
* The length of a human-friendly identity key pair string
|
||||
*/
|
||||
public static int ZTS_ID_STR_BUF_LEN = 384;
|
||||
|
||||
// public static native int zts_id_new(char* key, int* key_buf_len);
|
||||
// public static native int zts_id_pair_is_valid(/*const*/ char* key, int len);
|
||||
|
||||
public static native int zts_init_from_storage(String path);
|
||||
public static native int zts_init_set_event_handler(ZeroTierEventListener callbackClass);
|
||||
public static native int zts_init_set_port(short port);
|
||||
|
||||
// public static native int zts_init_from_memory(/*const*/ char* key, int len);
|
||||
public static native int zts_init_blacklist_if(/*const*/ String prefix, int len);
|
||||
// public static native int zts_init_set_roots(/*const*/ void* roots_data, int len);
|
||||
public static native int zts_init_allow_net_cache(int allowed);
|
||||
public static native int zts_init_allow_peer_cache(int allowed);
|
||||
public static native int zts_init_allow_roots_cache(int allowed);
|
||||
public static native int zts_init_allow_id_cache(int allowed);
|
||||
public static native int zts_addr_is_assigned(long net_id, int family);
|
||||
// public static native int zts_addr_get(long net_id, int family, struct sockaddr_storage* addr);
|
||||
// public static native int zts_addr_get_str(long net_id, int family, char* dst, int len);
|
||||
// public static native int zts_addr_get_all(long net_id, struct sockaddr_storage* addr, int* count);
|
||||
// public static native int zts_addr_compute_6plane(/*const*/ long net_id, /*const*/ long node_id, struct
|
||||
// sockaddr_storage* addr); public static native int zts_addr_compute_rfc4193(/*const*/ long net_id, /*const*/ long
|
||||
// node_id, struct sockaddr_storage* addr);
|
||||
public static native int zts_addr_compute_rfc4193_str(long net_id, long node_id, String dst, int len);
|
||||
public static native int zts_addr_compute_6plane_str(long net_id, long node_id, String dst, int len);
|
||||
|
||||
public static native long zts_net_compute_adhoc_id(short start_port, short end_port);
|
||||
public static native int zts_net_join(long net_id);
|
||||
public static native int zts_net_leave(long net_id);
|
||||
public static native int zts_net_transport_is_ready(/*const*/ long net_id);
|
||||
public static native long zts_net_get_mac(long net_id);
|
||||
public static native int zts_net_get_mac_str(long net_id, String dst, int len);
|
||||
public static native int zts_net_get_broadcast(long net_id);
|
||||
public static native int zts_net_get_mtu(long net_id);
|
||||
public static native int zts_net_get_name(long net_id, String dst, int len);
|
||||
public static native int zts_net_get_status(long net_id);
|
||||
public static native int zts_net_get_type(long net_id);
|
||||
|
||||
public static native int zts_route_is_assigned(long net_id, int family);
|
||||
|
||||
public static native int zts_node_start();
|
||||
public static native int zts_node_is_online();
|
||||
public static native long zts_node_get_id();
|
||||
// public static native int zts_node_get_id_pair(char* key, int* key_buf_len);
|
||||
public static native int zts_node_get_port();
|
||||
public static native int zts_node_stop();
|
||||
public static native int zts_node_free();
|
||||
|
||||
public static native int zts_moon_orbit(long moon_roots_id, long moon_seed);
|
||||
public static native int zts_moon_deorbit(long moon_roots_id);
|
||||
|
||||
// public static native int zts_socket(int family, int type, int protocol);
|
||||
// public static native int zts_connect(int fd, /*const*/ struct sockaddr* addr, socklen_t addrlen);
|
||||
// public static native int zts_bind(int fd, /*const*/ struct sockaddr* addr, socklen_t addrlen);
|
||||
// public static native int zts_listen(int fd, int backlog);
|
||||
// public static native int zts_accept(int fd, struct sockaddr* addr, socklen_t* addrlen);
|
||||
// public static native int zts_setsockopt(int fd, int level, int optname, /*const*/ void* optval, socklen_t
|
||||
// optlen); public static native int zts_getsockopt(int fd, int level, int optname, void* optval, socklen_t*
|
||||
// optlen); public static native int zts_getsockname(int fd, struct sockaddr* addr, socklen_t* addrlen); public
|
||||
// static native int zts_getpeername(int fd, struct sockaddr* addr, socklen_t* addrlen); public static native int
|
||||
// zts_close(int fd); public static native int zts_select(int nfds, fd_set* readfds, fd_set* writefds, fd_set*
|
||||
// exceptfds, struct timeval* timeout); public static native int zts_fcntl(int fd, int cmd, int flags); public
|
||||
// static native int zts_poll(struct pollfd* fds, nfds_t nfds, int timeout); public static native int zts_ioctl(int
|
||||
// fd, long request, void* argp); public static native int send(int fd, /*const*/ void* buf, size_t len, int
|
||||
// flags); public static native int sendto(int fd,
|
||||
// /*const*/ void* buf, size_t len, int flags, /*const*/ struct sockaddr* addr, socklen_t addrlen); public static
|
||||
// native int sendmsg(int fd, /*const*/ struct msghdr* msg, int flags); public static native int recv(int fd,
|
||||
// void* buf, size_t len, int flags); public static native int recvfrom(int fd, void* buf, size_t len, int flags,
|
||||
// struct sockaddr* addr, socklen_t* addrlen); public static native int recvmsg(int fd, struct msghdr* msg, int
|
||||
// flags); public static native int read(int fd, void* buf, size_t len); public static native int readv(int fd,
|
||||
// /*const*/ struct iovec* iov, int iovcnt); public static native int write(int fd, /*const*/ void* buf, size_t
|
||||
// len); public static native int writev(int fd, /*const*/ struct iovec* iov, int iovcnt); public static native int
|
||||
// shutdown(int fd, int how);
|
||||
public static native int zts_simple_connect(int fd, /*const*/ String ipstr, int port, int timeout_ms);
|
||||
public static native int zts_simple_bind(int fd, /*const*/ String ipstr, int port);
|
||||
// public static native int zts_simple_accept(int fd, String remote_addr, int len, int* port);
|
||||
public static native int zts_simple_tcp_client(/*const*/ String remote_ipstr, int remote_port);
|
||||
// public static native int zts_simple_tcp_server(/*const*/ String local_ipstr, int local_port, String remote_ipstr,
|
||||
// int len, int* remote_port);
|
||||
public static native int zts_simple_udp_server(/*const*/ String local_ipstr, int local_port);
|
||||
public static native int zts_simple_udp_client(/*const*/ String remote_ipstr);
|
||||
public static native int zts_simple_set_no_delay(int fd, int enabled);
|
||||
public static native int zts_simple_get_no_delay(int fd);
|
||||
public static native int zts_simple_set_linger(int fd, int enabled, int value);
|
||||
public static native int zts_simple_get_linger_enabled(int fd);
|
||||
public static native int zts_simple_get_linger_value(int fd);
|
||||
public static native int zts_simple_get_pending_data_size(int fd);
|
||||
public static native int zts_simple_set_reuse_addr(int fd, int enabled);
|
||||
public static native int zts_simple_get_reuse_addr(int fd);
|
||||
public static native int zts_simple_set_recv_timeout(int fd, int seconds, int microseconds);
|
||||
public static native int zts_simple_get_recv_timeout(int fd);
|
||||
public static native int zts_simple_set_send_timeout(int fd, int seconds, int microseconds);
|
||||
public static native int zts_simple_get_send_timeout(int fd);
|
||||
public static native int zts_simple_set_send_buf_size(int fd, int size);
|
||||
public static native int zts_simple_get_send_buf_size(int fd);
|
||||
public static native int zts_simple_set_recv_buf_size(int fd, int size);
|
||||
public static native int zts_simple_get_recv_buf_size(int fd);
|
||||
public static native int zts_simple_set_ttl(int fd, int ttl);
|
||||
public static native int zts_simple_get_ttl(int fd);
|
||||
public static native int zts_simple_set_blocking(int fd, int enabled);
|
||||
public static native int zts_simple_get_blocking(int fd);
|
||||
public static native int zts_simple_set_keepalive(int fd, int enabled);
|
||||
public static native int zts_simple_get_keepalive(int fd);
|
||||
// struct hostent* gethostbyname(/*const*/ String name);
|
||||
// public static native int zts_dns_set_server(uint8_t index, /*const*/ ip_addr* addr);
|
||||
// ZTS_API /*const*/ ip_addr* ZTCALL dns_get_server(uint8_t index);
|
||||
public static native int zts_core_lock_obtain();
|
||||
public static native int zts_core_lock_release();
|
||||
public static native int zts_core_query_addr_count(long net_id);
|
||||
public static native int zts_core_query_addr(long net_id, int idx, String addr, int len);
|
||||
public static native int zts_core_query_route_count(long net_id);
|
||||
/*
|
||||
public static native int zts_core_query_route(
|
||||
long net_id,
|
||||
int idx,
|
||||
String target,
|
||||
String via,
|
||||
int len,
|
||||
short* flags,
|
||||
short* metric);
|
||||
*/
|
||||
public static native int zts_core_query_path_count(long peer_id);
|
||||
public static native int zts_core_query_path(long peer_id, int idx, String dst, int len);
|
||||
public static native int zts_core_query_mc_count(long net_id);
|
||||
// public static native int zts_core_query_mc(long net_id, int idx, long* mac, uint32_t* adi);
|
||||
/*
|
||||
public static native int zts_util_roots_new(
|
||||
char* roots_out,
|
||||
int* roots_len,
|
||||
char* prev_key,
|
||||
int* prev_key_len,
|
||||
char* curr_key,
|
||||
int* curr_key_len,
|
||||
long id,
|
||||
long ts,
|
||||
roots_t* roots_spec);
|
||||
*/
|
||||
public static native void zts_util_delay(long milliseconds);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// Socket API //
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
public static native int zts_socket(int family, int type, int protocol);
|
||||
// public static native int zts_connect(int fd, ZeroTierSocketAddress addr);
|
||||
// public static native int zts_bind(int fd, ZeroTierSocketAddress addr);
|
||||
public static native int zts_listen(int fd, int backlog);
|
||||
public static native int zts_accept(int fd, ZeroTierSocketAddress addr);
|
||||
|
||||
// public static native int zts_setsockopt(int fd, int level, int optname, ZeroTierSocketOptionValue optval);
|
||||
// public static native int zts_getsockopt(int fd, int level, int optname, ZeroTierSocketOptionValue optval);
|
||||
|
||||
public static native int zts_read(int fd, byte[] buf);
|
||||
public static native int zts_read_offset(int fd, byte[] buf, int offset, int len);
|
||||
public static native int zts_read_length(int fd, byte[] buf, int len);
|
||||
public static native int zts_recv(int fd, byte[] buf, int flags);
|
||||
public static native int zts_recvfrom(int fd, byte[] buf, int flags, ZeroTierSocketAddress addr);
|
||||
|
||||
public static native int zts_write(int fd, byte[] buf);
|
||||
public static native int zts_write_byte(int fd, byte b);
|
||||
public static native int zts_write_offset(int fd, byte[] buf, int offset, int len);
|
||||
public static native int zts_sendto(int fd, byte[] buf, int flags, ZeroTierSocketAddress addr);
|
||||
public static native int zts_send(int fd, byte[] buf, int flags);
|
||||
|
||||
public static native int zts_shutdown(int fd, int how);
|
||||
public static native int zts_close(int fd);
|
||||
|
||||
public static native boolean zts_getsockname(int fd, ZeroTierSocketAddress addr);
|
||||
public static native int zts_getpeername(int fd, ZeroTierSocketAddress addr);
|
||||
public static native int zts_fcntl(int sock, int cmd, int flag);
|
||||
// public static native int zts_ioctl(int fd, long request, ZeroTierIoctlArg arg);
|
||||
public static native int zts_select(
|
||||
int nfds,
|
||||
ZeroTierFileDescriptorSet readfds,
|
||||
ZeroTierFileDescriptorSet writefds,
|
||||
ZeroTierFileDescriptorSet exceptfds,
|
||||
int timeout_sec,
|
||||
int timeout_usec);
|
||||
}
|
||||
194
src/bindings/java/ZeroTierNode.java
Normal file
194
src/bindings/java/ZeroTierNode.java
Normal file
@@ -0,0 +1,194 @@
|
||||
/*
|
||||
* Copyright (c)2013-2021 ZeroTier, Inc.
|
||||
*
|
||||
* Use of this software is governed by the Business Source License included
|
||||
* in the LICENSE.TXT file in the project's root directory.
|
||||
*
|
||||
* Change Date: 2026-01-01
|
||||
*
|
||||
* On the date above, in accordance with the Business Source License, use
|
||||
* of this software will be governed by version 2.0 of the Apache License.
|
||||
*/
|
||||
/****/
|
||||
|
||||
package com.zerotier.sdk;
|
||||
|
||||
import com.zerotier.sdk.*;
|
||||
|
||||
/**
|
||||
* Class that provides a control interface for nodes and networks by
|
||||
* wrapping the ZeroTierNative class.
|
||||
*/
|
||||
public class ZeroTierNode {
|
||||
/**
|
||||
* Start the ZeroTier node
|
||||
*
|
||||
* @return Standard
|
||||
*/
|
||||
public int start()
|
||||
{
|
||||
return ZeroTierNative.zts_node_start();
|
||||
}
|
||||
|
||||
/**
|
||||
* Stop the ZeroTier node
|
||||
*
|
||||
* @return return
|
||||
*/
|
||||
public int stop()
|
||||
{
|
||||
return ZeroTierNative.zts_node_stop();
|
||||
}
|
||||
|
||||
/**
|
||||
* (Optional) Instruct ZeroTier to read and write identities and cache from a
|
||||
* storage location. Note that this is an initialization method that should
|
||||
* be called before {@code start()}.
|
||||
*
|
||||
* @param storagePath Where to read and write files
|
||||
*
|
||||
* @return return
|
||||
*/
|
||||
public int initFromStorage(String storagePath)
|
||||
{
|
||||
return ZeroTierNative.zts_init_from_storage(storagePath);
|
||||
}
|
||||
|
||||
/**
|
||||
* (Optional) Whether caching of peer address information to storage is allowed. This
|
||||
* is true by default if {@code initFromStorage()} is used. Note that this is an
|
||||
* initialization method that can only be called before {@code start()}.
|
||||
*
|
||||
* @param allowed Whether caching or storage of this item is allowed
|
||||
*
|
||||
* @return return
|
||||
*/
|
||||
public int initAllowPeerCache(boolean allowed)
|
||||
{
|
||||
return ZeroTierNative.zts_init_allow_peer_cache(allowed ? 1 : 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* (Optional) Whether caching of network configuration data to storage is allowed. This
|
||||
* is true by default if {@code initFromStorage()} is used. Note that this is an
|
||||
* initialization method that can only be called before {@code start()}.
|
||||
*
|
||||
* @param allowed Whether caching or storage of this item is allowed
|
||||
*
|
||||
* @return return
|
||||
*/
|
||||
public int initAllowNetworkCache(boolean allowed)
|
||||
{
|
||||
return ZeroTierNative.zts_init_allow_net_cache(allowed ? 1 : 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* (Optional) Whether caching of identity key pairs to storage is allowed. This
|
||||
* is true by default if {@code initFromStorage()} is used. Note that this is an
|
||||
* initialization method that can only be called before {@code start()}.
|
||||
*
|
||||
* @param allowed Whether caching or storage of this item is allowed
|
||||
*
|
||||
* @return return
|
||||
*/
|
||||
public int initAllowIdCache(boolean allowed)
|
||||
{
|
||||
return ZeroTierNative.zts_init_allow_id_cache(allowed ? 1 : 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* (Optional) Whether caching of root topology to storage is allowed. This
|
||||
* is true by default if {@code initFromStorage()} is used. Note that this is an
|
||||
* initialization method that can only be called before {@code start()}.
|
||||
*
|
||||
* @param allowed Whether caching or storage of this item is allowed
|
||||
*
|
||||
* @return return
|
||||
*/
|
||||
public int initAllowRootsCache(boolean allowed)
|
||||
{
|
||||
return ZeroTierNative.zts_init_allow_roots_cache(allowed ? 1 : 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* (Optional) Set the ZeroTier service port. Note that this is an
|
||||
* initialization method that can only be called before {@code start()}.
|
||||
*
|
||||
* @param port Port number
|
||||
*
|
||||
* @return return
|
||||
*/
|
||||
public int initSetPort(short port)
|
||||
{
|
||||
return ZeroTierNative.zts_init_set_port(port);
|
||||
}
|
||||
|
||||
/**
|
||||
* (Optional) Set the event handler function. Note that this is an
|
||||
* initialization method that can only be called before {@code start()}.
|
||||
*
|
||||
* @param handler Function to handle internal ZeroTier events
|
||||
*
|
||||
* @return return
|
||||
*/
|
||||
public int initSetEventHandler(ZeroTierEventListener handler)
|
||||
{
|
||||
return ZeroTierNative.zts_init_set_event_handler(handler);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return whether the ZeroTier node is currently online (able to reach a root)
|
||||
*
|
||||
* @return return
|
||||
*/
|
||||
public boolean isOnline()
|
||||
{
|
||||
return ZeroTierNative.zts_node_is_online() == 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Join a network
|
||||
*
|
||||
* @param networkId Network to join
|
||||
*
|
||||
* @return return
|
||||
*/
|
||||
public int join(long networkId)
|
||||
{
|
||||
return ZeroTierNative.zts_net_join(networkId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Leave a network
|
||||
*
|
||||
* @param networkId Network to leave
|
||||
*
|
||||
* @return return
|
||||
*/
|
||||
public int leave(long networkId)
|
||||
{
|
||||
return ZeroTierNative.zts_net_leave(networkId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return whether the given network is ready to process traffic
|
||||
*
|
||||
* @param networkId Network to test
|
||||
*
|
||||
* @return return
|
||||
*/
|
||||
public boolean isNetworkTransportReady(long networkId)
|
||||
{
|
||||
return ZeroTierNative.zts_net_transport_is_ready(networkId) == 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the identity of this node (public key)
|
||||
*
|
||||
* @return 64-bit integer representing the 10-digit hexadecimal node ID
|
||||
*/
|
||||
public long getId()
|
||||
{
|
||||
return ZeroTierNative.zts_node_get_id();
|
||||
}
|
||||
}
|
||||
97
src/bindings/java/ZeroTierOutputStream.java
Normal file
97
src/bindings/java/ZeroTierOutputStream.java
Normal file
@@ -0,0 +1,97 @@
|
||||
/*
|
||||
* Copyright (c)2013-2021 ZeroTier, Inc.
|
||||
*
|
||||
* Use of this software is governed by the Business Source License included
|
||||
* in the LICENSE.TXT file in the project's root directory.
|
||||
*
|
||||
* Change Date: 2026-01-01
|
||||
*
|
||||
* On the date above, in accordance with the Business Source License, use
|
||||
* of this software will be governed by version 2.0 of the Apache License.
|
||||
*/
|
||||
/****/
|
||||
|
||||
package com.zerotier.sdk;
|
||||
|
||||
import com.zerotier.sdk.*;
|
||||
import java.io.*;
|
||||
import java.util.Arrays;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* Extends OutputStream using ZeroTier as a transport
|
||||
*/
|
||||
public class ZeroTierOutputStream extends OutputStream {
|
||||
/**
|
||||
* File descriptor used by lower native layer
|
||||
*/
|
||||
public int zfd = -1;
|
||||
|
||||
/**
|
||||
* Close the stream
|
||||
* @exception IOException when an I/O error occurs
|
||||
*/
|
||||
public void close() throws IOException
|
||||
{
|
||||
/* Note: this operation currently only stops RX on a socket that is
|
||||
shared between both I/OStreams. This means that closing this stream
|
||||
will only shutdown that aspect of the socket but not actually close
|
||||
it and free resources. Resources will be properly freed when the
|
||||
socket implementation's native close() is called or if both I/OStreams
|
||||
are closed separately */
|
||||
ZeroTierNative.zts_shutdown(zfd, ZeroTierNative.ZTS_SHUT_WR);
|
||||
zfd = -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Write a buffer
|
||||
* @param originBuffer Source buffer
|
||||
* @exception IOException when an I/O error occurs
|
||||
*/
|
||||
public void write(byte[] originBuffer) throws IOException
|
||||
{
|
||||
int bytesWritten = ZeroTierNative.zts_write(zfd, originBuffer);
|
||||
if (bytesWritten < 0) {
|
||||
throw new IOException("write(originBuffer[]), errno=" + bytesWritten);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Write a buffer at offset
|
||||
* @param originBuffer Source buffer
|
||||
* @param offset Where in the buffer to start
|
||||
* @param numBytes Number of bytes to write
|
||||
* @exception IOException when an I/O error occurs
|
||||
*/
|
||||
public void write(byte[] originBuffer, int offset, int numBytes) throws IOException
|
||||
{
|
||||
Objects.requireNonNull(originBuffer, "input byte array (originBuffer) must not be null");
|
||||
if (offset < 0) {
|
||||
throw new IndexOutOfBoundsException("offset < 0");
|
||||
}
|
||||
if (numBytes < 0) {
|
||||
throw new IndexOutOfBoundsException("numBytes < 0");
|
||||
}
|
||||
if ((offset + numBytes) > originBuffer.length) {
|
||||
throw new IndexOutOfBoundsException("(offset+numBytes) > originBuffer.length");
|
||||
}
|
||||
int bytesWritten = ZeroTierNative.zts_write_offset(zfd, originBuffer, offset, numBytes);
|
||||
if (bytesWritten < 0) {
|
||||
throw new IOException("write(originBuffer[],offset,numBytes), errno=" + bytesWritten);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Write low byte
|
||||
* @param d Integer containing low byte to write
|
||||
* @exception IOException when an I/O error occurs
|
||||
*/
|
||||
public void write(int d) throws IOException
|
||||
{
|
||||
byte lowByte = (byte)(d & 0xFF);
|
||||
int bytesWritten = ZeroTierNative.zts_write_byte(zfd, lowByte);
|
||||
if (bytesWritten < 0) {
|
||||
throw new IOException("write(d), errno=" + bytesWritten);
|
||||
}
|
||||
}
|
||||
}
|
||||
61
src/bindings/java/ZeroTierPeerDetails.java
Normal file
61
src/bindings/java/ZeroTierPeerDetails.java
Normal file
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Copyright (c)2013-2021 ZeroTier, Inc.
|
||||
*
|
||||
* Use of this software is governed by the Business Source License included
|
||||
* in the LICENSE.TXT file in the project's root directory.
|
||||
*
|
||||
* Change Date: 2026-01-01
|
||||
*
|
||||
* On the date above, in accordance with the Business Source License, use
|
||||
* of this software will be governed by version 2.0 of the Apache License.
|
||||
*/
|
||||
/****/
|
||||
|
||||
package com.zerotier.sdk;
|
||||
|
||||
import com.zerotier.sdk.*;
|
||||
|
||||
/**
|
||||
* This class encapsulates details about a Peer on a ZeroTier network
|
||||
*/
|
||||
class ZeroTierPeerDetails {
|
||||
/**
|
||||
* ZeroTier address (40 bits)
|
||||
*/
|
||||
public long address;
|
||||
|
||||
/**
|
||||
* Remote major version or -1 if not known
|
||||
*/
|
||||
public int versionMajor;
|
||||
|
||||
/**
|
||||
* Remote minor version or -1 if not known
|
||||
*/
|
||||
public int versionMinor;
|
||||
|
||||
/**
|
||||
* Remote revision or -1 if not known
|
||||
*/
|
||||
public int versionRev;
|
||||
|
||||
/**
|
||||
* Last measured latency in milliseconds or -1 if unknown
|
||||
*/
|
||||
public int latency;
|
||||
|
||||
/**
|
||||
* What trust hierarchy role does this device have?
|
||||
*/
|
||||
public int role;
|
||||
|
||||
/**
|
||||
* Number of paths (size of paths[])
|
||||
*/
|
||||
public int pathCount;
|
||||
|
||||
/**
|
||||
* Known network paths to peer
|
||||
*/
|
||||
public ZeroTierSocketAddress[] paths = new ZeroTierSocketAddress[ZeroTierNative.ZTS_MAX_PEER_NETWORK_PATHS];
|
||||
}
|
||||
617
src/bindings/java/ZeroTierSocket.java
Normal file
617
src/bindings/java/ZeroTierSocket.java
Normal file
@@ -0,0 +1,617 @@
|
||||
/*
|
||||
* Copyright (c)2013-2021 ZeroTier, Inc.
|
||||
*
|
||||
* Use of this software is governed by the Business Source License included
|
||||
* in the LICENSE.TXT file in the project's root directory.
|
||||
*
|
||||
* Change Date: 2026-01-01
|
||||
*
|
||||
* On the date above, in accordance with the Business Source License, use
|
||||
* of this software will be governed by version 2.0 of the Apache License.
|
||||
*/
|
||||
/****/
|
||||
|
||||
package com.zerotier.sdk;
|
||||
|
||||
import com.zerotier.sdk.*;
|
||||
import java.io.*;
|
||||
import java.net.*;
|
||||
|
||||
/**
|
||||
* Implements Socket-like behavior over ZeroTier
|
||||
*
|
||||
* @author ZeroTier, Inc.
|
||||
*/
|
||||
public class ZeroTierSocket {
|
||||
// File descriptor from lower native layer
|
||||
private int _zfd = -1;
|
||||
private int _family = -1;
|
||||
private int _type = -1;
|
||||
private int _protocol = -1;
|
||||
|
||||
// State flags
|
||||
private boolean _isClosed = false;
|
||||
private boolean _isConnected = false;
|
||||
private boolean _isBound = false;
|
||||
private boolean _inputHasBeenShutdown = false;
|
||||
private boolean _outputHasBeenShutdown = false;
|
||||
|
||||
// Input and Output streams
|
||||
private ZeroTierInputStream _inputStream = new ZeroTierInputStream();
|
||||
private ZeroTierOutputStream _outputStream = new ZeroTierOutputStream();
|
||||
|
||||
// The remote address to which the ZeroTierSocket is connected
|
||||
private InetAddress _remoteAddr;
|
||||
private int _remotePort;
|
||||
private InetAddress _localAddr;
|
||||
private int _localPort;
|
||||
|
||||
private void setNativeFileDescriptor(int fd)
|
||||
{
|
||||
_zfd = fd;
|
||||
_inputStream.zfd = fd;
|
||||
_outputStream.zfd = fd;
|
||||
}
|
||||
|
||||
private ZeroTierSocket(int family, int type, int protocol, int zfd)
|
||||
{
|
||||
_family = family;
|
||||
_type = type;
|
||||
_protocol = protocol;
|
||||
setNativeFileDescriptor(zfd);
|
||||
// Since we only call this from accept() we will mark it as connected
|
||||
_isConnected = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new ZeroTierSocket with the given attributes
|
||||
* @param family The socket family
|
||||
* @param type The socket type
|
||||
* @param protocol Supported protocol
|
||||
*
|
||||
* @exception IOException when an I/O error occurs
|
||||
*/
|
||||
public ZeroTierSocket(int family, int type, int protocol) throws IOException
|
||||
{
|
||||
if (_zfd > -1) {
|
||||
throw new IOException("This socket has already been created (fd=" + _zfd + ")");
|
||||
}
|
||||
_zfd = ZeroTierNative.zts_socket(ZeroTierNative.ZTS_AF_INET, ZeroTierNative.ZTS_SOCK_STREAM, protocol);
|
||||
if (_zfd < 0) {
|
||||
throw new IOException("Error while creating socket (" + _zfd + ")");
|
||||
}
|
||||
_family = family;
|
||||
_type = type;
|
||||
_protocol = protocol;
|
||||
setNativeFileDescriptor(_zfd);
|
||||
}
|
||||
|
||||
/**
|
||||
* Connect to a remote host
|
||||
* @param remoteAddr Remote address to which this socket should connect
|
||||
* @param remotePort Remote port to which this socket should connect
|
||||
*
|
||||
* @exception IOException when an I/O error occurs
|
||||
*/
|
||||
public void connect(InetAddress remoteAddr, int remotePort) throws IOException
|
||||
{
|
||||
if (_zfd < 0) {
|
||||
throw new IOException("Invalid socket (fd < 0)");
|
||||
}
|
||||
if ((remoteAddr instanceof Inet4Address) && _family != ZeroTierNative.ZTS_AF_INET) {
|
||||
throw new IOException("Invalid address type. Socket is of type AF_INET");
|
||||
}
|
||||
if ((remoteAddr instanceof Inet6Address) && _family != ZeroTierNative.ZTS_AF_INET6) {
|
||||
throw new IOException("Invalid address type. Socket is of type AF_INET6");
|
||||
}
|
||||
int err;
|
||||
if ((err = ZeroTierNative.zts_simple_connect(_zfd, remoteAddr.getHostAddress(), remotePort, 0)) < 0) {
|
||||
throw new IOException("Error while connecting to remote host (" + err + ")");
|
||||
}
|
||||
_isConnected = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Connect to a remote host
|
||||
* @param remoteAddr Remote address to which this socket should connect
|
||||
* @param remotePort Remote port to which this socket should connect
|
||||
*
|
||||
* @exception IOException when an I/O error occurs
|
||||
*/
|
||||
public void connect(String remoteAddr, int remotePort) throws IOException
|
||||
{
|
||||
InetAddress remoteInetAddr = InetAddress.getByName(remoteAddr);
|
||||
connect(remoteInetAddr, remotePort);
|
||||
}
|
||||
|
||||
/**
|
||||
* Connect to a remote host
|
||||
* @param remoteAddr Remote address to which this socket should connect
|
||||
*
|
||||
* @exception IOException when an I/O error occurs
|
||||
*/
|
||||
public void connect(SocketAddress remoteAddr) throws IOException
|
||||
{
|
||||
int remotePort = ((InetSocketAddress)remoteAddr).getPort();
|
||||
connect(((InetSocketAddress)remoteAddr).getHostString(), remotePort);
|
||||
}
|
||||
|
||||
/**
|
||||
* Bind to a local address
|
||||
* @param localAddr Local address to which this socket should bind
|
||||
* @param localPort Local port to which this socket should bind
|
||||
*
|
||||
* @exception IOException when an I/O error occurs
|
||||
*/
|
||||
public void bind(InetAddress localAddr, int localPort) throws IOException
|
||||
{
|
||||
if (_zfd < 0) {
|
||||
throw new IOException("Invalid socket (fd < 0)");
|
||||
}
|
||||
if ((localAddr instanceof Inet4Address) && _family != ZeroTierNative.ZTS_AF_INET) {
|
||||
throw new IOException("Invalid address type. Socket is of type AF_INET");
|
||||
}
|
||||
if ((localAddr instanceof Inet6Address) && _family != ZeroTierNative.ZTS_AF_INET6) {
|
||||
throw new IOException("Invalid address type. Socket is of type AF_INET6");
|
||||
}
|
||||
int err;
|
||||
if ((err = ZeroTierNative.zts_simple_bind(_zfd, localAddr.getHostAddress(), localPort)) < 0) {
|
||||
throw new IOException("Error while connecting to remote host (" + err + ")");
|
||||
}
|
||||
_localPort = localPort;
|
||||
_isBound = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Bind to a local address
|
||||
* @param localAddr Local address to which this socket should bind
|
||||
* @param localPort Local port to which this socket should bind
|
||||
*
|
||||
* @exception IOException when an I/O error occurs
|
||||
*/
|
||||
public void bind(String localAddr, int localPort) throws IOException
|
||||
{
|
||||
InetAddress localInetAddr = InetAddress.getByName(localAddr);
|
||||
bind(localInetAddr, localPort);
|
||||
}
|
||||
|
||||
/**
|
||||
* Put the ZeroTierSocket into a listening state
|
||||
* @param backlog Size of connection backlog
|
||||
*
|
||||
* @exception IOException when an I/O error occurs
|
||||
*/
|
||||
public void listen(int backlog) throws IOException
|
||||
{
|
||||
if (_zfd < 0) {
|
||||
throw new IOException("Invalid socket (fd < 0)");
|
||||
}
|
||||
if (backlog < 0) {
|
||||
throw new IOException("Invalid backlog value");
|
||||
}
|
||||
int err;
|
||||
if ((err = ZeroTierNative.zts_listen(_zfd, backlog)) < 0) {
|
||||
throw new IOException("Error while putting socket into listening state (" + err + ")");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Accept incoming connections on this ZeroTierSocket
|
||||
* @return New ZeroTierSocket representing the accepted connection
|
||||
* @exception IOException when an I/O error occurs
|
||||
*/
|
||||
public ZeroTierSocket accept() throws IOException
|
||||
{
|
||||
if (_zfd < 0) {
|
||||
throw new IOException("Invalid socket (fd < 0)");
|
||||
}
|
||||
int accetpedFd = -1;
|
||||
ZeroTierSocketAddress addr = new ZeroTierSocketAddress();
|
||||
if ((accetpedFd = ZeroTierNative.zts_accept(_zfd, addr)) < 0) {
|
||||
throw new IOException("Error while accepting connection (" + accetpedFd + ")");
|
||||
}
|
||||
return new ZeroTierSocket(_family, _type, _protocol, accetpedFd);
|
||||
}
|
||||
|
||||
/**
|
||||
* Close the ZeroTierSocket.
|
||||
*
|
||||
* @exception IOException when an I/O error occurs
|
||||
*/
|
||||
public void close() throws IOException
|
||||
{
|
||||
if (_zfd < 0) {
|
||||
throw new IOException("Invalid socket (fd < 0)");
|
||||
}
|
||||
ZeroTierNative.zts_close(_zfd);
|
||||
_isClosed = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return whether keepalive is enabled.
|
||||
* @return true or false
|
||||
* @exception SocketException when an error occurs in the native socket layer
|
||||
*/
|
||||
public boolean getKeepAlive() throws SocketException
|
||||
{
|
||||
if (_isClosed) {
|
||||
throw new SocketException("Error: ZeroTierSocket is closed");
|
||||
}
|
||||
return ZeroTierNative.zts_simple_get_keepalive(_zfd) == 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the local port to which this ZeroTierSocket is bound
|
||||
* @return Local port
|
||||
*/
|
||||
public int getLocalPort()
|
||||
{
|
||||
if (! _isBound) {
|
||||
return -1;
|
||||
}
|
||||
return _localPort;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the local address to which this ZeroTierSocket is bound
|
||||
* @return Local address
|
||||
*/
|
||||
public InetAddress getLocalAddress()
|
||||
{
|
||||
if (! _isBound) {
|
||||
return null;
|
||||
}
|
||||
return _localAddr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the remote port to which this ZeroTierSocket is bound
|
||||
* @return Remote port
|
||||
*/
|
||||
public int getRemotePort()
|
||||
{
|
||||
if (! _isConnected) {
|
||||
return -1;
|
||||
}
|
||||
return _remotePort;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the remote address to which this ZeroTierSocket is bound
|
||||
* @return Remote address
|
||||
*/
|
||||
public InetAddress getRemoteAddress()
|
||||
{
|
||||
if (! _isConnected) {
|
||||
return null;
|
||||
}
|
||||
return _remoteAddr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the size of the receive buffer for the ZeroTierSocket's ZeroTierInputStream (SO_RCVBUF)
|
||||
* @return Size of the receive buffer
|
||||
* @exception SocketException when an error occurs in the native socket layer
|
||||
*/
|
||||
public int getReceiveBufferSize() throws SocketException
|
||||
{
|
||||
if (_isClosed) {
|
||||
throw new SocketException("Error: ZeroTierSocket is closed");
|
||||
}
|
||||
return ZeroTierNative.zts_simple_get_recv_buf_size(_zfd);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the size of the send buffer for the ZeroTierSocket's ZeroTierOutputStream (SO_SNDBUF)
|
||||
* @return Size of the send buffer
|
||||
* @exception SocketException when an error occurs in the native socket layer
|
||||
*/
|
||||
public int getSendBufferSize() throws SocketException
|
||||
{
|
||||
if (_isClosed) {
|
||||
throw new SocketException("Error: ZeroTierSocket is closed");
|
||||
}
|
||||
return ZeroTierNative.zts_simple_get_send_buf_size(_zfd);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return whether address reuse is enabled on this ZeroTierSocket (SO_REUSEADDR)
|
||||
* @return true or false
|
||||
* @exception SocketException when an error occurs in the native socket layer
|
||||
*/
|
||||
public boolean getReuseAddressEnabled() throws SocketException
|
||||
{
|
||||
if (_isClosed) {
|
||||
throw new SocketException("Error: ZeroTierSocket is closed");
|
||||
}
|
||||
return ZeroTierNative.zts_simple_get_reuse_addr(_zfd) == 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the amount of time that a ZeroTierSocket will linger after closure (SO_LINGER)
|
||||
* @return Nothing.
|
||||
* @exception SocketException when an error occurs in the native socket layer
|
||||
*/
|
||||
public int getSoLingerTime() throws SocketException
|
||||
{
|
||||
if (_isClosed) {
|
||||
throw new SocketException("Error: ZeroTierSocket is closed");
|
||||
}
|
||||
return ZeroTierNative.zts_simple_get_linger_value(_zfd);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the ZeroTierSocket's timeout value (SO_RCVTIMEO)
|
||||
* @return Nothing.
|
||||
* @exception SocketException when an error occurs in the native socket layer
|
||||
*/
|
||||
public int getSoTimeout() throws SocketException
|
||||
{
|
||||
if (_isClosed) {
|
||||
throw new SocketException("Error: ZeroTierSocket is closed");
|
||||
}
|
||||
return ZeroTierNative.zts_simple_get_recv_timeout(_zfd);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return whether TCP no-delay is enabled (TCP_NODELAY)
|
||||
* @return true or false
|
||||
* @exception SocketException when an error occurs in the native socket layer
|
||||
*/
|
||||
public boolean tcpNoDelayEnabled() throws SocketException
|
||||
{
|
||||
if (_isClosed) {
|
||||
throw new SocketException("Error: ZeroTierSocket is closed");
|
||||
}
|
||||
return ZeroTierNative.zts_simple_get_no_delay(_zfd) == 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return whether this ZeroTierSocket is bound to a local address
|
||||
* @return true or false
|
||||
*/
|
||||
public boolean isBound()
|
||||
{
|
||||
return _isBound;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return whether this ZeroTierSocket has been closed
|
||||
* @return true or false
|
||||
*/
|
||||
public boolean isClosed()
|
||||
{
|
||||
return _isClosed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return whether this ZeroTierSocket is connected to a remote address
|
||||
* @return true or false
|
||||
*/
|
||||
public boolean isConnected()
|
||||
{
|
||||
return _isConnected;
|
||||
}
|
||||
|
||||
/**
|
||||
* Disable the input-aspect of the ZeroTierSocket.
|
||||
*
|
||||
* @exception SocketException when an error occurs in the native socket layer
|
||||
*/
|
||||
public void shutdownInput() throws SocketException
|
||||
{
|
||||
if (! _isConnected) {
|
||||
throw new SocketException("Error: ZeroTierSocket is not connected");
|
||||
}
|
||||
if (_isClosed) {
|
||||
throw new SocketException("Error: ZeroTierSocket is closed");
|
||||
}
|
||||
if (_inputHasBeenShutdown) {
|
||||
throw new SocketException("Error: ZeroTierSocket input has been shut down");
|
||||
}
|
||||
ZeroTierNative.zts_shutdown(_zfd, ZeroTierNative.ZTS_SHUT_RD);
|
||||
_inputHasBeenShutdown = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Disable the output-aspect of the ZeroTierSocket.
|
||||
*
|
||||
* @exception SocketException when an error occurs in the native socket layer
|
||||
*/
|
||||
public void shutdownOutput() throws SocketException
|
||||
{
|
||||
if (! _isConnected) {
|
||||
throw new SocketException("Error: ZeroTierSocket is not connected");
|
||||
}
|
||||
if (_isClosed) {
|
||||
throw new SocketException("Error: ZeroTierSocket is closed");
|
||||
}
|
||||
if (_outputHasBeenShutdown) {
|
||||
throw new SocketException("Error: ZeroTierSocket output has been shut down");
|
||||
}
|
||||
ZeroTierNative.zts_shutdown(_zfd, ZeroTierNative.ZTS_SHUT_WR);
|
||||
_outputHasBeenShutdown = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a reference to the ZeroTierInputStream used by this ZeroTierSocket
|
||||
* @return A reference to the ZeroTierInputStream
|
||||
* @exception SocketException when an error occurs in the native socket layer
|
||||
*/
|
||||
public ZeroTierInputStream getInputStream() throws SocketException
|
||||
{
|
||||
if (! _isConnected) {
|
||||
throw new SocketException("Error: ZeroTierSocket is not connected");
|
||||
}
|
||||
if (_isClosed) {
|
||||
throw new SocketException("Error: ZeroTierSocket is closed");
|
||||
}
|
||||
if (_inputHasBeenShutdown) {
|
||||
throw new SocketException("Error: ZeroTierSocket input has been shut down");
|
||||
}
|
||||
return _inputStream;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a reference to the ZeroTierOutputStream used by this ZeroTierSocket
|
||||
* @return A reference to the ZeroTierOutputStream
|
||||
* @exception SocketException when an error occurs in the native socket layer
|
||||
*/
|
||||
public ZeroTierOutputStream getOutputStream() throws SocketException
|
||||
{
|
||||
if (! _isConnected) {
|
||||
throw new SocketException("Error: ZeroTierSocket is not connected");
|
||||
}
|
||||
if (_isClosed) {
|
||||
throw new SocketException("Error: ZeroTierSocket is closed");
|
||||
}
|
||||
if (_outputHasBeenShutdown) {
|
||||
throw new SocketException("Error: ZeroTierSocket output has been shut down");
|
||||
}
|
||||
return _outputStream;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return whether the input-aspect of the ZeroTierSocket has been disabled.
|
||||
* @return true or false
|
||||
*/
|
||||
public boolean inputStreamHasBeenShutdown()
|
||||
{
|
||||
return _inputHasBeenShutdown;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return whether the output-aspect of the ZeroTierSocket has been disabled.
|
||||
* @return true or false
|
||||
*/
|
||||
public boolean outputStreamHasBeenShutdown()
|
||||
{
|
||||
return _outputHasBeenShutdown;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable or disable the keepalive setting (SO_KEEPALIVE)
|
||||
* @param enabled Whether SO_KEEPALIVE is enabled.
|
||||
*
|
||||
* @exception SocketException when an error occurs in the native socket layer
|
||||
*/
|
||||
public void setKeepAliveEnabled(boolean enabled) throws SocketException
|
||||
{
|
||||
if (_isClosed) {
|
||||
throw new SocketException("Error: ZeroTierSocket is closed");
|
||||
}
|
||||
if (ZeroTierNative.zts_simple_set_keepalive(_zfd, (enabled ? 1 : 0)) != ZeroTierNative.ZTS_ERR_OK) {
|
||||
throw new SocketException("Error: Could not set SO_KEEPALIVE");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the size of the receive buffer for the ZeroTierSocket's ZeroTierInputStream.
|
||||
* @param bufferSize Size of receive buffer
|
||||
*
|
||||
* @exception SocketException when an error occurs in the native socket layer
|
||||
*/
|
||||
public void setReceiveBufferSize(int bufferSize) throws SocketException
|
||||
{
|
||||
if (_isClosed) {
|
||||
throw new SocketException("Error: ZeroTierSocket is closed");
|
||||
}
|
||||
if (bufferSize <= 0) {
|
||||
throw new IllegalArgumentException("Error: bufferSize <= 0");
|
||||
}
|
||||
if (ZeroTierNative.zts_simple_set_recv_buf_size(_zfd, bufferSize) != ZeroTierNative.ZTS_ERR_OK) {
|
||||
throw new SocketException("Error: Could not set receive buffer size");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable or disable the re-use of addresses (SO_REUSEADDR)
|
||||
* @param enabled Whether SO_REUSEADDR is enabled
|
||||
*
|
||||
* @exception SocketException when an error occurs in the native socket layer
|
||||
*/
|
||||
public void setReuseAddress(boolean enabled) throws SocketException
|
||||
{
|
||||
if (_isClosed) {
|
||||
throw new SocketException("Error: ZeroTierSocket is closed");
|
||||
}
|
||||
if (ZeroTierNative.zts_simple_set_reuse_addr(_zfd, (enabled ? 1 : 0)) != ZeroTierNative.ZTS_ERR_OK) {
|
||||
throw new SocketException("Error: Could not set SO_REUSEADDR");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the size of the send buffer for the ZeroTierSocket's ZeroTierOutputStream (SO_SNDBUF)
|
||||
* @param bufferSize Size of send buffer
|
||||
*
|
||||
* @exception SocketException when an error occurs in the native socket layer
|
||||
*/
|
||||
public void setSendBufferSize(int bufferSize) throws SocketException
|
||||
{
|
||||
if (_isClosed) {
|
||||
throw new SocketException("Error: ZeroTierSocket is closed");
|
||||
}
|
||||
if (bufferSize <= 0) {
|
||||
throw new IllegalArgumentException("Error: bufferSize <= 0");
|
||||
}
|
||||
if (ZeroTierNative.zts_simple_set_send_buf_size(_zfd, bufferSize) != ZeroTierNative.ZTS_ERR_OK) {
|
||||
throw new SocketException("Error: Could not set SO_SNDBUF");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the amount of time that a ZeroTierSocket will linger after closure (SO_LINGER)
|
||||
* @param enabled Whether SO_LINGER is enabled
|
||||
* @param lingerTime SO_LINGER time
|
||||
*
|
||||
* @exception SocketException when an error occurs in the native socket layer
|
||||
*/
|
||||
public void setSoLinger(boolean enabled, int lingerTime) throws SocketException
|
||||
{
|
||||
if (_isClosed) {
|
||||
throw new SocketException("Error: ZeroTierSocket is closed");
|
||||
}
|
||||
if (lingerTime < 0) {
|
||||
throw new IllegalArgumentException("Error: lingerTime < 0");
|
||||
}
|
||||
if (ZeroTierNative.zts_simple_set_linger(_zfd, (enabled ? 1 : 0), lingerTime) != ZeroTierNative.ZTS_ERR_OK) {
|
||||
throw new SocketException("Error: Could not set ZTS_SO_LINGER");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the timeout value for SO_RCVTIMEO
|
||||
* @param timeout Socket receive timeout value.
|
||||
*
|
||||
* @exception SocketException when an error occurs in the native socket layer
|
||||
*/
|
||||
public void setSoTimeoutValue(int timeout) throws SocketException
|
||||
{
|
||||
if (_isClosed) {
|
||||
throw new SocketException("Error: ZeroTierSocket is closed");
|
||||
}
|
||||
if (timeout < 0) {
|
||||
throw new IllegalArgumentException("Error: SO_TIMEOUT < 0");
|
||||
}
|
||||
// TODO: This is incorrect
|
||||
if (ZeroTierNative.zts_simple_set_recv_timeout(_zfd, timeout, timeout) != ZeroTierNative.ZTS_ERR_OK) {
|
||||
throw new SocketException("Error: Could not set SO_RCVTIMEO");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable or disable TCP_NODELAY
|
||||
* @param enabled Whether TCP_NODELAY is enabled
|
||||
*
|
||||
* @exception SocketException when an error occurs in the native socket layer
|
||||
*/
|
||||
public void setTcpNoDelayEnabled(boolean enabled) throws SocketException
|
||||
{
|
||||
if (_isClosed) {
|
||||
throw new SocketException("Error: ZeroTierSocket is closed");
|
||||
}
|
||||
if (ZeroTierNative.zts_simple_set_no_delay(_zfd, (enabled ? 1 : 0)) != ZeroTierNative.ZTS_ERR_OK) {
|
||||
throw new SocketException("Error: Could not set TCP_NODELAY");
|
||||
}
|
||||
}
|
||||
}
|
||||
124
src/bindings/java/ZeroTierSocketAddress.java
Normal file
124
src/bindings/java/ZeroTierSocketAddress.java
Normal file
@@ -0,0 +1,124 @@
|
||||
/*
|
||||
* Copyright (c)2013-2021 ZeroTier, Inc.
|
||||
*
|
||||
* Use of this software is governed by the Business Source License included
|
||||
* in the LICENSE.TXT file in the project's root directory.
|
||||
*
|
||||
* Change Date: 2026-01-01
|
||||
*
|
||||
* On the date above, in accordance with the Business Source License, use
|
||||
* of this software will be governed by version 2.0 of the Apache License.
|
||||
*/
|
||||
/****/
|
||||
|
||||
package com.zerotier.sdk;
|
||||
|
||||
import com.zerotier.sdk.ZeroTierNative;
|
||||
import java.net.InetAddress;
|
||||
|
||||
/**
|
||||
* Convenience class for holding address information. Used internally by JNI layer.
|
||||
*/
|
||||
class ZeroTierSocketAddress {
|
||||
private byte[] _ip6 = new byte[16];
|
||||
private byte[] _ip4 = new byte[4];
|
||||
|
||||
private int _family;
|
||||
private int _port; // Also reused for netmask or prefix
|
||||
|
||||
public ZeroTierSocketAddress()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public ZeroTierSocketAddress(String ipStr, int port)
|
||||
{
|
||||
if (ipStr.contains(":")) {
|
||||
_family = ZeroTierNative.ZTS_AF_INET6;
|
||||
try {
|
||||
InetAddress ip = InetAddress.getByName(ipStr);
|
||||
_ip6 = ip.getAddress();
|
||||
}
|
||||
catch (Exception e) {
|
||||
}
|
||||
}
|
||||
else if (ipStr.contains(".")) {
|
||||
_family = ZeroTierNative.ZTS_AF_INET;
|
||||
try {
|
||||
InetAddress ip = InetAddress.getByName(ipStr);
|
||||
_ip4 = ip.getAddress();
|
||||
}
|
||||
catch (Exception e) {
|
||||
}
|
||||
}
|
||||
_port = port;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert to string (ip portion only)
|
||||
*/
|
||||
public String ipString()
|
||||
{
|
||||
if (_family == ZeroTierNative.ZTS_AF_INET) {
|
||||
try {
|
||||
InetAddress inet = InetAddress.getByAddress(_ip4);
|
||||
return "" + inet.getHostAddress();
|
||||
}
|
||||
catch (Exception e) {
|
||||
System.out.println(e);
|
||||
}
|
||||
}
|
||||
if (_family == ZeroTierNative.ZTS_AF_INET6) {
|
||||
try {
|
||||
InetAddress inet = InetAddress.getByAddress(_ip6);
|
||||
return "" + inet.getHostAddress();
|
||||
}
|
||||
catch (Exception e) {
|
||||
System.out.println(e);
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert to string (ip and port)
|
||||
*/
|
||||
public String toString()
|
||||
{
|
||||
return ipString() + ":" + _port;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert to string (ip+netmask and port)
|
||||
*/
|
||||
public String toCIDR()
|
||||
{
|
||||
return ipString() + "/" + _port;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get port
|
||||
*/
|
||||
public int getPort()
|
||||
{
|
||||
return _port;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get netmask
|
||||
*/
|
||||
public int getNetmask()
|
||||
{
|
||||
return _port;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get prefix (stored in port)
|
||||
*/
|
||||
public int getPrefix()
|
||||
{
|
||||
return _port;
|
||||
}
|
||||
}
|
||||
138
test/selftest.java
Normal file
138
test/selftest.java
Normal file
@@ -0,0 +1,138 @@
|
||||
import com.zerotier.sdk.*;
|
||||
import java.io.DataInputStream;
|
||||
import java.io.DataOutputStream;
|
||||
import java.math.BigInteger;
|
||||
|
||||
public class selftest {
|
||||
public static void main(String[] args)
|
||||
{
|
||||
System.err.println(args.length);
|
||||
if (args.length < 4 || args.length > 5) {
|
||||
System.err.println("Invalid arguments");
|
||||
System.err.println(" Usage: <server|client> <id_path> <network> <addr> <port>");
|
||||
System.err.println(" example server ./ 0123456789abcdef 8080");
|
||||
System.err.println(" example client ./ 0123456789abcdef 192.168.22.1 8080\n");
|
||||
System.exit(1);
|
||||
}
|
||||
|
||||
String storagePath = "";
|
||||
String remoteAddr = "";
|
||||
int port = 0;
|
||||
String mode = args[0];
|
||||
storagePath = args[1];
|
||||
BigInteger networkId = new BigInteger(args[2], 16);
|
||||
if (args.length == 4) {
|
||||
port = Integer.parseInt(args[3]);
|
||||
}
|
||||
if (args.length == 5) {
|
||||
remoteAddr = args[3];
|
||||
port = Integer.parseInt(args[4]);
|
||||
}
|
||||
System.out.println("mode = " + mode);
|
||||
System.out.println("networkId = " + Long.toHexString(networkId.longValue()));
|
||||
System.out.println("storagePath = " + storagePath);
|
||||
System.out.println("remoteAddr = " + remoteAddr);
|
||||
System.out.println("port = " + port);
|
||||
|
||||
// ZeroTier setup
|
||||
|
||||
ZeroTierNode node = new ZeroTierNode();
|
||||
|
||||
node.initFromStorage(storagePath);
|
||||
// node.initSetEventHandler(new MyZeroTierEventListener());
|
||||
// node.initSetPort(9994);
|
||||
node.start();
|
||||
|
||||
System.out.println("Waiting for node to come online...");
|
||||
while (! node.isOnline()) {
|
||||
ZeroTierNative.zts_util_delay(50);
|
||||
}
|
||||
System.out.println("Node ID: " + Long.toHexString(node.getId()));
|
||||
System.out.println("Joining network...");
|
||||
node.join(networkId.longValue());
|
||||
System.out.println("Waiting for network...");
|
||||
while (! node.isNetworkTransportReady(networkId.longValue())) {
|
||||
ZeroTierNative.zts_util_delay(50);
|
||||
}
|
||||
System.out.println("joined");
|
||||
|
||||
// Socket logic
|
||||
|
||||
if (mode.equals("server")) {
|
||||
System.out.println("Starting server...");
|
||||
try {
|
||||
ZeroTierSocket socket =
|
||||
new ZeroTierSocket(ZeroTierNative.ZTS_AF_INET, ZeroTierNative.ZTS_SOCK_STREAM, 0);
|
||||
socket.bind("0.0.0.0", port);
|
||||
socket.listen(100);
|
||||
ZeroTierSocket newConnection = socket.accept();
|
||||
ZeroTierInputStream inputStream = newConnection.getInputStream();
|
||||
DataInputStream dataInputStream = new DataInputStream(inputStream);
|
||||
String message = dataInputStream.readUTF();
|
||||
System.out.println("recv: " + message);
|
||||
socket.close();
|
||||
newConnection.close();
|
||||
}
|
||||
catch (Exception ex) {
|
||||
System.out.println(ex);
|
||||
}
|
||||
}
|
||||
|
||||
if (mode.equals("client")) {
|
||||
System.out.println("Starting client...");
|
||||
try {
|
||||
ZeroTierSocket socket =
|
||||
new ZeroTierSocket(ZeroTierNative.ZTS_AF_INET, ZeroTierNative.ZTS_SOCK_STREAM, 0);
|
||||
socket.connect(remoteAddr, port);
|
||||
ZeroTierOutputStream outputStream = socket.getOutputStream();
|
||||
DataOutputStream dataOutputStream = new DataOutputStream(outputStream);
|
||||
dataOutputStream.writeUTF("Hello from java!");
|
||||
socket.close();
|
||||
}
|
||||
catch (Exception ex) {
|
||||
System.out.println(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* (OPTIONAL) event handler
|
||||
*/
|
||||
/*
|
||||
class MyZeroTierEventListener implements ZeroTierEventListener {
|
||||
public void onZeroTierEvent(long id, int event_code)
|
||||
{
|
||||
if (event_code == ZeroTierNative.ZTS_EVENT_NODE_UP) {
|
||||
System.out.println("EVENT_NODE_UP");
|
||||
}
|
||||
if (event_code == ZeroTierNative.ZTS_EVENT_NODE_ONLINE) {
|
||||
System.out.println("EVENT_NODE_ONLINE: " + Long.toHexString(id));
|
||||
}
|
||||
if (event_code == ZeroTierNative.ZTS_EVENT_NODE_OFFLINE) {
|
||||
System.out.println("EVENT_NODE_OFFLINE");
|
||||
}
|
||||
if (event_code == ZeroTierNative.ZTS_EVENT_NODE_DOWN) {
|
||||
System.out.println("EVENT_NODE_DOWN");
|
||||
}
|
||||
if (event_code == ZeroTierNative.ZTS_EVENT_NETWORK_READY_IP4) {
|
||||
System.out.println("ZTS_EVENT_NETWORK_READY_IP4: " + Long.toHexString(id));
|
||||
}
|
||||
if (event_code == ZeroTierNative.ZTS_EVENT_NETWORK_READY_IP6) {
|
||||
System.out.println("ZTS_EVENT_NETWORK_READY_IP6: " + Long.toHexString(id));
|
||||
}
|
||||
if (event_code == ZeroTierNative.ZTS_EVENT_NETWORK_DOWN) {
|
||||
System.out.println("EVENT_NETWORK_DOWN: " + Long.toHexString(id));
|
||||
}
|
||||
if (event_code == ZeroTierNative.ZTS_EVENT_NETWORK_OK) {
|
||||
System.out.println("EVENT_NETWORK_OK: " + Long.toHexString(id));
|
||||
}
|
||||
if (event_code == ZeroTierNative.ZTS_EVENT_NETWORK_ACCESS_DENIED) {
|
||||
System.out.println("EVENT_NETWORK_ACCESS_DENIED: " + Long.toHexString(id));
|
||||
}
|
||||
if (event_code == ZeroTierNative.ZTS_EVENT_NETWORK_NOT_FOUND) {
|
||||
System.out.println("EVENT_NETWORK_NOT_FOUND: " + Long.toHexString(id));
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
Reference in New Issue
Block a user