mirror of
https://github.com/refraction-networking/uquic.git
synced 2025-04-05 05:07:36 +03:00
101 lines
2.5 KiB
Go
101 lines
2.5 KiB
Go
package handshake
|
|
|
|
import (
|
|
"bytes"
|
|
"io"
|
|
"net"
|
|
"time"
|
|
)
|
|
|
|
// The CryptoStreamConn is used as the net.Conn passed to mint.
|
|
// It has two operating modes:
|
|
// 1. It can read and write to bytes.Buffers.
|
|
// 2. It can use a quic.Stream for reading and writing.
|
|
// The buffer-mode is only used by the server, in order to statelessly handle retries.
|
|
type CryptoStreamConn struct {
|
|
remoteAddr net.Addr
|
|
|
|
// the buffers are used before the session is initialized
|
|
readBuf bytes.Buffer
|
|
writeBuf bytes.Buffer
|
|
|
|
// stream will be set once the session is initialized
|
|
stream io.ReadWriter
|
|
}
|
|
|
|
var _ net.Conn = &CryptoStreamConn{}
|
|
|
|
// NewCryptoStreamConn creates a new CryptoStreamConn
|
|
func NewCryptoStreamConn(remoteAddr net.Addr) *CryptoStreamConn {
|
|
return &CryptoStreamConn{remoteAddr: remoteAddr}
|
|
}
|
|
|
|
func (c *CryptoStreamConn) Read(b []byte) (int, error) {
|
|
if c.stream != nil {
|
|
return c.stream.Read(b)
|
|
}
|
|
return c.readBuf.Read(b)
|
|
}
|
|
|
|
// AddDataForReading adds data to the read buffer.
|
|
// This data will ONLY be read when the stream has not been set.
|
|
func (c *CryptoStreamConn) AddDataForReading(data []byte) {
|
|
c.readBuf.Write(data)
|
|
}
|
|
|
|
func (c *CryptoStreamConn) Write(p []byte) (int, error) {
|
|
if c.stream != nil {
|
|
return c.stream.Write(p)
|
|
}
|
|
return c.writeBuf.Write(p)
|
|
}
|
|
|
|
// GetDataForWriting returns all data currently in the write buffer, and resets this buffer.
|
|
func (c *CryptoStreamConn) GetDataForWriting() []byte {
|
|
defer c.writeBuf.Reset()
|
|
data := make([]byte, c.writeBuf.Len())
|
|
copy(data, c.writeBuf.Bytes())
|
|
return data
|
|
}
|
|
|
|
// SetStream sets the stream.
|
|
// After setting the stream, the read and write buffer won't be used any more.
|
|
func (c *CryptoStreamConn) SetStream(stream io.ReadWriter) {
|
|
c.stream = stream
|
|
}
|
|
|
|
// Flush copies the contents of the write buffer to the stream
|
|
func (c *CryptoStreamConn) Flush() (int, error) {
|
|
n, err := io.Copy(c.stream, &c.writeBuf)
|
|
return int(n), err
|
|
}
|
|
|
|
// Close is not implemented
|
|
func (c *CryptoStreamConn) Close() error {
|
|
return nil
|
|
}
|
|
|
|
// LocalAddr is not implemented
|
|
func (c *CryptoStreamConn) LocalAddr() net.Addr {
|
|
return nil
|
|
}
|
|
|
|
// RemoteAddr returns the remote address
|
|
func (c *CryptoStreamConn) RemoteAddr() net.Addr {
|
|
return c.remoteAddr
|
|
}
|
|
|
|
// SetReadDeadline is not implemented
|
|
func (c *CryptoStreamConn) SetReadDeadline(time.Time) error {
|
|
return nil
|
|
}
|
|
|
|
// SetWriteDeadline is not implemented
|
|
func (c *CryptoStreamConn) SetWriteDeadline(time.Time) error {
|
|
return nil
|
|
}
|
|
|
|
// SetDeadline is not implemented
|
|
func (c *CryptoStreamConn) SetDeadline(time.Time) error {
|
|
return nil
|
|
}
|