sing-box/protocol/naive/inbound_conn.go

424 lines
8.5 KiB
Go
Raw Normal View History

2024-11-01 16:39:02 +00:00
package naive
2022-08-10 12:19:16 +00:00
import (
"encoding/binary"
"io"
"math/rand"
"net"
"net/http"
"os"
"strings"
"time"
"github.com/sagernet/sing/common"
"github.com/sagernet/sing/common/buf"
M "github.com/sagernet/sing/common/metadata"
"github.com/sagernet/sing/common/rw"
)
const kFirstPaddings = 8
2022-08-23 05:22:03 +00:00
type naiveH1Conn struct {
net.Conn
readPadding int
writePadding int
readRemaining int
paddingRemaining int
}
func (c *naiveH1Conn) Read(p []byte) (n int, err error) {
n, err = c.read(p)
return n, wrapHttpError(err)
}
func (c *naiveH1Conn) read(p []byte) (n int, err error) {
if c.readRemaining > 0 {
if len(p) > c.readRemaining {
p = p[:c.readRemaining]
}
n, err = c.Conn.Read(p)
if err != nil {
return
}
c.readRemaining -= n
return
}
if c.paddingRemaining > 0 {
err = rw.SkipN(c.Conn, c.paddingRemaining)
if err != nil {
return
}
2022-08-24 02:21:56 +00:00
c.paddingRemaining = 0
2022-08-23 05:22:03 +00:00
}
if c.readPadding < kFirstPaddings {
2022-10-18 09:52:52 +00:00
var paddingHdr []byte
if len(p) >= 3 {
paddingHdr = p[:3]
} else {
2023-07-03 13:45:32 +00:00
paddingHdr = make([]byte, 3)
2022-10-18 09:52:52 +00:00
}
2022-08-23 05:22:03 +00:00
_, err = io.ReadFull(c.Conn, paddingHdr)
if err != nil {
return
}
originalDataSize := int(binary.BigEndian.Uint16(paddingHdr[:2]))
paddingSize := int(paddingHdr[2])
if len(p) > originalDataSize {
p = p[:originalDataSize]
}
n, err = c.Conn.Read(p)
if err != nil {
return
}
c.readPadding++
c.readRemaining = originalDataSize - n
c.paddingRemaining = paddingSize
return
}
return c.Conn.Read(p)
}
func (c *naiveH1Conn) Write(p []byte) (n int, err error) {
for pLen := len(p); pLen > 0; {
var data []byte
if pLen > 65535 {
data = p[:65535]
p = p[65535:]
pLen -= 65535
} else {
data = p
pLen = 0
}
var writeN int
writeN, err = c.write(data)
n += writeN
if err != nil {
break
}
}
return n, wrapHttpError(err)
}
func (c *naiveH1Conn) write(p []byte) (n int, err error) {
if c.writePadding < kFirstPaddings {
paddingSize := rand.Intn(256)
2023-07-03 13:45:32 +00:00
buffer := buf.NewSize(3 + len(p) + paddingSize)
2022-08-23 05:22:03 +00:00
defer buffer.Release()
header := buffer.Extend(3)
binary.BigEndian.PutUint16(header, uint16(len(p)))
header[2] = byte(paddingSize)
common.Must1(buffer.Write(p))
_, err = c.Conn.Write(buffer.Bytes())
if err == nil {
n = len(p)
}
c.writePadding++
return
}
return c.Conn.Write(p)
}
func (c *naiveH1Conn) FrontHeadroom() int {
if c.writePadding < kFirstPaddings {
return 3
}
return 0
}
func (c *naiveH1Conn) RearHeadroom() int {
if c.writePadding < kFirstPaddings {
return 255
}
return 0
}
func (c *naiveH1Conn) WriterMTU() int {
if c.writePadding < kFirstPaddings {
return 65535
}
return 0
}
func (c *naiveH1Conn) WriteBuffer(buffer *buf.Buffer) error {
defer buffer.Release()
if c.writePadding < kFirstPaddings {
bufferLen := buffer.Len()
if bufferLen > 65535 {
return common.Error(c.Write(buffer.Bytes()))
}
paddingSize := rand.Intn(256)
header := buffer.ExtendHeader(3)
binary.BigEndian.PutUint16(header, uint16(bufferLen))
header[2] = byte(paddingSize)
buffer.Extend(paddingSize)
c.writePadding++
}
return wrapHttpError(common.Error(c.Conn.Write(buffer.Bytes())))
}
2022-08-10 12:19:16 +00:00
2022-08-24 02:21:56 +00:00
// FIXME
/*func (c *naiveH1Conn) WriteTo(w io.Writer) (n int64, err error) {
2022-08-23 05:22:03 +00:00
if c.readPadding < kFirstPaddings {
n, err = bufio.WriteToN(c, w, kFirstPaddings-c.readPadding)
} else {
n, err = bufio.Copy(w, c.Conn)
}
return n, wrapHttpError(err)
2022-09-07 04:28:41 +00:00
}
2022-08-23 05:22:03 +00:00
func (c *naiveH1Conn) ReadFrom(r io.Reader) (n int64, err error) {
if c.writePadding < kFirstPaddings {
n, err = bufio.ReadFromN(c, r, kFirstPaddings-c.writePadding)
} else {
n, err = bufio.Copy(c.Conn, r)
}
return n, wrapHttpError(err)
}
2022-09-07 04:28:41 +00:00
*/
2022-08-23 05:22:03 +00:00
func (c *naiveH1Conn) Upstream() any {
return c.Conn
}
func (c *naiveH1Conn) ReaderReplaceable() bool {
2022-09-07 04:28:41 +00:00
return c.readPadding == kFirstPaddings
2022-08-23 05:22:03 +00:00
}
func (c *naiveH1Conn) WriterReplaceable() bool {
return c.writePadding == kFirstPaddings
}
type naiveH2Conn struct {
2022-08-10 12:19:16 +00:00
reader io.Reader
writer io.Writer
flusher http.Flusher
rAddr net.Addr
readPadding int
writePadding int
readRemaining int
paddingRemaining int
}
2022-08-23 05:22:03 +00:00
func (c *naiveH2Conn) Read(p []byte) (n int, err error) {
2022-08-10 12:19:16 +00:00
n, err = c.read(p)
2022-08-22 04:02:16 +00:00
return n, wrapHttpError(err)
2022-08-10 12:19:16 +00:00
}
2022-08-23 05:22:03 +00:00
func (c *naiveH2Conn) read(p []byte) (n int, err error) {
2022-08-10 12:19:16 +00:00
if c.readRemaining > 0 {
if len(p) > c.readRemaining {
p = p[:c.readRemaining]
}
2022-08-22 04:02:16 +00:00
n, err = c.reader.Read(p)
2022-08-10 12:19:16 +00:00
if err != nil {
return
}
c.readRemaining -= n
return
}
if c.paddingRemaining > 0 {
err = rw.SkipN(c.reader, c.paddingRemaining)
if err != nil {
return
}
2022-08-24 02:21:56 +00:00
c.paddingRemaining = 0
2022-08-10 12:19:16 +00:00
}
if c.readPadding < kFirstPaddings {
2022-10-18 09:52:52 +00:00
var paddingHdr []byte
if len(p) >= 3 {
paddingHdr = p[:3]
} else {
2023-07-03 13:45:32 +00:00
paddingHdr = make([]byte, 3)
2022-10-18 09:52:52 +00:00
}
2022-08-10 12:19:16 +00:00
_, err = io.ReadFull(c.reader, paddingHdr)
if err != nil {
return
}
originalDataSize := int(binary.BigEndian.Uint16(paddingHdr[:2]))
paddingSize := int(paddingHdr[2])
if len(p) > originalDataSize {
p = p[:originalDataSize]
}
n, err = c.reader.Read(p)
if err != nil {
return
}
c.readPadding++
c.readRemaining = originalDataSize - n
c.paddingRemaining = paddingSize
return
}
return c.reader.Read(p)
}
2022-08-23 05:22:03 +00:00
func (c *naiveH2Conn) Write(p []byte) (n int, err error) {
2022-08-22 04:02:16 +00:00
for pLen := len(p); pLen > 0; {
var data []byte
if pLen > 65535 {
data = p[:65535]
p = p[65535:]
pLen -= 65535
} else {
data = p
pLen = 0
}
var writeN int
writeN, err = c.write(data)
n += writeN
if err != nil {
break
}
}
2022-08-10 12:19:16 +00:00
if err == nil {
c.flusher.Flush()
}
2022-08-22 04:02:16 +00:00
return n, wrapHttpError(err)
2022-08-10 12:19:16 +00:00
}
2022-08-23 05:22:03 +00:00
func (c *naiveH2Conn) write(p []byte) (n int, err error) {
2022-08-10 12:19:16 +00:00
if c.writePadding < kFirstPaddings {
paddingSize := rand.Intn(256)
2022-08-22 04:02:16 +00:00
2023-07-03 13:45:32 +00:00
buffer := buf.NewSize(3 + len(p) + paddingSize)
2022-08-22 04:02:16 +00:00
defer buffer.Release()
header := buffer.Extend(3)
binary.BigEndian.PutUint16(header, uint16(len(p)))
header[2] = byte(paddingSize)
common.Must1(buffer.Write(p))
_, err = c.writer.Write(buffer.Bytes())
if err == nil {
n = len(p)
2022-08-10 12:19:16 +00:00
}
c.writePadding++
2022-08-22 04:02:16 +00:00
return
2022-08-10 12:19:16 +00:00
}
return c.writer.Write(p)
}
2022-08-23 05:22:03 +00:00
func (c *naiveH2Conn) FrontHeadroom() int {
2022-08-11 15:59:22 +00:00
if c.writePadding < kFirstPaddings {
2022-08-22 04:02:16 +00:00
return 3
}
return 0
}
2022-08-23 05:22:03 +00:00
func (c *naiveH2Conn) RearHeadroom() int {
2022-08-22 04:02:16 +00:00
if c.writePadding < kFirstPaddings {
return 255
}
return 0
}
2022-08-23 05:22:03 +00:00
func (c *naiveH2Conn) WriterMTU() int {
2022-08-22 04:02:16 +00:00
if c.writePadding < kFirstPaddings {
return 65535
2022-08-11 15:59:22 +00:00
}
return 0
}
2022-08-23 05:22:03 +00:00
func (c *naiveH2Conn) WriteBuffer(buffer *buf.Buffer) error {
2022-08-10 12:19:16 +00:00
defer buffer.Release()
if c.writePadding < kFirstPaddings {
bufferLen := buffer.Len()
2022-08-22 04:02:16 +00:00
if bufferLen > 65535 {
return common.Error(c.Write(buffer.Bytes()))
}
2022-08-10 12:19:16 +00:00
paddingSize := rand.Intn(256)
header := buffer.ExtendHeader(3)
binary.BigEndian.PutUint16(header, uint16(bufferLen))
header[2] = byte(paddingSize)
buffer.Extend(paddingSize)
c.writePadding++
}
err := common.Error(c.writer.Write(buffer.Bytes()))
if err == nil {
c.flusher.Flush()
}
return wrapHttpError(err)
}
2022-08-24 02:21:56 +00:00
// FIXME
/*func (c *naiveH2Conn) WriteTo(w io.Writer) (n int64, err error) {
2022-08-10 12:19:16 +00:00
if c.readPadding < kFirstPaddings {
2022-08-22 04:02:16 +00:00
n, err = bufio.WriteToN(c, w, kFirstPaddings-c.readPadding)
} else {
n, err = bufio.Copy(w, c.reader)
2022-08-10 12:19:16 +00:00
}
2022-08-22 04:02:16 +00:00
return n, wrapHttpError(err)
2022-09-07 04:28:41 +00:00
}
2022-08-10 12:19:16 +00:00
2022-08-23 05:22:03 +00:00
func (c *naiveH2Conn) ReadFrom(r io.Reader) (n int64, err error) {
2022-08-10 12:19:16 +00:00
if c.writePadding < kFirstPaddings {
2022-08-22 04:02:16 +00:00
n, err = bufio.ReadFromN(c, r, kFirstPaddings-c.writePadding)
} else {
n, err = bufio.Copy(c.writer, r)
2022-08-10 12:19:16 +00:00
}
2022-08-22 04:02:16 +00:00
return n, wrapHttpError(err)
2022-09-07 04:28:41 +00:00
}*/
2022-08-10 12:19:16 +00:00
2022-08-23 05:22:03 +00:00
func (c *naiveH2Conn) Close() error {
2022-08-10 12:19:16 +00:00
return common.Close(
c.reader,
c.writer,
)
}
2022-08-23 05:22:03 +00:00
func (c *naiveH2Conn) LocalAddr() net.Addr {
2023-08-30 09:53:37 +00:00
return M.Socksaddr{}
2022-08-10 12:19:16 +00:00
}
2022-08-23 05:22:03 +00:00
func (c *naiveH2Conn) RemoteAddr() net.Addr {
2022-08-10 12:19:16 +00:00
return c.rAddr
}
2022-08-23 05:22:03 +00:00
func (c *naiveH2Conn) SetDeadline(t time.Time) error {
2022-08-10 12:19:16 +00:00
return os.ErrInvalid
}
2022-08-23 05:22:03 +00:00
func (c *naiveH2Conn) SetReadDeadline(t time.Time) error {
2022-08-10 12:19:16 +00:00
return os.ErrInvalid
}
2022-08-23 05:22:03 +00:00
func (c *naiveH2Conn) SetWriteDeadline(t time.Time) error {
2022-08-10 12:19:16 +00:00
return os.ErrInvalid
}
2023-04-19 13:48:54 +00:00
func (c *naiveH2Conn) NeedAdditionalReadDeadline() bool {
return true
}
2022-08-23 05:22:03 +00:00
func (c *naiveH2Conn) UpstreamReader() any {
return c.reader
}
func (c *naiveH2Conn) UpstreamWriter() any {
return c.writer
}
func (c *naiveH2Conn) ReaderReplaceable() bool {
2022-09-07 04:28:41 +00:00
return c.readPadding == kFirstPaddings
2022-08-23 05:22:03 +00:00
}
func (c *naiveH2Conn) WriterReplaceable() bool {
return c.writePadding == kFirstPaddings
}
2022-08-10 12:19:16 +00:00
func wrapHttpError(err error) error {
if err == nil {
return err
}
2022-08-22 04:02:16 +00:00
if strings.Contains(err.Error(), "client disconnected") {
return net.ErrClosed
}
if strings.Contains(err.Error(), "body closed by handler") {
2022-08-10 12:19:16 +00:00
return net.ErrClosed
}
2022-08-25 02:56:57 +00:00
if strings.Contains(err.Error(), "canceled with error code 268") {
return io.EOF
}
2022-08-10 12:19:16 +00:00
return err
}