Browse Source

Improve smux write

世界 3 years ago
parent
commit
51bbf93ff2
7 changed files with 49 additions and 50 deletions
  1. 6 1
      common/mux/client.go
  2. 2 27
      common/mux/protocol.go
  3. 21 0
      common/mux/session.go
  4. 3 3
      go.mod
  5. 7 8
      go.sum
  6. 3 3
      test/go.mod
  7. 7 8
      test/go.sum

+ 6 - 1
common/mux/client.go

@@ -146,7 +146,12 @@ func (c *Client) offerNew() (abstractSession, error) {
 	if err != nil {
 		return nil, err
 	}
-	session, err := c.protocol.newClient(&protocolConn{Conn: conn, protocol: c.protocol})
+	if vectorisedWriter, isVectorised := bufio.CreateVectorisedWriter(conn); isVectorised {
+		conn = &vectorisedProtocolConn{protocolConn{Conn: conn, protocol: c.protocol}, vectorisedWriter}
+	} else {
+		conn = &protocolConn{Conn: conn, protocol: c.protocol}
+	}
+	session, err := c.protocol.newClient(conn)
 	if err != nil {
 		return nil, err
 	}

+ 2 - 27
common/mux/protocol.go

@@ -43,7 +43,7 @@ func ParseProtocol(name string) (Protocol, error) {
 func (p Protocol) newServer(conn net.Conn) (abstractSession, error) {
 	switch p {
 	case ProtocolSMux:
-		session, err := smux.Server(wrapSMuxConn(conn), nil)
+		session, err := smux.Server(conn, nil)
 		if err != nil {
 			return nil, err
 		}
@@ -58,7 +58,7 @@ func (p Protocol) newServer(conn net.Conn) (abstractSession, error) {
 func (p Protocol) newClient(conn net.Conn) (abstractSession, error) {
 	switch p {
 	case ProtocolSMux:
-		session, err := smux.Client(wrapSMuxConn(conn), nil)
+		session, err := smux.Client(conn, nil)
 		if err != nil {
 			return nil, err
 		}
@@ -201,31 +201,6 @@ func ReadStreamResponse(reader io.Reader) (*StreamResponse, error) {
 	return &response, nil
 }
 
-type smuxTCPConn struct {
-	*net.TCPConn
-}
-
-func wrapSMuxConn(originConn net.Conn) net.Conn {
-	switch conn := originConn.(type) {
-	case *net.TCPConn:
-		return &smuxTCPConn{conn}
-	}
-	return originConn
-}
-
-func (w *smuxTCPConn) WriteBuffers(v [][]byte) (n int, err error) {
-	buffers := net.Buffers(v)
-	writeN, err := buffers.WriteTo(w.TCPConn)
-	if err != nil {
-		return
-	}
-	return int(writeN), nil
-}
-
-func (w *smuxTCPConn) Upstream() any {
-	return w.TCPConn
-}
-
 type wrapStream struct {
 	net.Conn
 }

+ 21 - 0
common/mux/session.go

@@ -7,6 +7,7 @@ import (
 	"github.com/sagernet/sing/common"
 	"github.com/sagernet/sing/common/buf"
 	"github.com/sagernet/sing/common/bufio"
+	N "github.com/sagernet/sing/common/network"
 	"github.com/sagernet/smux"
 )
 
@@ -68,3 +69,23 @@ func (c *protocolConn) ReadFrom(r io.Reader) (n int64, err error) {
 func (c *protocolConn) Upstream() any {
 	return c.Conn
 }
+
+type vectorisedProtocolConn struct {
+	protocolConn
+	N.VectorisedWriter
+}
+
+func (c *vectorisedProtocolConn) WriteVectorised(buffers []*buf.Buffer) error {
+	if c.protocolWritten {
+		return c.VectorisedWriter.WriteVectorised(buffers)
+	}
+	c.protocolWritten = true
+	_buffer := buf.StackNewSize(2)
+	defer common.KeepAlive(_buffer)
+	buffer := common.Dup(_buffer)
+	defer buffer.Release()
+	EncodeRequest(buffer, Request{
+		Protocol: c.protocol,
+	})
+	return c.VectorisedWriter.WriteVectorised(append([]*buf.Buffer{buffer}, buffers...))
+}

+ 3 - 3
go.mod

@@ -15,12 +15,12 @@ require (
 	github.com/logrusorgru/aurora v2.0.3+incompatible
 	github.com/lucas-clemente/quic-go v0.28.1
 	github.com/oschwald/maxminddb-golang v1.10.0
-	github.com/sagernet/sing v0.0.0-20220812041020-13f394e2021c
+	github.com/sagernet/sing v0.0.0-20220812082120-05f9836bff8f
 	github.com/sagernet/sing-dns v0.0.0-20220803121532-9e1ffb850d91
-	github.com/sagernet/sing-shadowsocks v0.0.0-20220811135826-7e47fd1a99d9
+	github.com/sagernet/sing-shadowsocks v0.0.0-20220812082714-484a11603b48
 	github.com/sagernet/sing-tun v0.0.0-20220808133432-d378b6ca536d
 	github.com/sagernet/sing-vmess v0.0.0-20220811135656-4f3f07acf9c4
-	github.com/sagernet/smux v0.0.0-20220812032842-6d45eecb473e
+	github.com/sagernet/smux v0.0.0-20220812084127-e2d085ee3939
 	github.com/spf13/cobra v1.5.0
 	github.com/stretchr/testify v1.8.0
 	go.uber.org/atomic v1.10.0

+ 7 - 8
go.sum

@@ -152,19 +152,18 @@ github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR
 github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
 github.com/sagernet/netlink v0.0.0-20220803045538-bdac49abf805 h1:hE+vtsjBCCPmxkRz9jZA+CicHgVkDT6H+Av5ZzskVxs=
 github.com/sagernet/netlink v0.0.0-20220803045538-bdac49abf805/go.mod h1:xLnfdiJbSp8rNqYEdIW/6eDO4mVoogml14Bh2hSiFpM=
-github.com/sagernet/sing v0.0.0-20220801112236-1bb95f9661fc/go.mod h1:GbtQfZSpmtD3cXeD1qX2LCMwY8dH+bnnInDTqd92IsM=
-github.com/sagernet/sing v0.0.0-20220812041020-13f394e2021c h1:/HDyukJrLGbr/eXyhpzPv2FGnXJeNj/bvQ/3GSYJhTo=
-github.com/sagernet/sing v0.0.0-20220812041020-13f394e2021c/go.mod h1:QVsS5L/ZA2Q5UhQwLrn0Trw+msNd/NPGEhBKR/ioWiY=
+github.com/sagernet/sing v0.0.0-20220812082120-05f9836bff8f h1:ekLjKIYjtkZNRN1c1IoNcpAsVZNKtO+Qe5cuHOwX0EI=
+github.com/sagernet/sing v0.0.0-20220812082120-05f9836bff8f/go.mod h1:QVsS5L/ZA2Q5UhQwLrn0Trw+msNd/NPGEhBKR/ioWiY=
 github.com/sagernet/sing-dns v0.0.0-20220803121532-9e1ffb850d91 h1:jxt2PYixIkK2i7nUGW3f+PzJagEZcbNyQddBWGuqNnw=
 github.com/sagernet/sing-dns v0.0.0-20220803121532-9e1ffb850d91/go.mod h1:T77zZdE2Cm6VqnFumrpwsq+kxYsbq+vWDhmjtdSl/oM=
-github.com/sagernet/sing-shadowsocks v0.0.0-20220811135826-7e47fd1a99d9 h1:/FFNyglfOlk1x6NWhBWI+bc/kVQc7SFOSYAJ2m7FwHc=
-github.com/sagernet/sing-shadowsocks v0.0.0-20220811135826-7e47fd1a99d9/go.mod h1:3Pe1OCs1zrMyZmMB4st8GF/IL6EMHLSVnUHSS5VjnfM=
+github.com/sagernet/sing-shadowsocks v0.0.0-20220812082714-484a11603b48 h1:NlcTFKldteZvYBDyr+V9MjZEI0rAWCSFCyLgPvc5n/Y=
+github.com/sagernet/sing-shadowsocks v0.0.0-20220812082714-484a11603b48/go.mod h1:EX3RbZvrwAkPI2nuGa78T2iQXmrkT+/VQtskjou42xM=
 github.com/sagernet/sing-tun v0.0.0-20220808133432-d378b6ca536d h1:AQpkoUiF8FxYVI1lf2W9Rbkk914eHjVH9M8y+F/0+Nw=
 github.com/sagernet/sing-tun v0.0.0-20220808133432-d378b6ca536d/go.mod h1:gWwYd53AqXl+Y+q6WlXUc6PkqU28sfu5VTQhyeEIFbw=
 github.com/sagernet/sing-vmess v0.0.0-20220811135656-4f3f07acf9c4 h1:2hLETh97+S4WnfMR27XyC7QVU1SH7FTNoCznP229YJU=
 github.com/sagernet/sing-vmess v0.0.0-20220811135656-4f3f07acf9c4/go.mod h1:82O6gzbxLha/W/jxSVQbsqf2lVdRTjMIgyLug0lpJps=
-github.com/sagernet/smux v0.0.0-20220812032842-6d45eecb473e h1:x+COm0plODjqCs8ypUbI8IJ6kclhNirmCsaVbnBXDoA=
-github.com/sagernet/smux v0.0.0-20220812032842-6d45eecb473e/go.mod h1:WFWe+7nAIPcVfJTonJwe8dRIX7JAV2Hc0/p5+X55nM4=
+github.com/sagernet/smux v0.0.0-20220812084127-e2d085ee3939 h1:pB1Dh1NbwVrLhQhotr4O4Hs3yhiBzmg3AvnUyYjL4x4=
+github.com/sagernet/smux v0.0.0-20220812084127-e2d085ee3939/go.mod h1:yedWtra8nyGJ+SyI+ziwuaGMzBatbB10P1IOOZbbSK8=
 github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
 github.com/shurcooL/component v0.0.0-20170202220835-f88ec8f54cc4/go.mod h1:XhFIlyj5a1fBNx5aJTbKoIq0mNaPvOagO+HjB3EtxrY=
 github.com/shurcooL/events v0.0.0-20181021180414-410e4ca65f48/go.mod h1:5u70Mqkb5O5cxEA8nxTsgrgLehJeAw6Oc4Ab1c/P1HM=
@@ -285,7 +284,7 @@ golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBc
 golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220731174439-a90be440212d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab h1:2QkjZIsXupsJbJIdSjjUOgWK3aEtzyuh2mPt3l/CkeU=
 golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=

+ 3 - 3
test/go.mod

@@ -10,8 +10,8 @@ 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-20220812041020-13f394e2021c
-	github.com/sagernet/sing-shadowsocks v0.0.0-20220811135826-7e47fd1a99d9
+	github.com/sagernet/sing v0.0.0-20220812082120-05f9836bff8f
+	github.com/sagernet/sing-shadowsocks v0.0.0-20220812082714-484a11603b48
 	github.com/spyzhov/ajson v0.7.1
 	github.com/stretchr/testify v1.8.0
 	golang.org/x/net v0.0.0-20220811182439-13a9a731de15
@@ -56,7 +56,7 @@ require (
 	github.com/sagernet/sing-dns v0.0.0-20220803121532-9e1ffb850d91 // indirect
 	github.com/sagernet/sing-tun v0.0.0-20220808133432-d378b6ca536d // indirect
 	github.com/sagernet/sing-vmess v0.0.0-20220811135656-4f3f07acf9c4 // indirect
-	github.com/sagernet/smux v0.0.0-20220812032842-6d45eecb473e // indirect
+	github.com/sagernet/smux v0.0.0-20220812084127-e2d085ee3939 // indirect
 	github.com/sirupsen/logrus v1.8.1 // indirect
 	github.com/vishvananda/netns v0.0.0-20211101163701-50045581ed74 // indirect
 	go.uber.org/atomic v1.10.0 // indirect

+ 7 - 8
test/go.sum

@@ -174,19 +174,18 @@ github.com/prometheus/procfs v0.0.0-20180725123919-05ee40e3a273/go.mod h1:c3At6R
 github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
 github.com/sagernet/netlink v0.0.0-20220803045538-bdac49abf805 h1:hE+vtsjBCCPmxkRz9jZA+CicHgVkDT6H+Av5ZzskVxs=
 github.com/sagernet/netlink v0.0.0-20220803045538-bdac49abf805/go.mod h1:xLnfdiJbSp8rNqYEdIW/6eDO4mVoogml14Bh2hSiFpM=
-github.com/sagernet/sing v0.0.0-20220801112236-1bb95f9661fc/go.mod h1:GbtQfZSpmtD3cXeD1qX2LCMwY8dH+bnnInDTqd92IsM=
-github.com/sagernet/sing v0.0.0-20220812041020-13f394e2021c h1:/HDyukJrLGbr/eXyhpzPv2FGnXJeNj/bvQ/3GSYJhTo=
-github.com/sagernet/sing v0.0.0-20220812041020-13f394e2021c/go.mod h1:QVsS5L/ZA2Q5UhQwLrn0Trw+msNd/NPGEhBKR/ioWiY=
+github.com/sagernet/sing v0.0.0-20220812082120-05f9836bff8f h1:ekLjKIYjtkZNRN1c1IoNcpAsVZNKtO+Qe5cuHOwX0EI=
+github.com/sagernet/sing v0.0.0-20220812082120-05f9836bff8f/go.mod h1:QVsS5L/ZA2Q5UhQwLrn0Trw+msNd/NPGEhBKR/ioWiY=
 github.com/sagernet/sing-dns v0.0.0-20220803121532-9e1ffb850d91 h1:jxt2PYixIkK2i7nUGW3f+PzJagEZcbNyQddBWGuqNnw=
 github.com/sagernet/sing-dns v0.0.0-20220803121532-9e1ffb850d91/go.mod h1:T77zZdE2Cm6VqnFumrpwsq+kxYsbq+vWDhmjtdSl/oM=
-github.com/sagernet/sing-shadowsocks v0.0.0-20220811135826-7e47fd1a99d9 h1:/FFNyglfOlk1x6NWhBWI+bc/kVQc7SFOSYAJ2m7FwHc=
-github.com/sagernet/sing-shadowsocks v0.0.0-20220811135826-7e47fd1a99d9/go.mod h1:3Pe1OCs1zrMyZmMB4st8GF/IL6EMHLSVnUHSS5VjnfM=
+github.com/sagernet/sing-shadowsocks v0.0.0-20220812082714-484a11603b48 h1:NlcTFKldteZvYBDyr+V9MjZEI0rAWCSFCyLgPvc5n/Y=
+github.com/sagernet/sing-shadowsocks v0.0.0-20220812082714-484a11603b48/go.mod h1:EX3RbZvrwAkPI2nuGa78T2iQXmrkT+/VQtskjou42xM=
 github.com/sagernet/sing-tun v0.0.0-20220808133432-d378b6ca536d h1:AQpkoUiF8FxYVI1lf2W9Rbkk914eHjVH9M8y+F/0+Nw=
 github.com/sagernet/sing-tun v0.0.0-20220808133432-d378b6ca536d/go.mod h1:gWwYd53AqXl+Y+q6WlXUc6PkqU28sfu5VTQhyeEIFbw=
 github.com/sagernet/sing-vmess v0.0.0-20220811135656-4f3f07acf9c4 h1:2hLETh97+S4WnfMR27XyC7QVU1SH7FTNoCznP229YJU=
 github.com/sagernet/sing-vmess v0.0.0-20220811135656-4f3f07acf9c4/go.mod h1:82O6gzbxLha/W/jxSVQbsqf2lVdRTjMIgyLug0lpJps=
-github.com/sagernet/smux v0.0.0-20220812032842-6d45eecb473e h1:x+COm0plODjqCs8ypUbI8IJ6kclhNirmCsaVbnBXDoA=
-github.com/sagernet/smux v0.0.0-20220812032842-6d45eecb473e/go.mod h1:WFWe+7nAIPcVfJTonJwe8dRIX7JAV2Hc0/p5+X55nM4=
+github.com/sagernet/smux v0.0.0-20220812084127-e2d085ee3939 h1:pB1Dh1NbwVrLhQhotr4O4Hs3yhiBzmg3AvnUyYjL4x4=
+github.com/sagernet/smux v0.0.0-20220812084127-e2d085ee3939/go.mod h1:yedWtra8nyGJ+SyI+ziwuaGMzBatbB10P1IOOZbbSK8=
 github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
 github.com/shurcooL/component v0.0.0-20170202220835-f88ec8f54cc4/go.mod h1:XhFIlyj5a1fBNx5aJTbKoIq0mNaPvOagO+HjB3EtxrY=
 github.com/shurcooL/events v0.0.0-20181021180414-410e4ca65f48/go.mod h1:5u70Mqkb5O5cxEA8nxTsgrgLehJeAw6Oc4Ab1c/P1HM=
@@ -316,7 +315,7 @@ golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBc
 golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220731174439-a90be440212d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab h1:2QkjZIsXupsJbJIdSjjUOgWK3aEtzyuh2mPt3l/CkeU=
 golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=