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  }