Skip to content

Commit

Permalink
Add EXP_UDPConn interface
Browse files Browse the repository at this point in the history
  • Loading branch information
nekohasekai committed Apr 23, 2024
1 parent eec2fc3 commit 0a97c0a
Show file tree
Hide file tree
Showing 3 changed files with 105 additions and 25 deletions.
88 changes: 79 additions & 9 deletions common/bufio/bind.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,25 @@ type bindPacketConn struct {
addr net.Addr
}

type bindUDPConn struct {
bindPacketConn
N.EXP_UDPConn
}

func NewBindPacketConn(conn net.PacketConn, addr net.Addr) BindPacketConn {
return &bindPacketConn{
NewPacketConn(conn),
addr,
if udpConn, isUDPConn := conn.(N.EXP_UDPConn); isUDPConn {
return &bindUDPConn{
bindPacketConn{
NewPacketConn(conn),
addr,
},
udpConn,
}
} else {
return &bindPacketConn{
NewPacketConn(conn),
addr,
}
}
}

Expand Down Expand Up @@ -61,16 +76,36 @@ type UnbindPacketConn struct {
}

func NewUnbindPacketConn(conn net.Conn) N.NetPacketConn {
return &UnbindPacketConn{
NewExtendedConn(conn),
M.SocksaddrFromNet(conn.RemoteAddr()),
if udpConn, isUDPConn := conn.(N.EXP_UDPConn); isUDPConn {
return &UnbindUDPConn{
UnbindPacketConn{
NewExtendedConn(conn),
M.SocksaddrFromNet(conn.RemoteAddr()),
},
udpConn,
}
} else {
return &UnbindPacketConn{
NewExtendedConn(conn),
M.SocksaddrFromNet(conn.RemoteAddr()),
}
}
}

func NewUnbindPacketConnWithAddr(conn net.Conn, addr M.Socksaddr) N.NetPacketConn {
return &UnbindPacketConn{
NewExtendedConn(conn),
addr,
if udpConn, isUDPConn := conn.(N.EXP_UDPConn); isUDPConn {
return &UnbindUDPConn{
UnbindPacketConn{
NewExtendedConn(conn),
addr,
},
udpConn,
}
} else {
return &UnbindPacketConn{
NewExtendedConn(conn),
addr,
}
}
}

Expand Down Expand Up @@ -110,3 +145,38 @@ func (c *UnbindPacketConn) CreateReadWaiter() (N.PacketReadWaiter, bool) {
func (c *UnbindPacketConn) Upstream() any {
return c.ExtendedConn
}

var _ N.EXP_UDPConn = (*UnbindUDPConn)(nil)

type UnbindUDPConn struct {
UnbindPacketConn
N.EXP_UDPConn
}

func (c *UnbindUDPConn) ReadFrom(p []byte) (n int, addr net.Addr, err error) {
return c.UnbindPacketConn.ReadFrom(p)
}

func (c *UnbindUDPConn) WriteTo(p []byte, _ net.Addr) (n int, err error) {
return c.ExtendedConn.Write(p)
}

func (c *UnbindUDPConn) ReadPacket(buffer *buf.Buffer) (destination M.Socksaddr, err error) {
return c.UnbindPacketConn.ReadPacket(buffer)
}

func (c *UnbindUDPConn) WritePacket(buffer *buf.Buffer, _ M.Socksaddr) error {
return c.ExtendedConn.WriteBuffer(buffer)
}

func (c *UnbindUDPConn) ReadMsgUDP(b, oob []byte) (n, oobn, flags int, addr *net.UDPAddr, err error) {
n, oobn, flags, addr, err = c.EXP_UDPConn.ReadMsgUDP(b, oob)
if err == nil {
addr = c.addr.UDPAddr()
}
return
}

func (c *UnbindUDPConn) WriteMsgUDP(b, oob []byte, _ *net.UDPAddr) (n, oobn int, err error) {
return c.EXP_UDPConn.WriteMsgUDP(b, oob, c.addr.UDPAddr())
}
32 changes: 16 additions & 16 deletions common/bufio/conn.go
Original file line number Diff line number Diff line change
Expand Up @@ -148,40 +148,40 @@ type ExtendedConnWrapper struct {
writer N.ExtendedWriter
}

func (w *ExtendedConnWrapper) ReadBuffer(buffer *buf.Buffer) error {
return w.reader.ReadBuffer(buffer)
func (c *ExtendedConnWrapper) ReadBuffer(buffer *buf.Buffer) error {
return c.reader.ReadBuffer(buffer)
}

func (w *ExtendedConnWrapper) WriteBuffer(buffer *buf.Buffer) error {
return w.writer.WriteBuffer(buffer)
func (c *ExtendedConnWrapper) WriteBuffer(buffer *buf.Buffer) error {
return c.writer.WriteBuffer(buffer)
}

func (w *ExtendedConnWrapper) ReadFrom(r io.Reader) (n int64, err error) {
return Copy(w.writer, r)
func (c *ExtendedConnWrapper) ReadFrom(r io.Reader) (n int64, err error) {
return Copy(c.writer, r)
}

func (r *ExtendedConnWrapper) WriteTo(w io.Writer) (n int64, err error) {
return Copy(w, r.reader)
func (c *ExtendedConnWrapper) WriteTo(w io.Writer) (n int64, err error) {
return Copy(w, c.reader)
}

func (w *ExtendedConnWrapper) UpstreamReader() any {
return w.reader
func (c *ExtendedConnWrapper) UpstreamReader() any {
return c.reader
}

func (w *ExtendedConnWrapper) ReaderReplaceable() bool {
func (c *ExtendedConnWrapper) ReaderReplaceable() bool {
return true
}

func (w *ExtendedConnWrapper) UpstreamWriter() any {
return w.writer
func (c *ExtendedConnWrapper) UpstreamWriter() any {
return c.writer
}

func (w *ExtendedConnWrapper) WriterReplaceable() bool {
func (c *ExtendedConnWrapper) WriterReplaceable() bool {
return true
}

func (w *ExtendedConnWrapper) Upstream() any {
return w.Conn
func (c *ExtendedConnWrapper) Upstream() any {
return c.Conn
}

func NewExtendedConn(conn net.Conn) N.ExtendedConn {
Expand Down
10 changes: 10 additions & 0 deletions common/network/conn.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"context"
"io"
"net"
"syscall"
"time"

"github.com/sagernet/sing/common"
Expand Down Expand Up @@ -85,6 +86,15 @@ type BindPacketConn interface {
net.Conn
}

// EXP_UDPConn is a interface used x/net/ipv4 and quic-go
type EXP_UDPConn interface {
net.PacketConn
syscall.Conn
SetReadBuffer(bytes int) error
ReadMsgUDP(b, oob []byte) (n, oobn, flags int, addr *net.UDPAddr, err error)
WriteMsgUDP(b, oob []byte, addr *net.UDPAddr) (n, oobn int, err error)
}

type UDPHandler interface {
NewPacket(ctx context.Context, conn PacketConn, buffer *buf.Buffer, metadata M.Metadata) error
}
Expand Down

0 comments on commit 0a97c0a

Please sign in to comment.