Compare commits

..

74 Commits

Author SHA1 Message Date
renovate[bot]
d7a88a2ae3
[dependencies] Update golangci/golangci-lint-action action to v7 (#2808)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-04-06 22:05:45 +08:00
iikira
eb8170b4b7
Fix UDP DNS server crash
Signed-off-by: iikira <i2@mail.iikira.com>
2025-04-06 22:03:24 +08:00
世界
536ae39cc3
documentation: Bump version 2025-04-06 20:40:10 +08:00
ReleTor
579b92161b
Fix fetch ECH configs 2025-04-06 20:40:07 +08:00
世界
4a25eb422a
release: Update Go to 1.24.2 2025-04-06 20:40:07 +08:00
世界
75686656bf
Allow direct outbounds without domain_resolver 2025-04-06 20:40:06 +08:00
世界
aba73a2f58
Fix Tailscale dialer 2025-04-06 20:40:06 +08:00
dyhkwong
a63ba6e2a0
Fix DNS over QUIC stream close 2025-04-06 20:40:06 +08:00
anytls
2954a2653b
Update anytls
Co-authored-by: anytls <anytls>
2025-04-06 20:40:05 +08:00
Rambling2076
c903ed41ad
Fix missing with_tailscale in Dockerfile
Signed-off-by: Rambling2076 <Rambling2076@proton.me>
2025-04-06 20:40:05 +08:00
世界
8c9eff621f
Fail when default DNS server not found 2025-04-06 20:40:05 +08:00
世界
ca6d7226bb
Update gVisor to 20250319.0 2025-04-06 20:40:05 +08:00
世界
193363d13e
release: Do not build tailscale on iOS and tvOS 2025-04-06 20:40:04 +08:00
世界
345f3a5eb0
Explicitly reject detour to empty direct outbounds 2025-04-06 20:40:04 +08:00
世界
ec0a3644c0
Add netns support 2025-04-06 20:40:04 +08:00
世界
d4f887f363
Add wildcard name support for predefined records 2025-04-06 20:40:03 +08:00
世界
c237f0aa22
Remove map usage in options 2025-04-06 20:40:03 +08:00
世界
e92713989c
Fix unhandled DNS loop 2025-04-06 20:40:03 +08:00
世界
e78c98e8c3
Add wildcard-sni support for shadow-tls inbound 2025-04-06 20:40:02 +08:00
世界
9d4e6b8d4d
Fix Tailscale DNS 2025-04-06 20:40:02 +08:00
k9982874
eccf0e9392
Add ntp protocol sniffing 2025-04-06 20:40:02 +08:00
世界
4ef4431217
option: Fix marshal legacy DNS options 2025-04-06 20:40:02 +08:00
世界
573eaedce2
Make domain_resolver optional when only one DNS server is configured 2025-04-06 20:40:01 +08:00
世界
a206399047
Fix DNS lookup context pollution 2025-04-06 20:40:01 +08:00
世界
93f12a87f2
Fix http3 DNS server connecting to wrong address 2025-04-06 20:40:01 +08:00
Restia-Ashbell
ca27cf4e7a
documentation: Fix typo 2025-04-06 20:40:00 +08:00
anytls
fa13bb9d7c
Update sing-anytls
Co-authored-by: anytls <anytls>
2025-04-06 20:40:00 +08:00
k9982874
2d3e02c2a3
Fix hosts DNS server 2025-04-06 20:40:00 +08:00
世界
fb5000c6e7
Fix UDP DNS server crash 2025-04-06 20:40:00 +08:00
世界
14cd3506db
documentation: Fix missing ip_accept_any DNS rule option 2025-04-06 20:39:59 +08:00
世界
2948be1d3d
Fix anytls dialer usage 2025-04-06 20:39:59 +08:00
世界
4f1c62db4d
Move predefined DNS server to rule action 2025-04-06 20:39:59 +08:00
世界
ee5739a395
Fix domain resolver on direct outbound 2025-04-06 20:39:58 +08:00
Zephyruso
edd96dea15
Fix missing AnyTLS display name 2025-04-06 20:39:58 +08:00
anytls
042ffecaf4
Update sing-anytls
Co-authored-by: anytls <anytls>
2025-04-06 20:39:58 +08:00
Estel
9866cc065b
documentation: Fix typo
Signed-off-by: Estel <callmebedrockdigger@gmail.com>
2025-04-06 20:39:58 +08:00
TargetLocked
03de355135
Fix parsing legacy DNS options 2025-04-06 20:39:57 +08:00
世界
1a8645ca87
Fix DNS fallback 2025-04-06 20:39:57 +08:00
世界
8f76b733d6
documentation: Fix missing hosts DNS server 2025-04-06 20:39:57 +08:00
anytls
4dd206c756
Add MinIdleSession option to AnyTLS outbound
Co-authored-by: anytls <anytls>
2025-04-06 20:39:56 +08:00
ReleTor
64e3071441
documentation: Minor fixes 2025-04-06 20:39:56 +08:00
libtry486
121e5ed762
documentation: Fix typo
fix typo

Signed-off-by: libtry486 <89328481+libtry486@users.noreply.github.com>
2025-04-06 20:39:56 +08:00
Alireza Ahmadi
49a83266d8
Fix Outbound deadlock 2025-04-06 20:39:56 +08:00
世界
3c853bd1d6
documentation: Fix AnyTLS doc 2025-04-06 20:39:55 +08:00
anytls
0f94d53a01
Add AnyTLS protocol 2025-04-06 20:39:54 +08:00
世界
a6c98a3eb4
Migrate to stdlib ECH support 2025-04-06 20:39:54 +08:00
世界
085153438a
Add fallback local DNS server for iOS 2025-04-06 20:39:54 +08:00
世界
0fd71861cd
Get darwin local DNS server from libresolv 2025-04-06 20:39:53 +08:00
世界
2b5e4ad830
Improve resolve action 2025-04-06 20:39:53 +08:00
世界
f6bdda4f79
Fix toolchain version 2025-04-06 20:39:52 +08:00
世界
a99fbe9da6
Add back port hopping to hysteria 1 2025-04-06 20:39:52 +08:00
世界
bda3583fe9
Update dependencies 2025-04-06 20:39:51 +08:00
xchacha20-poly1305
59c1560616
Remove single quotes of raw Moziila certs 2025-04-06 20:39:51 +08:00
世界
03322ba9d0
Add Tailscale endpoint 2025-04-06 20:39:51 +08:00
世界
3346a3ea0e
Build legacy binaries with latest Go 2025-04-06 20:39:51 +08:00
世界
b810d48560
documentation: Remove outdated icons 2025-04-06 20:39:50 +08:00
世界
9bbe116f53
documentation: Certificate store 2025-04-06 20:39:50 +08:00
世界
eafd7a7709
documentation: TLS fragment 2025-04-06 20:39:50 +08:00
世界
8c495c4b4f
documentation: Outbound domain resolver 2025-04-06 20:39:50 +08:00
世界
d1cdece862
documentation: Refactor DNS 2025-04-06 20:39:49 +08:00
世界
a08aa0ea4e
Add certificate store 2025-04-06 20:39:49 +08:00
世界
ae65178b8f
Add TLS fragment support 2025-04-06 20:39:49 +08:00
世界
cdfef2bfd6
refactor: Outbound domain resolver 2025-04-06 20:39:49 +08:00
世界
fc7b188ec7
refactor: DNS 2025-04-06 20:39:48 +08:00
世界
4c4e61d0b5
Bump version 2025-04-06 20:38:54 +08:00
testing
38009eed8a
documentation: Fix typo
Signed-off-by: testing <58134720+testing765@users.noreply.github.com>
2025-04-06 20:38:54 +08:00
世界
e1689ce632
option: Fix listable 2025-04-06 20:22:01 +08:00
世界
ad632ad871
Fix no_drop not work 2025-04-06 20:07:19 +08:00
Mahdi
8cd8aecc5a
Fix conn copy 2025-04-06 20:07:19 +08:00
世界
9063e3a86e
Improve pause management 2025-04-06 19:21:47 +08:00
世界
d378904cf6
Fix uTP sniffer 2025-04-06 19:21:41 +08:00
世界
1a66fcf634
Improve sniffer 2025-04-06 16:41:32 +08:00
世界
f891b0babb
Fix hysteria2 close 2025-04-06 16:41:32 +08:00
xchacha20-poly1305
12554e9433
Fix multiple trackers 2025-04-06 16:41:32 +08:00
21 changed files with 110 additions and 93 deletions

View File

@ -30,7 +30,7 @@ jobs:
with:
go-version: ^1.24.2
- name: golangci-lint
uses: golangci/golangci-lint-action@v6
uses: golangci/golangci-lint-action@v7
with:
version: latest
args: --timeout=30m

View File

@ -24,7 +24,7 @@ type Router interface {
RuleSet(tag string) (RuleSet, bool)
NeedWIFIState() bool
Rules() []Rule
SetTracker(tracker ConnectionTracker)
AppendTracker(tracker ConnectionTracker)
ResetNetwork()
}

4
box.go
View File

@ -314,7 +314,7 @@ func New(options Options) (*Box, error) {
if err != nil {
return nil, E.Cause(err, "create clash-server")
}
router.SetTracker(clashServer)
router.AppendTracker(clashServer)
service.MustRegister[adapter.ClashServer](ctx, clashServer)
services = append(services, clashServer)
}
@ -324,7 +324,7 @@ func New(options Options) (*Box, error) {
return nil, E.Cause(err, "create v2ray-server")
}
if v2rayServer.StatsService() != nil {
router.SetTracker(v2rayServer.StatsService())
router.AppendTracker(v2rayServer.StatsService())
services = append(services, v2rayServer)
service.MustRegister[adapter.V2RayServer](ctx, v2rayServer)
}

View File

@ -68,7 +68,9 @@ func UTP(_ context.Context, metadata *adapter.InboundContext, packet []byte) err
if err != nil {
return err
}
if extension > 0x04 {
return os.ErrInvalid
}
var length byte
err = binary.Read(reader, binary.BigEndian, &length)
if err != nil {

View File

@ -71,3 +71,19 @@ func TestSniffUDPTracker(t *testing.T) {
require.Equal(t, C.ProtocolBitTorrent, metadata.Protocol)
}
}
func TestSniffNotUTP(t *testing.T) {
t.Parallel()
packets := []string{
"0102736470696e674958d580121500000000000079aaed6717a39c27b07c0c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
}
for _, pkt := range packets {
pkt, err := hex.DecodeString(pkt)
require.NoError(t, err)
var metadata adapter.InboundContext
err = sniff.UTP(context.TODO(), &metadata, pkt)
require.Error(t, err)
}
}

View File

@ -123,6 +123,7 @@ func (s *STDECHClientConfig) ClientHandshake(ctx context.Context, conn net.Conn)
if response.Rcode != mDNS.RcodeSuccess {
return nil, E.Cause(dns.RcodeError(response.Rcode), "fetch ECH config list")
}
match:
for _, rr := range response.Answer {
switch resource := rr.(type) {
case *mDNS.HTTPS:
@ -133,12 +134,15 @@ func (s *STDECHClientConfig) ClientHandshake(ctx context.Context, conn net.Conn)
return nil, E.Cause(err, "decode ECH config")
}
s.config.EncryptedClientHelloConfigList = echConfigList
break match
}
}
}
}
if len(s.config.EncryptedClientHelloConfigList) == 0 {
return nil, E.New("no ECH config found in DNS records")
}
}
tlsConn, err := s.Client(conn)
if err != nil {
return nil, err

View File

@ -11,7 +11,6 @@ const (
ProtocolSSH = "ssh"
ProtocolRDP = "rdp"
ProtocolNTP = "ntp"
ProtocolMTProto = "mtproto"
)
const (

View File

@ -212,8 +212,8 @@ type dnsConnection struct {
func (c *dnsConnection) Close(err error) {
c.closeOnce.Do(func() {
close(c.done)
c.err = err
close(c.done)
})
c.Conn.Close()
}

View File

@ -26,7 +26,7 @@ If enabled in the inbound, the protocol and domain name (if present) of by the c
| QUIC Client | Type |
|:------------------------:|:----------:|
| Chromium/Cronet | `chrimium` |
| Chromium/Cronet | `chromium` |
| Safari/Apple Network API | `safari` |
| Firefox / uquic firefox | `firefox` |
| quic-go / uquic chrome | `quic-go` |

View File

@ -39,7 +39,7 @@ type BoxService struct {
clashServer adapter.ClashServer
pauseManager pause.Manager
servicePauseFields
iOSPauseFields
}
func NewService(configContent string, platformInterface PlatformInterface) (*BoxService, error) {

View File

@ -1,31 +1,33 @@
package libbox
import (
"sync"
"time"
C "github.com/sagernet/sing-box/constant"
)
type servicePauseFields struct {
pauseAccess sync.Mutex
pauseTimer *time.Timer
type iOSPauseFields struct {
endPauseTimer *time.Timer
}
func (s *BoxService) Pause() {
s.pauseAccess.Lock()
defer s.pauseAccess.Unlock()
if s.pauseTimer != nil {
s.pauseTimer.Stop()
s.pauseManager.DevicePause()
if !C.IsIos {
s.instance.Router().ResetNetwork()
} else {
if s.endPauseTimer == nil {
s.endPauseTimer = time.AfterFunc(time.Minute, s.pauseManager.DeviceWake)
} else {
s.endPauseTimer.Reset(time.Minute)
}
}
s.pauseTimer = time.AfterFunc(3*time.Second, s.ResetNetwork)
}
func (s *BoxService) Wake() {
s.pauseAccess.Lock()
defer s.pauseAccess.Unlock()
if s.pauseTimer != nil {
s.pauseTimer.Stop()
if !C.IsIos {
s.pauseManager.DeviceWake()
s.instance.Router().ResetNetwork()
}
s.pauseTimer = time.AfterFunc(3*time.Minute, s.ResetNetwork)
}
func (s *BoxService) ResetNetwork() {

6
go.mod
View File

@ -9,7 +9,7 @@ require (
github.com/cretz/bine v0.2.0
github.com/go-chi/chi/v5 v5.2.1
github.com/go-chi/render v1.0.3
github.com/gofrs/uuid/v5 v5.3.1
github.com/gofrs/uuid/v5 v5.3.2
github.com/insomniacslk/dhcp v0.0.0-20250109001534-8abf58130905
github.com/libdns/alidns v1.0.3
github.com/libdns/cloudflare v0.1.1
@ -26,9 +26,9 @@ require (
github.com/sagernet/gvisor v0.0.0-20250325023245-7a9c0f5725fb
github.com/sagernet/quic-go v0.49.0-beta.1
github.com/sagernet/reality v0.0.0-20230406110435-ee17307e7691
github.com/sagernet/sing v0.6.6-0.20250403102645-159e489fc399
github.com/sagernet/sing v0.6.6-0.20250406122223-d47540857e58
github.com/sagernet/sing-mux v0.3.1
github.com/sagernet/sing-quic v0.4.1-beta.1
github.com/sagernet/sing-quic v0.4.1
github.com/sagernet/sing-shadowsocks v0.2.7
github.com/sagernet/sing-shadowsocks2 v0.2.0
github.com/sagernet/sing-shadowtls v0.2.1-0.20250316154757-6f9e732e5056

12
go.sum
View File

@ -66,8 +66,8 @@ github.com/gobwas/pool v0.2.1 h1:xfeeEhW7pwmX8nuLVlqbzVc7udMDrwetjEv+TZIz1og=
github.com/gobwas/pool v0.2.1/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw=
github.com/godbus/dbus/v5 v5.1.1-0.20230522191255-76236955d466 h1:sQspH8M4niEijh3PFscJRLDnkL547IeP7kpPe3uUhEg=
github.com/godbus/dbus/v5 v5.1.1-0.20230522191255-76236955d466/go.mod h1:ZiQxhyQ+bbbfxUKVvjfO498oPYvtYhZzycal3G/NHmU=
github.com/gofrs/uuid/v5 v5.3.1 h1:aPx49MwJbekCzOyhZDjJVb0hx3A0KLjlbLx6p2gY0p0=
github.com/gofrs/uuid/v5 v5.3.1/go.mod h1:CDOjlDMVAtN56jqyRUZh58JT31Tiw7/oQyEXZV+9bD8=
github.com/gofrs/uuid/v5 v5.3.2 h1:2jfO8j3XgSwlz/wHqemAEugfnTlikAYHhnqQ8Xh4fE0=
github.com/gofrs/uuid/v5 v5.3.2/go.mod h1:CDOjlDMVAtN56jqyRUZh58JT31Tiw7/oQyEXZV+9bD8=
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE=
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
@ -178,12 +178,12 @@ github.com/sagernet/quic-go v0.49.0-beta.1/go.mod h1:uesWD1Ihrldq1M3XtjuEvIUqi8W
github.com/sagernet/reality v0.0.0-20230406110435-ee17307e7691 h1:5Th31OC6yj8byLGkEnIYp6grlXfo1QYUfiYFGjewIdc=
github.com/sagernet/reality v0.0.0-20230406110435-ee17307e7691/go.mod h1:B8lp4WkQ1PwNnrVMM6KyuFR20pU8jYBD+A4EhJovEXU=
github.com/sagernet/sing v0.2.18/go.mod h1:OL6k2F0vHmEzXz2KW19qQzu172FDgSbUSODylighuVo=
github.com/sagernet/sing v0.6.6-0.20250403102645-159e489fc399 h1:jQ5sGyxICxdPqoakOEE6TbSTYOf/grmt31e/ad749O4=
github.com/sagernet/sing v0.6.6-0.20250403102645-159e489fc399/go.mod h1:ARkL0gM13/Iv5VCZmci/NuoOlePoIsW0m7BWfln/Hak=
github.com/sagernet/sing v0.6.6-0.20250406122223-d47540857e58 h1:hq0W1/K6/UOrv+tCm9YrZ/yDFZJlPVtLmBvayuwUxDM=
github.com/sagernet/sing v0.6.6-0.20250406122223-d47540857e58/go.mod h1:ARkL0gM13/Iv5VCZmci/NuoOlePoIsW0m7BWfln/Hak=
github.com/sagernet/sing-mux v0.3.1 h1:kvCc8HyGAskDHDQ0yQvoTi/7J4cZPB/VJMsAM3MmdQI=
github.com/sagernet/sing-mux v0.3.1/go.mod h1:Mkdz8LnDstthz0HWuA/5foncnDIdcNN5KZ6AdJX+x78=
github.com/sagernet/sing-quic v0.4.1-beta.1 h1:V2VfMckT3EQR3ZdfSzJgZZDsvfZZH42QAZpnOnHKa0s=
github.com/sagernet/sing-quic v0.4.1-beta.1/go.mod h1:c+CytOEyeN20KCTFIP8YQUkNDVFLSzjrEPqP7Hlnxys=
github.com/sagernet/sing-quic v0.4.1 h1:pxlMa4efZu/M07RgGagNNDDyl6ZUwpmNUjRTpgHOWK4=
github.com/sagernet/sing-quic v0.4.1/go.mod h1:tqPa0/Wqa19MkkSlKVZZX5sHxtiDR9BROcn4ufcbVdY=
github.com/sagernet/sing-shadowsocks v0.2.7 h1:zaopR1tbHEw5Nk6FAkM05wCslV6ahVegEZaKMv9ipx8=
github.com/sagernet/sing-shadowsocks v0.2.7/go.mod h1:0rIKJZBR65Qi0zwdKezt4s57y/Tl1ofkaq6NlkzVuyE=
github.com/sagernet/sing-shadowsocks2 v0.2.0 h1:wpZNs6wKnR7mh1wV9OHwOyUr21VkS3wKFHi+8XwgADg=

View File

@ -19,6 +19,7 @@ import (
E "github.com/sagernet/sing/common/exceptions"
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"
)
@ -27,10 +28,7 @@ func RegisterURLTest(registry *outbound.Registry) {
outbound.Register[option.URLTestOutboundOptions](registry, C.TypeURLTest, NewURLTest)
}
var (
_ adapter.OutboundGroup = (*URLTest)(nil)
_ adapter.InterfaceUpdateListener = (*URLTest)(nil)
)
var _ adapter.OutboundGroup = (*URLTest)(nil)
type URLTest struct {
outbound.Adapter
@ -172,15 +170,12 @@ func (s *URLTest) NewPacketConnectionEx(ctx context.Context, conn N.PacketConn,
s.connection.NewPacketConnection(ctx, s, conn, metadata, onClose)
}
func (s *URLTest) InterfaceUpdated() {
go s.group.CheckOutbounds(true)
return
}
type URLTestGroup struct {
ctx context.Context
router adapter.Router
outboundManager adapter.OutboundManager
outbound adapter.OutboundManager
pause pause.Manager
pauseCallback *list.Element[pause.Callback]
logger log.Logger
outbounds []adapter.Outbound
link string
@ -189,12 +184,10 @@ type URLTestGroup struct {
idleTimeout time.Duration
history adapter.URLTestHistoryStorage
checking atomic.Bool
pauseManager pause.Manager
selectedOutboundTCP adapter.Outbound
selectedOutboundUDP adapter.Outbound
interruptGroup *interrupt.Group
interruptExternalConnections bool
access sync.Mutex
ticker *time.Ticker
close chan struct{}
@ -225,7 +218,7 @@ func NewURLTestGroup(ctx context.Context, outboundManager adapter.OutboundManage
}
return &URLTestGroup{
ctx: ctx,
outboundManager: outboundManager,
outbound: outboundManager,
logger: logger,
outbounds: outbounds,
link: link,
@ -234,13 +227,15 @@ func NewURLTestGroup(ctx context.Context, outboundManager adapter.OutboundManage
idleTimeout: idleTimeout,
history: history,
close: make(chan struct{}),
pauseManager: service.FromContext[pause.Manager](ctx),
pause: service.FromContext[pause.Manager](ctx),
interruptGroup: interrupt.NewGroup(),
interruptExternalConnections: interruptExternalConnections,
}, nil
}
func (g *URLTestGroup) PostStart() {
g.access.Lock()
defer g.access.Unlock()
g.started = true
g.lastActive.Store(time.Now())
go g.CheckOutbounds(false)
@ -250,24 +245,25 @@ func (g *URLTestGroup) Touch() {
if !g.started {
return
}
g.access.Lock()
defer g.access.Unlock()
if g.ticker != nil {
g.lastActive.Store(time.Now())
return
}
g.access.Lock()
defer g.access.Unlock()
if g.ticker != nil {
return
}
g.ticker = time.NewTicker(g.interval)
go g.loopCheck()
g.pauseCallback = pause.RegisterTicker(g.pause, g.ticker, g.interval, nil)
}
func (g *URLTestGroup) Close() error {
g.access.Lock()
defer g.access.Unlock()
if g.ticker == nil {
return nil
}
g.ticker.Stop()
g.pause.UnregisterCallback(g.pauseCallback)
close(g.close)
return nil
}
@ -331,10 +327,11 @@ func (g *URLTestGroup) loopCheck() {
g.access.Lock()
g.ticker.Stop()
g.ticker = nil
g.pause.UnregisterCallback(g.pauseCallback)
g.pauseCallback = nil
g.access.Unlock()
return
}
g.pauseManager.WaitActive()
g.CheckOutbounds(false)
}
}
@ -367,7 +364,7 @@ func (g *URLTestGroup) urlTest(ctx context.Context, force bool) (map[string]uint
continue
}
checked[realTag] = true
p, loaded := g.outboundManager.Outbound(realTag)
p, loaded := g.outbound.Outbound(realTag)
if !loaded {
continue
}

View File

@ -129,7 +129,6 @@ func (w *Endpoint) Close() error {
func (w *Endpoint) InterfaceUpdated() {
w.endpoint.BindUpdate()
return
}
func (w *Endpoint) PrepareConnection(network string, source M.Socksaddr, destination M.Socksaddr) error {

View File

@ -133,7 +133,6 @@ func (o *Outbound) Close() error {
func (o *Outbound) InterfaceUpdated() {
o.endpoint.BindUpdate()
return
}
func (o *Outbound) DialContext(ctx context.Context, network string, destination M.Socksaddr) (net.Conn, error) {

View File

@ -59,10 +59,6 @@ func (r *Router) RouteConnectionEx(ctx context.Context, conn net.Conn, metadata
}
func (r *Router) routeConnection(ctx context.Context, conn net.Conn, metadata adapter.InboundContext, onClose N.CloseHandlerFunc) error {
if r.pauseManager.IsDevicePaused() {
return E.New("reject connection to ", metadata.Destination, " while device paused")
}
//nolint:staticcheck
if metadata.InboundDetour != "" {
if metadata.LastInbound == metadata.InboundDetour {
@ -139,8 +135,8 @@ func (r *Router) routeConnection(ctx context.Context, conn net.Conn, metadata ad
for _, buffer := range buffers {
conn = bufio.NewCachedConn(conn, buffer)
}
if r.tracker != nil {
conn = r.tracker.RoutedConnection(ctx, conn, metadata, selectedRule, selectedOutbound)
for _, tracker := range r.trackers {
conn = tracker.RoutedConnection(ctx, conn, metadata, selectedRule, selectedOutbound)
}
if outboundHandler, isHandler := selectedOutbound.(adapter.ConnectionHandlerEx); isHandler {
outboundHandler.NewConnectionEx(ctx, conn, metadata, onClose)
@ -185,9 +181,6 @@ func (r *Router) RoutePacketConnectionEx(ctx context.Context, conn N.PacketConn,
}
func (r *Router) routePacketConnection(ctx context.Context, conn N.PacketConn, metadata adapter.InboundContext, onClose N.CloseHandlerFunc) error {
if r.pauseManager.IsDevicePaused() {
return E.New("reject packet connection to ", metadata.Destination, " while device paused")
}
//nolint:staticcheck
if metadata.InboundDetour != "" {
if metadata.LastInbound == metadata.InboundDetour {
@ -257,8 +250,8 @@ func (r *Router) routePacketConnection(ctx context.Context, conn N.PacketConn, m
conn = bufio.NewCachedPacketConn(conn, buffer.Buffer, buffer.Destination)
N.PutPacketBuffer(buffer)
}
if r.tracker != nil {
conn = r.tracker.RoutedPacketConnection(ctx, conn, metadata, selectedRule, selectedOutbound)
for _, tracker := range r.trackers {
conn = tracker.RoutedPacketConnection(ctx, conn, metadata, selectedRule, selectedOutbound)
}
if metadata.FakeIP {
conn = bufio.NewNATPacketConn(bufio.NewNetPacketConn(conn), metadata.OriginDestination, metadata.Destination)

View File

@ -36,7 +36,7 @@ type Router struct {
ruleSetMap map[string]adapter.RuleSet
processSearcher process.Searcher
pauseManager pause.Manager
tracker adapter.ConnectionTracker
trackers []adapter.ConnectionTracker
platformInterface platform.Interface
needWIFIState bool
started bool
@ -203,8 +203,8 @@ func (r *Router) Rules() []adapter.Rule {
return r.rules
}
func (r *Router) SetTracker(tracker adapter.ConnectionTracker) {
r.tracker = tracker
func (r *Router) AppendTracker(tracker adapter.ConnectionTracker) {
r.trackers = append(r.trackers, tracker)
}
func (r *Router) ResetNetwork() {

View File

@ -305,6 +305,9 @@ func (r *RuleActionReject) Error(ctx context.Context) error {
default:
panic(F.ToString("unknown reject method: ", r.Method))
}
if r.NoDrop {
return returnErr
}
r.dropAccess.Lock()
defer r.dropAccess.Unlock()
timeNow := time.Now()

View File

@ -105,7 +105,7 @@ func (s *RemoteRuleSet) StartContext(ctx context.Context, startContext *adapter.
}
}
if s.lastUpdated.IsZero() {
err := s.fetchOnce(ctx, startContext)
err := s.fetch(ctx, startContext)
if err != nil {
return E.Cause(err, "initial rule-set: ", s.options.Tag)
}
@ -200,7 +200,7 @@ func (s *RemoteRuleSet) loadBytes(content []byte) error {
func (s *RemoteRuleSet) loopUpdate() {
if time.Since(s.lastUpdated) > s.updateInterval {
err := s.fetchOnce(s.ctx, nil)
err := s.fetch(s.ctx, nil)
if err != nil {
s.logger.Error("fetch rule-set ", s.options.Tag, ": ", err)
} else if s.refs.Load() == 0 {
@ -213,18 +213,21 @@ func (s *RemoteRuleSet) loopUpdate() {
case <-s.ctx.Done():
return
case <-s.updateTicker.C:
s.pauseManager.WaitActive()
err := s.fetchOnce(s.ctx, nil)
s.updateOnce()
}
}
}
func (s *RemoteRuleSet) updateOnce() {
err := s.fetch(s.ctx, nil)
if err != nil {
s.logger.Error("fetch rule-set ", s.options.Tag, ": ", err)
} else if s.refs.Load() == 0 {
s.rules = nil
}
}
}
}
func (s *RemoteRuleSet) fetchOnce(ctx context.Context, startContext *adapter.HTTPStartContext) error {
func (s *RemoteRuleSet) fetch(ctx context.Context, startContext *adapter.HTTPStartContext) error {
s.logger.Debug("updating rule-set ", s.options.Tag, " from URL: ", s.options.RemoteOptions.URL)
var httpClient *http.Client
if startContext != nil {

View File

@ -30,7 +30,7 @@ type Endpoint struct {
allowedAddress []netip.Prefix
tunDevice Device
device *device.Device
pauseManager pause.Manager
pause pause.Manager
pauseCallback *list.Element[pause.Callback]
}
@ -187,9 +187,9 @@ func (e *Endpoint) Start(resolve bool) error {
return E.Cause(err, "setup wireguard: \n", ipcConf)
}
e.device = wgDevice
e.pauseManager = service.FromContext[pause.Manager](e.options.Context)
if e.pauseManager != nil {
e.pauseCallback = e.pauseManager.RegisterCallback(e.onPauseUpdated)
e.pause = service.FromContext[pause.Manager](e.options.Context)
if e.pause != nil {
e.pauseCallback = e.pause.RegisterCallback(e.onPauseUpdated)
}
return nil
}
@ -217,16 +217,16 @@ func (e *Endpoint) Close() error {
e.device.Close()
}
if e.pauseCallback != nil {
e.pauseManager.UnregisterCallback(e.pauseCallback)
e.pause.UnregisterCallback(e.pauseCallback)
}
return nil
}
func (e *Endpoint) onPauseUpdated(event int) {
switch event {
case pause.EventDevicePaused:
case pause.EventDevicePaused, pause.EventNetworkPause:
e.device.Down()
case pause.EventDeviceWake:
case pause.EventDeviceWake, pause.EventNetworkWake:
e.device.Up()
}
}