Add buffered conn

This commit is contained in:
世界 2022-05-01 09:33:31 +08:00
parent 118c423774
commit 9df018b07f
No known key found for this signature in database
GPG key ID: CD109927C34A63C4
3 changed files with 121 additions and 8 deletions

View file

@ -2,11 +2,126 @@ package rw
import (
"io"
"net"
"time"
"github.com/sagernet/sing/common"
"github.com/sagernet/sing/common/buf"
)
type CachedReader interface {
common.ReaderWithUpstream
ReadCached() *buf.Buffer
}
type BufferedConn struct {
net.Conn
Buffer *buf.Buffer
}
func (c *BufferedConn) ReadCached() *buf.Buffer {
buffer := c.Buffer
c.Buffer = nil
return buffer
}
func (c *BufferedConn) Read(p []byte) (n int, err error) {
if c.Buffer != nil {
n, err = c.Buffer.Read(p)
if err == nil {
return
}
c.Buffer.Release()
c.Buffer = nil
}
return c.Conn.Read(p)
}
func (c *BufferedConn) WriteTo(w io.Writer) (n int64, err error) {
if c.Buffer != nil {
wn, wErr := w.Write(c.Buffer.Bytes())
if wErr != nil {
c.Buffer.Release()
c.Buffer = nil
}
n += int64(wn)
}
cn, err := Copy(w, c.Conn)
n += cn
return
}
func (c *BufferedConn) SetReadDeadline(t time.Time) error {
if c.Buffer != nil && !c.Buffer.IsEmpty() {
return nil
}
return c.Conn.SetReadDeadline(t)
}
func (c *BufferedConn) ReadFrom(r io.Reader) (n int64, err error) {
return Copy(c.Conn, r)
}
func (c *BufferedConn) UpstreamReader() io.Reader {
return c.Conn
}
func (c *BufferedConn) ReaderReplaceable() bool {
return c.Buffer == nil
}
func (c *BufferedConn) UpstreamWriter() io.Writer {
return c.Conn
}
func (c *BufferedConn) WriterReplaceable() bool {
return true
}
type BufferedReader struct {
Reader io.Reader
Buffer *buf.Buffer
}
func (c *BufferedReader) ReadCached() *buf.Buffer {
buffer := c.Buffer
c.Buffer = nil
return buffer
}
func (r *BufferedReader) Read(p []byte) (n int, err error) {
if r.Buffer != nil {
n, err = r.Buffer.Read(p)
if err == nil {
return
}
r.Buffer.Release()
r.Buffer = nil
}
return r.Reader.Read(p)
}
func (r *BufferedReader) WriteTo(w io.Writer) (n int64, err error) {
if r.Buffer != nil {
wn, wErr := w.Write(r.Buffer.Bytes())
if wErr != nil {
return 0, wErr
}
n += int64(wn)
}
cn, err := Copy(w, r.Reader)
n += cn
return
}
func (w *BufferedReader) UpstreamReader() io.Reader {
return w.Reader
}
func (w *BufferedReader) ReaderReplaceable() bool {
return w.Buffer == nil
}
type BufferedWriter struct {
Writer io.Writer
Buffer *buf.Buffer

5
go.mod
View file

@ -3,7 +3,7 @@ module github.com/sagernet/sing
go 1.18
require (
github.com/cloudflare/cloudflare-go v0.38.0
github.com/cloudflare/cloudflare-go v0.30.0
github.com/go-acme/lego/v4 v4.6.0
github.com/go-resty/resty/v2 v2.7.0
github.com/openacid/low v0.1.21
@ -19,7 +19,7 @@ require (
github.com/vishvananda/netlink v1.1.0
golang.org/x/crypto v0.0.0-20220427172511-eb4f295cb31f
golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4
golang.org/x/sys v0.0.0-20220422013727-9388b58f7150
golang.org/x/sys v0.0.0-20220429233432-b5fbb4746d32
golang.zx2c4.com/wireguard v0.0.0-20220407013110-ef5c587f782d
google.golang.org/protobuf v1.28.0
lukechampine.com/blake3 v1.1.7
@ -30,7 +30,6 @@ require (
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/dgryski/go-metro v0.0.0-20211217172704-adc40b04c140 // indirect
github.com/golang/protobuf v1.5.2 // indirect
github.com/google/go-querystring v1.1.0 // indirect
github.com/inconshreveable/mousetrap v1.0.0 // indirect
github.com/klauspost/cpuid/v2 v2.0.12 // indirect
github.com/kr/text v0.2.0 // indirect

9
go.sum
View file

@ -67,8 +67,8 @@ github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5P
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/cloudflare/cloudflare-go v0.20.0/go.mod h1:sPWL/lIC6biLEdyGZwBQ1rGQKF1FhM7N60fuNiFdYTI=
github.com/cloudflare/cloudflare-go v0.38.0 h1:Qf/oVlDmQgb4RfCxqkR0hJoEUQKHvDE4A09MHWssa/w=
github.com/cloudflare/cloudflare-go v0.38.0/go.mod h1:tWDVF03nA9VS9TvFRTrOeY78uSFQzS+n429EcBZszzg=
github.com/cloudflare/cloudflare-go v0.30.0 h1:ho2ObQ1iZfjMqP9RcovvT1Jwp/ZW4Ji5baWVwl2T//A=
github.com/cloudflare/cloudflare-go v0.30.0/go.mod h1:B55yGpU9NdzhWPYu0CDq8smftKrqB/PSDQAdIBEKApw=
github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
@ -162,7 +162,6 @@ github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ=
github.com/google/go-github/v32 v32.1.0/go.mod h1:rIEpZD9CTDQwDK9GDrtMTycQNA4JU3qBsCizh3q2WCI=
github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8=
github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
@ -606,8 +605,8 @@ golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220422013727-9388b58f7150 h1:xHms4gcpe1YE7A3yIllJXP16CMAGuqwO2lX1mTyyRRc=
golang.org/x/sys v0.0.0-20220422013727-9388b58f7150/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220429233432-b5fbb4746d32 h1:Js08h5hqB5xyWR789+QqueR6sDE8mk+YvpETZ+F6X9Y=
golang.org/x/sys v0.0.0-20220429233432-b5fbb4746d32/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=