github.com/v2fly/v2ray-core/v4@v4.45.2/transport/internet/quic/conn.go (about) 1 //go:build !confonly 2 // +build !confonly 3 4 package quic 5 6 import ( 7 "crypto/cipher" 8 "crypto/rand" 9 "errors" 10 "time" 11 12 "github.com/lucas-clemente/quic-go" 13 14 "github.com/v2fly/v2ray-core/v4/common" 15 "github.com/v2fly/v2ray-core/v4/common/buf" 16 "github.com/v2fly/v2ray-core/v4/common/net" 17 "github.com/v2fly/v2ray-core/v4/transport/internet" 18 ) 19 20 type sysConn struct { 21 conn net.PacketConn 22 header internet.PacketHeader 23 auth cipher.AEAD 24 } 25 26 func wrapSysConn(rawConn net.PacketConn, config *Config) (*sysConn, error) { 27 header, err := getHeader(config) 28 if err != nil { 29 return nil, err 30 } 31 auth, err := getAuth(config) 32 if err != nil { 33 return nil, err 34 } 35 return &sysConn{ 36 conn: rawConn, 37 header: header, 38 auth: auth, 39 }, nil 40 } 41 42 var errInvalidPacket = errors.New("invalid packet") 43 44 func (c *sysConn) readFromInternal(p []byte) (int, net.Addr, error) { 45 buffer := getBuffer() 46 defer putBuffer(buffer) 47 48 nBytes, addr, err := c.conn.ReadFrom(buffer) 49 if err != nil { 50 return 0, nil, err 51 } 52 53 payload := buffer[:nBytes] 54 if c.header != nil { 55 if len(payload) <= int(c.header.Size()) { 56 return 0, nil, errInvalidPacket 57 } 58 payload = payload[c.header.Size():] 59 } 60 61 if c.auth == nil { 62 n := copy(p, payload) 63 return n, addr, nil 64 } 65 66 if len(payload) <= c.auth.NonceSize() { 67 return 0, nil, errInvalidPacket 68 } 69 70 nonce := payload[:c.auth.NonceSize()] 71 payload = payload[c.auth.NonceSize():] 72 73 p, err = c.auth.Open(p[:0], nonce, payload, nil) 74 if err != nil { 75 return 0, nil, errInvalidPacket 76 } 77 78 return len(p), addr, nil 79 } 80 81 func (c *sysConn) ReadFrom(p []byte) (int, net.Addr, error) { 82 if c.header == nil && c.auth == nil { 83 return c.conn.ReadFrom(p) 84 } 85 86 for { 87 n, addr, err := c.readFromInternal(p) 88 if err != nil && err != errInvalidPacket { 89 return 0, nil, err 90 } 91 if err == nil { 92 return n, addr, nil 93 } 94 } 95 } 96 97 func (c *sysConn) WriteTo(p []byte, addr net.Addr) (int, error) { 98 if c.header == nil && c.auth == nil { 99 return c.conn.WriteTo(p, addr) 100 } 101 102 buffer := getBuffer() 103 defer putBuffer(buffer) 104 105 payload := buffer 106 n := 0 107 if c.header != nil { 108 c.header.Serialize(payload) 109 n = int(c.header.Size()) 110 } 111 112 if c.auth == nil { 113 nBytes := copy(payload[n:], p) 114 n += nBytes 115 } else { 116 nounce := payload[n : n+c.auth.NonceSize()] 117 common.Must2(rand.Read(nounce)) 118 n += c.auth.NonceSize() 119 pp := c.auth.Seal(payload[:n], nounce, p, nil) 120 n = len(pp) 121 } 122 123 return c.conn.WriteTo(payload[:n], addr) 124 } 125 126 func (c *sysConn) Close() error { 127 return c.conn.Close() 128 } 129 130 func (c *sysConn) LocalAddr() net.Addr { 131 return c.conn.LocalAddr() 132 } 133 134 func (c *sysConn) SetDeadline(t time.Time) error { 135 return c.conn.SetDeadline(t) 136 } 137 138 func (c *sysConn) SetReadDeadline(t time.Time) error { 139 return c.conn.SetReadDeadline(t) 140 } 141 142 func (c *sysConn) SetWriteDeadline(t time.Time) error { 143 return c.conn.SetWriteDeadline(t) 144 } 145 146 type interConn struct { 147 stream quic.Stream 148 local net.Addr 149 remote net.Addr 150 } 151 152 func (c *interConn) Read(b []byte) (int, error) { 153 return c.stream.Read(b) 154 } 155 156 func (c *interConn) WriteMultiBuffer(mb buf.MultiBuffer) error { 157 mb = buf.Compact(mb) 158 mb, err := buf.WriteMultiBuffer(c, mb) 159 buf.ReleaseMulti(mb) 160 return err 161 } 162 163 func (c *interConn) Write(b []byte) (int, error) { 164 return c.stream.Write(b) 165 } 166 167 func (c *interConn) Close() error { 168 return c.stream.Close() 169 } 170 171 func (c *interConn) LocalAddr() net.Addr { 172 return c.local 173 } 174 175 func (c *interConn) RemoteAddr() net.Addr { 176 return c.remote 177 } 178 179 func (c *interConn) SetDeadline(t time.Time) error { 180 return c.stream.SetDeadline(t) 181 } 182 183 func (c *interConn) SetReadDeadline(t time.Time) error { 184 return c.stream.SetReadDeadline(t) 185 } 186 187 func (c *interConn) SetWriteDeadline(t time.Time) error { 188 return c.stream.SetWriteDeadline(t) 189 }