github.com/sagernet/sing-box@v1.9.0-rc.20/transport/v2raygrpclite/conn.go (about) 1 package v2raygrpclite 2 3 import ( 4 std_bufio "bufio" 5 "encoding/binary" 6 "io" 7 "net" 8 "net/http" 9 "os" 10 "time" 11 12 "github.com/sagernet/sing/common" 13 "github.com/sagernet/sing/common/baderror" 14 "github.com/sagernet/sing/common/buf" 15 M "github.com/sagernet/sing/common/metadata" 16 "github.com/sagernet/sing/common/rw" 17 ) 18 19 // kanged from: https://github.com/Qv2ray/gun-lite 20 21 var _ net.Conn = (*GunConn)(nil) 22 23 type GunConn struct { 24 reader *std_bufio.Reader 25 writer io.Writer 26 flusher http.Flusher 27 create chan struct{} 28 err error 29 readRemaining int 30 } 31 32 func newGunConn(reader io.Reader, writer io.Writer, flusher http.Flusher) *GunConn { 33 return &GunConn{ 34 reader: std_bufio.NewReader(reader), 35 writer: writer, 36 flusher: flusher, 37 } 38 } 39 40 func newLateGunConn(writer io.Writer) *GunConn { 41 return &GunConn{ 42 create: make(chan struct{}), 43 writer: writer, 44 } 45 } 46 47 func (c *GunConn) setup(reader io.Reader, err error) { 48 if reader != nil { 49 c.reader = std_bufio.NewReader(reader) 50 } 51 c.err = err 52 close(c.create) 53 } 54 55 func (c *GunConn) Read(b []byte) (n int, err error) { 56 n, err = c.read(b) 57 return n, baderror.WrapH2(err) 58 } 59 60 func (c *GunConn) read(b []byte) (n int, err error) { 61 if c.reader == nil { 62 <-c.create 63 if c.err != nil { 64 return 0, c.err 65 } 66 } 67 68 if c.readRemaining > 0 { 69 if len(b) > c.readRemaining { 70 b = b[:c.readRemaining] 71 } 72 n, err = c.reader.Read(b) 73 c.readRemaining -= n 74 return 75 } 76 77 _, err = c.reader.Discard(6) 78 if err != nil { 79 return 80 } 81 82 dataLen, err := binary.ReadUvarint(c.reader) 83 if err != nil { 84 return 85 } 86 87 readLen := int(dataLen) 88 c.readRemaining = readLen 89 if len(b) > readLen { 90 b = b[:readLen] 91 } 92 93 n, err = c.reader.Read(b) 94 c.readRemaining -= n 95 return 96 } 97 98 func (c *GunConn) Write(b []byte) (n int, err error) { 99 varLen := rw.UVariantLen(uint64(len(b))) 100 buffer := buf.NewSize(6 + varLen + len(b)) 101 header := buffer.Extend(6 + varLen) 102 header[0] = 0x00 103 binary.BigEndian.PutUint32(header[1:5], uint32(1+varLen+len(b))) 104 header[5] = 0x0A 105 binary.PutUvarint(header[6:], uint64(len(b))) 106 common.Must1(buffer.Write(b)) 107 _, err = c.writer.Write(buffer.Bytes()) 108 if err != nil { 109 return 0, baderror.WrapH2(err) 110 } 111 if c.flusher != nil { 112 c.flusher.Flush() 113 } 114 return len(b), nil 115 } 116 117 func (c *GunConn) WriteBuffer(buffer *buf.Buffer) error { 118 defer buffer.Release() 119 dataLen := buffer.Len() 120 varLen := rw.UVariantLen(uint64(dataLen)) 121 header := buffer.ExtendHeader(6 + varLen) 122 header[0] = 0x00 123 binary.BigEndian.PutUint32(header[1:5], uint32(1+varLen+dataLen)) 124 header[5] = 0x0A 125 binary.PutUvarint(header[6:], uint64(dataLen)) 126 err := rw.WriteBytes(c.writer, buffer.Bytes()) 127 if err != nil { 128 return baderror.WrapH2(err) 129 } 130 if c.flusher != nil { 131 c.flusher.Flush() 132 } 133 return nil 134 } 135 136 func (c *GunConn) FrontHeadroom() int { 137 return 6 + binary.MaxVarintLen64 138 } 139 140 func (c *GunConn) Close() error { 141 return common.Close(c.reader, c.writer) 142 } 143 144 func (c *GunConn) LocalAddr() net.Addr { 145 return M.Socksaddr{} 146 } 147 148 func (c *GunConn) RemoteAddr() net.Addr { 149 return M.Socksaddr{} 150 } 151 152 func (c *GunConn) SetDeadline(t time.Time) error { 153 return os.ErrInvalid 154 } 155 156 func (c *GunConn) SetReadDeadline(t time.Time) error { 157 return os.ErrInvalid 158 } 159 160 func (c *GunConn) SetWriteDeadline(t time.Time) error { 161 return os.ErrInvalid 162 } 163 164 func (c *GunConn) NeedAdditionalReadDeadline() bool { 165 return true 166 }