github.com/bepass-org/wireguard-go@v1.0.4-rc2.0.20240304192354-ebce6572bc24/main.go (about)

     1  package main
     2  
     3  import (
     4  	"context"
     5  	"errors"
     6  	"fmt"
     7  	"log"
     8  	"net/netip"
     9  	"os"
    10  	"os/signal"
    11  	"syscall"
    12  	"time"
    13  
    14  	"github.com/bepass-org/wireguard-go/app"
    15  	"github.com/bepass-org/wireguard-go/warp"
    16  
    17  	"github.com/peterbourgon/ff/v4"
    18  	"github.com/peterbourgon/ff/v4/ffhelp"
    19  )
    20  
    21  var psiphonCountries = []string{
    22  	"AT",
    23  	"BE",
    24  	"BG",
    25  	"BR",
    26  	"CA",
    27  	"CH",
    28  	"CZ",
    29  	"DE",
    30  	"DK",
    31  	"EE",
    32  	"ES",
    33  	"FI",
    34  	"FR",
    35  	"GB",
    36  	"HU",
    37  	"IE",
    38  	"IN",
    39  	"IT",
    40  	"JP",
    41  	"LV",
    42  	"NL",
    43  	"NO",
    44  	"PL",
    45  	"RO",
    46  	"RS",
    47  	"SE",
    48  	"SG",
    49  	"SK",
    50  	"UA",
    51  	"US",
    52  }
    53  
    54  func main() {
    55  	fs := ff.NewFlagSet("warp")
    56  	var (
    57  		verbose  = fs.Bool('v', "verbose", "enable verbose logging")
    58  		bind     = fs.String('b', "bind", "127.0.0.1:8086", "socks bind address")
    59  		endpoint = fs.String('e', "endpoint", "", "warp endpoint")
    60  		key      = fs.String('k', "key", "", "warp key")
    61  		country  = fs.StringEnumLong("country", fmt.Sprintf("psiphon country code (valid values: %s)", psiphonCountries), psiphonCountries...)
    62  		psiphon  = fs.BoolLong("cfon", "enable psiphon mode (must provide country as well)")
    63  		gool     = fs.BoolLong("gool", "enable gool mode (warp in warp)")
    64  		scan     = fs.BoolLong("scan", "enable warp scanning (experimental)")
    65  		rtt      = fs.DurationLong("rtt", 1000*time.Millisecond, "scanner rtt limit")
    66  	)
    67  
    68  	// Config file and envvars can be added through ff later
    69  	err := ff.Parse(fs, os.Args[1:])
    70  	switch {
    71  	case errors.Is(err, ff.ErrHelp):
    72  		fmt.Fprintf(os.Stderr, "%s\n", ffhelp.Flags(fs))
    73  		os.Exit(0)
    74  	case err != nil:
    75  		fmt.Fprintf(os.Stderr, "error: %v\n", err)
    76  		os.Exit(1)
    77  	}
    78  
    79  	if *psiphon && *gool {
    80  		log.Fatal(errors.New("can't use cfon and gool at the same time"))
    81  	}
    82  
    83  	bindAddrPort, err := netip.ParseAddrPort(*bind)
    84  	if err != nil {
    85  		log.Fatal(fmt.Errorf("invalid bind address: %w", err))
    86  	}
    87  
    88  	opts := app.WarpOptions{
    89  		Bind:     bindAddrPort,
    90  		Endpoint: *endpoint,
    91  		License:  *key,
    92  		Gool:     *gool,
    93  	}
    94  
    95  	if *verbose {
    96  		opts.LogLevel = "debug"
    97  		log.Printf("setting log level to: %s", opts.LogLevel)
    98  	}
    99  
   100  	if *psiphon {
   101  		log.Printf("psiphon mode enabled, using country %s", *country)
   102  		opts.Psiphon = &app.PsiphonOptions{Country: *country}
   103  	}
   104  
   105  	if *scan {
   106  		log.Printf("scanner mode enabled, using %s max RTT", rtt)
   107  		opts.Scan = &app.ScanOptions{MaxRTT: *rtt}
   108  	}
   109  
   110  	// If the endpoint is not set, choose a random warp endpoint
   111  	if opts.Endpoint == "" {
   112  		addrPort, err := warp.RandomWarpEndpoint()
   113  		if err != nil {
   114  			log.Fatal(err)
   115  		}
   116  		opts.Endpoint = addrPort.String()
   117  	}
   118  
   119  	ctx, _ := signal.NotifyContext(context.Background(), os.Interrupt, syscall.SIGTERM)
   120  	go func() {
   121  		if err := app.RunWarp(ctx, opts); err != nil {
   122  			log.Fatal(err)
   123  		}
   124  	}()
   125  
   126  	<-ctx.Done()
   127  }