mirror of
https://github.com/SagerNet/sing-box.git
synced 2024-11-22 08:31:30 +00:00
Fix leaks and add test
This commit is contained in:
parent
9856b73cb5
commit
407509c985
|
@ -14,6 +14,7 @@ import (
|
||||||
M "github.com/sagernet/sing/common/metadata"
|
M "github.com/sagernet/sing/common/metadata"
|
||||||
N "github.com/sagernet/sing/common/network"
|
N "github.com/sagernet/sing/common/network"
|
||||||
"github.com/sagernet/sing/common/rw"
|
"github.com/sagernet/sing/common/rw"
|
||||||
|
"github.com/sagernet/sing/common/task"
|
||||||
)
|
)
|
||||||
|
|
||||||
func NewConnection(ctx context.Context, router adapter.Router, errorHandler E.Handler, logger log.ContextLogger, conn net.Conn, metadata adapter.InboundContext) error {
|
func NewConnection(ctx context.Context, router adapter.Router, errorHandler E.Handler, logger log.ContextLogger, conn net.Conn, metadata adapter.InboundContext) error {
|
||||||
|
@ -25,6 +26,8 @@ func NewConnection(ctx context.Context, router adapter.Router, errorHandler E.Ha
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
var group task.Group
|
||||||
|
group.Append0(func(ctx context.Context) error {
|
||||||
var stream net.Conn
|
var stream net.Conn
|
||||||
for {
|
for {
|
||||||
stream, err = session.Accept()
|
stream, err = session.Accept()
|
||||||
|
@ -33,6 +36,11 @@ func NewConnection(ctx context.Context, router adapter.Router, errorHandler E.Ha
|
||||||
}
|
}
|
||||||
go newConnection(ctx, router, errorHandler, logger, stream, metadata)
|
go newConnection(ctx, router, errorHandler, logger, stream, metadata)
|
||||||
}
|
}
|
||||||
|
})
|
||||||
|
group.Cleanup(func() {
|
||||||
|
session.Close()
|
||||||
|
})
|
||||||
|
return group.Run(ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
func newConnection(ctx context.Context, router adapter.Router, errorHandler E.Handler, logger log.ContextLogger, stream net.Conn, metadata adapter.InboundContext) {
|
func newConnection(ctx context.Context, router adapter.Router, errorHandler E.Handler, logger log.ContextLogger, stream net.Conn, metadata adapter.InboundContext) {
|
||||||
|
|
2
go.mod
2
go.mod
|
@ -27,7 +27,7 @@ require (
|
||||||
github.com/sagernet/sing-dns v0.0.0-20220915084601-812e0864b45b
|
github.com/sagernet/sing-dns v0.0.0-20220915084601-812e0864b45b
|
||||||
github.com/sagernet/sing-shadowsocks v0.0.0-20220819002358-7461bb09a8f6
|
github.com/sagernet/sing-shadowsocks v0.0.0-20220819002358-7461bb09a8f6
|
||||||
github.com/sagernet/sing-tun v0.0.0-20220922083325-80ee99472704
|
github.com/sagernet/sing-tun v0.0.0-20220922083325-80ee99472704
|
||||||
github.com/sagernet/sing-vmess v0.0.0-20220921140858-b6a1bdee672f
|
github.com/sagernet/sing-vmess v0.0.0-20220923035311-d70afe4ab2c9
|
||||||
github.com/sagernet/smux v0.0.0-20220831015742-e0f1988e3195
|
github.com/sagernet/smux v0.0.0-20220831015742-e0f1988e3195
|
||||||
github.com/sagernet/websocket v0.0.0-20220913015213-615516348b4e
|
github.com/sagernet/websocket v0.0.0-20220913015213-615516348b4e
|
||||||
github.com/spf13/cobra v1.5.0
|
github.com/spf13/cobra v1.5.0
|
||||||
|
|
4
go.sum
4
go.sum
|
@ -153,8 +153,8 @@ github.com/sagernet/sing-shadowsocks v0.0.0-20220819002358-7461bb09a8f6 h1:JJfDe
|
||||||
github.com/sagernet/sing-shadowsocks v0.0.0-20220819002358-7461bb09a8f6/go.mod h1:EX3RbZvrwAkPI2nuGa78T2iQXmrkT+/VQtskjou42xM=
|
github.com/sagernet/sing-shadowsocks v0.0.0-20220819002358-7461bb09a8f6/go.mod h1:EX3RbZvrwAkPI2nuGa78T2iQXmrkT+/VQtskjou42xM=
|
||||||
github.com/sagernet/sing-tun v0.0.0-20220922083325-80ee99472704 h1:DOQQXQbB2gq4n2FuMHrL07HRs2naCCsuiu/9l1JFb9A=
|
github.com/sagernet/sing-tun v0.0.0-20220922083325-80ee99472704 h1:DOQQXQbB2gq4n2FuMHrL07HRs2naCCsuiu/9l1JFb9A=
|
||||||
github.com/sagernet/sing-tun v0.0.0-20220922083325-80ee99472704/go.mod h1:5AhPUv9jWDQ3pv3Mj78SL/1TSjhoaj6WNASxRKLqXqM=
|
github.com/sagernet/sing-tun v0.0.0-20220922083325-80ee99472704/go.mod h1:5AhPUv9jWDQ3pv3Mj78SL/1TSjhoaj6WNASxRKLqXqM=
|
||||||
github.com/sagernet/sing-vmess v0.0.0-20220921140858-b6a1bdee672f h1:xyJ3Wbibcug4DxLi/FCHX2Td667SfieyZv645b8+eEE=
|
github.com/sagernet/sing-vmess v0.0.0-20220923035311-d70afe4ab2c9 h1:w7JlEa4xHXuuPTL3Opb+Z5f/l66SYi54rSfobzuxSF8=
|
||||||
github.com/sagernet/sing-vmess v0.0.0-20220921140858-b6a1bdee672f/go.mod h1:bwhAdSNET1X+j9DOXGj9NIQR39xgcWIk1rOQ9lLD+gM=
|
github.com/sagernet/sing-vmess v0.0.0-20220923035311-d70afe4ab2c9/go.mod h1:bwhAdSNET1X+j9DOXGj9NIQR39xgcWIk1rOQ9lLD+gM=
|
||||||
github.com/sagernet/smux v0.0.0-20220831015742-e0f1988e3195 h1:5VBIbVw9q7aKbrFdT83mjkyvQ+VaRsQ6yflTepfln38=
|
github.com/sagernet/smux v0.0.0-20220831015742-e0f1988e3195 h1:5VBIbVw9q7aKbrFdT83mjkyvQ+VaRsQ6yflTepfln38=
|
||||||
github.com/sagernet/smux v0.0.0-20220831015742-e0f1988e3195/go.mod h1:yedWtra8nyGJ+SyI+ziwuaGMzBatbB10P1IOOZbbSK8=
|
github.com/sagernet/smux v0.0.0-20220831015742-e0f1988e3195/go.mod h1:yedWtra8nyGJ+SyI+ziwuaGMzBatbB10P1IOOZbbSK8=
|
||||||
github.com/sagernet/websocket v0.0.0-20220913015213-615516348b4e h1:7uw2njHFGE+VpWamge6o56j2RWk4omF6uLKKxMmcWvs=
|
github.com/sagernet/websocket v0.0.0-20220913015213-615516348b4e h1:7uw2njHFGE+VpWamge6o56j2RWk4omF6uLKKxMmcWvs=
|
||||||
|
|
|
@ -38,6 +38,7 @@ type Hysteria struct {
|
||||||
recvBPS uint64
|
recvBPS uint64
|
||||||
connAccess sync.Mutex
|
connAccess sync.Mutex
|
||||||
conn quic.Connection
|
conn quic.Connection
|
||||||
|
rawConn net.Conn
|
||||||
udpAccess sync.RWMutex
|
udpAccess sync.RWMutex
|
||||||
udpSessions map[uint32]chan *hysteria.UDPMessage
|
udpSessions map[uint32]chan *hysteria.UDPMessage
|
||||||
udpDefragger hysteria.Defragger
|
udpDefragger hysteria.Defragger
|
||||||
|
@ -149,7 +150,6 @@ func (h *Hysteria) offer(ctx context.Context) (quic.Connection, error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
h.conn = conn
|
|
||||||
if common.Contains(h.network, N.NetworkUDP) {
|
if common.Contains(h.network, N.NetworkUDP) {
|
||||||
for _, session := range h.udpSessions {
|
for _, session := range h.udpSessions {
|
||||||
close(session)
|
close(session)
|
||||||
|
@ -201,6 +201,8 @@ func (h *Hysteria) offerNew(ctx context.Context) (quic.Connection, error) {
|
||||||
return nil, E.New("remote error: ", serverHello.Message)
|
return nil, E.New("remote error: ", serverHello.Message)
|
||||||
}
|
}
|
||||||
quicConn.SetCongestionControl(hysteria.NewBrutalSender(congestion.ByteCount(serverHello.RecvBPS)))
|
quicConn.SetCongestionControl(hysteria.NewBrutalSender(congestion.ByteCount(serverHello.RecvBPS)))
|
||||||
|
h.conn = quicConn
|
||||||
|
h.rawConn = udpConn
|
||||||
return quicConn, nil
|
return quicConn, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -240,6 +242,7 @@ func (h *Hysteria) Close() error {
|
||||||
defer h.udpAccess.Unlock()
|
defer h.udpAccess.Unlock()
|
||||||
if h.conn != nil {
|
if h.conn != nil {
|
||||||
h.conn.CloseWithError(0, "")
|
h.conn.CloseWithError(0, "")
|
||||||
|
h.rawConn.Close()
|
||||||
}
|
}
|
||||||
for _, session := range h.udpSessions {
|
for _, session := range h.udpSessions {
|
||||||
close(session)
|
close(session)
|
||||||
|
|
|
@ -103,6 +103,10 @@ func (h *Trojan) NewPacketConnection(ctx context.Context, conn N.PacketConn, met
|
||||||
return NewPacketConnection(ctx, h, conn, metadata)
|
return NewPacketConnection(ctx, h, conn, metadata)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (h *Trojan) Close() error {
|
||||||
|
return common.Close(h.multiplexDialer, h.transport)
|
||||||
|
}
|
||||||
|
|
||||||
type trojanDialer Trojan
|
type trojanDialer Trojan
|
||||||
|
|
||||||
func (h *trojanDialer) DialContext(ctx context.Context, network string, destination M.Socksaddr) (net.Conn, error) {
|
func (h *trojanDialer) DialContext(ctx context.Context, network string, destination M.Socksaddr) (net.Conn, error) {
|
||||||
|
|
|
@ -74,10 +74,6 @@ func NewVLESS(ctx context.Context, router adapter.Router, logger log.ContextLogg
|
||||||
return outbound, nil
|
return outbound, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *VLESS) Close() error {
|
|
||||||
return common.Close(h.transport)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (h *VLESS) DialContext(ctx context.Context, network string, destination M.Socksaddr) (net.Conn, error) {
|
func (h *VLESS) DialContext(ctx context.Context, network string, destination M.Socksaddr) (net.Conn, error) {
|
||||||
ctx, metadata := adapter.AppendContext(ctx)
|
ctx, metadata := adapter.AppendContext(ctx)
|
||||||
metadata.Outbound = h.tag
|
metadata.Outbound = h.tag
|
||||||
|
@ -145,3 +141,7 @@ func (h *VLESS) NewConnection(ctx context.Context, conn net.Conn, metadata adapt
|
||||||
func (h *VLESS) NewPacketConnection(ctx context.Context, conn N.PacketConn, metadata adapter.InboundContext) error {
|
func (h *VLESS) NewPacketConnection(ctx context.Context, conn N.PacketConn, metadata adapter.InboundContext) error {
|
||||||
return NewPacketConnection(ctx, h, conn, metadata)
|
return NewPacketConnection(ctx, h, conn, metadata)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (h *VLESS) Close() error {
|
||||||
|
return common.Close(h.transport)
|
||||||
|
}
|
||||||
|
|
|
@ -96,7 +96,7 @@ func NewVMess(ctx context.Context, router adapter.Router, logger log.ContextLogg
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *VMess) Close() error {
|
func (h *VMess) Close() error {
|
||||||
return common.Close(h.transport)
|
return common.Close(h.multiplexDialer, h.transport)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *VMess) DialContext(ctx context.Context, network string, destination M.Socksaddr) (net.Conn, error) {
|
func (h *VMess) DialContext(ctx context.Context, network string, destination M.Socksaddr) (net.Conn, error) {
|
||||||
|
|
|
@ -162,9 +162,8 @@ func (w *WireGuard) Start() error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *WireGuard) Close() error {
|
func (w *WireGuard) Close() error {
|
||||||
return common.Close(
|
if w.device != nil {
|
||||||
w.tunDevice,
|
w.device.Close()
|
||||||
common.PtrOrNil(w.device),
|
}
|
||||||
common.PtrOrNil(w.bind),
|
return common.Close(w.tunDevice)
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,9 +15,14 @@ import (
|
||||||
"github.com/sagernet/sing/protocol/socks"
|
"github.com/sagernet/sing/protocol/socks"
|
||||||
|
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
"go.uber.org/goleak"
|
||||||
)
|
)
|
||||||
|
|
||||||
func startInstance(t *testing.T, options option.Options) {
|
func TestMain(m *testing.M) {
|
||||||
|
goleak.VerifyTestMain(m)
|
||||||
|
}
|
||||||
|
|
||||||
|
func startInstance(t *testing.T, options option.Options) *box.Box {
|
||||||
if debug.Enabled {
|
if debug.Enabled {
|
||||||
options.Log = &option.LogOptions{
|
options.Log = &option.LogOptions{
|
||||||
Level: "trace",
|
Level: "trace",
|
||||||
|
@ -27,10 +32,12 @@ func startInstance(t *testing.T, options option.Options) {
|
||||||
Level: "warning",
|
Level: "warning",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// ctx := context.Background()
|
||||||
|
ctx, cancel := context.WithCancel(context.Background())
|
||||||
var instance *box.Box
|
var instance *box.Box
|
||||||
var err error
|
var err error
|
||||||
for retry := 0; retry < 3; retry++ {
|
for retry := 0; retry < 3; retry++ {
|
||||||
instance, err = box.New(context.Background(), options)
|
instance, err = box.New(ctx, options)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
err = instance.Start()
|
err = instance.Start()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -42,7 +49,9 @@ func startInstance(t *testing.T, options option.Options) {
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
t.Cleanup(func() {
|
t.Cleanup(func() {
|
||||||
instance.Close()
|
instance.Close()
|
||||||
|
cancel()
|
||||||
})
|
})
|
||||||
|
return instance
|
||||||
}
|
}
|
||||||
|
|
||||||
func testSuit(t *testing.T, clientPort uint16, testPort uint16) {
|
func testSuit(t *testing.T, clientPort uint16, testPort uint16) {
|
||||||
|
|
|
@ -7,7 +7,6 @@ import (
|
||||||
"errors"
|
"errors"
|
||||||
"io"
|
"io"
|
||||||
"net"
|
"net"
|
||||||
"net/http"
|
|
||||||
_ "net/http/pprof"
|
_ "net/http/pprof"
|
||||||
"net/netip"
|
"net/netip"
|
||||||
"sync"
|
"sync"
|
||||||
|
@ -101,12 +100,6 @@ func init() {
|
||||||
|
|
||||||
io.Copy(io.Discard, imageStream)
|
io.Copy(io.Discard, imageStream)
|
||||||
}
|
}
|
||||||
go func() {
|
|
||||||
err = http.ListenAndServe("0.0.0.0:8965", nil)
|
|
||||||
if err != nil {
|
|
||||||
log.Debug(err)
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func newPingPongPair() (chan []byte, chan []byte, func(t *testing.T) error) {
|
func newPingPongPair() (chan []byte, chan []byte, func(t *testing.T) error) {
|
||||||
|
|
|
@ -10,10 +10,11 @@ require (
|
||||||
github.com/docker/docker v20.10.18+incompatible
|
github.com/docker/docker v20.10.18+incompatible
|
||||||
github.com/docker/go-connections v0.4.0
|
github.com/docker/go-connections v0.4.0
|
||||||
github.com/gofrs/uuid v4.3.0+incompatible
|
github.com/gofrs/uuid v4.3.0+incompatible
|
||||||
github.com/sagernet/sing v0.0.0-20220916071326-834794b006ea
|
github.com/sagernet/sing v0.0.0-20220921101604-86d7d510231f
|
||||||
github.com/sagernet/sing-shadowsocks v0.0.0-20220819002358-7461bb09a8f6
|
github.com/sagernet/sing-shadowsocks v0.0.0-20220819002358-7461bb09a8f6
|
||||||
github.com/spyzhov/ajson v0.7.1
|
github.com/spyzhov/ajson v0.7.1
|
||||||
github.com/stretchr/testify v1.8.0
|
github.com/stretchr/testify v1.8.0
|
||||||
|
go.uber.org/goleak v1.2.0
|
||||||
golang.org/x/net v0.0.0-20220909164309-bea034e7d591
|
golang.org/x/net v0.0.0-20220909164309-bea034e7d591
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -67,8 +68,8 @@ require (
|
||||||
github.com/sagernet/netlink v0.0.0-20220905062125-8043b4a9aa97 // indirect
|
github.com/sagernet/netlink v0.0.0-20220905062125-8043b4a9aa97 // indirect
|
||||||
github.com/sagernet/quic-go v0.0.0-20220818150011-de611ab3e2bb // indirect
|
github.com/sagernet/quic-go v0.0.0-20220818150011-de611ab3e2bb // indirect
|
||||||
github.com/sagernet/sing-dns v0.0.0-20220915084601-812e0864b45b // indirect
|
github.com/sagernet/sing-dns v0.0.0-20220915084601-812e0864b45b // indirect
|
||||||
github.com/sagernet/sing-tun v0.0.0-20220916073459-0032242c9617 // indirect
|
github.com/sagernet/sing-tun v0.0.0-20220922083325-80ee99472704 // indirect
|
||||||
github.com/sagernet/sing-vmess v0.0.0-20220917033734-9b634758039d // indirect
|
github.com/sagernet/sing-vmess v0.0.0-20220923035311-d70afe4ab2c9 // indirect
|
||||||
github.com/sagernet/smux v0.0.0-20220831015742-e0f1988e3195 // indirect
|
github.com/sagernet/smux v0.0.0-20220831015742-e0f1988e3195 // indirect
|
||||||
github.com/sagernet/websocket v0.0.0-20220913015213-615516348b4e // indirect
|
github.com/sagernet/websocket v0.0.0-20220913015213-615516348b4e // indirect
|
||||||
github.com/sirupsen/logrus v1.9.0 // indirect
|
github.com/sirupsen/logrus v1.9.0 // indirect
|
||||||
|
@ -78,7 +79,7 @@ require (
|
||||||
go.uber.org/multierr v1.6.0 // indirect
|
go.uber.org/multierr v1.6.0 // indirect
|
||||||
go.uber.org/zap v1.22.0 // indirect
|
go.uber.org/zap v1.22.0 // indirect
|
||||||
go4.org/netipx v0.0.0-20220812043211-3cc044ffd68d // indirect
|
go4.org/netipx v0.0.0-20220812043211-3cc044ffd68d // indirect
|
||||||
golang.org/x/crypto v0.0.0-20220829220503-c86fa9a7ed90 // indirect
|
golang.org/x/crypto v0.0.0-20220919173607-35f4265a4bc0 // indirect
|
||||||
golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e // indirect
|
golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e // indirect
|
||||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 // indirect
|
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 // indirect
|
||||||
golang.org/x/sys v0.0.0-20220913120320-3275c407cedc // indirect
|
golang.org/x/sys v0.0.0-20220913120320-3275c407cedc // indirect
|
||||||
|
|
20
test/go.sum
20
test/go.sum
|
@ -165,16 +165,16 @@ github.com/sagernet/quic-go v0.0.0-20220818150011-de611ab3e2bb h1:wc0yQ+SBn4TaTY
|
||||||
github.com/sagernet/quic-go v0.0.0-20220818150011-de611ab3e2bb/go.mod h1:MIccjRKnPTjWwAOpl+AUGWOkzyTd9tERytudxu+1ra4=
|
github.com/sagernet/quic-go v0.0.0-20220818150011-de611ab3e2bb/go.mod h1:MIccjRKnPTjWwAOpl+AUGWOkzyTd9tERytudxu+1ra4=
|
||||||
github.com/sagernet/sing v0.0.0-20220812082120-05f9836bff8f/go.mod h1:QVsS5L/ZA2Q5UhQwLrn0Trw+msNd/NPGEhBKR/ioWiY=
|
github.com/sagernet/sing v0.0.0-20220812082120-05f9836bff8f/go.mod h1:QVsS5L/ZA2Q5UhQwLrn0Trw+msNd/NPGEhBKR/ioWiY=
|
||||||
github.com/sagernet/sing v0.0.0-20220817130738-ce854cda8522/go.mod h1:QVsS5L/ZA2Q5UhQwLrn0Trw+msNd/NPGEhBKR/ioWiY=
|
github.com/sagernet/sing v0.0.0-20220817130738-ce854cda8522/go.mod h1:QVsS5L/ZA2Q5UhQwLrn0Trw+msNd/NPGEhBKR/ioWiY=
|
||||||
github.com/sagernet/sing v0.0.0-20220916071326-834794b006ea h1:ZAWvZdeByPBBz3Vs+w3Erbh+DDo7D4biokoPhXl0nNU=
|
github.com/sagernet/sing v0.0.0-20220921101604-86d7d510231f h1:GX416thAwyc0vHBOal/qplvdhFgYO2dHD5GqADCJ0Ig=
|
||||||
github.com/sagernet/sing v0.0.0-20220916071326-834794b006ea/go.mod h1:x3NHUeJBQwV75L51zwmLKQdLtRvR+M4PmXkfQtU1vIY=
|
github.com/sagernet/sing v0.0.0-20220921101604-86d7d510231f/go.mod h1:x3NHUeJBQwV75L51zwmLKQdLtRvR+M4PmXkfQtU1vIY=
|
||||||
github.com/sagernet/sing-dns v0.0.0-20220915084601-812e0864b45b h1:cXCMNJ9heZ+c6l+qUcku60x9KyXo4SOAaJfg/6spOmU=
|
github.com/sagernet/sing-dns v0.0.0-20220915084601-812e0864b45b h1:cXCMNJ9heZ+c6l+qUcku60x9KyXo4SOAaJfg/6spOmU=
|
||||||
github.com/sagernet/sing-dns v0.0.0-20220915084601-812e0864b45b/go.mod h1:SrvWLfOSlnFmH32CWXicfilAGgIXR0VjrH6yRbuXYww=
|
github.com/sagernet/sing-dns v0.0.0-20220915084601-812e0864b45b/go.mod h1:SrvWLfOSlnFmH32CWXicfilAGgIXR0VjrH6yRbuXYww=
|
||||||
github.com/sagernet/sing-shadowsocks v0.0.0-20220819002358-7461bb09a8f6 h1:JJfDeYYhWunvtxsU/mOVNTmFQmnzGx9dY034qG6G3g4=
|
github.com/sagernet/sing-shadowsocks v0.0.0-20220819002358-7461bb09a8f6 h1:JJfDeYYhWunvtxsU/mOVNTmFQmnzGx9dY034qG6G3g4=
|
||||||
github.com/sagernet/sing-shadowsocks v0.0.0-20220819002358-7461bb09a8f6/go.mod h1:EX3RbZvrwAkPI2nuGa78T2iQXmrkT+/VQtskjou42xM=
|
github.com/sagernet/sing-shadowsocks v0.0.0-20220819002358-7461bb09a8f6/go.mod h1:EX3RbZvrwAkPI2nuGa78T2iQXmrkT+/VQtskjou42xM=
|
||||||
github.com/sagernet/sing-tun v0.0.0-20220916073459-0032242c9617 h1:fNTNmylhB/UjoBLusmrFu2B1fat4OCkDkQXTgrE7ZsE=
|
github.com/sagernet/sing-tun v0.0.0-20220922083325-80ee99472704 h1:DOQQXQbB2gq4n2FuMHrL07HRs2naCCsuiu/9l1JFb9A=
|
||||||
github.com/sagernet/sing-tun v0.0.0-20220916073459-0032242c9617/go.mod h1:5AhPUv9jWDQ3pv3Mj78SL/1TSjhoaj6WNASxRKLqXqM=
|
github.com/sagernet/sing-tun v0.0.0-20220922083325-80ee99472704/go.mod h1:5AhPUv9jWDQ3pv3Mj78SL/1TSjhoaj6WNASxRKLqXqM=
|
||||||
github.com/sagernet/sing-vmess v0.0.0-20220917033734-9b634758039d h1:/GNWxSrQj4chFYk2jahIXNPdvUa9DW8IdgyqYFbq9oQ=
|
github.com/sagernet/sing-vmess v0.0.0-20220923035311-d70afe4ab2c9 h1:w7JlEa4xHXuuPTL3Opb+Z5f/l66SYi54rSfobzuxSF8=
|
||||||
github.com/sagernet/sing-vmess v0.0.0-20220917033734-9b634758039d/go.mod h1:u66Vv7NHXJWfeAmhh7JuJp/cwxmuQlM56QoZ7B7Mmd0=
|
github.com/sagernet/sing-vmess v0.0.0-20220923035311-d70afe4ab2c9/go.mod h1:bwhAdSNET1X+j9DOXGj9NIQR39xgcWIk1rOQ9lLD+gM=
|
||||||
github.com/sagernet/smux v0.0.0-20220831015742-e0f1988e3195 h1:5VBIbVw9q7aKbrFdT83mjkyvQ+VaRsQ6yflTepfln38=
|
github.com/sagernet/smux v0.0.0-20220831015742-e0f1988e3195 h1:5VBIbVw9q7aKbrFdT83mjkyvQ+VaRsQ6yflTepfln38=
|
||||||
github.com/sagernet/smux v0.0.0-20220831015742-e0f1988e3195/go.mod h1:yedWtra8nyGJ+SyI+ziwuaGMzBatbB10P1IOOZbbSK8=
|
github.com/sagernet/smux v0.0.0-20220831015742-e0f1988e3195/go.mod h1:yedWtra8nyGJ+SyI+ziwuaGMzBatbB10P1IOOZbbSK8=
|
||||||
github.com/sagernet/websocket v0.0.0-20220913015213-615516348b4e h1:7uw2njHFGE+VpWamge6o56j2RWk4omF6uLKKxMmcWvs=
|
github.com/sagernet/websocket v0.0.0-20220913015213-615516348b4e h1:7uw2njHFGE+VpWamge6o56j2RWk4omF6uLKKxMmcWvs=
|
||||||
|
@ -205,8 +205,9 @@ go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqe
|
||||||
go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
|
go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
|
||||||
go.uber.org/atomic v1.10.0 h1:9qC72Qh0+3MqyJbAn8YU5xVq1frD8bn3JtD2oXtafVQ=
|
go.uber.org/atomic v1.10.0 h1:9qC72Qh0+3MqyJbAn8YU5xVq1frD8bn3JtD2oXtafVQ=
|
||||||
go.uber.org/atomic v1.10.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0=
|
go.uber.org/atomic v1.10.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0=
|
||||||
go.uber.org/goleak v1.1.11 h1:wy28qYRKZgnJTxGxvye5/wgWr1EKjmUDGYox5mGlRlI=
|
|
||||||
go.uber.org/goleak v1.1.11/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ=
|
go.uber.org/goleak v1.1.11/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ=
|
||||||
|
go.uber.org/goleak v1.2.0 h1:xqgm/S+aQvhWFTtR0XK3Jvg7z8kGV8P4X14IzwN3Eqk=
|
||||||
|
go.uber.org/goleak v1.2.0/go.mod h1:XJYK+MuIchqpmGmUSAzotztawfKvYLUIgg7guXrwVUo=
|
||||||
go.uber.org/multierr v1.6.0 h1:y6IPFStTAIT5Ytl7/XYmHvzXQ7S3g/IeZW9hyZ5thw4=
|
go.uber.org/multierr v1.6.0 h1:y6IPFStTAIT5Ytl7/XYmHvzXQ7S3g/IeZW9hyZ5thw4=
|
||||||
go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU=
|
go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU=
|
||||||
go.uber.org/zap v1.21.0/go.mod h1:wjWOCqI0f2ZZrJF/UufIOkiC8ii6tm1iqIsLo76RfJw=
|
go.uber.org/zap v1.21.0/go.mod h1:wjWOCqI0f2ZZrJF/UufIOkiC8ii6tm1iqIsLo76RfJw=
|
||||||
|
@ -220,8 +221,8 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U
|
||||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||||
golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8=
|
golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8=
|
||||||
golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||||
golang.org/x/crypto v0.0.0-20220829220503-c86fa9a7ed90 h1:Y/gsMcFOcR+6S6f3YeMKl5g+dZMEWqcz5Czj/GWYbkM=
|
golang.org/x/crypto v0.0.0-20220919173607-35f4265a4bc0 h1:a5Yg6ylndHHYJqIPrdq0AhvR6KTvDTAvgBtaidhEevY=
|
||||||
golang.org/x/crypto v0.0.0-20220829220503-c86fa9a7ed90/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
golang.org/x/crypto v0.0.0-20220919173607-35f4265a4bc0/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||||
golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e h1:+WEEuIdZHnUeJJmEUjyYC2gfUMj69yZXw17EnHg/otA=
|
golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e h1:+WEEuIdZHnUeJJmEUjyYC2gfUMj69yZXw17EnHg/otA=
|
||||||
golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e/go.mod h1:Kr81I6Kryrl9sr8s2FK3vxD90NdsKWRuOIl2O4CvYbA=
|
golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e/go.mod h1:Kr81I6Kryrl9sr8s2FK3vxD90NdsKWRuOIl2O4CvYbA=
|
||||||
|
@ -229,6 +230,7 @@ golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTk
|
||||||
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
||||||
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||||
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||||
|
golang.org/x/lint v0.0.0-20210508222113-6edffad5e616 h1:VLliZ0d+/avPrXXH+OakdXhpJuEoBZuwh1m2j7U6Iug=
|
||||||
golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
|
golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
|
||||||
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
|
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
|
||||||
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||||
|
|
|
@ -107,3 +107,64 @@ func TestMuxCoolClient(t *testing.T) {
|
||||||
})
|
})
|
||||||
testSuit(t, clientPort, testPort)
|
testSuit(t, clientPort, testPort)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestMuxCoolSelf(t *testing.T) {
|
||||||
|
user := newUUID()
|
||||||
|
startInstance(t, option.Options{
|
||||||
|
Inbounds: []option.Inbound{
|
||||||
|
{
|
||||||
|
Type: C.TypeMixed,
|
||||||
|
Tag: "mixed-in",
|
||||||
|
MixedOptions: option.HTTPMixedInboundOptions{
|
||||||
|
ListenOptions: option.ListenOptions{
|
||||||
|
Listen: option.ListenAddress(netip.IPv4Unspecified()),
|
||||||
|
ListenPort: clientPort,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Type: C.TypeVMess,
|
||||||
|
VMessOptions: option.VMessInboundOptions{
|
||||||
|
ListenOptions: option.ListenOptions{
|
||||||
|
Listen: option.ListenAddress(netip.IPv4Unspecified()),
|
||||||
|
ListenPort: serverPort,
|
||||||
|
},
|
||||||
|
Users: []option.VMessUser{
|
||||||
|
{
|
||||||
|
Name: "sekai",
|
||||||
|
UUID: user.String(),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Outbounds: []option.Outbound{
|
||||||
|
{
|
||||||
|
Type: C.TypeDirect,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Type: C.TypeVMess,
|
||||||
|
Tag: "vmess-out",
|
||||||
|
VMessOptions: option.VMessOutboundOptions{
|
||||||
|
ServerOptions: option.ServerOptions{
|
||||||
|
Server: "127.0.0.1",
|
||||||
|
ServerPort: serverPort,
|
||||||
|
},
|
||||||
|
UUID: user.String(),
|
||||||
|
PacketEncoding: "xudp",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Route: &option.RouteOptions{
|
||||||
|
Rules: []option.Rule{
|
||||||
|
{
|
||||||
|
DefaultOptions: option.DefaultRule{
|
||||||
|
Inbound: []string{"mixed-in"},
|
||||||
|
Outbound: "vmess-out",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
testSuit(t, clientPort, testPort)
|
||||||
|
}
|
||||||
|
|
|
@ -17,6 +17,10 @@ var muxProtocols = []mux.Protocol{
|
||||||
mux.ProtocolSMux,
|
mux.ProtocolSMux,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestVMessSMux(t *testing.T) {
|
||||||
|
testVMessMux(t, mux.ProtocolSMux.String())
|
||||||
|
}
|
||||||
|
|
||||||
func TestShadowsocksMux(t *testing.T) {
|
func TestShadowsocksMux(t *testing.T) {
|
||||||
for _, protocol := range muxProtocols {
|
for _, protocol := range muxProtocols {
|
||||||
t.Run(protocol.String(), func(t *testing.T) {
|
t.Run(protocol.String(), func(t *testing.T) {
|
||||||
|
@ -25,14 +29,6 @@ func TestShadowsocksMux(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestVMessMux(t *testing.T) {
|
|
||||||
for _, protocol := range muxProtocols {
|
|
||||||
t.Run(protocol.String(), func(t *testing.T) {
|
|
||||||
testVMessMux(t, protocol.String())
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func testShadowsocksMux(t *testing.T, protocol string) {
|
func testShadowsocksMux(t *testing.T, protocol string) {
|
||||||
method := shadowaead_2022.List[0]
|
method := shadowaead_2022.List[0]
|
||||||
password := mkBase64(t, 16)
|
password := mkBase64(t, 16)
|
||||||
|
|
|
@ -18,7 +18,7 @@ func newUUID() uuid.UUID {
|
||||||
return user
|
return user
|
||||||
}
|
}
|
||||||
|
|
||||||
func _TestVMessAuto(t *testing.T) {
|
func TestVMessAuto(t *testing.T) {
|
||||||
security := "auto"
|
security := "auto"
|
||||||
t.Run("self", func(t *testing.T) {
|
t.Run("self", func(t *testing.T) {
|
||||||
testVMessSelf(t, security, 0, false, false, false)
|
testVMessSelf(t, security, 0, false, false, false)
|
||||||
|
|
|
@ -25,8 +25,9 @@ type Client struct {
|
||||||
serverAddr M.Socksaddr
|
serverAddr M.Socksaddr
|
||||||
tlsConfig *tls.STDConfig
|
tlsConfig *tls.STDConfig
|
||||||
quicConfig *quic.Config
|
quicConfig *quic.Config
|
||||||
conn quic.Connection
|
|
||||||
connAccess sync.Mutex
|
connAccess sync.Mutex
|
||||||
|
conn quic.Connection
|
||||||
|
rawConn net.Conn
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewClient(ctx context.Context, dialer N.Dialer, serverAddr M.Socksaddr, options option.V2RayQUICOptions, tlsConfig tls.Config) (adapter.V2RayClientTransport, error) {
|
func NewClient(ctx context.Context, dialer N.Dialer, serverAddr M.Socksaddr, options option.V2RayQUICOptions, tlsConfig tls.Config) (adapter.V2RayClientTransport, error) {
|
||||||
|
@ -64,7 +65,6 @@ func (c *Client) offer() (quic.Connection, error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
c.conn = conn
|
|
||||||
return conn, nil
|
return conn, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -80,6 +80,8 @@ func (c *Client) offerNew() (quic.Connection, error) {
|
||||||
packetConn.Close()
|
packetConn.Close()
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
c.conn = quicConn
|
||||||
|
c.rawConn = udpConn
|
||||||
return quicConn, nil
|
return quicConn, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -94,3 +96,7 @@ func (c *Client) DialContext(ctx context.Context) (net.Conn, error) {
|
||||||
}
|
}
|
||||||
return &hysteria.StreamWrapper{Conn: conn, Stream: stream}, nil
|
return &hysteria.StreamWrapper{Conn: conn, Stream: stream}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *Client) Close() error {
|
||||||
|
return common.Close(c.conn, c.rawConn)
|
||||||
|
}
|
||||||
|
|
|
@ -20,6 +20,7 @@ type ClientBind struct {
|
||||||
peerAddr M.Socksaddr
|
peerAddr M.Socksaddr
|
||||||
connAccess sync.Mutex
|
connAccess sync.Mutex
|
||||||
conn *wireConn
|
conn *wireConn
|
||||||
|
done chan struct{}
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewClientBind(ctx context.Context, dialer N.Dialer, peerAddr M.Socksaddr) *ClientBind {
|
func NewClientBind(ctx context.Context, dialer N.Dialer, peerAddr M.Socksaddr) *ClientBind {
|
||||||
|
@ -63,6 +64,12 @@ func (c *ClientBind) connect() (*wireConn, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *ClientBind) Open(port uint16) (fns []conn.ReceiveFunc, actualPort uint16, err error) {
|
func (c *ClientBind) Open(port uint16) (fns []conn.ReceiveFunc, actualPort uint16, err error) {
|
||||||
|
select {
|
||||||
|
case <-c.done:
|
||||||
|
err = net.ErrClosed
|
||||||
|
return
|
||||||
|
default:
|
||||||
|
}
|
||||||
return []conn.ReceiveFunc{c.receive}, 0, nil
|
return []conn.ReceiveFunc{c.receive}, 0, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -75,8 +82,13 @@ func (c *ClientBind) receive(b []byte) (n int, ep conn.Endpoint, err error) {
|
||||||
n, err = udpConn.Read(b)
|
n, err = udpConn.Read(b)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
udpConn.Close()
|
udpConn.Close()
|
||||||
|
select {
|
||||||
|
case <-c.done:
|
||||||
|
default:
|
||||||
err = &wireError{err}
|
err = &wireError{err}
|
||||||
}
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
ep = Endpoint(c.peerAddr)
|
ep = Endpoint(c.peerAddr)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -85,6 +97,16 @@ func (c *ClientBind) Close() error {
|
||||||
c.connAccess.Lock()
|
c.connAccess.Lock()
|
||||||
defer c.connAccess.Unlock()
|
defer c.connAccess.Unlock()
|
||||||
common.Close(common.PtrOrNil(c.conn))
|
common.Close(common.PtrOrNil(c.conn))
|
||||||
|
if c.done == nil {
|
||||||
|
c.done = make(chan struct{})
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
select {
|
||||||
|
case <-c.done:
|
||||||
|
return net.ErrClosed
|
||||||
|
default:
|
||||||
|
close(c.done)
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -35,7 +35,6 @@ type StackDevice struct {
|
||||||
events chan tun.Event
|
events chan tun.Event
|
||||||
outbound chan *stack.PacketBuffer
|
outbound chan *stack.PacketBuffer
|
||||||
dispatcher stack.NetworkDispatcher
|
dispatcher stack.NetworkDispatcher
|
||||||
done chan struct{}
|
|
||||||
addr4 tcpip.Address
|
addr4 tcpip.Address
|
||||||
addr6 tcpip.Address
|
addr6 tcpip.Address
|
||||||
}
|
}
|
||||||
|
@ -51,7 +50,6 @@ func NewStackDevice(localAddresses []netip.Prefix, mtu uint32) (*StackDevice, er
|
||||||
mtu: mtu,
|
mtu: mtu,
|
||||||
events: make(chan tun.Event, 1),
|
events: make(chan tun.Event, 1),
|
||||||
outbound: make(chan *stack.PacketBuffer, 256),
|
outbound: make(chan *stack.PacketBuffer, 256),
|
||||||
done: make(chan struct{}),
|
|
||||||
}
|
}
|
||||||
err := ipStack.CreateNIC(defaultNIC, (*wireEndpoint)(tunDevice))
|
err := ipStack.CreateNIC(defaultNIC, (*wireEndpoint)(tunDevice))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -193,11 +191,11 @@ func (w *StackDevice) Events() chan tun.Event {
|
||||||
|
|
||||||
func (w *StackDevice) Close() error {
|
func (w *StackDevice) Close() error {
|
||||||
select {
|
select {
|
||||||
case <-w.done:
|
case <-w.events:
|
||||||
return os.ErrClosed
|
return os.ErrClosed
|
||||||
default:
|
default:
|
||||||
|
close(w.events)
|
||||||
}
|
}
|
||||||
close(w.done)
|
|
||||||
w.stack.Close()
|
w.stack.Close()
|
||||||
for _, endpoint := range w.stack.CleanupEndpoints() {
|
for _, endpoint := range w.stack.CleanupEndpoints() {
|
||||||
endpoint.Abort()
|
endpoint.Abort()
|
||||||
|
|
|
@ -106,5 +106,11 @@ func (w *SystemDevice) Events() chan wgTun.Event {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *SystemDevice) Close() error {
|
func (w *SystemDevice) Close() error {
|
||||||
|
select {
|
||||||
|
case <-w.events:
|
||||||
|
return os.ErrClosed
|
||||||
|
default:
|
||||||
|
close(w.events)
|
||||||
|
}
|
||||||
return w.device.Close()
|
return w.device.Close()
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue