diff --git a/common/mux/client.go b/common/mux/client.go index 5bf29727..3e83ccb0 100644 --- a/common/mux/client.go +++ b/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 } diff --git a/common/mux/protocol.go b/common/mux/protocol.go index ad99cd6b..706512a2 100644 --- a/common/mux/protocol.go +++ b/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 } diff --git a/common/mux/session.go b/common/mux/session.go index afae7723..04d1426e 100644 --- a/common/mux/session.go +++ b/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...)) +} diff --git a/go.mod b/go.mod index 4be98bba..a257ce95 100644 --- a/go.mod +++ b/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 diff --git a/go.sum b/go.sum index 0d24e3db..1058dad6 100644 --- a/go.sum +++ b/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= diff --git a/test/go.mod b/test/go.mod index e8fcb948..5940f338 100644 --- a/test/go.mod +++ b/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 diff --git a/test/go.sum b/test/go.sum index 9b6cf1fb..3daa2efb 100644 --- a/test/go.sum +++ b/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=