diff --git a/ClientLibrary/Makefile b/ClientLibrary/Makefile index 00bea2d6e..86964d091 100644 --- a/ClientLibrary/Makefile +++ b/ClientLibrary/Makefile @@ -1,8 +1,8 @@ shared: - go build -buildmode=c-shared -o PsiphonTunnel.dylib PsiphonTunnel.go + go build -buildmode=c-shared -o libpsiphontunnel.so PsiphonTunnel.go .PHONY: shared static: - go build -buildmode=c-archive -o PsiphonTunnel.a PsiphonTunnel.go + go build -buildmode=c-archive -o libpsiphontunnel.a PsiphonTunnel.go .PHONY: static diff --git a/ClientLibrary/PsiphonTunnel.go b/ClientLibrary/PsiphonTunnel.go index 036a26dec..cb0eda5be 100644 --- a/ClientLibrary/PsiphonTunnel.go +++ b/ClientLibrary/PsiphonTunnel.go @@ -111,6 +111,8 @@ var managedStartResult *C.char // iOS: // - https://github.com/Psiphon-Labs/psiphon-tunnel-core/blob/3d344194d21b250e0f18ededa4b4459a373b0690/MobileLibrary/iOS/PsiphonTunnel/PsiphonTunnel/PsiphonTunnel.m#L1105 func Start(configJSON, embeddedServerEntryList, clientPlatform, networkID string, timeout int64) *C.char { + // NOTE: all arguments which are still referenced once Start returns should be copied onto the Go heap + // to ensure that they don't disappear later on and cause Go to crash. // Load provided config @@ -122,13 +124,15 @@ func Start(configJSON, embeddedServerEntryList, clientPlatform, networkID string // Set network ID if networkID != "" { - config.NetworkID = networkID + // Ensure config.NetworkID is on the Go heap + config.NetworkID = deepCopy(networkID) } // Set client platform if clientPlatform != "" { - config.ClientPlatform = clientPlatform + // Ensure config.ClientPlatform is on the Go heap + config.ClientPlatform = deepCopy(clientPlatform) } // All config fields should be set before calling commit @@ -314,6 +318,11 @@ func startErrorJson(err error) *C.char { return marshalStartResult(result) } +// deepCopy copies a string's underlying buffer and returns a new string which references the new buffer. +func deepCopy(s string) string { + return string([]byte(s)) +} + // freeManagedStartResult frees the memory on the heap pointed to by managedStartResult. func freeManagedStartResult() { if managedStartResult != nil { @@ -321,6 +330,7 @@ func freeManagedStartResult() { if managedMemory != nil { C.free(managedMemory) } + managedStartResult = nil } } diff --git a/ClientLibrary/build-darwin.sh b/ClientLibrary/build-darwin.sh index 1e61a0326..b96f968a6 100755 --- a/ClientLibrary/build-darwin.sh +++ b/ClientLibrary/build-darwin.sh @@ -133,13 +133,13 @@ build_for_ios () { CXX=${TEMP_DIR}/clangwrap.sh \ CGO_LDFLAGS="-arch armv7 -isysroot $(xcrun --sdk iphoneos --show-sdk-path)" \ CGO_CFLAGS=-isysroot$(xcrun --sdk iphoneos --show-sdk-path) \ - CGO_ENABLED=1 GOOS=darwin GOARCH=arm GOARM=7 go build -buildmode=c-archive -ldflags "$LDFLAGS" -tags "${IOS_BUILD_TAGS}" -o ${IOS_BUILD_DIR}/PsiphonTunnel-ios-arm.dylib PsiphonTunnel.go + CGO_ENABLED=1 GOOS=darwin GOARCH=arm GOARM=7 go build -buildmode=c-archive -ldflags "$LDFLAGS" -tags "${IOS_BUILD_TAGS}" -o ${IOS_BUILD_DIR}/arm7/libpsiphontunnel.a PsiphonTunnel.go CC=${TEMP_DIR}/clangwrap.sh \ CXX=${TEMP_DIR}/clangwrap.sh \ CGO_LDFLAGS="-arch arm64 -isysroot $(xcrun --sdk iphoneos --show-sdk-path)" \ CGO_CFLAGS=-isysroot$(xcrun --sdk iphoneos --show-sdk-path) \ - CGO_ENABLED=1 GOOS=darwin GOARCH=arm64 go build -buildmode=c-archive -ldflags "$LDFLAGS" -tags "${IOS_BUILD_TAGS}" -o ${IOS_BUILD_DIR}/PsiphonTunnel-ios-arm64.dylib PsiphonTunnel.go + CGO_ENABLED=1 GOOS=darwin GOARCH=arm64 go build -buildmode=c-archive -ldflags "$LDFLAGS" -tags "${IOS_BUILD_TAGS}" -o ${IOS_BUILD_DIR}/arm64/libpsiphontunnel.a PsiphonTunnel.go } @@ -159,10 +159,10 @@ build_for_macos () { fi TARGET_ARCH=386 - CGO_ENABLED=1 GOOS=darwin GOARCH="${TARGET_ARCH}" go build -buildmode=c-archive -ldflags "$LDFLAGS" -tags "${MACOS_BUILD_TAGS}" -o "${MACOS_BUILD_DIR}/PsiphonTunnel-macos-${TARGET_ARCH}.dylib" PsiphonTunnel.go + CGO_ENABLED=1 GOOS=darwin GOARCH="${TARGET_ARCH}" go build -buildmode=c-shared -ldflags "-s ${LDFLAGS}" -tags "${MACOS_BUILD_TAGS}" -o "${MACOS_BUILD_DIR}/${TARGET_ARCH}/libpsiphontunnel.dylib" PsiphonTunnel.go TARGET_ARCH=amd64 - CGO_ENABLED=1 GOOS=darwin GOARCH="${TARGET_ARCH}" go build -buildmode=c-archive -ldflags "$LDFLAGS" -tags "${MACOS_BUILD_TAGS}" -o "${MACOS_BUILD_DIR}/PsiphonTunnel-macos-${TARGET_ARCH}.dylib" PsiphonTunnel.go + CGO_ENABLED=1 GOOS=darwin GOARCH="${TARGET_ARCH}" go build -buildmode=c-shared -ldflags "-s ${LDFLAGS}" -tags "${MACOS_BUILD_TAGS}" -o "${MACOS_BUILD_DIR}/${TARGET_ARCH}/libpsiphontunnel.dylib" PsiphonTunnel.go } diff --git a/ClientLibrary/example/Makefile b/ClientLibrary/example/Makefile index e0e7968b8..e171abf20 100644 --- a/ClientLibrary/example/Makefile +++ b/ClientLibrary/example/Makefile @@ -1,12 +1,12 @@ -main: PsiphonTunnel.dylib main.o - gcc PsiphonTunnel.dylib -o main main.o +main: libpsiphontunnel.so main.o + gcc -I. -o main main.o -L. -lpsiphontunnel main.o: main.c gcc -I.. -c main.c -PsiphonTunnel.dylib: ../PsiphonTunnel.go - go build -buildmode=c-shared -o PsiphonTunnel.dylib ../PsiphonTunnel.go +libpsiphontunnel.so: ../PsiphonTunnel.go + go build -buildmode=c-shared -o libpsiphontunnel.so ../PsiphonTunnel.go clean: - rm PsiphonTunnel.dylib PsiphonTunnel.h main main.o + rm libpsiphontunnel.so PsiphonTunnel.h main main.o diff --git a/ClientLibrary/example/main.c b/ClientLibrary/example/main.c index afb9c7c88..844e3e12e 100644 --- a/ClientLibrary/example/main.c +++ b/ClientLibrary/example/main.c @@ -1,4 +1,4 @@ -#include "PsiphonTunnel.h" +#include "libpsiphontunnel.h" #include #include #include @@ -64,13 +64,16 @@ int main(int argc, char *argv[]) { // set timout long long timeout = 60; - // start will return once Psiphon connects or does not connect for timeout seconds - char *result = Start(psiphon_config, serverList, client_platform, network_id, timeout); + // connect 5 times + for (int i = 0; i < 5; i++) { + // start will return once Psiphon connects or does not connect for timeout seconds + char *result = Start(psiphon_config, serverList, client_platform, network_id, timeout); - // print results - printf("Result: %s\n", result); + // print results + printf("Result: %s\n", result); - // The underlying memory of `result` is managed by PsiphonTunnel and is freed in Stop - Stop(); + // The underlying memory of `result` is managed by PsiphonTunnel and is freed in Stop + Stop(); + } } diff --git a/ClientLibrary/make.bash b/ClientLibrary/make.bash index e9ae68314..225998d53 100755 --- a/ClientLibrary/make.bash +++ b/ClientLibrary/make.bash @@ -97,7 +97,7 @@ build_for_android () { CC="${NDK_TOOLCHAIN_DIR}/${TARGET_ARCH}/bin/arm-linux-androideabi-clang" \ CXX="${NDK_TOOLCHAIN_DIR}/${TARGET_ARCH}/bin/arm-linux-androideabi-clang++" \ GOARM=${ARMV} \ - GOOS=${TARGET_OS} GOARCH=${TARGET_ARCH} go build -buildmode=c-shared -ldflags "$LDFLAGS" -tags "$ANDROID_BUILD_TAGS" -o "${OUTPUT_DIR}/PsiphonTunnel-${TARGET_OS}-${TARGET_ARCH}${ARMV}.so" PsiphonTunnel.go + GOOS=${TARGET_OS} GOARCH=${TARGET_ARCH} go build -buildmode=c-shared -ldflags "$LDFLAGS" -tags "$ANDROID_BUILD_TAGS" -o "${OUTPUT_DIR}/${TARGET_ARCH}${ARMV}/libpsiphontunnel.so" PsiphonTunnel.go TARGET_ARCH=arm64 @@ -105,7 +105,7 @@ build_for_android () { CC="${NDK_TOOLCHAIN_DIR}/${TARGET_ARCH}/bin/aarch64-linux-android-clang" \ CXX="${NDK_TOOLCHAIN_DIR}/${TARGET_ARCH}/bin/aarch64-linux-android-clang++" \ - GOOS=${TARGET_OS} GOARCH=${TARGET_ARCH} go build -buildmode=c-shared -ldflags "$LDFLAGS" -tags "$ANDROID_BUILD_TAGS" -o "${OUTPUT_DIR}/PsiphonTunnel-${TARGET_OS}-${TARGET_ARCH}.so" PsiphonTunnel.go + GOOS=${TARGET_OS} GOARCH=${TARGET_ARCH} go build -buildmode=c-shared -ldflags "$LDFLAGS" -tags "$ANDROID_BUILD_TAGS" -o "${OUTPUT_DIR}/${TARGET_ARCH}/libpsiphontunnel.so" PsiphonTunnel.go } @@ -126,11 +126,11 @@ build_for_linux () { TARGET_ARCH=386 # TODO: is "CFLAGS=-m32" required? CFLAGS=-m32 \ - GOOS=${TARGET_OS} GOARCH=${TARGET_ARCH} go build -buildmode=c-shared -ldflags "$LDFLAGS" -tags "$LINUX_BUILD_TAGS" -o "${OUTPUT_DIR}/PsiphonTunnel-${TARGET_OS}-${TARGET_ARCH}.so" PsiphonTunnel.go + GOOS=${TARGET_OS} GOARCH=${TARGET_ARCH} go build -buildmode=c-shared -ldflags "$LDFLAGS" -tags "$LINUX_BUILD_TAGS" -o "${OUTPUT_DIR}/${TARGET_ARCH}/libpsiphontunnel.so" PsiphonTunnel.go TARGET_ARCH=amd64 - GOOS=${TARGET_OS} GOARCH=${TARGET_ARCH} go build -buildmode=c-shared -ldflags "$LDFLAGS" -tags "$LINUX_BUILD_TAGS" -o "${OUTPUT_DIR}/PsiphonTunnel-${TARGET_OS}-${TARGET_ARCH}.so" PsiphonTunnel.go + GOOS=${TARGET_OS} GOARCH=${TARGET_ARCH} go build -buildmode=c-shared -ldflags "$LDFLAGS" -tags "$LINUX_BUILD_TAGS" -o "${OUTPUT_DIR}/${TARGET_ARCH}/libpsiphontunnel.so" PsiphonTunnel.go } @@ -153,7 +153,7 @@ build_for_windows () { CGO_ENABLED=1 \ CGO_LDFLAGS="-static-libgcc -L /usr/i686-w64-mingw32/lib/ -lwsock32 -lcrypt32 -lgdi32" \ CC=/usr/bin/i686-w64-mingw32-gcc \ - GOOS=${TARGET_OS} GOARCH=${TARGET_ARCH} go build -buildmode=c-shared -ldflags "$LDFLAGS" -tags "$WINDOWS_BUILD_TAGS" -o "${OUTPUT_DIR}/PsiphonTunnel-${TARGET_OS}-${TARGET_ARCH}.dll" PsiphonTunnel.go + GOOS=${TARGET_OS} GOARCH=${TARGET_ARCH} go build -buildmode=c-shared -ldflags "$LDFLAGS" -tags "$WINDOWS_BUILD_TAGS" -o "${OUTPUT_DIR}/${TARGET_ARCH}/psiphontunnel.dll" PsiphonTunnel.go TARGET_ARCH=amd64 @@ -161,7 +161,7 @@ build_for_windows () { CGO_ENABLED=1 \ CGO_LDFLAGS="-static-libgcc -L /usr/x86_64-w64-mingw32/lib/ -lwsock32 -lcrypt32 -lgdi32" \ CC=/usr/bin/x86_64-w64-mingw32-gcc \ - GOOS=${TARGET_OS} GOARCH=${TARGET_ARCH} go build -buildmode=c-shared -ldflags "$LDFLAGS" -tags "$WINDOWS_BUILD_TAGS" -o "${OUTPUT_DIR}/PsiphonTunnel-${TARGET_OS}-${TARGET_ARCH}.dll" PsiphonTunnel.go + GOOS=${TARGET_OS} GOARCH=${TARGET_ARCH} go build -buildmode=c-shared -ldflags "$LDFLAGS" -tags "$WINDOWS_BUILD_TAGS" -o "${OUTPUT_DIR}/${TARGET_ARCH}/psiphontunnel.dll" PsiphonTunnel.go } diff --git a/MobileLibrary/Android/README.md b/MobileLibrary/Android/README.md index 20e1151c2..aa8e85281 100644 --- a/MobileLibrary/Android/README.md +++ b/MobileLibrary/Android/README.md @@ -69,10 +69,10 @@ then add PsiphonTunnel dependency like following ``` dependencies { ... - implementation 'ca.psiphon:psiphontunnel:1.0.6' + implementation 'ca.psiphon:psiphontunnel:1.0.7' } ``` -Latest available release version can be found at https://github.com/Psiphon-Labs/psiphon-tunnel-core-Android-library +Where 1.0.7 is the target version. Latest available release version can be found at https://github.com/Psiphon-Labs/psiphon-tunnel-core-Android-library See example usage in [TunneledWebView sample app](./SampleApps/TunneledWebView/README.md) diff --git a/MobileLibrary/Android/SampleApps/TunneledWebView/app/build.gradle b/MobileLibrary/Android/SampleApps/TunneledWebView/app/build.gradle index 5460fde1d..c2b1a98af 100644 --- a/MobileLibrary/Android/SampleApps/TunneledWebView/app/build.gradle +++ b/MobileLibrary/Android/SampleApps/TunneledWebView/app/build.gradle @@ -34,5 +34,5 @@ dependencies { implementation fileTree(dir: 'libs', include: ['*.jar']) testImplementation 'junit:junit:4.12' implementation 'com.android.support:appcompat-v7:26.1.0' - implementation 'ca.psiphon:psiphontunnel:1.0.6' + implementation 'ca.psiphon:psiphontunnel:1.0.7' }