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