mirror of
https://github.com/SagerNet/sing-box.git
synced 2026-04-14 20:58:33 +10:00
refactor: WireGuard endpoint
This commit is contained in:
@@ -26,7 +26,7 @@ type Outbound struct {
|
||||
|
||||
func New(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, _ option.StubOptions) (adapter.Outbound, error) {
|
||||
return &Outbound{
|
||||
Adapter: outbound.NewAdapter(C.TypeBlock, []string{N.NetworkTCP, N.NetworkUDP}, tag, nil),
|
||||
Adapter: outbound.NewAdapter(C.TypeBlock, tag, []string{N.NetworkTCP, N.NetworkUDP}, nil),
|
||||
logger: logger,
|
||||
}, nil
|
||||
}
|
||||
|
||||
@@ -68,7 +68,10 @@ func NewInbound(ctx context.Context, router adapter.Router, logger log.ContextLo
|
||||
return inbound, nil
|
||||
}
|
||||
|
||||
func (i *Inbound) Start() error {
|
||||
func (i *Inbound) Start(stage adapter.StartStage) error {
|
||||
if stage != adapter.StartStateStart {
|
||||
return nil
|
||||
}
|
||||
return i.listener.Start()
|
||||
}
|
||||
|
||||
|
||||
@@ -52,7 +52,7 @@ func NewOutbound(ctx context.Context, router adapter.Router, logger log.ContextL
|
||||
return nil, err
|
||||
}
|
||||
outbound := &Outbound{
|
||||
Adapter: outbound.NewAdapterWithDialerOptions(C.TypeDirect, []string{N.NetworkTCP, N.NetworkUDP}, tag, options.DialerOptions),
|
||||
Adapter: outbound.NewAdapterWithDialerOptions(C.TypeDirect, tag, []string{N.NetworkTCP, N.NetworkUDP}, options.DialerOptions),
|
||||
logger: logger,
|
||||
domainStrategy: dns.DomainStrategy(options.DomainStrategy),
|
||||
fallbackDelay: time.Duration(options.FallbackDelay),
|
||||
|
||||
@@ -28,7 +28,7 @@ type Outbound struct {
|
||||
|
||||
func NewOutbound(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, options option.StubOptions) (adapter.Outbound, error) {
|
||||
return &Outbound{
|
||||
Adapter: outbound.NewAdapter(C.TypeDNS, []string{N.NetworkTCP, N.NetworkUDP}, tag, nil),
|
||||
Adapter: outbound.NewAdapter(C.TypeDNS, tag, []string{N.NetworkTCP, N.NetworkUDP}, nil),
|
||||
router: router,
|
||||
logger: logger,
|
||||
}, nil
|
||||
|
||||
@@ -38,7 +38,7 @@ type Selector struct {
|
||||
|
||||
func NewSelector(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, options option.SelectorOutboundOptions) (adapter.Outbound, error) {
|
||||
outbound := &Selector{
|
||||
Adapter: outbound.NewAdapter(C.TypeSelector, nil, tag, options.Outbounds),
|
||||
Adapter: outbound.NewAdapter(C.TypeSelector, tag, nil, options.Outbounds),
|
||||
ctx: ctx,
|
||||
outboundManager: service.FromContext[adapter.OutboundManager](ctx),
|
||||
logger: logger,
|
||||
|
||||
@@ -49,7 +49,7 @@ type URLTest struct {
|
||||
|
||||
func NewURLTest(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, options option.URLTestOutboundOptions) (adapter.Outbound, error) {
|
||||
outbound := &URLTest{
|
||||
Adapter: outbound.NewAdapter(C.TypeURLTest, []string{N.NetworkTCP, N.NetworkUDP}, tag, options.Outbounds),
|
||||
Adapter: outbound.NewAdapter(C.TypeURLTest, tag, []string{N.NetworkTCP, N.NetworkUDP}, options.Outbounds),
|
||||
ctx: ctx,
|
||||
router: router,
|
||||
outboundManager: service.FromContext[adapter.OutboundManager](ctx),
|
||||
|
||||
@@ -61,7 +61,10 @@ func NewInbound(ctx context.Context, router adapter.Router, logger log.ContextLo
|
||||
return inbound, nil
|
||||
}
|
||||
|
||||
func (h *Inbound) Start() error {
|
||||
func (h *Inbound) Start(stage adapter.StartStage) error {
|
||||
if stage != adapter.StartStateStart {
|
||||
return nil
|
||||
}
|
||||
if h.tlsConfig != nil {
|
||||
err := h.tlsConfig.Start()
|
||||
if err != nil {
|
||||
|
||||
@@ -39,7 +39,7 @@ func NewOutbound(ctx context.Context, router adapter.Router, logger log.ContextL
|
||||
return nil, err
|
||||
}
|
||||
return &Outbound{
|
||||
Adapter: outbound.NewAdapterWithDialerOptions(C.TypeHTTP, []string{N.NetworkTCP}, tag, options.DialerOptions),
|
||||
Adapter: outbound.NewAdapterWithDialerOptions(C.TypeHTTP, tag, []string{N.NetworkTCP}, options.DialerOptions),
|
||||
logger: logger,
|
||||
client: sHTTP.NewClient(sHTTP.Options{
|
||||
Dialer: detour,
|
||||
|
||||
@@ -160,7 +160,10 @@ func (h *Inbound) NewPacketConnectionEx(ctx context.Context, conn N.PacketConn,
|
||||
h.router.RoutePacketConnectionEx(ctx, conn, metadata, onClose)
|
||||
}
|
||||
|
||||
func (h *Inbound) Start() error {
|
||||
func (h *Inbound) Start(stage adapter.StartStage) error {
|
||||
if stage != adapter.StartStateStart {
|
||||
return nil
|
||||
}
|
||||
if h.tlsConfig != nil {
|
||||
err := h.tlsConfig.Start()
|
||||
if err != nil {
|
||||
|
||||
@@ -95,7 +95,7 @@ func NewOutbound(ctx context.Context, router adapter.Router, logger log.ContextL
|
||||
return nil, err
|
||||
}
|
||||
return &Outbound{
|
||||
Adapter: outbound.NewAdapterWithDialerOptions(C.TypeHysteria, networkList, tag, options.DialerOptions),
|
||||
Adapter: outbound.NewAdapterWithDialerOptions(C.TypeHysteria, tag, networkList, options.DialerOptions),
|
||||
logger: logger,
|
||||
client: client,
|
||||
}, nil
|
||||
|
||||
@@ -171,7 +171,10 @@ func (h *Inbound) NewPacketConnectionEx(ctx context.Context, conn N.PacketConn,
|
||||
h.router.RoutePacketConnectionEx(ctx, conn, metadata, onClose)
|
||||
}
|
||||
|
||||
func (h *Inbound) Start() error {
|
||||
func (h *Inbound) Start(stage adapter.StartStage) error {
|
||||
if stage != adapter.StartStateStart {
|
||||
return nil
|
||||
}
|
||||
if h.tlsConfig != nil {
|
||||
err := h.tlsConfig.Start()
|
||||
if err != nil {
|
||||
|
||||
@@ -81,7 +81,7 @@ func NewOutbound(ctx context.Context, router adapter.Router, logger log.ContextL
|
||||
return nil, err
|
||||
}
|
||||
return &Outbound{
|
||||
Adapter: outbound.NewAdapterWithDialerOptions(C.TypeHysteria2, networkList, tag, options.DialerOptions),
|
||||
Adapter: outbound.NewAdapterWithDialerOptions(C.TypeHysteria2, tag, networkList, options.DialerOptions),
|
||||
logger: logger,
|
||||
client: client,
|
||||
}, nil
|
||||
|
||||
@@ -54,7 +54,10 @@ func NewInbound(ctx context.Context, router adapter.Router, logger log.ContextLo
|
||||
return inbound, nil
|
||||
}
|
||||
|
||||
func (h *Inbound) Start() error {
|
||||
func (h *Inbound) Start(stage adapter.StartStage) error {
|
||||
if stage != adapter.StartStateStart {
|
||||
return nil
|
||||
}
|
||||
return h.listener.Start()
|
||||
}
|
||||
|
||||
|
||||
@@ -78,7 +78,10 @@ func NewInbound(ctx context.Context, router adapter.Router, logger log.ContextLo
|
||||
return inbound, nil
|
||||
}
|
||||
|
||||
func (n *Inbound) Start() error {
|
||||
func (n *Inbound) Start(stage adapter.StartStage) error {
|
||||
if stage != adapter.StartStateStart {
|
||||
return nil
|
||||
}
|
||||
var tlsConfig *tls.STDConfig
|
||||
if n.tlsConfig != nil {
|
||||
err := n.tlsConfig.Start()
|
||||
|
||||
@@ -42,7 +42,10 @@ func NewRedirect(ctx context.Context, router adapter.Router, logger log.ContextL
|
||||
return redirect, nil
|
||||
}
|
||||
|
||||
func (h *Redirect) Start() error {
|
||||
func (h *Redirect) Start(stage adapter.StartStage) error {
|
||||
if stage != adapter.StartStateStart {
|
||||
return nil
|
||||
}
|
||||
return h.listener.Start()
|
||||
}
|
||||
|
||||
|
||||
@@ -61,7 +61,10 @@ func NewTProxy(ctx context.Context, router adapter.Router, logger log.ContextLog
|
||||
return tproxy, nil
|
||||
}
|
||||
|
||||
func (t *TProxy) Start() error {
|
||||
func (t *TProxy) Start(stage adapter.StartStage) error {
|
||||
if stage != adapter.StartStateStart {
|
||||
return nil
|
||||
}
|
||||
err := t.listener.Start()
|
||||
if err != nil {
|
||||
return err
|
||||
|
||||
@@ -93,7 +93,10 @@ func newInbound(ctx context.Context, router adapter.Router, logger log.ContextLo
|
||||
return inbound, err
|
||||
}
|
||||
|
||||
func (h *Inbound) Start() error {
|
||||
func (h *Inbound) Start(stage adapter.StartStage) error {
|
||||
if stage != adapter.StartStateStart {
|
||||
return nil
|
||||
}
|
||||
return h.listener.Start()
|
||||
}
|
||||
|
||||
|
||||
@@ -101,7 +101,10 @@ func newMultiInbound(ctx context.Context, router adapter.Router, logger log.Cont
|
||||
return inbound, err
|
||||
}
|
||||
|
||||
func (h *MultiInbound) Start() error {
|
||||
func (h *MultiInbound) Start(stage adapter.StartStage) error {
|
||||
if stage != adapter.StartStateStart {
|
||||
return nil
|
||||
}
|
||||
return h.listener.Start()
|
||||
}
|
||||
|
||||
|
||||
@@ -86,7 +86,10 @@ func newRelayInbound(ctx context.Context, router adapter.Router, logger log.Cont
|
||||
return inbound, err
|
||||
}
|
||||
|
||||
func (h *RelayInbound) Start() error {
|
||||
func (h *RelayInbound) Start(stage adapter.StartStage) error {
|
||||
if stage != adapter.StartStateStart {
|
||||
return nil
|
||||
}
|
||||
return h.listener.Start()
|
||||
}
|
||||
|
||||
|
||||
@@ -49,7 +49,7 @@ func NewOutbound(ctx context.Context, router adapter.Router, logger log.ContextL
|
||||
return nil, err
|
||||
}
|
||||
outbound := &Outbound{
|
||||
Adapter: outbound.NewAdapterWithDialerOptions(C.TypeShadowsocks, options.Network.Build(), tag, options.DialerOptions),
|
||||
Adapter: outbound.NewAdapterWithDialerOptions(C.TypeShadowsocks, tag, options.Network.Build(), options.DialerOptions),
|
||||
logger: logger,
|
||||
dialer: outboundDialer,
|
||||
method: method,
|
||||
|
||||
@@ -90,7 +90,10 @@ func NewInbound(ctx context.Context, router adapter.Router, logger log.ContextLo
|
||||
return inbound, nil
|
||||
}
|
||||
|
||||
func (h *Inbound) Start() error {
|
||||
func (h *Inbound) Start(stage adapter.StartStage) error {
|
||||
if stage != adapter.StartStateStart {
|
||||
return nil
|
||||
}
|
||||
return h.listener.Start()
|
||||
}
|
||||
|
||||
|
||||
@@ -29,7 +29,7 @@ type Outbound struct {
|
||||
|
||||
func NewOutbound(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, options option.ShadowTLSOutboundOptions) (adapter.Outbound, error) {
|
||||
outbound := &Outbound{
|
||||
Adapter: outbound.NewAdapterWithDialerOptions(C.TypeShadowTLS, []string{N.NetworkTCP}, tag, options.DialerOptions),
|
||||
Adapter: outbound.NewAdapterWithDialerOptions(C.TypeShadowTLS, tag, []string{N.NetworkTCP}, options.DialerOptions),
|
||||
}
|
||||
if options.TLS == nil || !options.TLS.Enabled {
|
||||
return nil, C.ErrTLSRequired
|
||||
|
||||
@@ -50,7 +50,10 @@ func NewInbound(ctx context.Context, router adapter.Router, logger log.ContextLo
|
||||
return inbound, nil
|
||||
}
|
||||
|
||||
func (h *Inbound) Start() error {
|
||||
func (h *Inbound) Start(stage adapter.StartStage) error {
|
||||
if stage != adapter.StartStateStart {
|
||||
return nil
|
||||
}
|
||||
return h.listener.Start()
|
||||
}
|
||||
|
||||
|
||||
@@ -50,7 +50,7 @@ func NewOutbound(ctx context.Context, router adapter.Router, logger log.ContextL
|
||||
return nil, err
|
||||
}
|
||||
outbound := &Outbound{
|
||||
Adapter: outbound.NewAdapterWithDialerOptions(C.TypeSOCKS, options.Network.Build(), tag, options.DialerOptions),
|
||||
Adapter: outbound.NewAdapterWithDialerOptions(C.TypeSOCKS, tag, options.Network.Build(), options.DialerOptions),
|
||||
router: router,
|
||||
logger: logger,
|
||||
client: socks.NewClient(outboundDialer, options.ServerOptions.Build(), version, options.Username, options.Password),
|
||||
|
||||
@@ -54,7 +54,7 @@ func NewOutbound(ctx context.Context, router adapter.Router, logger log.ContextL
|
||||
return nil, err
|
||||
}
|
||||
outbound := &Outbound{
|
||||
Adapter: outbound.NewAdapterWithDialerOptions(C.TypeSSH, []string{N.NetworkTCP}, tag, options.DialerOptions),
|
||||
Adapter: outbound.NewAdapterWithDialerOptions(C.TypeSSH, tag, []string{N.NetworkTCP}, options.DialerOptions),
|
||||
ctx: ctx,
|
||||
logger: logger,
|
||||
dialer: outboundDialer,
|
||||
|
||||
@@ -80,7 +80,7 @@ func NewOutbound(ctx context.Context, router adapter.Router, logger log.ContextL
|
||||
return nil, err
|
||||
}
|
||||
return &Outbound{
|
||||
Adapter: outbound.NewAdapterWithDialerOptions(C.TypeTor, []string{N.NetworkTCP}, tag, options.DialerOptions),
|
||||
Adapter: outbound.NewAdapterWithDialerOptions(C.TypeTor, tag, []string{N.NetworkTCP}, options.DialerOptions),
|
||||
ctx: ctx,
|
||||
logger: logger,
|
||||
proxy: NewProxyListener(ctx, logger, outboundDialer),
|
||||
|
||||
@@ -110,7 +110,10 @@ func NewInbound(ctx context.Context, router adapter.Router, logger log.ContextLo
|
||||
return inbound, nil
|
||||
}
|
||||
|
||||
func (h *Inbound) Start() error {
|
||||
func (h *Inbound) Start(stage adapter.StartStage) error {
|
||||
if stage != adapter.StartStateStart {
|
||||
return nil
|
||||
}
|
||||
if h.tlsConfig != nil {
|
||||
err := h.tlsConfig.Start()
|
||||
if err != nil {
|
||||
|
||||
@@ -43,7 +43,7 @@ func NewOutbound(ctx context.Context, router adapter.Router, logger log.ContextL
|
||||
return nil, err
|
||||
}
|
||||
outbound := &Outbound{
|
||||
Adapter: outbound.NewAdapterWithDialerOptions(C.TypeTrojan, options.Network.Build(), tag, options.DialerOptions),
|
||||
Adapter: outbound.NewAdapterWithDialerOptions(C.TypeTrojan, tag, options.Network.Build(), options.DialerOptions),
|
||||
logger: logger,
|
||||
dialer: outboundDialer,
|
||||
serverAddr: options.ServerOptions.Build(),
|
||||
|
||||
@@ -142,7 +142,10 @@ func (h *Inbound) NewPacketConnectionEx(ctx context.Context, conn N.PacketConn,
|
||||
h.router.RoutePacketConnectionEx(ctx, conn, metadata, onClose)
|
||||
}
|
||||
|
||||
func (h *Inbound) Start() error {
|
||||
func (h *Inbound) Start(stage adapter.StartStage) error {
|
||||
if stage != adapter.StartStateStart {
|
||||
return nil
|
||||
}
|
||||
if h.tlsConfig != nil {
|
||||
err := h.tlsConfig.Start()
|
||||
if err != nil {
|
||||
|
||||
@@ -80,7 +80,7 @@ func NewOutbound(ctx context.Context, router adapter.Router, logger log.ContextL
|
||||
return nil, err
|
||||
}
|
||||
return &Outbound{
|
||||
Adapter: outbound.NewAdapterWithDialerOptions(C.TypeTUIC, options.Network.Build(), tag, options.DialerOptions),
|
||||
Adapter: outbound.NewAdapterWithDialerOptions(C.TypeTUIC, tag, options.Network.Build(), options.DialerOptions),
|
||||
logger: logger,
|
||||
client: client,
|
||||
udpStream: options.UDPOverStream,
|
||||
|
||||
@@ -300,104 +300,104 @@ func (t *Inbound) Tag() string {
|
||||
return t.tag
|
||||
}
|
||||
|
||||
func (t *Inbound) Start() error {
|
||||
if C.IsAndroid && t.platformInterface == nil {
|
||||
t.tunOptions.BuildAndroidRules(t.networkManager.PackageManager())
|
||||
}
|
||||
if t.tunOptions.Name == "" {
|
||||
t.tunOptions.Name = tun.CalculateInterfaceName("")
|
||||
}
|
||||
var (
|
||||
tunInterface tun.Tun
|
||||
err error
|
||||
)
|
||||
monitor := taskmonitor.New(t.logger, C.StartTimeout)
|
||||
monitor.Start("open tun interface")
|
||||
if t.platformInterface != nil {
|
||||
tunInterface, err = t.platformInterface.OpenTun(&t.tunOptions, t.platformOptions)
|
||||
} else {
|
||||
tunInterface, err = tun.New(t.tunOptions)
|
||||
}
|
||||
monitor.Finish()
|
||||
if err != nil {
|
||||
return E.Cause(err, "configure tun interface")
|
||||
}
|
||||
t.logger.Trace("creating stack")
|
||||
t.tunIf = tunInterface
|
||||
var (
|
||||
forwarderBindInterface bool
|
||||
includeAllNetworks bool
|
||||
)
|
||||
if t.platformInterface != nil {
|
||||
forwarderBindInterface = true
|
||||
includeAllNetworks = t.platformInterface.IncludeAllNetworks()
|
||||
}
|
||||
tunStack, err := tun.NewStack(t.stack, tun.StackOptions{
|
||||
Context: t.ctx,
|
||||
Tun: tunInterface,
|
||||
TunOptions: t.tunOptions,
|
||||
UDPTimeout: t.udpTimeout,
|
||||
Handler: t,
|
||||
Logger: t.logger,
|
||||
ForwarderBindInterface: forwarderBindInterface,
|
||||
InterfaceFinder: t.networkManager.InterfaceFinder(),
|
||||
IncludeAllNetworks: includeAllNetworks,
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
t.tunStack = tunStack
|
||||
t.logger.Info("started at ", t.tunOptions.Name)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t *Inbound) PostStart() error {
|
||||
monitor := taskmonitor.New(t.logger, C.StartTimeout)
|
||||
monitor.Start("starting tun stack")
|
||||
err := t.tunStack.Start()
|
||||
monitor.Finish()
|
||||
if err != nil {
|
||||
return E.Cause(err, "starting tun stack")
|
||||
}
|
||||
monitor.Start("starting tun interface")
|
||||
err = t.tunIf.Start()
|
||||
monitor.Finish()
|
||||
if err != nil {
|
||||
return E.Cause(err, "starting TUN interface")
|
||||
}
|
||||
if t.autoRedirect != nil {
|
||||
t.routeAddressSet = common.FlatMap(t.routeRuleSet, adapter.RuleSet.ExtractIPSet)
|
||||
for _, routeRuleSet := range t.routeRuleSet {
|
||||
ipSets := routeRuleSet.ExtractIPSet()
|
||||
if len(ipSets) == 0 {
|
||||
t.logger.Warn("route_address_set: no destination IP CIDR rules found in rule-set: ", routeRuleSet.Name())
|
||||
}
|
||||
t.routeAddressSet = append(t.routeAddressSet, ipSets...)
|
||||
func (t *Inbound) Start(stage adapter.StartStage) error {
|
||||
switch stage {
|
||||
case adapter.StartStateStart:
|
||||
if C.IsAndroid && t.platformInterface == nil {
|
||||
t.tunOptions.BuildAndroidRules(t.networkManager.PackageManager())
|
||||
}
|
||||
t.routeExcludeAddressSet = common.FlatMap(t.routeExcludeRuleSet, adapter.RuleSet.ExtractIPSet)
|
||||
for _, routeExcludeRuleSet := range t.routeExcludeRuleSet {
|
||||
ipSets := routeExcludeRuleSet.ExtractIPSet()
|
||||
if len(ipSets) == 0 {
|
||||
t.logger.Warn("route_address_set: no destination IP CIDR rules found in rule-set: ", routeExcludeRuleSet.Name())
|
||||
}
|
||||
t.routeExcludeAddressSet = append(t.routeExcludeAddressSet, ipSets...)
|
||||
if t.tunOptions.Name == "" {
|
||||
t.tunOptions.Name = tun.CalculateInterfaceName("")
|
||||
}
|
||||
var (
|
||||
tunInterface tun.Tun
|
||||
err error
|
||||
)
|
||||
monitor := taskmonitor.New(t.logger, C.StartTimeout)
|
||||
monitor.Start("open tun interface")
|
||||
if t.platformInterface != nil {
|
||||
tunInterface, err = t.platformInterface.OpenTun(&t.tunOptions, t.platformOptions)
|
||||
} else {
|
||||
tunInterface, err = tun.New(t.tunOptions)
|
||||
}
|
||||
monitor.Start("initialize auto-redirect")
|
||||
err := t.autoRedirect.Start()
|
||||
monitor.Finish()
|
||||
if err != nil {
|
||||
return E.Cause(err, "auto-redirect")
|
||||
return E.Cause(err, "configure tun interface")
|
||||
}
|
||||
for _, routeRuleSet := range t.routeRuleSet {
|
||||
t.routeRuleSetCallback = append(t.routeRuleSetCallback, routeRuleSet.RegisterCallback(t.updateRouteAddressSet))
|
||||
routeRuleSet.DecRef()
|
||||
t.logger.Trace("creating stack")
|
||||
t.tunIf = tunInterface
|
||||
var (
|
||||
forwarderBindInterface bool
|
||||
includeAllNetworks bool
|
||||
)
|
||||
if t.platformInterface != nil {
|
||||
forwarderBindInterface = true
|
||||
includeAllNetworks = t.platformInterface.IncludeAllNetworks()
|
||||
}
|
||||
for _, routeExcludeRuleSet := range t.routeExcludeRuleSet {
|
||||
t.routeExcludeRuleSetCallback = append(t.routeExcludeRuleSetCallback, routeExcludeRuleSet.RegisterCallback(t.updateRouteAddressSet))
|
||||
routeExcludeRuleSet.DecRef()
|
||||
tunStack, err := tun.NewStack(t.stack, tun.StackOptions{
|
||||
Context: t.ctx,
|
||||
Tun: tunInterface,
|
||||
TunOptions: t.tunOptions,
|
||||
UDPTimeout: t.udpTimeout,
|
||||
Handler: t,
|
||||
Logger: t.logger,
|
||||
ForwarderBindInterface: forwarderBindInterface,
|
||||
InterfaceFinder: t.networkManager.InterfaceFinder(),
|
||||
IncludeAllNetworks: includeAllNetworks,
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
t.tunStack = tunStack
|
||||
t.logger.Info("started at ", t.tunOptions.Name)
|
||||
case adapter.StartStatePostStart:
|
||||
monitor := taskmonitor.New(t.logger, C.StartTimeout)
|
||||
monitor.Start("starting tun stack")
|
||||
err := t.tunStack.Start()
|
||||
monitor.Finish()
|
||||
if err != nil {
|
||||
return E.Cause(err, "starting tun stack")
|
||||
}
|
||||
monitor.Start("starting tun interface")
|
||||
err = t.tunIf.Start()
|
||||
monitor.Finish()
|
||||
if err != nil {
|
||||
return E.Cause(err, "starting TUN interface")
|
||||
}
|
||||
if t.autoRedirect != nil {
|
||||
t.routeAddressSet = common.FlatMap(t.routeRuleSet, adapter.RuleSet.ExtractIPSet)
|
||||
for _, routeRuleSet := range t.routeRuleSet {
|
||||
ipSets := routeRuleSet.ExtractIPSet()
|
||||
if len(ipSets) == 0 {
|
||||
t.logger.Warn("route_address_set: no destination IP CIDR rules found in rule-set: ", routeRuleSet.Name())
|
||||
}
|
||||
t.routeAddressSet = append(t.routeAddressSet, ipSets...)
|
||||
}
|
||||
t.routeExcludeAddressSet = common.FlatMap(t.routeExcludeRuleSet, adapter.RuleSet.ExtractIPSet)
|
||||
for _, routeExcludeRuleSet := range t.routeExcludeRuleSet {
|
||||
ipSets := routeExcludeRuleSet.ExtractIPSet()
|
||||
if len(ipSets) == 0 {
|
||||
t.logger.Warn("route_address_set: no destination IP CIDR rules found in rule-set: ", routeExcludeRuleSet.Name())
|
||||
}
|
||||
t.routeExcludeAddressSet = append(t.routeExcludeAddressSet, ipSets...)
|
||||
}
|
||||
monitor.Start("initialize auto-redirect")
|
||||
err := t.autoRedirect.Start()
|
||||
monitor.Finish()
|
||||
if err != nil {
|
||||
return E.Cause(err, "auto-redirect")
|
||||
}
|
||||
for _, routeRuleSet := range t.routeRuleSet {
|
||||
t.routeRuleSetCallback = append(t.routeRuleSetCallback, routeRuleSet.RegisterCallback(t.updateRouteAddressSet))
|
||||
routeRuleSet.DecRef()
|
||||
}
|
||||
for _, routeExcludeRuleSet := range t.routeExcludeRuleSet {
|
||||
t.routeExcludeRuleSetCallback = append(t.routeExcludeRuleSetCallback, routeExcludeRuleSet.RegisterCallback(t.updateRouteAddressSet))
|
||||
routeExcludeRuleSet.DecRef()
|
||||
}
|
||||
t.routeAddressSet = nil
|
||||
t.routeExcludeAddressSet = nil
|
||||
}
|
||||
t.routeAddressSet = nil
|
||||
t.routeExcludeAddressSet = nil
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -89,7 +89,10 @@ func NewInbound(ctx context.Context, router adapter.Router, logger log.ContextLo
|
||||
return inbound, nil
|
||||
}
|
||||
|
||||
func (h *Inbound) Start() error {
|
||||
func (h *Inbound) Start(stage adapter.StartStage) error {
|
||||
if stage != adapter.StartStateStart {
|
||||
return nil
|
||||
}
|
||||
if h.tlsConfig != nil {
|
||||
err := h.tlsConfig.Start()
|
||||
if err != nil {
|
||||
|
||||
@@ -46,7 +46,7 @@ func NewOutbound(ctx context.Context, router adapter.Router, logger log.ContextL
|
||||
return nil, err
|
||||
}
|
||||
outbound := &Outbound{
|
||||
Adapter: outbound.NewAdapterWithDialerOptions(C.TypeVLESS, options.Network.Build(), tag, options.DialerOptions),
|
||||
Adapter: outbound.NewAdapterWithDialerOptions(C.TypeVLESS, tag, options.Network.Build(), options.DialerOptions),
|
||||
logger: logger,
|
||||
dialer: outboundDialer,
|
||||
serverAddr: options.ServerOptions.Build(),
|
||||
|
||||
@@ -99,7 +99,10 @@ func NewInbound(ctx context.Context, router adapter.Router, logger log.ContextLo
|
||||
return inbound, nil
|
||||
}
|
||||
|
||||
func (h *Inbound) Start() error {
|
||||
func (h *Inbound) Start(stage adapter.StartStage) error {
|
||||
if stage != adapter.StartStateStart {
|
||||
return nil
|
||||
}
|
||||
err := h.service.Start()
|
||||
if err != nil {
|
||||
return err
|
||||
|
||||
@@ -46,7 +46,7 @@ func NewOutbound(ctx context.Context, router adapter.Router, logger log.ContextL
|
||||
return nil, err
|
||||
}
|
||||
outbound := &Outbound{
|
||||
Adapter: outbound.NewAdapterWithDialerOptions(C.TypeVMess, options.Network.Build(), tag, options.DialerOptions),
|
||||
Adapter: outbound.NewAdapterWithDialerOptions(C.TypeVMess, tag, options.Network.Build(), options.DialerOptions),
|
||||
logger: logger,
|
||||
dialer: outboundDialer,
|
||||
serverAddr: options.ServerOptions.Build(),
|
||||
|
||||
211
protocol/wireguard/endpoint.go
Normal file
211
protocol/wireguard/endpoint.go
Normal file
@@ -0,0 +1,211 @@
|
||||
package wireguard
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net"
|
||||
"net/netip"
|
||||
"time"
|
||||
|
||||
"github.com/sagernet/sing-box/adapter"
|
||||
"github.com/sagernet/sing-box/adapter/endpoint"
|
||||
"github.com/sagernet/sing-box/common/dialer"
|
||||
C "github.com/sagernet/sing-box/constant"
|
||||
"github.com/sagernet/sing-box/log"
|
||||
"github.com/sagernet/sing-box/option"
|
||||
"github.com/sagernet/sing-box/transport/wireguard"
|
||||
"github.com/sagernet/sing-dns"
|
||||
"github.com/sagernet/sing/common"
|
||||
"github.com/sagernet/sing/common/bufio"
|
||||
E "github.com/sagernet/sing/common/exceptions"
|
||||
"github.com/sagernet/sing/common/logger"
|
||||
M "github.com/sagernet/sing/common/metadata"
|
||||
N "github.com/sagernet/sing/common/network"
|
||||
"github.com/sagernet/sing/service"
|
||||
)
|
||||
|
||||
func RegisterEndpoint(registry *endpoint.Registry) {
|
||||
endpoint.Register[option.WireGuardEndpointOptions](registry, C.TypeWireGuard, NewEndpoint)
|
||||
}
|
||||
|
||||
var (
|
||||
_ adapter.Endpoint = (*Endpoint)(nil)
|
||||
_ adapter.InterfaceUpdateListener = (*Endpoint)(nil)
|
||||
)
|
||||
|
||||
type Endpoint struct {
|
||||
endpoint.Adapter
|
||||
ctx context.Context
|
||||
router adapter.Router
|
||||
logger logger.ContextLogger
|
||||
localAddresses []netip.Prefix
|
||||
endpoint *wireguard.Endpoint
|
||||
}
|
||||
|
||||
func NewEndpoint(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, options option.WireGuardEndpointOptions) (adapter.Endpoint, error) {
|
||||
ep := &Endpoint{
|
||||
Adapter: endpoint.NewAdapterWithDialerOptions(C.TypeWireGuard, tag, []string{N.NetworkTCP, N.NetworkUDP}, options.DialerOptions),
|
||||
ctx: ctx,
|
||||
router: router,
|
||||
logger: logger,
|
||||
localAddresses: options.Address,
|
||||
}
|
||||
if options.Detour == "" {
|
||||
options.IsWireGuardListener = true
|
||||
} else if options.GSO {
|
||||
return nil, E.New("gso is conflict with detour")
|
||||
}
|
||||
outboundDialer, err := dialer.New(ctx, options.DialerOptions)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
wgEndpoint, err := wireguard.NewEndpoint(wireguard.EndpointOptions{
|
||||
Context: ctx,
|
||||
Logger: logger,
|
||||
System: options.System,
|
||||
Handler: ep,
|
||||
UDPTimeout: time.Duration(options.UDPTimeout),
|
||||
Dialer: outboundDialer,
|
||||
CreateDialer: func(interfaceName string) N.Dialer {
|
||||
return common.Must1(dialer.NewDefault(service.FromContext[adapter.NetworkManager](ctx), option.DialerOptions{
|
||||
BindInterface: interfaceName,
|
||||
}))
|
||||
},
|
||||
Name: options.Name,
|
||||
MTU: options.MTU,
|
||||
GSO: options.GSO,
|
||||
Address: options.Address,
|
||||
PrivateKey: options.PrivateKey,
|
||||
ListenPort: options.ListenPort,
|
||||
ResolvePeer: func(domain string) (netip.Addr, error) {
|
||||
endpointAddresses, lookupErr := router.Lookup(ctx, domain, dns.DomainStrategy(options.DomainStrategy))
|
||||
if lookupErr != nil {
|
||||
return netip.Addr{}, lookupErr
|
||||
}
|
||||
return endpointAddresses[0], nil
|
||||
},
|
||||
Peers: common.Map(options.Peers, func(it option.WireGuardPeer) wireguard.PeerOptions {
|
||||
return wireguard.PeerOptions{
|
||||
Endpoint: M.ParseSocksaddrHostPort(it.Address, it.Port),
|
||||
PublicKey: it.PublicKey,
|
||||
PreSharedKey: it.PreSharedKey,
|
||||
AllowedIPs: it.AllowedIPs,
|
||||
PersistentKeepaliveInterval: it.PersistentKeepaliveInterval,
|
||||
Reserved: it.Reserved,
|
||||
}
|
||||
}),
|
||||
Workers: options.Workers,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ep.endpoint = wgEndpoint
|
||||
return ep, nil
|
||||
}
|
||||
|
||||
func (w *Endpoint) Start(stage adapter.StartStage) error {
|
||||
switch stage {
|
||||
case adapter.StartStateStart:
|
||||
return w.endpoint.Start(false)
|
||||
case adapter.StartStatePostStart:
|
||||
return w.endpoint.Start(true)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (w *Endpoint) Close() error {
|
||||
return w.endpoint.Close()
|
||||
}
|
||||
|
||||
func (w *Endpoint) InterfaceUpdated() {
|
||||
w.endpoint.BindUpdate()
|
||||
return
|
||||
}
|
||||
|
||||
func (w *Endpoint) PrepareConnection(network string, source M.Socksaddr, destination M.Socksaddr) error {
|
||||
return w.router.PreMatch(adapter.InboundContext{
|
||||
Inbound: w.Tag(),
|
||||
InboundType: w.Type(),
|
||||
Network: network,
|
||||
Source: source,
|
||||
Destination: destination,
|
||||
})
|
||||
}
|
||||
|
||||
func (w *Endpoint) NewConnectionEx(ctx context.Context, conn net.Conn, source M.Socksaddr, destination M.Socksaddr, onClose N.CloseHandlerFunc) {
|
||||
var metadata adapter.InboundContext
|
||||
metadata.Inbound = w.Tag()
|
||||
metadata.InboundType = w.Type()
|
||||
metadata.Source = source
|
||||
for _, localPrefix := range w.localAddresses {
|
||||
if localPrefix.Contains(destination.Addr) {
|
||||
metadata.OriginDestination = destination
|
||||
if destination.Addr.Is4() {
|
||||
destination.Addr = netip.AddrFrom4([4]uint8{127, 0, 0, 1})
|
||||
} else {
|
||||
destination.Addr = netip.IPv6Loopback()
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
metadata.Destination = destination
|
||||
w.logger.InfoContext(ctx, "inbound connection from ", source)
|
||||
w.logger.InfoContext(ctx, "inbound connection to ", metadata.Destination)
|
||||
w.router.RouteConnectionEx(ctx, conn, metadata, onClose)
|
||||
}
|
||||
|
||||
func (w *Endpoint) NewPacketConnectionEx(ctx context.Context, conn N.PacketConn, source M.Socksaddr, destination M.Socksaddr, onClose N.CloseHandlerFunc) {
|
||||
var metadata adapter.InboundContext
|
||||
metadata.Inbound = w.Tag()
|
||||
metadata.InboundType = w.Type()
|
||||
metadata.Source = source
|
||||
metadata.Destination = destination
|
||||
for _, localPrefix := range w.localAddresses {
|
||||
if localPrefix.Contains(destination.Addr) {
|
||||
metadata.OriginDestination = destination
|
||||
if destination.Addr.Is4() {
|
||||
metadata.Destination.Addr = netip.AddrFrom4([4]uint8{127, 0, 0, 1})
|
||||
} else {
|
||||
metadata.Destination.Addr = netip.IPv6Loopback()
|
||||
}
|
||||
conn = bufio.NewNATPacketConn(bufio.NewNetPacketConn(conn), metadata.OriginDestination, metadata.Destination)
|
||||
}
|
||||
}
|
||||
w.logger.InfoContext(ctx, "inbound packet connection from ", source)
|
||||
w.logger.InfoContext(ctx, "inbound packet connection to ", destination)
|
||||
w.router.RoutePacketConnectionEx(ctx, conn, metadata, onClose)
|
||||
}
|
||||
|
||||
func (w *Endpoint) DialContext(ctx context.Context, network string, destination M.Socksaddr) (net.Conn, error) {
|
||||
switch network {
|
||||
case N.NetworkTCP:
|
||||
w.logger.InfoContext(ctx, "outbound connection to ", destination)
|
||||
case N.NetworkUDP:
|
||||
w.logger.InfoContext(ctx, "outbound packet connection to ", destination)
|
||||
}
|
||||
if destination.IsFqdn() {
|
||||
destinationAddresses, err := w.router.LookupDefault(ctx, destination.Fqdn)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return N.DialSerial(ctx, w.endpoint, network, destination, destinationAddresses)
|
||||
} else if !destination.Addr.IsValid() {
|
||||
return nil, E.New("invalid destination: ", destination)
|
||||
}
|
||||
return w.endpoint.DialContext(ctx, network, destination)
|
||||
}
|
||||
|
||||
func (w *Endpoint) ListenPacket(ctx context.Context, destination M.Socksaddr) (net.PacketConn, error) {
|
||||
w.logger.InfoContext(ctx, "outbound packet connection to ", destination)
|
||||
if destination.IsFqdn() {
|
||||
destinationAddresses, err := w.router.LookupDefault(ctx, destination.Fqdn)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
packetConn, _, err := N.ListenSerial(ctx, w.endpoint, destination, destinationAddresses)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return packetConn, err
|
||||
}
|
||||
return w.endpoint.ListenPacket(ctx, destination)
|
||||
}
|
||||
@@ -2,231 +2,153 @@ package wireguard
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/base64"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"net"
|
||||
"net/netip"
|
||||
"strings"
|
||||
|
||||
"github.com/sagernet/sing-box/adapter"
|
||||
"github.com/sagernet/sing-box/adapter/outbound"
|
||||
"github.com/sagernet/sing-box/common/dialer"
|
||||
C "github.com/sagernet/sing-box/constant"
|
||||
"github.com/sagernet/sing-box/experimental/deprecated"
|
||||
"github.com/sagernet/sing-box/log"
|
||||
"github.com/sagernet/sing-box/option"
|
||||
"github.com/sagernet/sing-box/transport/wireguard"
|
||||
"github.com/sagernet/sing-tun"
|
||||
"github.com/sagernet/sing-dns"
|
||||
"github.com/sagernet/sing/common"
|
||||
E "github.com/sagernet/sing/common/exceptions"
|
||||
"github.com/sagernet/sing/common/logger"
|
||||
M "github.com/sagernet/sing/common/metadata"
|
||||
N "github.com/sagernet/sing/common/network"
|
||||
"github.com/sagernet/sing/common/x/list"
|
||||
"github.com/sagernet/sing/service"
|
||||
"github.com/sagernet/sing/service/pause"
|
||||
"github.com/sagernet/wireguard-go/conn"
|
||||
"github.com/sagernet/wireguard-go/device"
|
||||
)
|
||||
|
||||
func RegisterOutbound(registry *outbound.Registry) {
|
||||
outbound.Register[option.WireGuardOutboundOptions](registry, C.TypeWireGuard, NewOutbound)
|
||||
outbound.Register[option.LegacyWireGuardOutboundOptions](registry, C.TypeWireGuard, NewOutbound)
|
||||
}
|
||||
|
||||
var _ adapter.InterfaceUpdateListener = (*Outbound)(nil)
|
||||
var (
|
||||
_ adapter.Endpoint = (*Endpoint)(nil)
|
||||
_ adapter.InterfaceUpdateListener = (*Endpoint)(nil)
|
||||
)
|
||||
|
||||
type Outbound struct {
|
||||
outbound.Adapter
|
||||
ctx context.Context
|
||||
router adapter.Router
|
||||
logger logger.ContextLogger
|
||||
workers int
|
||||
peers []wireguard.PeerConfig
|
||||
useStdNetBind bool
|
||||
listener N.Dialer
|
||||
ipcConf string
|
||||
|
||||
pauseManager pause.Manager
|
||||
pauseCallback *list.Element[pause.Callback]
|
||||
bind conn.Bind
|
||||
device *device.Device
|
||||
tunDevice wireguard.Device
|
||||
ctx context.Context
|
||||
router adapter.Router
|
||||
logger logger.ContextLogger
|
||||
localAddresses []netip.Prefix
|
||||
endpoint *wireguard.Endpoint
|
||||
}
|
||||
|
||||
func NewOutbound(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, options option.WireGuardOutboundOptions) (adapter.Outbound, error) {
|
||||
func NewOutbound(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, options option.LegacyWireGuardOutboundOptions) (adapter.Outbound, error) {
|
||||
deprecated.Report(ctx, deprecated.OptionWireGuardOutbound)
|
||||
outbound := &Outbound{
|
||||
Adapter: outbound.NewAdapterWithDialerOptions(C.TypeWireGuard, options.Network.Build(), tag, options.DialerOptions),
|
||||
ctx: ctx,
|
||||
router: router,
|
||||
logger: logger,
|
||||
workers: options.Workers,
|
||||
pauseManager: service.FromContext[pause.Manager](ctx),
|
||||
Adapter: outbound.NewAdapterWithDialerOptions(C.TypeWireGuard, tag, []string{N.NetworkTCP, N.NetworkUDP}, options.DialerOptions),
|
||||
ctx: ctx,
|
||||
router: router,
|
||||
logger: logger,
|
||||
localAddresses: options.LocalAddress,
|
||||
}
|
||||
peers, err := wireguard.ParsePeers(options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
outbound.peers = peers
|
||||
if len(options.LocalAddress) == 0 {
|
||||
return nil, E.New("missing local address")
|
||||
}
|
||||
if options.GSO {
|
||||
if options.GSO && options.Detour != "" {
|
||||
return nil, E.New("gso is conflict with detour")
|
||||
}
|
||||
if options.Detour == "" {
|
||||
options.IsWireGuardListener = true
|
||||
outbound.useStdNetBind = true
|
||||
} else if options.GSO {
|
||||
return nil, E.New("gso is conflict with detour")
|
||||
}
|
||||
listener, err := dialer.New(ctx, options.DialerOptions)
|
||||
outboundDialer, err := dialer.New(ctx, options.DialerOptions)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
outbound.listener = listener
|
||||
var privateKey string
|
||||
{
|
||||
bytes, err := base64.StdEncoding.DecodeString(options.PrivateKey)
|
||||
if err != nil {
|
||||
return nil, E.Cause(err, "decode private key")
|
||||
}
|
||||
privateKey = hex.EncodeToString(bytes)
|
||||
}
|
||||
outbound.ipcConf = "private_key=" + privateKey
|
||||
mtu := options.MTU
|
||||
if mtu == 0 {
|
||||
mtu = 1408
|
||||
}
|
||||
var wireTunDevice wireguard.Device
|
||||
if !options.SystemInterface && tun.WithGVisor {
|
||||
wireTunDevice, err = wireguard.NewStackDevice(options.LocalAddress, mtu)
|
||||
} else {
|
||||
wireTunDevice, err = wireguard.NewSystemDevice(service.FromContext[adapter.NetworkManager](ctx), options.InterfaceName, options.LocalAddress, mtu, options.GSO)
|
||||
}
|
||||
wgEndpoint, err := wireguard.NewEndpoint(wireguard.EndpointOptions{
|
||||
Context: ctx,
|
||||
Logger: logger,
|
||||
System: options.SystemInterface,
|
||||
Dialer: outboundDialer,
|
||||
CreateDialer: func(interfaceName string) N.Dialer {
|
||||
return common.Must1(dialer.NewDefault(service.FromContext[adapter.NetworkManager](ctx), option.DialerOptions{
|
||||
BindInterface: interfaceName,
|
||||
}))
|
||||
},
|
||||
Name: options.InterfaceName,
|
||||
MTU: options.MTU,
|
||||
GSO: options.GSO,
|
||||
Address: options.LocalAddress,
|
||||
PrivateKey: options.PrivateKey,
|
||||
ResolvePeer: func(domain string) (netip.Addr, error) {
|
||||
endpointAddresses, lookupErr := router.Lookup(ctx, domain, dns.DomainStrategy(options.DomainStrategy))
|
||||
if lookupErr != nil {
|
||||
return netip.Addr{}, lookupErr
|
||||
}
|
||||
return endpointAddresses[0], nil
|
||||
},
|
||||
Peers: common.Map(options.Peers, func(it option.LegacyWireGuardPeer) wireguard.PeerOptions {
|
||||
return wireguard.PeerOptions{
|
||||
Endpoint: it.ServerOptions.Build(),
|
||||
PublicKey: it.PublicKey,
|
||||
PreSharedKey: it.PreSharedKey,
|
||||
AllowedIPs: it.AllowedIPs,
|
||||
// PersistentKeepaliveInterval: time.Duration(it.PersistentKeepaliveInterval),
|
||||
Reserved: it.Reserved,
|
||||
}
|
||||
}),
|
||||
Workers: options.Workers,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, E.Cause(err, "create WireGuard device")
|
||||
return nil, err
|
||||
}
|
||||
outbound.tunDevice = wireTunDevice
|
||||
outbound.endpoint = wgEndpoint
|
||||
return outbound, nil
|
||||
}
|
||||
|
||||
func (w *Outbound) Start() error {
|
||||
if common.Any(w.peers, func(peer wireguard.PeerConfig) bool {
|
||||
return !peer.Endpoint.IsValid()
|
||||
}) {
|
||||
// wait for all outbounds to be started and continue in PortStart
|
||||
return nil
|
||||
}
|
||||
return w.start()
|
||||
}
|
||||
|
||||
func (w *Outbound) PostStart() error {
|
||||
if common.All(w.peers, func(peer wireguard.PeerConfig) bool {
|
||||
return peer.Endpoint.IsValid()
|
||||
}) {
|
||||
return nil
|
||||
}
|
||||
return w.start()
|
||||
}
|
||||
|
||||
func (w *Outbound) start() error {
|
||||
err := wireguard.ResolvePeers(w.ctx, w.router, w.peers)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
var bind conn.Bind
|
||||
if w.useStdNetBind {
|
||||
bind = conn.NewStdNetBind(w.listener.(dialer.WireGuardListener))
|
||||
} else {
|
||||
var (
|
||||
isConnect bool
|
||||
connectAddr netip.AddrPort
|
||||
reserved [3]uint8
|
||||
)
|
||||
peerLen := len(w.peers)
|
||||
if peerLen == 1 {
|
||||
isConnect = true
|
||||
connectAddr = w.peers[0].Endpoint
|
||||
reserved = w.peers[0].Reserved
|
||||
}
|
||||
bind = wireguard.NewClientBind(w.ctx, w.logger, w.listener, isConnect, connectAddr, reserved)
|
||||
}
|
||||
err = w.tunDevice.Start()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
wgDevice := device.NewDevice(w.tunDevice, bind, &device.Logger{
|
||||
Verbosef: func(format string, args ...interface{}) {
|
||||
w.logger.Debug(fmt.Sprintf(strings.ToLower(format), args...))
|
||||
},
|
||||
Errorf: func(format string, args ...interface{}) {
|
||||
w.logger.Error(fmt.Sprintf(strings.ToLower(format), args...))
|
||||
},
|
||||
}, w.workers)
|
||||
ipcConf := w.ipcConf
|
||||
for _, peer := range w.peers {
|
||||
ipcConf += peer.GenerateIpcLines()
|
||||
}
|
||||
err = wgDevice.IpcSet(ipcConf)
|
||||
if err != nil {
|
||||
return E.Cause(err, "setup wireguard: \n", ipcConf)
|
||||
}
|
||||
w.device = wgDevice
|
||||
w.pauseCallback = w.pauseManager.RegisterCallback(w.onPauseUpdated)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (w *Outbound) Close() error {
|
||||
if w.device != nil {
|
||||
w.device.Close()
|
||||
}
|
||||
if w.pauseCallback != nil {
|
||||
w.pauseManager.UnregisterCallback(w.pauseCallback)
|
||||
func (o *Outbound) Start(stage adapter.StartStage) error {
|
||||
switch stage {
|
||||
case adapter.StartStateStart:
|
||||
return o.endpoint.Start(false)
|
||||
case adapter.StartStatePostStart:
|
||||
return o.endpoint.Start(true)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (w *Outbound) InterfaceUpdated() {
|
||||
w.device.BindUpdate()
|
||||
func (o *Outbound) Close() error {
|
||||
return o.endpoint.Close()
|
||||
}
|
||||
|
||||
func (o *Outbound) InterfaceUpdated() {
|
||||
o.endpoint.BindUpdate()
|
||||
return
|
||||
}
|
||||
|
||||
func (w *Outbound) onPauseUpdated(event int) {
|
||||
switch event {
|
||||
case pause.EventDevicePaused:
|
||||
w.device.Down()
|
||||
case pause.EventDeviceWake:
|
||||
w.device.Up()
|
||||
}
|
||||
}
|
||||
|
||||
func (w *Outbound) DialContext(ctx context.Context, network string, destination M.Socksaddr) (net.Conn, error) {
|
||||
func (o *Outbound) DialContext(ctx context.Context, network string, destination M.Socksaddr) (net.Conn, error) {
|
||||
switch network {
|
||||
case N.NetworkTCP:
|
||||
w.logger.InfoContext(ctx, "outbound connection to ", destination)
|
||||
o.logger.InfoContext(ctx, "outbound connection to ", destination)
|
||||
case N.NetworkUDP:
|
||||
w.logger.InfoContext(ctx, "outbound packet connection to ", destination)
|
||||
o.logger.InfoContext(ctx, "outbound packet connection to ", destination)
|
||||
}
|
||||
if destination.IsFqdn() {
|
||||
destinationAddresses, err := w.router.LookupDefault(ctx, destination.Fqdn)
|
||||
destinationAddresses, err := o.router.LookupDefault(ctx, destination.Fqdn)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return N.DialSerial(ctx, w.tunDevice, network, destination, destinationAddresses)
|
||||
return N.DialSerial(ctx, o.endpoint, network, destination, destinationAddresses)
|
||||
} else if !destination.Addr.IsValid() {
|
||||
return nil, E.New("invalid destination: ", destination)
|
||||
}
|
||||
return w.tunDevice.DialContext(ctx, network, destination)
|
||||
return o.endpoint.DialContext(ctx, network, destination)
|
||||
}
|
||||
|
||||
func (w *Outbound) ListenPacket(ctx context.Context, destination M.Socksaddr) (net.PacketConn, error) {
|
||||
w.logger.InfoContext(ctx, "outbound packet connection to ", destination)
|
||||
func (o *Outbound) ListenPacket(ctx context.Context, destination M.Socksaddr) (net.PacketConn, error) {
|
||||
o.logger.InfoContext(ctx, "outbound packet connection to ", destination)
|
||||
if destination.IsFqdn() {
|
||||
destinationAddresses, err := w.router.LookupDefault(ctx, destination.Fqdn)
|
||||
destinationAddresses, err := o.router.LookupDefault(ctx, destination.Fqdn)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
packetConn, _, err := N.ListenSerial(ctx, w.tunDevice, destination, destinationAddresses)
|
||||
packetConn, _, err := N.ListenSerial(ctx, o.endpoint, destination, destinationAddresses)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return packetConn, err
|
||||
}
|
||||
return w.tunDevice.ListenPacket(ctx, destination)
|
||||
return o.endpoint.ListenPacket(ctx, destination)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user