github.com/xtls/xray-core@v1.8.12-0.20240518155711-3168d27b0bdb/proxy/wireguard/wireguard.go (about) 1 package wireguard 2 3 import ( 4 "context" 5 "fmt" 6 "net/netip" 7 "strings" 8 9 "github.com/xtls/xray-core/common" 10 "github.com/xtls/xray-core/common/log" 11 "golang.zx2c4.com/wireguard/device" 12 ) 13 14 //go:generate go run github.com/xtls/xray-core/common/errors/errorgen 15 16 var wgLogger = &device.Logger{ 17 Verbosef: func(format string, args ...any) { 18 log.Record(&log.GeneralMessage{ 19 Severity: log.Severity_Debug, 20 Content: fmt.Sprintf(format, args...), 21 }) 22 }, 23 Errorf: func(format string, args ...any) { 24 log.Record(&log.GeneralMessage{ 25 Severity: log.Severity_Error, 26 Content: fmt.Sprintf(format, args...), 27 }) 28 }, 29 } 30 31 func init() { 32 common.Must(common.RegisterConfig((*DeviceConfig)(nil), func(ctx context.Context, config interface{}) (interface{}, error) { 33 deviceConfig := config.(*DeviceConfig) 34 if deviceConfig.IsClient { 35 return New(ctx, deviceConfig) 36 } else { 37 return NewServer(ctx, deviceConfig) 38 } 39 })) 40 } 41 42 // convert endpoint string to netip.Addr 43 func parseEndpoints(conf *DeviceConfig) ([]netip.Addr, bool, bool, error) { 44 var hasIPv4, hasIPv6 bool 45 46 endpoints := make([]netip.Addr, len(conf.Endpoint)) 47 for i, str := range conf.Endpoint { 48 var addr netip.Addr 49 if strings.Contains(str, "/") { 50 prefix, err := netip.ParsePrefix(str) 51 if err != nil { 52 return nil, false, false, err 53 } 54 addr = prefix.Addr() 55 if prefix.Bits() != addr.BitLen() { 56 return nil, false, false, newError("interface address subnet should be /32 for IPv4 and /128 for IPv6") 57 } 58 } else { 59 var err error 60 addr, err = netip.ParseAddr(str) 61 if err != nil { 62 return nil, false, false, err 63 } 64 } 65 endpoints[i] = addr 66 67 if addr.Is4() { 68 hasIPv4 = true 69 } else if addr.Is6() { 70 hasIPv6 = true 71 } 72 } 73 74 return endpoints, hasIPv4, hasIPv6, nil 75 } 76 77 // serialize the config into an IPC request 78 func createIPCRequest(conf *DeviceConfig) string { 79 var request strings.Builder 80 81 request.WriteString(fmt.Sprintf("private_key=%s\n", conf.SecretKey)) 82 83 if !conf.IsClient { 84 // placeholder, we'll handle actual port listening on Xray 85 request.WriteString("listen_port=1337\n") 86 } 87 88 for _, peer := range conf.Peers { 89 if peer.PublicKey != "" { 90 request.WriteString(fmt.Sprintf("public_key=%s\n", peer.PublicKey)) 91 } 92 93 if peer.PreSharedKey != "" { 94 request.WriteString(fmt.Sprintf("preshared_key=%s\n", peer.PreSharedKey)) 95 } 96 97 if peer.Endpoint != "" { 98 request.WriteString(fmt.Sprintf("endpoint=%s\n", peer.Endpoint)) 99 } 100 101 for _, ip := range peer.AllowedIps { 102 request.WriteString(fmt.Sprintf("allowed_ip=%s\n", ip)) 103 } 104 105 if peer.KeepAlive != 0 { 106 request.WriteString(fmt.Sprintf("persistent_keepalive_interval=%d\n", peer.KeepAlive)) 107 } 108 } 109 110 return request.String()[:request.Len()] 111 }