sing-box/transport/v2raygrpclite/conn.go

167 lines
3.3 KiB
Go
Raw Normal View History

2022-08-27 21:05:15 +08:00
package v2raygrpclite
import (
std_bufio "bufio"
"encoding/binary"
"io"
"net"
"net/http"
"os"
"time"
"github.com/sagernet/sing/common"
2023-09-07 19:26:45 +08:00
"github.com/sagernet/sing/common/baderror"
2022-08-27 21:05:15 +08:00
"github.com/sagernet/sing/common/buf"
2023-08-30 17:53:37 +08:00
M "github.com/sagernet/sing/common/metadata"
2024-06-24 09:49:15 +08:00
"github.com/sagernet/sing/common/varbin"
2022-08-27 21:05:15 +08:00
)
// kanged from: https://github.com/Qv2ray/gun-lite
var _ net.Conn = (*GunConn)(nil)
type GunConn struct {
reader *std_bufio.Reader
writer io.Writer
flusher http.Flusher
create chan struct{}
err error
readRemaining int
}
func newGunConn(reader io.Reader, writer io.Writer, flusher http.Flusher) *GunConn {
return &GunConn{
reader: std_bufio.NewReader(reader),
writer: writer,
flusher: flusher,
}
}
func newLateGunConn(writer io.Writer) *GunConn {
return &GunConn{
create: make(chan struct{}),
writer: writer,
}
}
func (c *GunConn) setup(reader io.Reader, err error) {
2023-12-08 21:10:13 +08:00
if reader != nil {
c.reader = std_bufio.NewReader(reader)
}
2022-08-27 21:05:15 +08:00
c.err = err
close(c.create)
}
func (c *GunConn) Read(b []byte) (n int, err error) {
n, err = c.read(b)
2022-08-29 10:10:41 +08:00
return n, baderror.WrapH2(err)
2022-08-27 21:05:15 +08:00
}
func (c *GunConn) read(b []byte) (n int, err error) {
if c.reader == nil {
<-c.create
if c.err != nil {
return 0, c.err
}
}
if c.readRemaining > 0 {
if len(b) > c.readRemaining {
b = b[:c.readRemaining]
}
n, err = c.reader.Read(b)
c.readRemaining -= n
return
}
_, err = c.reader.Discard(6)
if err != nil {
return
}
dataLen, err := binary.ReadUvarint(c.reader)
if err != nil {
return
}
readLen := int(dataLen)
c.readRemaining = readLen
if len(b) > readLen {
b = b[:readLen]
}
n, err = c.reader.Read(b)
c.readRemaining -= n
return
}
func (c *GunConn) Write(b []byte) (n int, err error) {
2024-06-24 09:49:15 +08:00
varLen := varbin.UvarintLen(uint64(len(b)))
2024-01-01 16:13:50 +08:00
buffer := buf.NewSize(6 + varLen + len(b))
header := buffer.Extend(6 + varLen)
header[0] = 0x00
binary.BigEndian.PutUint32(header[1:5], uint32(1+varLen+len(b)))
header[5] = 0x0A
binary.PutUvarint(header[6:], uint64(len(b)))
common.Must1(buffer.Write(b))
_, err = c.writer.Write(buffer.Bytes())
if err != nil {
return 0, baderror.WrapH2(err)
}
if c.flusher != nil {
c.flusher.Flush()
2022-08-27 21:05:15 +08:00
}
2024-01-01 16:13:50 +08:00
return len(b), nil
2022-08-27 21:05:15 +08:00
}
func (c *GunConn) WriteBuffer(buffer *buf.Buffer) error {
defer buffer.Release()
dataLen := buffer.Len()
2024-06-24 09:49:15 +08:00
varLen := varbin.UvarintLen(uint64(dataLen))
2022-08-27 21:05:15 +08:00
header := buffer.ExtendHeader(6 + varLen)
header[0] = 0x00
2022-08-27 21:05:15 +08:00
binary.BigEndian.PutUint32(header[1:5], uint32(1+varLen+dataLen))
header[5] = 0x0A
binary.PutUvarint(header[6:], uint64(dataLen))
2024-06-24 09:49:15 +08:00
err := common.Error(c.writer.Write(buffer.Bytes()))
2024-01-01 16:13:50 +08:00
if err != nil {
return baderror.WrapH2(err)
}
if c.flusher != nil {
2022-08-27 21:05:15 +08:00
c.flusher.Flush()
}
2024-01-01 16:13:50 +08:00
return nil
2022-08-27 21:05:15 +08:00
}
func (c *GunConn) FrontHeadroom() int {
return 6 + binary.MaxVarintLen64
}
func (c *GunConn) Close() error {
return common.Close(c.reader, c.writer)
}
func (c *GunConn) LocalAddr() net.Addr {
2023-08-30 17:53:37 +08:00
return M.Socksaddr{}
2022-08-27 21:05:15 +08:00
}
func (c *GunConn) RemoteAddr() net.Addr {
2023-12-05 15:10:51 +08:00
return M.Socksaddr{}
2022-08-27 21:05:15 +08:00
}
func (c *GunConn) SetDeadline(t time.Time) error {
2022-11-23 14:56:31 +08:00
return os.ErrInvalid
2022-08-27 21:05:15 +08:00
}
func (c *GunConn) SetReadDeadline(t time.Time) error {
2022-11-23 14:56:31 +08:00
return os.ErrInvalid
2022-08-27 21:05:15 +08:00
}
func (c *GunConn) SetWriteDeadline(t time.Time) error {
2022-11-23 14:56:31 +08:00
return os.ErrInvalid
2022-08-27 21:05:15 +08:00
}
2023-04-19 21:48:54 +08:00
func (c *GunConn) NeedAdditionalReadDeadline() bool {
return true
}