summaryrefslogtreecommitdiffhomepage
path: root/src/main.go
diff options
context:
space:
mode:
Diffstat (limited to 'src/main.go')
-rw-r--r--src/main.go130
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")
}