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