Compare commits

...

5 Commits

Author SHA1 Message Date
世界
1b680d4748 documentation: Update changelog 2023-04-14 19:24:16 +08:00
世界
d407b35b49 Update dependencies 2023-04-14 19:19:27 +08:00
世界
7f49c45673 urltest: Recheck after network change 2023-04-13 19:07:20 +08:00
世界
221cce6e57 Fix wireguard reconnect 2023-04-13 19:07:19 +08:00
世界
95809dce11 Fix deadline race 2023-04-13 19:07:19 +08:00
9 changed files with 57 additions and 53 deletions

View File

@@ -1,3 +1,9 @@
#### 1.3-beta6
* Fix WireGuard reconnect
* Perform URLTest recheck after network changes
* Fix bugs and update dependencies
#### 1.3-beta5
* Add Clash.Meta API compatibility for Clash API

4
go.mod
View File

@@ -4,7 +4,7 @@ go 1.18
require (
berty.tech/go-libtor v1.0.385
github.com/Dreamacro/clash v1.14.0
github.com/Dreamacro/clash v1.15.0
github.com/caddyserver/certmagic v0.17.2
github.com/cretz/bine v0.2.0
github.com/dustin/go-humanize v1.0.1
@@ -25,7 +25,7 @@ require (
github.com/sagernet/gomobile v0.0.0-20230413023804-244d7ff07035
github.com/sagernet/quic-go v0.0.0-20230202071646-a8c8afb18b32
github.com/sagernet/reality v0.0.0-20230406110435-ee17307e7691
github.com/sagernet/sing v0.2.3-0.20230413023204-48b019b13e78
github.com/sagernet/sing v0.2.3-0.20230413105021-520dd58fb01d
github.com/sagernet/sing-dns v0.1.5-0.20230408004833-5adaf486d440
github.com/sagernet/sing-shadowsocks v0.2.1-0.20230412123110-1a7c32b4e2e7
github.com/sagernet/sing-shadowtls v0.1.1-0.20230409094821-9abef019436f

10
go.sum
View File

@@ -1,7 +1,7 @@
berty.tech/go-libtor v1.0.385 h1:RWK94C3hZj6Z2GdvePpHJLnWYobFr3bY/OdUJ5aoEXw=
berty.tech/go-libtor v1.0.385/go.mod h1:9swOOQVb+kmvuAlsgWUK/4c52pm69AdbJsxLzk+fJEw=
github.com/Dreamacro/clash v1.14.0 h1:ehJ/C/1m9LEjmME72WSE/Y2YqbR3Q54AbjqiRCvtyW4=
github.com/Dreamacro/clash v1.14.0/go.mod h1:ia2CU7V713H1QdCqMwOLK9U9V5Ay8X0voj3yQr2tk+I=
github.com/Dreamacro/clash v1.15.0 h1:mlpD950VEggXZBNahV66hyKDRxcczkj3vymoAt78KyE=
github.com/Dreamacro/clash v1.15.0/go.mod h1:WNH69bN11LiAdgdSr4hpkEuXVMfBbWyhEKMCTx9BtNE=
github.com/ajg/form v1.5.1 h1:t9c7v8JUKu/XxOGBU0yjNpaMloxGEJhUkqFRq0ibGeU=
github.com/ajg/form v1.5.1/go.mod h1:uL1WgH+h2mgNtvBq0339dVnzXdBETtL2LeUXaIv25UY=
github.com/andybalholm/brotli v1.0.5 h1:8uQZIdzKmjc/iuPu7O2ioW48L81FgatrcpfFmiq/cCs=
@@ -101,8 +101,6 @@ github.com/sagernet/cloudflare-tls v0.0.0-20221031050923-d70792f4c3a0 h1:KyhtFFt
github.com/sagernet/cloudflare-tls v0.0.0-20221031050923-d70792f4c3a0/go.mod h1:D4SFEOkJK+4W1v86ZhX0jPM0rAL498fyQAChqMtes/I=
github.com/sagernet/go-tun2socks v1.16.12-0.20220818015926-16cb67876a61 h1:5+m7c6AkmAylhauulqN/c5dnh8/KssrE9c93TQrXldA=
github.com/sagernet/go-tun2socks v1.16.12-0.20220818015926-16cb67876a61/go.mod h1:QUQ4RRHD6hGGHdFMEtR8T2P6GS6R3D/CXKdaYHKKXms=
github.com/sagernet/gomobile v0.0.0-20230413023437-ec061884b992 h1:WkcHhOX3ce9ElLKDUQKJrAt7SjpKNnASsPbMfqfZEPc=
github.com/sagernet/gomobile v0.0.0-20230413023437-ec061884b992/go.mod h1:5YE39YkJkCcMsfq1jMKkjsrM2GfBoF9JVWnvU89hmvU=
github.com/sagernet/gomobile v0.0.0-20230413023804-244d7ff07035 h1:KttYh6bBhIw8Y6/Ljn7CGwC3CKZn788rzMJmeAKjY+8=
github.com/sagernet/gomobile v0.0.0-20230413023804-244d7ff07035/go.mod h1:5YE39YkJkCcMsfq1jMKkjsrM2GfBoF9JVWnvU89hmvU=
github.com/sagernet/netlink v0.0.0-20220905062125-8043b4a9aa97 h1:iL5gZI3uFp0X6EslacyapiRz7LLSJyr4RajF/BhMVyE=
@@ -113,8 +111,8 @@ github.com/sagernet/reality v0.0.0-20230406110435-ee17307e7691 h1:5Th31OC6yj8byL
github.com/sagernet/reality v0.0.0-20230406110435-ee17307e7691/go.mod h1:B8lp4WkQ1PwNnrVMM6KyuFR20pU8jYBD+A4EhJovEXU=
github.com/sagernet/sing v0.0.0-20220817130738-ce854cda8522/go.mod h1:QVsS5L/ZA2Q5UhQwLrn0Trw+msNd/NPGEhBKR/ioWiY=
github.com/sagernet/sing v0.1.8/go.mod h1:jt1w2u7lJQFFSGLiRrRIs5YWmx4kAPfWuOejuDW9qMk=
github.com/sagernet/sing v0.2.3-0.20230413023204-48b019b13e78 h1:bTE9RgURmiFiTjXaYN6q9BYPTBPKIzlFYNy2p+WOubI=
github.com/sagernet/sing v0.2.3-0.20230413023204-48b019b13e78/go.mod h1:Ta8nHnDLAwqySzKhGoKk4ZIB+vJ3GTKj7UPrWYvM+4w=
github.com/sagernet/sing v0.2.3-0.20230413105021-520dd58fb01d h1:+hp4necjzOvjg9dQwqmTfH/jAgCCnguVNQzIRUOpO00=
github.com/sagernet/sing v0.2.3-0.20230413105021-520dd58fb01d/go.mod h1:Ta8nHnDLAwqySzKhGoKk4ZIB+vJ3GTKj7UPrWYvM+4w=
github.com/sagernet/sing-dns v0.1.5-0.20230408004833-5adaf486d440 h1:VH8/BcOVuApHtS+vKP+khxlGRcXH7KKhgkTDtNynqSQ=
github.com/sagernet/sing-dns v0.1.5-0.20230408004833-5adaf486d440/go.mod h1:69PNSHyEmXdjf6C+bXBOdr2GQnPeEyWjIzo/MV8gmz8=
github.com/sagernet/sing-shadowsocks v0.2.1-0.20230412123110-1a7c32b4e2e7 h1:3WDMIF1aE/twc5gJ+9PF2ZJqUxwZ80MPtNBKE3yBevU=

View File

@@ -39,6 +39,10 @@ func (a *myOutboundAdapter) Network() []string {
return a.network
}
func (a *myOutboundAdapter) NewError(ctx context.Context, err error) {
NewError(a.logger, ctx, err)
}
func NewConnection(ctx context.Context, this N.Dialer, conn net.Conn, metadata adapter.InboundContext) error {
ctx = adapter.WithContext(ctx, &metadata)
var outConn net.Conn
@@ -121,3 +125,12 @@ func CopyEarlyConn(ctx context.Context, conn net.Conn, serverConn net.Conn) erro
}
return bufio.CopyConn(ctx, conn, serverConn)
}
func NewError(logger log.ContextLogger, ctx context.Context, err error) {
common.Close(err)
if E.IsClosedOrCanceled(err) {
logger.DebugContext(ctx, "connection closed: ", err)
return
}
logger.ErrorContext(ctx, err)
}

View File

@@ -20,8 +20,9 @@ import (
)
var (
_ adapter.Outbound = (*URLTest)(nil)
_ adapter.OutboundGroup = (*URLTest)(nil)
_ adapter.Outbound = (*URLTest)(nil)
_ adapter.OutboundGroup = (*URLTest)(nil)
_ adapter.InterfaceUpdateListener = (*URLTest)(nil)
)
type URLTest struct {
@@ -122,6 +123,11 @@ func (s *URLTest) NewPacketConnection(ctx context.Context, conn N.PacketConn, me
return NewPacketConnection(ctx, s, conn, metadata)
}
func (s *URLTest) InterfaceUpdated() error {
go s.group.checkOutbounds()
return nil
}
type URLTestGroup struct {
ctx context.Context
router adapter.Router

View File

@@ -67,7 +67,7 @@ func NewWireGuard(ctx context.Context, router adapter.Router, logger log.Context
connectAddr = options.ServerOptions.Build()
}
}
outbound.bind = wireguard.NewClientBind(ctx, dialer.New(router, options.DialerOptions), isConnect, connectAddr, reserved)
outbound.bind = wireguard.NewClientBind(ctx, outbound, dialer.New(router, options.DialerOptions), isConnect, connectAddr, reserved)
localPrefixes := common.Map(options.LocalAddress, option.ListenPrefix.Build)
if len(localPrefixes) == 0 {
return nil, E.New("missing local address")

View File

@@ -32,10 +32,10 @@ type TLSObfs struct {
func (to *TLSObfs) read(b []byte, discardN int) (int, error) {
buf := B.Get(discardN)
_, err := io.ReadFull(to.Conn, buf)
B.Put(buf)
if err != nil {
return 0, err
}
B.Put(buf)
sizeBuf := make([]byte, 2)
_, err = io.ReadFull(to.Conn, sizeBuf)

View File

@@ -7,8 +7,8 @@ import (
"sync"
"github.com/sagernet/sing/common"
"github.com/sagernet/sing/common/buf"
"github.com/sagernet/sing/common/bufio"
E "github.com/sagernet/sing/common/exceptions"
M "github.com/sagernet/sing/common/metadata"
N "github.com/sagernet/sing/common/network"
"github.com/sagernet/wireguard-go/conn"
@@ -18,6 +18,7 @@ var _ conn.Bind = (*ClientBind)(nil)
type ClientBind struct {
ctx context.Context
errorHandler E.Handler
dialer N.Dialer
reservedForEndpoint map[M.Socksaddr][3]uint8
connAccess sync.Mutex
@@ -28,9 +29,10 @@ type ClientBind struct {
reserved [3]uint8
}
func NewClientBind(ctx context.Context, dialer N.Dialer, isConnect bool, connectAddr M.Socksaddr, reserved [3]uint8) *ClientBind {
func NewClientBind(ctx context.Context, errorHandler E.Handler, dialer N.Dialer, isConnect bool, connectAddr M.Socksaddr, reserved [3]uint8) *ClientBind {
return &ClientBind{
ctx: ctx,
errorHandler: errorHandler,
dialer: dialer,
reservedForEndpoint: make(map[M.Socksaddr][3]uint8),
isConnect: isConnect,
@@ -67,10 +69,10 @@ func (c *ClientBind) connect() (*wireConn, error) {
if c.isConnect {
udpConn, err := c.dialer.DialContext(c.ctx, N.NetworkUDP, c.connectAddr)
if err != nil {
return nil, &wireError{err}
return nil, err
}
c.conn = &wireConn{
NetPacketConn: &bufio.UnbindPacketConn{
PacketConn: &bufio.UnbindPacketConn{
ExtendedConn: bufio.NewExtendedConn(udpConn),
Addr: c.connectAddr,
},
@@ -79,11 +81,11 @@ func (c *ClientBind) connect() (*wireConn, error) {
} else {
udpConn, err := c.dialer.ListenPacket(c.ctx, M.Socksaddr{Addr: netip.IPv4Unspecified()})
if err != nil {
return nil, &wireError{err}
return nil, err
}
c.conn = &wireConn{
NetPacketConn: bufio.NewPacketConn(udpConn),
done: make(chan struct{}),
PacketConn: bufio.NewPacketConn(udpConn),
done: make(chan struct{}),
}
}
return c.conn, nil
@@ -102,30 +104,31 @@ func (c *ClientBind) Open(port uint16) (fns []conn.ReceiveFunc, actualPort uint1
func (c *ClientBind) receive(b []byte) (n int, ep conn.Endpoint, err error) {
udpConn, err := c.connect()
if err != nil {
err = &wireError{err}
select {
case <-c.done:
return
default:
}
c.errorHandler.NewError(context.Background(), E.Cause(err, "connect to server"))
err = nil
return
}
buffer := buf.With(b)
destination, err := udpConn.ReadPacket(buffer)
n, addr, err := udpConn.ReadFrom(b)
if err != nil {
udpConn.Close()
select {
case <-c.done:
default:
err = &wireError{err}
c.errorHandler.NewError(context.Background(), E.Cause(err, "read packet"))
}
return
}
n = buffer.Len()
if buffer.Start() > 0 {
copy(b, buffer.Bytes())
}
if n > 3 {
b[1] = 0
b[2] = 0
b[3] = 0
}
ep = Endpoint(destination)
ep = Endpoint(M.SocksaddrFromNet(addr))
return
}
@@ -167,7 +170,7 @@ func (c *ClientBind) Send(b []byte, ep conn.Endpoint) error {
b[2] = reserved[1]
b[3] = reserved[2]
}
err = udpConn.WritePacket(buf.As(b), destination)
_, err = udpConn.WriteTo(b, destination)
if err != nil {
udpConn.Close()
}
@@ -179,7 +182,7 @@ func (c *ClientBind) ParseEndpoint(s string) (conn.Endpoint, error) {
}
type wireConn struct {
N.NetPacketConn
net.PacketConn
access sync.Mutex
done chan struct{}
}
@@ -192,7 +195,7 @@ func (w *wireConn) Close() error {
return net.ErrClosed
default:
}
w.NetPacketConn.Close()
w.PacketConn.Close()
close(w.done)
return nil
}

View File

@@ -1,22 +0,0 @@
package wireguard
import "net"
type wireError struct {
cause error
}
func (w *wireError) Error() string {
return w.cause.Error()
}
func (w *wireError) Timeout() bool {
if cause, causeNet := w.cause.(net.Error); causeNet {
return cause.Timeout()
}
return false
}
func (w *wireError) Temporary() bool {
return true
}