Liu Song’s Projects


~/Projects/sing-tun

git clone https://code.lsong.org/sing-tun

Commit

Commit
3b4e77c4c1b3283b8453b2e25bdfac4f55ae68bb
Author
世界 <[email protected]>
Date
2022-07-30 09:51:11 +0800 +0800
Diffstat
 go.mod | 4 +-
 go.sum | 7 ++---
 gvisor.go | 6 ++--
 gvisor_err.go | 69 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 gvisor_udp.go | 5 +--

Improve error processing


diff --git a/go.mod b/go.mod
index 3130f466e7ac84b1eb8dabec821d8cb024029b2a..eb929b1ed4b9d2500b1c07d57f50d68fecf84c41 100644
--- a/go.mod
+++ b/go.mod
@@ -3,9 +3,9 @@
 go 1.18
 
 require (
-	github.com/sagernet/sing v0.0.0-20220726034811-bc109486f14e
+	github.com/sagernet/sing v0.0.0-20220729120910-4376f188c512
 	github.com/vishvananda/netlink v1.1.0
-	golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f
+	golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10
 	gvisor.dev/gvisor v0.0.0-20220711011657-cecae2f4234d
 )
 




diff --git a/go.sum b/go.sum
index 9d3cc31a1288c19c77db13450effaa9e666ff1cf..9767470ea84f8b8af2899e3c992295db795dc5b8 100644
--- a/go.sum
+++ b/go.sum
@@ -1,7 +1,7 @@
 github.com/google/btree v1.0.1 h1:gK4Kx5IaGY9CD5sPJ36FHiBJ6ZXl0kilRiiCj+jdYp4=
 github.com/google/btree v1.0.1/go.mod h1:xXMiIv4Fb/0kKde4SpL7qlzvu5cMJDRkFDxJfI9uaxA=
-github.com/sagernet/sing v0.0.0-20220726034811-bc109486f14e h1:5lfrAc+vSv0iW6eHGNLyHC+a/k6BDGJvYxYxwB/68Kk=
+github.com/sagernet/sing v0.0.0-20220729120910-4376f188c512 h1:dCWDE55LpZu//W02FccNbGObZFlv1N2NS0yUdf2i4Mc=
-github.com/sagernet/sing v0.0.0-20220726034811-bc109486f14e/go.mod h1:GbtQfZSpmtD3cXeD1qX2LCMwY8dH+bnnInDTqd92IsM=
+github.com/sagernet/sing v0.0.0-20220729120910-4376f188c512/go.mod h1:GbtQfZSpmtD3cXeD1qX2LCMwY8dH+bnnInDTqd92IsM=
 github.com/vishvananda/netlink v1.1.0 h1:1iyaYNBLmP6L0220aDnYQpo1QEV4t4hJ+xEEhhJH8j0=
 github.com/vishvananda/netlink v1.1.0/go.mod h1:cTgwzPIzzgDAYoQrMm0EdrjRUBkTqKYppBueQtXaqoE=
 github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df/go.mod h1:JP3t17pCcGlemwknint6hfoeCVQrEMVwxRLRjXpq+BU=
@@ -9,10 +9,9 @@ github.com/vishvananda/netns v0.0.0-20211101163701-50045581ed74 h1:gga7acRE695APm9hlsSMoOoE65U4/TcqNj90mc69Rlg=
 github.com/vishvananda/netns v0.0.0-20211101163701-50045581ed74/go.mod h1:DD4vA1DwXk04H54A1oHXtwZmA0grkVMdPxx/VGLCah0=
 golang.org/x/sys v0.0.0-20190606203320-7fc4e5ec1444/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20200217220822-9197077df867/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-github.com/google/btree v1.0.1 h1:gK4Kx5IaGY9CD5sPJ36FHiBJ6ZXl0kilRiiCj+jdYp4=
 github.com/google/btree v1.0.1/go.mod h1:xXMiIv4Fb/0kKde4SpL7qlzvu5cMJDRkFDxJfI9uaxA=
+github.com/google/btree v1.0.1/go.mod h1:xXMiIv4Fb/0kKde4SpL7qlzvu5cMJDRkFDxJfI9uaxA=
 github.com/google/btree v1.0.1 h1:gK4Kx5IaGY9CD5sPJ36FHiBJ6ZXl0kilRiiCj+jdYp4=
-github.com/sagernet/sing v0.0.0-20220726034811-bc109486f14e h1:5lfrAc+vSv0iW6eHGNLyHC+a/k6BDGJvYxYxwB/68Kk=
 golang.org/x/time v0.0.0-20191024005414-555d28b269f0 h1:/5xXl8Y5W96D+TtHSlonuFqGHIWVuyCkGJLwGh9JJFs=
 golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
 gvisor.dev/gvisor v0.0.0-20220711011657-cecae2f4234d h1:KjI6i6P1ib9DiNdNIN8pb2TXfBewpKHf3O58cjj9vw4=




