Skip to content

Commit

Permalink
Wireguard resolve strategy (#2717)
Browse files Browse the repository at this point in the history
* 增加 wireguard 出站选项 `resolveStrategy`.

* They become a part of you.

* 移除不必要的选项别名.

* aliases NG.

* 微调.

---------

Co-authored-by: rui0572 <125641819+rui0572@users.noreply.github.com>
  • Loading branch information
yuhan6665 and rui0572 authored Nov 12, 2023
1 parent cc4b28b commit a109389
Show file tree
Hide file tree
Showing 6 changed files with 175 additions and 35 deletions.
29 changes: 23 additions & 6 deletions infra/conf/wireguard.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package conf
import (
"encoding/base64"
"encoding/hex"
"strings"

"github.com/xtls/xray-core/proxy/wireguard"
"google.golang.org/protobuf/proto"
Expand Down Expand Up @@ -47,12 +48,13 @@ func (c *WireGuardPeerConfig) Build() (proto.Message, error) {
}

type WireGuardConfig struct {
SecretKey string `json:"secretKey"`
Address []string `json:"address"`
Peers []*WireGuardPeerConfig `json:"peers"`
MTU int `json:"mtu"`
NumWorkers int `json:"workers"`
Reserved []byte `json:"reserved"`
SecretKey string `json:"secretKey"`
Address []string `json:"address"`
Peers []*WireGuardPeerConfig `json:"peers"`
MTU int `json:"mtu"`
NumWorkers int `json:"workers"`
Reserved []byte `json:"reserved"`
DomainStrategy string `json:"domainStrategy"`
}

func (c *WireGuardConfig) Build() (proto.Message, error) {
Expand Down Expand Up @@ -96,6 +98,21 @@ func (c *WireGuardConfig) Build() (proto.Message, error) {
}
config.Reserved = c.Reserved

switch strings.ToLower(c.DomainStrategy) {
case "forceip", "":
config.DomainStrategy = wireguard.DeviceConfig_FORCE_IP
case "forceipv4":
config.DomainStrategy = wireguard.DeviceConfig_FORCE_IP4
case "forceipv6":
config.DomainStrategy = wireguard.DeviceConfig_FORCE_IP6
case "forceipv4v6":
config.DomainStrategy = wireguard.DeviceConfig_FORCE_IP46
case "forceipv6v4":
config.DomainStrategy = wireguard.DeviceConfig_FORCE_IP64
default:
return nil, newError("unsupported domain strategy: ", c.DomainStrategy)
}

return config, nil
}

Expand Down
8 changes: 5 additions & 3 deletions infra/conf/wireguard_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@ func TestWireGuardOutbound(t *testing.T) {
}
],
"mtu": 1300,
"workers": 2
"workers": 2,
"domainStrategy": "ForceIPv6v4"
}`,
Parser: loadJSON(creator),
Output: &wireguard.DeviceConfig{
Expand All @@ -41,8 +42,9 @@ func TestWireGuardOutbound(t *testing.T) {
AllowedIps: []string{"0.0.0.0/0", "::0/0"},
},
},
Mtu: 1300,
NumWorkers: 2,
Mtu: 1300,
NumWorkers: 2,
DomainStrategy: wireguard.DeviceConfig_FORCE_IP64,
},
},
})
Expand Down
25 changes: 25 additions & 0 deletions proxy/wireguard/config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package wireguard

func (c *DeviceConfig) preferIP4() bool {
return c.DomainStrategy == DeviceConfig_FORCE_IP ||
c.DomainStrategy == DeviceConfig_FORCE_IP4 ||
c.DomainStrategy == DeviceConfig_FORCE_IP46
}

func (c *DeviceConfig) preferIP6() bool {
return c.DomainStrategy == DeviceConfig_FORCE_IP ||
c.DomainStrategy == DeviceConfig_FORCE_IP6 ||
c.DomainStrategy == DeviceConfig_FORCE_IP64
}

func (c *DeviceConfig) hasFallback() bool {
return c.DomainStrategy == DeviceConfig_FORCE_IP46 || c.DomainStrategy == DeviceConfig_FORCE_IP64
}

func (c *DeviceConfig) fallbackIP4() bool {
return c.DomainStrategy == DeviceConfig_FORCE_IP64
}

func (c *DeviceConfig) fallbackIP6() bool {
return c.DomainStrategy == DeviceConfig_FORCE_IP46
}
125 changes: 102 additions & 23 deletions proxy/wireguard/config.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 8 additions & 0 deletions proxy/wireguard/config.proto
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,18 @@ message PeerConfig {
}

message DeviceConfig {
enum DomainStrategy {
FORCE_IP = 0;
FORCE_IP4 = 1;
FORCE_IP6 = 2;
FORCE_IP46 = 3;
FORCE_IP64 = 4;
}
string secret_key = 1;
repeated string endpoint = 2;
repeated PeerConfig peers = 3;
int32 mtu = 4;
int32 num_workers = 5;
bytes reserved = 6;
DomainStrategy domain_strategy = 7;
}
15 changes: 12 additions & 3 deletions proxy/wireguard/wireguard.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import (

"github.com/xtls/xray-core/common"
"github.com/xtls/xray-core/common/buf"
"github.com/xtls/xray-core/common/dice"
"github.com/xtls/xray-core/common/log"
"github.com/xtls/xray-core/common/net"
"github.com/xtls/xray-core/common/protocol"
Expand Down Expand Up @@ -159,15 +160,23 @@ func (h *Handler) Process(ctx context.Context, link *transport.Link, dialer inte
addr := destination.Address
if addr.Family().IsDomain() {
ips, err := h.dns.LookupIP(addr.Domain(), dns.IPOption{
IPv4Enable: h.hasIPv4,
IPv6Enable: h.hasIPv6,
IPv4Enable: h.hasIPv4 && h.conf.preferIP4(),
IPv6Enable: h.hasIPv6 && h.conf.preferIP6(),
})
{ // Resolve fallback
if (len(ips) == 0 || err != nil) && h.conf.hasFallback() {
ips, err = h.dns.LookupIP(addr.Domain(), dns.IPOption{
IPv4Enable: h.hasIPv4 && h.conf.fallbackIP4(),
IPv6Enable: h.hasIPv6 && h.conf.fallbackIP6(),
})
}
}
if err != nil {
return newError("failed to lookup DNS").Base(err)
} else if len(ips) == 0 {
return dns.ErrEmptyResponse
}
addr = net.IPAddress(ips[0])
addr = net.IPAddress(ips[dice.Roll(len(ips))])
}

var newCtx context.Context
Expand Down

1 comment on commit a109389

@chika0801
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

原讨论链接:#2014

Please sign in to comment.