Add direct io option for clash api
This commit is contained in:
82
experimental/trackerconn/conn.go
Normal file
82
experimental/trackerconn/conn.go
Normal file
@@ -0,0 +1,82 @@
|
||||
package trackerconn
|
||||
|
||||
import (
|
||||
"io"
|
||||
"net"
|
||||
|
||||
"github.com/sagernet/sing/common/buf"
|
||||
"github.com/sagernet/sing/common/bufio"
|
||||
N "github.com/sagernet/sing/common/network"
|
||||
|
||||
"go.uber.org/atomic"
|
||||
)
|
||||
|
||||
func New(conn net.Conn, readCounter *atomic.Int64, writeCounter *atomic.Int64, direct bool) N.ExtendedConn {
|
||||
trackerConn := &Conn{bufio.NewExtendedConn(conn), readCounter, writeCounter}
|
||||
if direct {
|
||||
return (*DirectConn)(trackerConn)
|
||||
} else {
|
||||
return trackerConn
|
||||
}
|
||||
}
|
||||
|
||||
type Conn struct {
|
||||
N.ExtendedConn
|
||||
readCounter *atomic.Int64
|
||||
writeCounter *atomic.Int64
|
||||
}
|
||||
|
||||
func (c *Conn) Read(p []byte) (n int, err error) {
|
||||
n, err = c.ExtendedConn.Read(p)
|
||||
c.readCounter.Add(int64(n))
|
||||
return n, err
|
||||
}
|
||||
|
||||
func (c *Conn) ReadBuffer(buffer *buf.Buffer) error {
|
||||
err := c.ExtendedConn.ReadBuffer(buffer)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
c.readCounter.Add(int64(buffer.Len()))
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Conn) Write(p []byte) (n int, err error) {
|
||||
n, err = c.ExtendedConn.Write(p)
|
||||
c.writeCounter.Add(int64(n))
|
||||
return n, err
|
||||
}
|
||||
|
||||
func (c *Conn) WriteBuffer(buffer *buf.Buffer) error {
|
||||
dataLen := int64(buffer.Len())
|
||||
err := c.ExtendedConn.WriteBuffer(buffer)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
c.writeCounter.Add(dataLen)
|
||||
return nil
|
||||
}
|
||||
|
||||
type DirectConn Conn
|
||||
|
||||
func (c *DirectConn) WriteTo(w io.Writer) (n int64, err error) {
|
||||
reader := N.UnwrapReader(c.ExtendedConn)
|
||||
if wt, ok := reader.(io.WriterTo); ok {
|
||||
n, err = wt.WriteTo(w)
|
||||
c.readCounter.Add(n)
|
||||
return
|
||||
} else {
|
||||
return bufio.Copy(w, (*Conn)(c))
|
||||
}
|
||||
}
|
||||
|
||||
func (c *DirectConn) ReadFrom(r io.Reader) (n int64, err error) {
|
||||
writer := N.UnwrapWriter(c.ExtendedConn)
|
||||
if rt, ok := writer.(io.ReaderFrom); ok {
|
||||
n, err = rt.ReadFrom(r)
|
||||
c.writeCounter.Add(n)
|
||||
return
|
||||
} else {
|
||||
return bufio.Copy((*Conn)(c), r)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user