github.com/Uhtred009/v2ray-core-1@v4.31.2+incompatible/transport/internet/quic/conn.go (about) 1 // +build !confonly 2 3 package quic 4 5 import ( 6 "crypto/cipher" 7 "crypto/rand" 8 "errors" 9 "time" 10 11 "github.com/lucas-clemente/quic-go" 12 "v2ray.com/core/common" 13 "v2ray.com/core/common/buf" 14 "v2ray.com/core/common/net" 15 "v2ray.com/core/transport/internet" 16 ) 17 18 type sysConn struct { 19 conn net.PacketConn 20 header internet.PacketHeader 21 auth cipher.AEAD 22 } 23 24 func wrapSysConn(rawConn net.PacketConn, 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) SetDeadline(t time.Time) error { 133 return c.conn.SetDeadline(t) 134 } 135 136 func (c *sysConn) SetReadDeadline(t time.Time) error { 137 return c.conn.SetReadDeadline(t) 138 } 139 140 func (c *sysConn) SetWriteDeadline(t time.Time) error { 141 return c.conn.SetWriteDeadline(t) 142 } 143 144 type interConn struct { 145 stream quic.Stream 146 local net.Addr 147 remote net.Addr 148 } 149 150 func (c *interConn) Read(b []byte) (int, error) { 151 return c.stream.Read(b) 152 } 153 154 func (c *interConn) WriteMultiBuffer(mb buf.MultiBuffer) error { 155 mb = buf.Compact(mb) 156 mb, err := buf.WriteMultiBuffer(c, mb) 157 buf.ReleaseMulti(mb) 158 return err 159 } 160 161 func (c *interConn) Write(b []byte) (int, error) { 162 return c.stream.Write(b) 163 } 164 165 func (c *interConn) Close() error { 166 return c.stream.Close() 167 } 168 169 func (c *interConn) LocalAddr() net.Addr { 170 return c.local 171 } 172 173 func (c *interConn) RemoteAddr() net.Addr { 174 return c.remote 175 } 176 177 func (c *interConn) SetDeadline(t time.Time) error { 178 return c.stream.SetDeadline(t) 179 } 180 181 func (c *interConn) SetReadDeadline(t time.Time) error { 182 return c.stream.SetReadDeadline(t) 183 } 184 185 func (c *interConn) SetWriteDeadline(t time.Time) error { 186 return c.stream.SetWriteDeadline(t) 187 }