diff --git a/build b/build index f14d867..001b9a6 100755 --- a/build +++ b/build @@ -8,8 +8,9 @@ PKGVER=${PKGVER:-$(sh contrib/semver/version.sh --bare)} LDFLAGS="-X $PKGSRC.buildName=$PKGNAME -X $PKGSRC.buildVersion=$PKGVER" ARGS="-v" +DLL=false -while getopts "utc:l:dro:ps" option +while getopts "utc:l:dro:psk" option do case "$option" in @@ -22,6 +23,7 @@ do o) ARGS="$ARGS -o $OPTARG";; p) ARGS="$ARGS -buildmode=pie";; s) ARGS="$ARGS -tags netgo,osusersgo,static" LDFLAGS="$LDFLAGS -extldflags '-static'" CGO_ENABLED=0;; + k) DLL=true;; esac done @@ -29,11 +31,16 @@ if [ -z $TABLES ] && [ -z $DEBUG ]; then LDFLAGS="$LDFLAGS -s -w" fi -for CMD in yggstack ; do - echo "Building: $CMD" - go build $ARGS -ldflags="$LDFLAGS" -gcflags="$GCFLAGS" ./cmd/$CMD +if [ "$DLL" = true ]; then + echo "Building: shared library" + CGO_ENABLED=1 go build $ARGS -buildmode=c-shared -ldflags="$LDFLAGS" -gcflags="$GCFLAGS" -o yggstack ./pkg/yggstack +else + for CMD in yggstack ; do + echo "Building: $CMD" + go build $ARGS -ldflags="$LDFLAGS" -gcflags="$GCFLAGS" ./cmd/$CMD - if [ $UPX ]; then - upx --brute $CMD - fi -done + if [ $UPX ]; then + upx --brute $CMD + fi + done +fi diff --git a/cmd/yggstack/program.go b/cmd/yggstack/program.go new file mode 100644 index 0000000..f6e04b8 --- /dev/null +++ b/cmd/yggstack/program.go @@ -0,0 +1,11 @@ +package main + +import ( + "os" + + "github.com/yggdrasil-network/yggstack/src/driver" +) + +func main() { + driver.Run(os.Args[1:]) +} diff --git a/pkg/yggstack/lib.go b/pkg/yggstack/lib.go new file mode 100644 index 0000000..90a2616 --- /dev/null +++ b/pkg/yggstack/lib.go @@ -0,0 +1,28 @@ +//go:build cgo +// +build cgo + +package main + +/* +#include +*/ +import "C" +import ( + "unsafe" + + "github.com/yggdrasil-network/yggstack/src/driver" +) + +func main() {} + +//export YggstackMain +func YggstackMain(argc C.int, argv **C.char) { + length := int(argc) + args := make([]string, length) + argvPtr := unsafe.Pointer(argv) + for i := 0; i < length; i++ { + arg := *(**C.char)(unsafe.Add(argvPtr, uintptr(i)*unsafe.Sizeof((*C.char)(nil)))) + args[i] = C.GoString(arg) + } + driver.Run(args) +} diff --git a/cmd/yggstack/main.go b/src/driver/driver.go similarity index 99% rename from cmd/yggstack/main.go rename to src/driver/driver.go index efad372..d255637 100644 --- a/cmd/yggstack/main.go +++ b/src/driver/driver.go @@ -1,4 +1,4 @@ -package main +package driver import ( "context" @@ -47,8 +47,7 @@ type UDPSession struct { remoteAddr net.Addr } -// The main function is responsible for configuring and starting Yggdrasil. -func main() { +func Run(args []string) { var localtcp types.TCPLocalMappings var localudp types.UDPLocalMappings var remotetcp types.TCPRemoteMappings @@ -72,7 +71,7 @@ func main() { flag.Var(&localudp, "local-udp", "UDP ports to forward to the remote Yggdrasil node, e.g. 22:[a:b:c:d]:2022, 127.0.0.1:[a:b:c:d]:22") flag.Var(&remotetcp, "remote-tcp", "TCP ports to expose to the network, e.g. 22, 2022:22, 22:192.168.1.1:2022") flag.Var(&remoteudp, "remote-udp", "UDP ports to expose to the network, e.g. 22, 2022:22, 22:192.168.1.1:2022") - flag.Parse() + flag.CommandLine.Parse(args) // Catch interrupts from the operating system to exit gracefully. ctx, _ := signal.NotifyContext(context.Background(), os.Interrupt, syscall.SIGTERM)