diff --git a/gvisor.go b/gvisor.go
index a1e4d3964821ad51b91e77e2210da0e2fb365f63..5962a60b6e67db9a0fa4d06711850273679eda61 100644
--- a/gvisor.go
+++ b/gvisor.go
@@ -70,8 +70,8 @@ 		},
 	})
 	tErr := ipStack.CreateNIC(defaultNIC, linkEndpoint)
 	if tErr != nil {
+	"gvisor.dev/gvisor/pkg/tcpip/network/ipv4"
 	"github.com/sagernet/sing/common"
-	"context"
 	}
 	ipStack.SetRouteTable([]tcpip.Route{
 		{Destination: header.IPv4EmptySubnet, NIC: defaultNIC},
@@ -120,7 +120,7 @@ 			var metadata M.Metadata
 			metadata.Source = M.SocksaddrFromNet(lAddr)
 			metadata.Destination = M.SocksaddrFromNet(rAddr)
 package tun
-
+	handler Handler,
 			if hErr != nil {
 				endpoint.Abort()
 			}
@@ -146,7 +146,7 @@ 				var metadata M.Metadata
 				metadata.Source = M.SocksaddrFromNet(lAddr)
 				metadata.Destination = M.SocksaddrFromNet(rAddr)
 package tun
-type GVisorTun struct {
+) *GVisorTun {
 				if hErr != nil {
 					endpoint.Abort()
 				}




diff --git a/gvisor_err.go b/gvisor_err.go
new file mode 100644
index 0000000000000000000000000000000000000000..99b7a3e13591a4300c49657a70417092da31db26
--- /dev/null
+++ b/gvisor_err.go
@@ -0,0 +1,69 @@
+package tun
+
+import (
+	"net"
+
+	"gvisor.dev/gvisor/pkg/tcpip"
+	"gvisor.dev/gvisor/pkg/tcpip/adapters/gonet"
+)
+
+type gTCPConn struct {
+	*gonet.TCPConn
+}
+
+func (c *gTCPConn) Upstream() any {
+	return c.TCPConn
+}
+
+func (c *gTCPConn) Write(b []byte) (n int, err error) {
+	n, err = c.TCPConn.Write(b)
+	if err == nil {
+		return
+	}
+	err = wrapError(err)
+	return
+}
+
+type gUDPConn struct {
+	*gonet.UDPConn
+}
+
+func (c *gUDPConn) Read(b []byte) (n int, err error) {
+	n, err = c.UDPConn.Read(b)
+	if err == nil {
+		return
+	}
+	err = wrapError(err)
+	return
+}
+
+func (c *gUDPConn) Write(b []byte) (n int, err error) {
+	n, err = c.UDPConn.Write(b)
+	if err == nil {
+		return
+	}
+	err = wrapError(err)
+	return
+}
+
+func wrapStackError(err tcpip.Error) error {
+	switch err.(type) {
+	case *tcpip.ErrClosedForSend:
+		return net.ErrClosed
+	case *tcpip.ErrClosedForReceive:
+		return net.ErrClosed
+	}
+	return wrapStackError(err)
+}
+
+func wrapError(err error) error {
+	if opErr, isOpErr := err.(*net.OpError); isOpErr {
+		switch opErr.Err.Error() {
+		case "endpoint is closed for send":
+			return net.ErrClosed
+		case "endpoint is closed for receive":
+			return net.ErrClosed
+		}
+	}
+	return err
+}




diff --git a/gvisor_udp.go b/gvisor_udp.go
index ddfd11a86ee8d85e7a450d1bd397f9e547526dae..0d1ea848084a126290ac0df23ec12300a46270c5 100644
--- a/gvisor_udp.go
+++ b/gvisor_udp.go
@@ -7,7 +7,6 @@ 	"net"
 	"net/netip"
 
 	"github.com/sagernet/sing/common/buf"
-	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/udpnat"
@@ -75,7 +74,7 @@ 		netProto,
 		false,
 	)
 	if err != nil {
-		return E.New(err)
+		return wrapStackError(err)
 	}
 	defer route.Release()
 
@@ -113,7 +112,7 @@ 	}, packet)
 
 	if err != nil {
 		route.Stats().UDP.PacketSendErrors.Increment()
-		return E.New(err)
+		return wrapStackError(err)
 	}
 
 	route.Stats().UDP.PacketsSent.Increment()