mirror of
https://github.com/shtorm-7/sing-box-extended.git
synced 2026-07-29 18:16:47 +03:00
Compare commits
10 Commits
v1.13.14-e
...
v1.13.14-e
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c243a5b6e5 | ||
|
|
b4ec688f1a | ||
|
|
2e083b2d8f | ||
|
|
909f19640c | ||
|
|
a79e16c03c | ||
|
|
d2805ffcc9 | ||
|
|
7c19b660b4 | ||
|
|
33907d2e23 | ||
|
|
ea48501b1d | ||
|
|
425bfaf779 |
@@ -3,7 +3,7 @@
|
|||||||
[](LICENSE)
|
[](LICENSE)
|
||||||
[](go.mod)
|
[](go.mod)
|
||||||
[](https://codeberg.org/shtorm-7/sing-box-extended)
|
[](https://codeberg.org/shtorm-7/sing-box-extended)
|
||||||
[](https://t.me/sing_box_extended)
|
[](https://t.me/sing_box_extended)
|
||||||
|
|
||||||
Sing-box with extended features.
|
Sing-box with extended features.
|
||||||
|
|
||||||
|
|||||||
@@ -29,8 +29,8 @@ type Conn struct {
|
|||||||
|
|
||||||
func (c *Conn) Close() error {
|
func (c *Conn) Close() error {
|
||||||
c.group.access.Lock()
|
c.group.access.Lock()
|
||||||
defer c.group.access.Unlock()
|
|
||||||
c.group.connections.Remove(c.element)
|
c.group.connections.Remove(c.element)
|
||||||
|
c.group.access.Unlock()
|
||||||
return c.Conn.Close()
|
return c.Conn.Close()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -58,8 +58,8 @@ type PacketConn struct {
|
|||||||
|
|
||||||
func (c *PacketConn) Close() error {
|
func (c *PacketConn) Close() error {
|
||||||
c.group.access.Lock()
|
c.group.access.Lock()
|
||||||
defer c.group.access.Unlock()
|
|
||||||
c.group.connections.Remove(c.element)
|
c.group.connections.Remove(c.element)
|
||||||
|
c.group.access.Unlock()
|
||||||
return c.PacketConn.Close()
|
return c.PacketConn.Close()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -87,8 +87,8 @@ type SingPacketConn struct {
|
|||||||
|
|
||||||
func (c *SingPacketConn) Close() error {
|
func (c *SingPacketConn) Close() error {
|
||||||
c.group.access.Lock()
|
c.group.access.Lock()
|
||||||
defer c.group.access.Unlock()
|
|
||||||
c.group.connections.Remove(c.element)
|
c.group.connections.Remove(c.element)
|
||||||
|
c.group.access.Unlock()
|
||||||
return c.PacketConn.Close()
|
return c.PacketConn.Close()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -47,15 +47,19 @@ func (g *Group) NewSingPacketConn(conn N.PacketConn, isExternal bool, isProvider
|
|||||||
|
|
||||||
func (g *Group) Interrupt(interruptExternalConnections bool) {
|
func (g *Group) Interrupt(interruptExternalConnections bool) {
|
||||||
g.access.Lock()
|
g.access.Lock()
|
||||||
defer g.access.Unlock()
|
|
||||||
var toDelete []*list.Element[*groupConnItem]
|
var toDelete []*list.Element[*groupConnItem]
|
||||||
|
var toClose []io.Closer
|
||||||
for element := g.connections.Front(); element != nil; element = element.Next() {
|
for element := g.connections.Front(); element != nil; element = element.Next() {
|
||||||
if !element.Value.isExternal || interruptExternalConnections {
|
if !element.Value.isExternal || interruptExternalConnections {
|
||||||
element.Value.conn.Close()
|
|
||||||
toDelete = append(toDelete, element)
|
toDelete = append(toDelete, element)
|
||||||
|
toClose = append(toClose, element.Value.conn)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for _, element := range toDelete {
|
for _, element := range toDelete {
|
||||||
g.connections.Remove(element)
|
g.connections.Remove(element)
|
||||||
}
|
}
|
||||||
|
g.access.Unlock()
|
||||||
|
for _, conn := range toClose {
|
||||||
|
_ = conn.Close()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
66
common/interrupt/group_test.go
Normal file
66
common/interrupt/group_test.go
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
package interrupt
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net"
|
||||||
|
"sync"
|
||||||
|
"testing"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
type closeBarrierConn struct {
|
||||||
|
net.Conn
|
||||||
|
barrier *sync.WaitGroup
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *closeBarrierConn) Close() error {
|
||||||
|
c.barrier.Done()
|
||||||
|
c.barrier.Wait()
|
||||||
|
return c.Conn.Close()
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestNestedGroupsInterruptWithoutDeadlock(t *testing.T) {
|
||||||
|
groupA := NewGroup()
|
||||||
|
groupB := NewGroup()
|
||||||
|
barrier := &sync.WaitGroup{}
|
||||||
|
barrier.Add(2)
|
||||||
|
|
||||||
|
barrierA, barrierAPeer := net.Pipe()
|
||||||
|
barrierB, barrierBPeer := net.Pipe()
|
||||||
|
t.Cleanup(func() {
|
||||||
|
barrierAPeer.Close()
|
||||||
|
barrierBPeer.Close()
|
||||||
|
})
|
||||||
|
groupA.NewConn(&closeBarrierConn{Conn: barrierA, barrier: barrier}, true, false)
|
||||||
|
groupB.NewConn(&closeBarrierConn{Conn: barrierB, barrier: barrier}, true, false)
|
||||||
|
|
||||||
|
connA, connAPeer := net.Pipe()
|
||||||
|
connB, connBPeer := net.Pipe()
|
||||||
|
t.Cleanup(func() {
|
||||||
|
connAPeer.Close()
|
||||||
|
connBPeer.Close()
|
||||||
|
})
|
||||||
|
wrapperA := groupA.NewConn(connA, true, false)
|
||||||
|
wrapperB := groupB.NewConn(connB, true, false)
|
||||||
|
groupA.NewConn(wrapperB, true, false)
|
||||||
|
groupB.NewConn(wrapperA, true, false)
|
||||||
|
|
||||||
|
done := make(chan struct{}, 2)
|
||||||
|
go func() {
|
||||||
|
groupA.Interrupt(true)
|
||||||
|
done <- struct{}{}
|
||||||
|
}()
|
||||||
|
go func() {
|
||||||
|
groupB.Interrupt(true)
|
||||||
|
done <- struct{}{}
|
||||||
|
}()
|
||||||
|
|
||||||
|
timeout := time.NewTimer(time.Second)
|
||||||
|
defer timeout.Stop()
|
||||||
|
for range 2 {
|
||||||
|
select {
|
||||||
|
case <-done:
|
||||||
|
case <-timeout.C:
|
||||||
|
t.Fatal("nested group interrupt deadlocked")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -27,6 +27,7 @@
|
|||||||
"tag": "vless-out",
|
"tag": "vless-out",
|
||||||
// Supported protocols: hysteria, hysteria2, shadowsocks, trojan, tuic, vless, vmess
|
// Supported protocols: hysteria, hysteria2, shadowsocks, trojan, tuic, vless, vmess
|
||||||
"link": "vless://b5e41c8c-c437-4689-b863-76208a3efb4b@0.0.0.0:443?..."
|
"link": "vless://b5e41c8c-c437-4689-b863-76208a3efb4b@0.0.0.0:443?..."
|
||||||
|
// Dial Fields
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"route": {
|
"route": {
|
||||||
|
|||||||
2
go.mod
2
go.mod
@@ -231,7 +231,7 @@ replace github.com/sagernet/sing-mux => github.com/shtorm-7/sing-mux v0.3.4-exte
|
|||||||
|
|
||||||
replace github.com/ameshkov/dnscrypt/v2 => github.com/shtorm-7/dnscrypt/v2 v2.4.0-extended-1.0.0
|
replace github.com/ameshkov/dnscrypt/v2 => github.com/shtorm-7/dnscrypt/v2 v2.4.0-extended-1.0.0
|
||||||
|
|
||||||
replace github.com/sagernet/sing-vmess => github.com/shtorm-7/sing-vmess v0.2.7-extended-1.0.0
|
replace github.com/sagernet/sing-vmess => github.com/shtorm-7/sing-vmess v0.2.8-extended-1.0.0
|
||||||
|
|
||||||
replace github.com/dolonet/mtg-multi => github.com/shtorm-7/mtg-multi v1.11.0-extended-1.0.0
|
replace github.com/dolonet/mtg-multi => github.com/shtorm-7/mtg-multi v1.11.0-extended-1.0.0
|
||||||
|
|
||||||
|
|||||||
4
go.sum
4
go.sum
@@ -387,8 +387,8 @@ github.com/shtorm-7/sing v0.8.10-extended-1.2.0 h1:5yw9j0+P2QkRWvxBvb71wvNdpAlHm
|
|||||||
github.com/shtorm-7/sing v0.8.10-extended-1.2.0/go.mod h1:olXxWQNqRW/l2Q6JI3b2Qmz8iQnIFlOeeH8bx6JhgUA=
|
github.com/shtorm-7/sing v0.8.10-extended-1.2.0/go.mod h1:olXxWQNqRW/l2Q6JI3b2Qmz8iQnIFlOeeH8bx6JhgUA=
|
||||||
github.com/shtorm-7/sing-mux v0.3.4-extended-1.0.0 h1:a5OoXr3e2ACbM6vDIaaGL44IdHQ6wPjcSoU13vfC0Sw=
|
github.com/shtorm-7/sing-mux v0.3.4-extended-1.0.0 h1:a5OoXr3e2ACbM6vDIaaGL44IdHQ6wPjcSoU13vfC0Sw=
|
||||||
github.com/shtorm-7/sing-mux v0.3.4-extended-1.0.0/go.mod h1:QvlKMyNBNrQoyX4x+gq028uPbLM2XeRpWtDsWBJbFSk=
|
github.com/shtorm-7/sing-mux v0.3.4-extended-1.0.0/go.mod h1:QvlKMyNBNrQoyX4x+gq028uPbLM2XeRpWtDsWBJbFSk=
|
||||||
github.com/shtorm-7/sing-vmess v0.2.7-extended-1.0.0 h1:WVheKmQH5hSQbJU1ZTKthKSutkTLWSb2hp4JuQhJBow=
|
github.com/shtorm-7/sing-vmess v0.2.8-extended-1.0.0 h1:OjvqZOhYSi9eIJGYC0iPDPqvgo/asujvhAGkFzbZ5/Y=
|
||||||
github.com/shtorm-7/sing-vmess v0.2.7-extended-1.0.0/go.mod h1:5aYoOtYksAyS0NXDm0qKeTYW1yoE1bJVcv+XLcVoyJs=
|
github.com/shtorm-7/sing-vmess v0.2.8-extended-1.0.0/go.mod h1:P11scgTxMxVVQ8dlM27yNm3Cro40mD0+gHbnqrNGDuY=
|
||||||
github.com/shtorm-7/tailscale v1.92.4-sing-box-1.13-mod.7-extended-1.0.2 h1:hSMjh97OszszOd8HrzpaYUQH9dWRRBluJCbwQyz8ZOk=
|
github.com/shtorm-7/tailscale v1.92.4-sing-box-1.13-mod.7-extended-1.0.2 h1:hSMjh97OszszOd8HrzpaYUQH9dWRRBluJCbwQyz8ZOk=
|
||||||
github.com/shtorm-7/tailscale v1.92.4-sing-box-1.13-mod.7-extended-1.0.2/go.mod h1:TYIIqO5sZpWq873rLIeO2usszSMUpR3h6WdqVVs65ug=
|
github.com/shtorm-7/tailscale v1.92.4-sing-box-1.13-mod.7-extended-1.0.2/go.mod h1:TYIIqO5sZpWq873rLIeO2usszSMUpR3h6WdqVVs65ug=
|
||||||
github.com/shtorm-7/wireguard-go v0.0.2-beta.1-extended-1.4.3 h1:jtOA73D4F5qRV70//ahOt20KBnWvQimAFjtIiOtt0ps=
|
github.com/shtorm-7/wireguard-go v0.0.2-beta.1-extended-1.4.3 h1:jtOA73D4F5qRV70//ahOt20KBnWvQimAFjtIiOtt0ps=
|
||||||
|
|||||||
@@ -77,7 +77,16 @@ func ConnectTunnel(ctx context.Context, dialer N.Dialer, tlsConfig aTLS.Config,
|
|||||||
if !ok || quicEndpoint == nil {
|
if !ok || quicEndpoint == nil {
|
||||||
return nil, nil, nil, errors.New("missing HTTP/3 UDP endpoint")
|
return nil, nil, nil, errors.New("missing HTTP/3 UDP endpoint")
|
||||||
}
|
}
|
||||||
udpConn, err := dialer.ListenPacket(ctx, M.SocksaddrFromNetIP(quicEndpoint.AddrPort()))
|
endpointAddrPort := quicEndpoint.AddrPort()
|
||||||
|
udpConn, err := dialer.ListenPacket(
|
||||||
|
ctx,
|
||||||
|
M.SocksaddrFromNetIP(
|
||||||
|
netip.AddrPortFrom(
|
||||||
|
endpointAddrPort.Addr().Unmap(),
|
||||||
|
endpointAddrPort.Port(),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, nil, err
|
return nil, nil, nil, err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -348,6 +348,7 @@ func createHTTPClient(ctx context.Context, dest M.Socksaddr, dialer N.Dialer, op
|
|||||||
}
|
}
|
||||||
conn, dErr := qtls.DialEarly(ctx, bufio.NewUnbindPacketConn(udpConn), udpConn.RemoteAddr(), tlsConfig, cfg)
|
conn, dErr := qtls.DialEarly(ctx, bufio.NewUnbindPacketConn(udpConn), udpConn.RemoteAddr(), tlsConfig, cfg)
|
||||||
if dErr != nil {
|
if dErr != nil {
|
||||||
|
_ = udpConn.Close()
|
||||||
return nil, dErr
|
return nil, dErr
|
||||||
}
|
}
|
||||||
if congestionControlFactory != nil {
|
if congestionControlFactory != nil {
|
||||||
|
|||||||
Reference in New Issue
Block a user