mihomo/common/net/sing.go
2025-09-16 09:49:41 +08:00

92 lines
2.2 KiB
Go

package net
import (
"io"
"net"
"github.com/metacubex/mihomo/common/net/deadline"
"github.com/metacubex/sing/common"
"github.com/metacubex/sing/common/bufio"
"github.com/metacubex/sing/common/network"
)
var NewExtendedConn = bufio.NewExtendedConn
var NewExtendedWriter = bufio.NewExtendedWriter
var NewExtendedReader = bufio.NewExtendedReader
type ExtendedConn = network.ExtendedConn
type ExtendedWriter = network.ExtendedWriter
type ExtendedReader = network.ExtendedReader
var WriteBuffer = bufio.WriteBuffer
type ReadWaitOptions = network.ReadWaitOptions
var NewReadWaitOptions = network.NewReadWaitOptions
type ReaderWithUpstream = network.ReaderWithUpstream
type WithUpstreamReader = network.WithUpstreamReader
type WriterWithUpstream = network.WriterWithUpstream
type WithUpstreamWriter = network.WithUpstreamWriter
type WithUpstream = common.WithUpstream
var UnwrapReader = network.UnwrapReader
var UnwrapWriter = network.UnwrapWriter
func NewDeadlineConn(conn net.Conn) ExtendedConn {
if deadline.IsPipe(conn) || deadline.IsPipe(UnwrapReader(conn)) {
return NewExtendedConn(conn) // pipe always have correctly deadline implement
}
if deadline.IsConn(conn) || deadline.IsConn(UnwrapReader(conn)) {
return NewExtendedConn(conn) // was a *deadline.Conn
}
return deadline.NewConn(conn)
}
func NeedHandshake(conn any) bool {
if earlyConn, isEarlyConn := common.Cast[network.EarlyConn](conn); isEarlyConn && earlyConn.NeedHandshake() {
return true
}
return false
}
type CountFunc = network.CountFunc
var Pipe = deadline.Pipe
func closeWrite(writer io.Closer) error {
if c, ok := common.Cast[network.WriteCloser](writer); ok {
return c.CloseWrite()
}
return writer.Close()
}
// Relay copies between left and right bidirectionally.
// like [bufio.CopyConn] but remove unneeded [context.Context] handle and the cost of [task.Group]
func Relay(leftConn, rightConn net.Conn) {
defer func() {
_ = leftConn.Close()
_ = rightConn.Close()
}()
ch := make(chan struct{})
go func() {
_, err := bufio.Copy(leftConn, rightConn)
if err == nil {
_ = closeWrite(leftConn)
} else {
_ = leftConn.Close()
}
close(ch)
}()
_, err := bufio.Copy(rightConn, leftConn)
if err == nil {
_ = closeWrite(rightConn)
} else {
_ = rightConn.Close()
}
<-ch
}