1
0
世界 3 жил өмнө
parent
commit
c4f4fd97d6
7 өөрчлөгдсөн 77 нэмэгдсэн , 34 устгасан
  1. 2 1
      Makefile
  2. 3 0
      inbound/hysteria.go
  3. 63 24
      inbound/naive.go
  4. 1 1
      test/box_test.go
  5. 2 2
      test/go.mod
  6. 4 4
      test/go.sum
  7. 2 2
      test/vmess_test.go

+ 2 - 1
Makefile

@@ -47,7 +47,8 @@ snapshot_install:
 test:
 	@go test -v . && \
 	pushd test && \
-	go test -v . && \
+	go mod tidy && \
+	go test -v -tags '$(TAGS)' . && \
 	popd
 
 clean:

+ 3 - 0
inbound/hysteria.go

@@ -37,6 +37,7 @@ type Hysteria struct {
 	xplusKey      []byte
 	sendBPS       uint64
 	recvBPS       uint64
+	udpListener   net.PacketConn
 	listener      quic.Listener
 	udpAccess     sync.RWMutex
 	udpSessionId  uint32
@@ -146,6 +147,7 @@ func (h *Hysteria) Start() error {
 		packetConn = hysteria.NewXPlusPacketConn(packetConn, h.xplusKey)
 		packetConn = &hysteria.PacketConnWrapper{PacketConn: packetConn}
 	}
+	h.udpListener = packetConn
 	err = h.tlsConfig.Start()
 	if err != nil {
 		return err
@@ -314,6 +316,7 @@ func (h *Hysteria) Close() error {
 	h.udpSessions = make(map[uint32]chan *hysteria.UDPMessage)
 	h.udpAccess.Unlock()
 	return common.Close(
+		h.udpListener,
 		h.listener,
 		common.PtrOrNil(h.tlsConfig),
 	)

+ 63 - 24
inbound/naive.go

@@ -10,7 +10,6 @@ import (
 	"net/http"
 	"net/netip"
 	"os"
-	"runtime"
 	"strings"
 	"time"
 
@@ -250,8 +249,7 @@ type naivePaddingConn struct {
 
 func (c *naivePaddingConn) Read(p []byte) (n int, err error) {
 	n, err = c.read(p)
-	err = wrapHttpError(err)
-	return
+	return n, wrapHttpError(err)
 }
 
 func (c *naivePaddingConn) read(p []byte) (n int, err error) {
@@ -259,7 +257,7 @@ func (c *naivePaddingConn) read(p []byte) (n int, err error) {
 		if len(p) > c.readRemaining {
 			p = p[:c.readRemaining]
 		}
-		n, err = c.read(p)
+		n, err = c.reader.Read(p)
 		if err != nil {
 			return
 		}
@@ -297,35 +295,69 @@ func (c *naivePaddingConn) read(p []byte) (n int, err error) {
 }
 
 func (c *naivePaddingConn) Write(p []byte) (n int, err error) {
-	n, err = c.write(p)
+	for pLen := len(p); pLen > 0; {
+		var data []byte
+		if pLen > 65535 {
+			data = p[:65535]
+			p = p[65535:]
+			pLen -= 65535
+		} else {
+			data = p
+			pLen = 0
+		}
+		var writeN int
+		writeN, err = c.write(data)
+		n += writeN
+		if err != nil {
+			break
+		}
+	}
 	if err == nil {
 		c.flusher.Flush()
 	}
-	err = wrapHttpError(err)
-	return
+	return n, wrapHttpError(err)
 }
 
 func (c *naivePaddingConn) write(p []byte) (n int, err error) {
 	if c.writePadding < kFirstPaddings {
 		paddingSize := rand.Intn(256)
-		_buffer := buf.Make(3 + len(p) + paddingSize)
-		defer runtime.KeepAlive(_buffer)
+
+		_buffer := buf.StackNewSize(3 + len(p) + paddingSize)
+		defer common.KeepAlive(_buffer)
 		buffer := common.Dup(_buffer)
-		binary.BigEndian.PutUint16(buffer, uint16(len(p)))
-		buffer[2] = byte(paddingSize)
-		copy(buffer[3:], p)
-		_, err = c.writer.Write(buffer)
-		if err != nil {
-			return
+		defer buffer.Release()
+		header := buffer.Extend(3)
+		binary.BigEndian.PutUint16(header, uint16(len(p)))
+		header[2] = byte(paddingSize)
+
+		common.Must1(buffer.Write(p))
+		_, err = c.writer.Write(buffer.Bytes())
+		if err == nil {
+			n = len(p)
 		}
 		c.writePadding++
+		return
 	}
 	return c.writer.Write(p)
 }
 
 func (c *naivePaddingConn) FrontHeadroom() int {
 	if c.writePadding < kFirstPaddings {
-		return 3 + 255
+		return 3
+	}
+	return 0
+}
+
+func (c *naivePaddingConn) RearHeadroom() int {
+	if c.writePadding < kFirstPaddings {
+		return 255
+	}
+	return 0
+}
+
+func (c *naivePaddingConn) WriterMTU() int {
+	if c.writePadding < kFirstPaddings {
+		return 65535
 	}
 	return 0
 }
@@ -334,6 +366,9 @@ func (c *naivePaddingConn) WriteBuffer(buffer *buf.Buffer) error {
 	defer buffer.Release()
 	if c.writePadding < kFirstPaddings {
 		bufferLen := buffer.Len()
+		if bufferLen > 65535 {
+			return common.Error(c.Write(buffer.Bytes()))
+		}
 		paddingSize := rand.Intn(256)
 		header := buffer.ExtendHeader(3)
 		binary.BigEndian.PutUint16(header, uint16(bufferLen))
@@ -350,16 +385,20 @@ func (c *naivePaddingConn) WriteBuffer(buffer *buf.Buffer) error {
 
 func (c *naivePaddingConn) WriteTo(w io.Writer) (n int64, err error) {
 	if c.readPadding < kFirstPaddings {
-		return bufio.WriteToN(c, w, kFirstPaddings-c.readPadding)
+		n, err = bufio.WriteToN(c, w, kFirstPaddings-c.readPadding)
+	} else {
+		n, err = bufio.Copy(w, c.reader)
 	}
-	return bufio.Copy(w, c.reader)
+	return n, wrapHttpError(err)
 }
 
 func (c *naivePaddingConn) ReadFrom(r io.Reader) (n int64, err error) {
 	if c.writePadding < kFirstPaddings {
-		return bufio.ReadFromN(c, r, kFirstPaddings-c.writePadding)
+		n, err = bufio.ReadFromN(c, r, kFirstPaddings-c.writePadding)
+	} else {
+		n, err = bufio.Copy(c.writer, r)
 	}
-	return bufio.Copy(c.writer, r)
+	return n, wrapHttpError(err)
 }
 
 func (c *naivePaddingConn) Close() error {
@@ -389,14 +428,14 @@ func (c *naivePaddingConn) SetWriteDeadline(t time.Time) error {
 	return os.ErrInvalid
 }
 
-var http2errClientDisconnected = "client disconnected"
-
 func wrapHttpError(err error) error {
 	if err == nil {
 		return err
 	}
-	switch err.Error() {
-	case http2errClientDisconnected:
+	if strings.Contains(err.Error(), "client disconnected") {
+		return net.ErrClosed
+	}
+	if strings.Contains(err.Error(), "body closed by handler") {
 		return net.ErrClosed
 	}
 	return err

+ 1 - 1
test/box_test.go

@@ -56,7 +56,7 @@ func testTCP(t *testing.T, clientPort uint16, testPort uint16) {
 	dialTCP := func() (net.Conn, error) {
 		return dialer.DialContext(context.Background(), "tcp", M.ParseSocksaddrHostPort("127.0.0.1", testPort))
 	}
-	require.NoError(t, testLargeDataWithConn(t, testPort, dialTCP))
+	require.NoError(t, testPingPongWithConn(t, testPort, dialTCP))
 }
 
 func testSuitHy(t *testing.T, clientPort uint16, testPort uint16) {

+ 2 - 2
test/go.mod

@@ -10,7 +10,7 @@ require (
 	github.com/docker/docker v20.10.17+incompatible
 	github.com/docker/go-connections v0.4.0
 	github.com/gofrs/uuid v4.2.0+incompatible
-	github.com/sagernet/sing v0.0.0-20220821143531-cee85dcd3013
+	github.com/sagernet/sing v0.0.0-20220822031040-57fe2e623c82
 	github.com/sagernet/sing-shadowsocks v0.0.0-20220819002358-7461bb09a8f6
 	github.com/spyzhov/ajson v0.7.1
 	github.com/stretchr/testify v1.8.0
@@ -57,7 +57,7 @@ require (
 	github.com/sagernet/go-tun2socks v1.16.12-0.20220818015926-16cb67876a61 // indirect
 	github.com/sagernet/netlink v0.0.0-20220820041223-3cd8365d17ac // indirect
 	github.com/sagernet/quic-go v0.0.0-20220818150011-de611ab3e2bb // indirect
-	github.com/sagernet/sing-dns v0.0.0-20220819010310-839eab1578c9 // indirect
+	github.com/sagernet/sing-dns v0.0.0-20220822023312-3e086b06d666 // indirect
 	github.com/sagernet/sing-tun v0.0.0-20220821033717-8b6630a3b006 // indirect
 	github.com/sagernet/sing-vmess v0.0.0-20220811135656-4f3f07acf9c4 // indirect
 	github.com/sagernet/smux v0.0.0-20220812084127-e2d085ee3939 // indirect

+ 4 - 4
test/go.sum

@@ -123,10 +123,10 @@ 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/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-20220821143531-cee85dcd3013 h1:i5jP3rs+3IFj0OWB22YB3wSJJAoZiBd3YeBk9/vbDHI=
-github.com/sagernet/sing v0.0.0-20220821143531-cee85dcd3013/go.mod h1:kZvzh1VDa/Dg/Bt5WaYKU0jl5ept8KKDpl3Ay4gRtRQ=
-github.com/sagernet/sing-dns v0.0.0-20220819010310-839eab1578c9 h1:XgXSOJv8e7+98SJvg1f0luuPR33r4yFcmzxb3R//BTI=
-github.com/sagernet/sing-dns v0.0.0-20220819010310-839eab1578c9/go.mod h1:MAHy2IKZAA101t3Gr2x0ldwn6XuAs2cjGzSzHy5RhWk=
+github.com/sagernet/sing v0.0.0-20220822031040-57fe2e623c82 h1:DUHIA4lKxDqYNQyzb7NjZp+//voV25Ue7QoDjUvhgio=
+github.com/sagernet/sing v0.0.0-20220822031040-57fe2e623c82/go.mod h1:kZvzh1VDa/Dg/Bt5WaYKU0jl5ept8KKDpl3Ay4gRtRQ=
+github.com/sagernet/sing-dns v0.0.0-20220822023312-3e086b06d666 h1:XUTocA/Ek0dFxUX+xJCWMPPFZCn2GC/uLrBjTSr1vHY=
+github.com/sagernet/sing-dns v0.0.0-20220822023312-3e086b06d666/go.mod h1:eDyH7AJmqBGjZQdQmpZIzlbTREudZuWDExMuGKgjRVM=
 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-tun v0.0.0-20220821033717-8b6630a3b006 h1:c1UyJ5H4CNLsg4GsAnNNoDAnHzLB13pm/T4zzvaWcFo=

+ 2 - 2
test/vmess_test.go

@@ -13,7 +13,7 @@ import (
 	"github.com/stretchr/testify/require"
 )
 
-func _TestVMessAuto(t *testing.T) {
+func TestVMessAuto(t *testing.T) {
 	security := "auto"
 	user, err := uuid.DefaultGenerator.NewV4()
 	require.NoError(t, err)
@@ -28,7 +28,7 @@ func _TestVMessAuto(t *testing.T) {
 	})
 }
 
-func TestVMess(t *testing.T) {
+func _TestVMess(t *testing.T) {
 	for _, security := range []string{
 		"zero",
 	} {