sing-mux/protocol_conn.go
2023-08-11 19:19:55 +08:00

69 lines
1.3 KiB
Go

package mux
import (
"net"
"github.com/sagernet/sing/common/buf"
"github.com/sagernet/sing/common/bufio"
N "github.com/sagernet/sing/common/network"
)
type protocolConn struct {
net.Conn
request Request
requestWritten bool
}
func newProtocolConn(conn net.Conn, request Request) net.Conn {
writer, isVectorised := bufio.CreateVectorisedWriter(conn)
if isVectorised {
return &vectorisedProtocolConn{
protocolConn{
Conn: conn,
request: request,
},
writer,
}
} else {
return &protocolConn{
Conn: conn,
request: request,
}
}
}
func (c *protocolConn) NeedHandshake() bool {
return !c.requestWritten
}
func (c *protocolConn) Write(p []byte) (n int, err error) {
if c.requestWritten {
return c.Conn.Write(p)
}
buffer := EncodeRequest(c.request, p)
n, err = c.Conn.Write(buffer.Bytes())
buffer.Release()
if err == nil {
n--
}
c.requestWritten = true
return n, err
}
func (c *protocolConn) Upstream() any {
return c.Conn
}
type vectorisedProtocolConn struct {
protocolConn
writer N.VectorisedWriter
}
func (c *vectorisedProtocolConn) WriteVectorised(buffers []*buf.Buffer) error {
if c.requestWritten {
return c.writer.WriteVectorised(buffers)
}
c.requestWritten = true
buffer := EncodeRequest(c.request, nil)
return c.writer.WriteVectorised(append([]*buf.Buffer{buffer}, buffers...))
}