2024-01-04 17:28:16 +08:00
|
|
|
/*
|
|
|
|
* SPDX-License-Identifier: AGPL-3.0-only
|
|
|
|
* Copyright (c) 2022-2024, daeuniverse Organization <dae@v2raya.org>
|
|
|
|
*/
|
|
|
|
|
2023-01-23 19:54:21 +08:00
|
|
|
package dialer
|
|
|
|
|
|
|
|
import (
|
2023-02-09 19:22:37 +08:00
|
|
|
"context"
|
2023-01-23 19:54:21 +08:00
|
|
|
"fmt"
|
|
|
|
"sync"
|
|
|
|
"time"
|
2024-09-08 22:13:06 +08:00
|
|
|
"unsafe"
|
2023-04-23 13:27:29 +08:00
|
|
|
|
2024-09-08 22:13:06 +08:00
|
|
|
"github.com/daeuniverse/dae/common"
|
|
|
|
"github.com/daeuniverse/dae/config"
|
2024-01-01 17:19:18 +08:00
|
|
|
D "github.com/daeuniverse/outbound/dialer"
|
2024-04-24 02:22:50 +08:00
|
|
|
"github.com/daeuniverse/outbound/netproxy"
|
2023-04-23 13:27:29 +08:00
|
|
|
"github.com/sirupsen/logrus"
|
2023-01-23 19:54:21 +08:00
|
|
|
)
|
|
|
|
|
|
|
|
var (
|
2023-02-08 20:15:24 +08:00
|
|
|
UnexpectedFieldErr = fmt.Errorf("unexpected field")
|
|
|
|
InvalidParameterErr = fmt.Errorf("invalid parameters")
|
2023-01-23 19:54:21 +08:00
|
|
|
)
|
|
|
|
|
|
|
|
type Dialer struct {
|
2023-01-28 01:50:21 +08:00
|
|
|
*GlobalOption
|
2023-07-23 20:36:57 +08:00
|
|
|
InstanceOption
|
2023-02-18 00:49:35 +08:00
|
|
|
netproxy.Dialer
|
2023-07-23 20:36:57 +08:00
|
|
|
property *Property
|
2023-02-08 20:15:24 +08:00
|
|
|
|
2023-02-08 21:28:08 +08:00
|
|
|
collectionFineMu sync.Mutex
|
2023-02-12 15:39:00 +08:00
|
|
|
collections [6]*collection
|
2023-01-23 19:54:21 +08:00
|
|
|
|
|
|
|
tickerMu sync.Mutex
|
|
|
|
ticker *time.Ticker
|
2023-02-09 19:22:37 +08:00
|
|
|
checkCh chan time.Time
|
|
|
|
ctx context.Context
|
|
|
|
cancel context.CancelFunc
|
2024-01-11 21:47:05 +08:00
|
|
|
|
|
|
|
checkActivated bool
|
2023-01-23 19:54:21 +08:00
|
|
|
}
|
|
|
|
|
2023-01-28 01:50:21 +08:00
|
|
|
type GlobalOption struct {
|
2024-01-01 17:19:18 +08:00
|
|
|
D.ExtraOption
|
2023-02-09 19:22:37 +08:00
|
|
|
Log *logrus.Logger
|
|
|
|
TcpCheckOptionRaw TcpCheckOptionRaw // Lazy parse
|
2023-02-12 15:39:00 +08:00
|
|
|
CheckDnsOptionRaw CheckDnsOptionRaw // Lazy parse
|
2023-02-09 19:22:37 +08:00
|
|
|
CheckInterval time.Duration
|
2023-02-09 21:16:51 +08:00
|
|
|
CheckTolerance time.Duration
|
2023-02-12 15:39:00 +08:00
|
|
|
CheckDnsTcp bool
|
2023-01-28 01:50:21 +08:00
|
|
|
}
|
|
|
|
|
2023-01-28 15:47:43 +08:00
|
|
|
type InstanceOption struct {
|
2024-01-11 21:47:05 +08:00
|
|
|
DisableCheck bool
|
2023-01-23 19:54:21 +08:00
|
|
|
}
|
|
|
|
|
2023-02-28 21:25:15 +08:00
|
|
|
type Property struct {
|
2024-01-01 17:19:18 +08:00
|
|
|
D.Property
|
2023-09-03 21:17:58 +08:00
|
|
|
SubscriptionTag string
|
2023-02-28 21:25:15 +08:00
|
|
|
}
|
|
|
|
|
2023-02-08 20:15:24 +08:00
|
|
|
type AliveDialerSetSet map[*AliveDialerSet]int
|
|
|
|
|
2024-09-08 22:13:06 +08:00
|
|
|
func NewGlobalOption(global *config.Global, log *logrus.Logger) *GlobalOption {
|
|
|
|
return &GlobalOption{
|
|
|
|
ExtraOption: D.ExtraOption{
|
|
|
|
AllowInsecure: global.AllowInsecure,
|
|
|
|
TlsImplementation: global.TlsImplementation,
|
|
|
|
UtlsImitate: global.UtlsImitate},
|
|
|
|
Log: log,
|
|
|
|
TcpCheckOptionRaw: TcpCheckOptionRaw{Raw: global.TcpCheckUrl, Log: log, ResolverNetwork: common.MagicNetwork("udp", global.SoMarkFromDae, global.Mptcp), Method: global.TcpCheckHttpMethod},
|
|
|
|
CheckDnsOptionRaw: CheckDnsOptionRaw{Raw: global.UdpCheckDns, ResolverNetwork: common.MagicNetwork("udp", global.SoMarkFromDae, global.Mptcp), Somark: global.SoMarkFromDae},
|
|
|
|
CheckInterval: global.CheckInterval,
|
|
|
|
CheckTolerance: global.CheckTolerance,
|
|
|
|
CheckDnsTcp: true,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-01-28 15:47:43 +08:00
|
|
|
// NewDialer is for register in general.
|
2023-07-23 20:36:57 +08:00
|
|
|
func NewDialer(dialer netproxy.Dialer, option *GlobalOption, iOption InstanceOption, property *Property) *Dialer {
|
2023-02-12 15:39:00 +08:00
|
|
|
var collections [6]*collection
|
2023-02-08 21:28:08 +08:00
|
|
|
for i := range collections {
|
|
|
|
collections[i] = newCollection()
|
|
|
|
}
|
2023-02-09 19:22:37 +08:00
|
|
|
ctx, cancel := context.WithCancel(context.Background())
|
2023-01-23 19:54:21 +08:00
|
|
|
d := &Dialer{
|
2023-02-09 19:22:37 +08:00
|
|
|
GlobalOption: option,
|
2023-07-10 19:44:56 +08:00
|
|
|
InstanceOption: iOption,
|
2023-02-09 19:22:37 +08:00
|
|
|
Dialer: dialer,
|
2023-02-28 21:25:15 +08:00
|
|
|
property: property,
|
2023-02-09 19:22:37 +08:00
|
|
|
collectionFineMu: sync.Mutex{},
|
|
|
|
collections: collections,
|
|
|
|
tickerMu: sync.Mutex{},
|
|
|
|
ticker: nil,
|
|
|
|
checkCh: make(chan time.Time, 1),
|
|
|
|
ctx: ctx,
|
|
|
|
cancel: cancel,
|
2023-01-23 19:54:21 +08:00
|
|
|
}
|
2024-09-08 22:13:06 +08:00
|
|
|
option.Log.WithField("dialer", d.Property().Name).
|
|
|
|
WithField("p", unsafe.Pointer(d)).
|
|
|
|
Traceln("NewDialer")
|
2023-01-23 19:54:21 +08:00
|
|
|
return d
|
|
|
|
}
|
|
|
|
|
2024-09-08 22:13:06 +08:00
|
|
|
func (d *Dialer) Clone() *Dialer {
|
|
|
|
return NewDialer(d.Dialer, d.GlobalOption, d.InstanceOption, d.property)
|
|
|
|
}
|
|
|
|
|
2023-01-23 19:54:21 +08:00
|
|
|
func (d *Dialer) Close() error {
|
2023-02-09 19:22:37 +08:00
|
|
|
d.cancel()
|
2023-01-23 19:54:21 +08:00
|
|
|
d.tickerMu.Lock()
|
2023-02-09 19:22:37 +08:00
|
|
|
if d.ticker != nil {
|
|
|
|
d.ticker.Stop()
|
|
|
|
}
|
2023-01-23 19:54:21 +08:00
|
|
|
d.tickerMu.Unlock()
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2023-07-23 20:36:57 +08:00
|
|
|
func (d *Dialer) Property() *Property {
|
2023-02-28 21:25:15 +08:00
|
|
|
return d.property
|
2023-01-23 19:54:21 +08:00
|
|
|
}
|