mirror of
https://github.com/netbirdio/netbird.git
synced 2026-04-16 07:16:38 +00:00
40 lines
984 B
Go
40 lines
984 B
Go
package tcp
|
|
|
|
import (
|
|
"bytes"
|
|
"io"
|
|
"net"
|
|
)
|
|
|
|
// peekedConn wraps a net.Conn and prepends previously peeked bytes
|
|
// so that readers see the full original stream transparently.
|
|
type peekedConn struct {
|
|
net.Conn
|
|
reader io.Reader
|
|
}
|
|
|
|
func newPeekedConn(conn net.Conn, peeked []byte) *peekedConn {
|
|
return &peekedConn{
|
|
Conn: conn,
|
|
reader: io.MultiReader(bytes.NewReader(peeked), conn),
|
|
}
|
|
}
|
|
|
|
// Read replays the peeked bytes first, then reads from the underlying conn.
|
|
func (c *peekedConn) Read(b []byte) (int, error) {
|
|
return c.reader.Read(b)
|
|
}
|
|
|
|
// CloseWrite delegates to the underlying connection if it supports
|
|
// half-close (e.g. *net.TCPConn). Without this, embedding net.Conn
|
|
// as an interface hides the concrete type's CloseWrite method, making
|
|
// half-close a silent no-op for all SNI-routed connections.
|
|
func (c *peekedConn) CloseWrite() error {
|
|
if hc, ok := c.Conn.(halfCloser); ok {
|
|
return hc.CloseWrite()
|
|
}
|
|
return nil
|
|
}
|
|
|
|
var _ halfCloser = (*peekedConn)(nil)
|