diff options
Diffstat (limited to 'src/main.go')
-rw-r--r-- | src/main.go | 130 |
1 files changed, 96 insertions, 34 deletions
diff --git a/src/main.go b/src/main.go index 196a4c6..7d86716 100644 --- a/src/main.go +++ b/src/main.go @@ -2,10 +2,15 @@ package main import ( "fmt" - "log" "os" "os/signal" "runtime" + "strconv" +) + +const ( + ENV_WG_TUN_FD = "WG_TUN_FD" + ENV_WG_UAPI_FD = "WG_UAPI_FD" ) func printUsage() { @@ -43,28 +48,6 @@ func main() { interfaceName = os.Args[1] } - // daemonize the process - - if !foreground { - err := Daemonize() - if err != nil { - log.Println("Failed to daemonize:", err) - } - return - } - - // increase number of go workers (for Go <1.5) - - runtime.GOMAXPROCS(runtime.NumCPU()) - - // open TUN device - - tun, err := CreateTUN(interfaceName) - if err != nil { - log.Println("Failed to create tun device:", err) - return - } - // get log level (default: info) logLevel := func() int { @@ -79,25 +62,103 @@ func main() { return LogLevelInfo }() - // create wireguard device + logger := NewLogger( + logLevel, + fmt.Sprintf("(%s) ", interfaceName), + ) + + logger.Debug.Println("Debug log enabled") + + // open TUN device (or use supplied fd) + + tun, err := func() (TUNDevice, error) { + tunFdStr := os.Getenv(ENV_WG_TUN_FD) + if tunFdStr == "" { + return CreateTUN(interfaceName) + } + + // construct tun device from supplied fd + + fd, err := strconv.ParseUint(tunFdStr, 10, 32) + if err != nil { + return nil, err + } + + file := os.NewFile(uintptr(fd), "") + return CreateTUNFromFile(interfaceName, file) + }() + + if err != nil { + logger.Error.Println("Failed to create TUN device:", err) + os.Exit(ExitSetupFailed) + } - device := NewDevice(tun, logLevel) + // open UAPI file (or use supplied fd) - logInfo := device.log.Info - logError := device.log.Error - logInfo.Println("Starting device") + fileUAPI, err := func() (*os.File, error) { + uapiFdStr := os.Getenv(ENV_WG_UAPI_FD) + if uapiFdStr == "" { + return UAPIOpen(interfaceName) + } + + // use supplied fd - // start configuration lister + fd, err := strconv.ParseUint(uapiFdStr, 10, 32) + if err != nil { + return nil, err + } + + return os.NewFile(uintptr(fd), ""), nil + }() - uapi, err := NewUAPIListener(interfaceName) if err != nil { - logError.Fatal("UAPI listen error:", err) + logger.Error.Println("UAPI listen error:", err) + os.Exit(ExitSetupFailed) + return } + // daemonize the process + + if !foreground { + env := os.Environ() + env = append(env, fmt.Sprintf("%s=3", ENV_WG_TUN_FD)) + env = append(env, fmt.Sprintf("%s=4", ENV_WG_UAPI_FD)) + attr := &os.ProcAttr{ + Files: []*os.File{ + nil, // stdin + nil, // stdout + nil, // stderr + tun.File(), + fileUAPI, + }, + Dir: ".", + Env: env, + } + err = Daemonize(attr) + if err != nil { + logger.Error.Println("Failed to daemonize:", err) + os.Exit(ExitSetupFailed) + } + return + } + + // increase number of go workers (for Go <1.5) + + runtime.GOMAXPROCS(runtime.NumCPU()) + + // create wireguard device + + device := NewDevice(tun, logger) + + logger.Info.Println("Device started") + + // start uapi listener errs := make(chan error) term := make(chan os.Signal) wait := device.WaitChannel() + uapi, err := UAPIListen(interfaceName, fileUAPI) + go func() { for { conn, err := uapi.Accept() @@ -109,7 +170,7 @@ func main() { } }() - logInfo.Println("UAPI listener started") + logger.Info.Println("UAPI listener started") // wait for program to terminate @@ -122,9 +183,10 @@ func main() { case <-errs: } - // clean up UAPI bind + // clean up uapi.Close() + device.Close() - logInfo.Println("Closing") + logger.Info.Println("Shutting down") } |