gitee.com/aurawing/surguard-go@v0.3.1-0.20240409071558-96509a61ecf3/main_windows.go (about)

     1  /* SPDX-License-Identifier: MIT
     2   *
     3   * Copyright (C) 2017-2023 WireGuard LLC. All Rights Reserved.
     4   */
     5  
     6  package main
     7  
     8  import (
     9  	"fmt"
    10  	"net"
    11  	"os"
    12  	"os/signal"
    13  	"strconv"
    14  
    15  	"golang.org/x/sys/windows"
    16  
    17  	"gitee.com/aurawing/surguard-go/conn"
    18  	"gitee.com/aurawing/surguard-go/device"
    19  	"gitee.com/aurawing/surguard-go/ipc"
    20  
    21  	"gitee.com/aurawing/surguard-go/tun"
    22  )
    23  
    24  const (
    25  	ExitSetupSuccess = 0
    26  	ExitSetupFailed  = 1
    27  )
    28  
    29  const (
    30  	ENV_SG_LEGACY_MODE = "SG_LEGACY_MODE"
    31  )
    32  
    33  func main() {
    34  	if len(os.Args) != 2 {
    35  		os.Exit(ExitSetupFailed)
    36  	}
    37  	interfaceName := os.Args[1]
    38  
    39  	fmt.Fprintln(os.Stderr, "Warning: this is a test program for Windows, mainly used for debugging this Go package. For a real WireGuard for Windows client, the repo you want is <https://git.zx2c4.com/wireguard-windows/>, which includes this code as a module.")
    40  
    41  	logger := device.NewLogger(
    42  		device.LogLevelVerbose,
    43  		fmt.Sprintf("(%s) ", interfaceName),
    44  	)
    45  	logger.Verbosef("Starting surguard version %s", Version)
    46  
    47  	tun, err := tun.CreateTUN(interfaceName, 0)
    48  	if err == nil {
    49  		realInterfaceName, err2 := tun.Name()
    50  		if err2 == nil {
    51  			interfaceName = realInterfaceName
    52  		}
    53  	} else {
    54  		logger.Errorf("Failed to create TUN device: %v", err)
    55  		os.Exit(ExitSetupFailed)
    56  	}
    57  
    58  	dev := device.NewDevice(tun, conn.NewDefaultBind(), logger)
    59  	err = dev.Up()
    60  	if err != nil {
    61  		logger.Errorf("Failed to bring up device: %v", err)
    62  		os.Exit(ExitSetupFailed)
    63  	}
    64  	logger.Verbosef("Device started")
    65  
    66  	errs := make(chan error)
    67  	term := make(chan os.Signal, 1)
    68  
    69  	var uapi net.Listener
    70  	legacymode := os.Getenv(ENV_SG_LEGACY_MODE)
    71  	statPortStr := os.Getenv(device.ENV_SG_LISTEN_PORT)
    72  	if statPortStr == "" {
    73  		statPortStr = strconv.FormatInt(device.DEFAULT_LISTEN_PORT, 10)
    74  	}
    75  	if legacymode == "true" {
    76  		uapi, err = ipc.UAPIListen(interfaceName)
    77  		if err != nil {
    78  			logger.Errorf("Failed to listen on uapi socket: %v", err)
    79  			os.Exit(ExitSetupFailed)
    80  		}
    81  
    82  		go func() {
    83  			for {
    84  				conn, err := uapi.Accept()
    85  				if err != nil {
    86  					errs <- err
    87  					return
    88  				}
    89  				go dev.IpcHandle(conn)
    90  			}
    91  		}()
    92  		logger.Verbosef("UAPI listener started")
    93  	} else {
    94  		err = startStatServer(interfaceName, statPortStr, logger, dev)
    95  		if err != nil {
    96  			logger.Errorf("start stat server failed: %v", err)
    97  			os.Exit(ExitSetupFailed)
    98  		}
    99  		dev.PostConfig()
   100  	}
   101  
   102  	// wait for program to terminate
   103  
   104  	signal.Notify(term, os.Interrupt)
   105  	signal.Notify(term, os.Kill)
   106  	signal.Notify(term, windows.SIGTERM)
   107  
   108  	select {
   109  	case <-term:
   110  	case <-errs:
   111  	case <-dev.Wait():
   112  	}
   113  
   114  	// clean up
   115  	if legacymode == "true" {
   116  		uapi.Close()
   117  	} else {
   118  		dev.ClearConfig()
   119  		stopStatServer(logger)
   120  	}
   121  	dev.Close()
   122  
   123  	logger.Verbosef("Shutting down")
   124  }