Skip to content

Commit 0a97c0a

Browse files
committed
Add EXP_UDPConn interface
1 parent eec2fc3 commit 0a97c0a

File tree

3 files changed

+105
-25
lines changed

3 files changed

+105
-25
lines changed

common/bufio/bind.go

Lines changed: 79 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,25 @@ type bindPacketConn struct {
1818
addr net.Addr
1919
}
2020

21+
type bindUDPConn struct {
22+
bindPacketConn
23+
N.EXP_UDPConn
24+
}
25+
2126
func NewBindPacketConn(conn net.PacketConn, addr net.Addr) BindPacketConn {
22-
return &bindPacketConn{
23-
NewPacketConn(conn),
24-
addr,
27+
if udpConn, isUDPConn := conn.(N.EXP_UDPConn); isUDPConn {
28+
return &bindUDPConn{
29+
bindPacketConn{
30+
NewPacketConn(conn),
31+
addr,
32+
},
33+
udpConn,
34+
}
35+
} else {
36+
return &bindPacketConn{
37+
NewPacketConn(conn),
38+
addr,
39+
}
2540
}
2641
}
2742

@@ -61,16 +76,36 @@ type UnbindPacketConn struct {
6176
}
6277

6378
func NewUnbindPacketConn(conn net.Conn) N.NetPacketConn {
64-
return &UnbindPacketConn{
65-
NewExtendedConn(conn),
66-
M.SocksaddrFromNet(conn.RemoteAddr()),
79+
if udpConn, isUDPConn := conn.(N.EXP_UDPConn); isUDPConn {
80+
return &UnbindUDPConn{
81+
UnbindPacketConn{
82+
NewExtendedConn(conn),
83+
M.SocksaddrFromNet(conn.RemoteAddr()),
84+
},
85+
udpConn,
86+
}
87+
} else {
88+
return &UnbindPacketConn{
89+
NewExtendedConn(conn),
90+
M.SocksaddrFromNet(conn.RemoteAddr()),
91+
}
6792
}
6893
}
6994

7095
func NewUnbindPacketConnWithAddr(conn net.Conn, addr M.Socksaddr) N.NetPacketConn {
71-
return &UnbindPacketConn{
72-
NewExtendedConn(conn),
73-
addr,
96+
if udpConn, isUDPConn := conn.(N.EXP_UDPConn); isUDPConn {
97+
return &UnbindUDPConn{
98+
UnbindPacketConn{
99+
NewExtendedConn(conn),
100+
addr,
101+
},
102+
udpConn,
103+
}
104+
} else {
105+
return &UnbindPacketConn{
106+
NewExtendedConn(conn),
107+
addr,
108+
}
74109
}
75110
}
76111

@@ -110,3 +145,38 @@ func (c *UnbindPacketConn) CreateReadWaiter() (N.PacketReadWaiter, bool) {
110145
func (c *UnbindPacketConn) Upstream() any {
111146
return c.ExtendedConn
112147
}
148+
149+
var _ N.EXP_UDPConn = (*UnbindUDPConn)(nil)
150+
151+
type UnbindUDPConn struct {
152+
UnbindPacketConn
153+
N.EXP_UDPConn
154+
}
155+
156+
func (c *UnbindUDPConn) ReadFrom(p []byte) (n int, addr net.Addr, err error) {
157+
return c.UnbindPacketConn.ReadFrom(p)
158+
}
159+
160+
func (c *UnbindUDPConn) WriteTo(p []byte, _ net.Addr) (n int, err error) {
161+
return c.ExtendedConn.Write(p)
162+
}
163+
164+
func (c *UnbindUDPConn) ReadPacket(buffer *buf.Buffer) (destination M.Socksaddr, err error) {
165+
return c.UnbindPacketConn.ReadPacket(buffer)
166+
}
167+
168+
func (c *UnbindUDPConn) WritePacket(buffer *buf.Buffer, _ M.Socksaddr) error {
169+
return c.ExtendedConn.WriteBuffer(buffer)
170+
}
171+
172+
func (c *UnbindUDPConn) ReadMsgUDP(b, oob []byte) (n, oobn, flags int, addr *net.UDPAddr, err error) {
173+
n, oobn, flags, addr, err = c.EXP_UDPConn.ReadMsgUDP(b, oob)
174+
if err == nil {
175+
addr = c.addr.UDPAddr()
176+
}
177+
return
178+
}
179+
180+
func (c *UnbindUDPConn) WriteMsgUDP(b, oob []byte, _ *net.UDPAddr) (n, oobn int, err error) {
181+
return c.EXP_UDPConn.WriteMsgUDP(b, oob, c.addr.UDPAddr())
182+
}

common/bufio/conn.go

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -148,40 +148,40 @@ type ExtendedConnWrapper struct {
148148
writer N.ExtendedWriter
149149
}
150150

151-
func (w *ExtendedConnWrapper) ReadBuffer(buffer *buf.Buffer) error {
152-
return w.reader.ReadBuffer(buffer)
151+
func (c *ExtendedConnWrapper) ReadBuffer(buffer *buf.Buffer) error {
152+
return c.reader.ReadBuffer(buffer)
153153
}
154154

155-
func (w *ExtendedConnWrapper) WriteBuffer(buffer *buf.Buffer) error {
156-
return w.writer.WriteBuffer(buffer)
155+
func (c *ExtendedConnWrapper) WriteBuffer(buffer *buf.Buffer) error {
156+
return c.writer.WriteBuffer(buffer)
157157
}
158158

159-
func (w *ExtendedConnWrapper) ReadFrom(r io.Reader) (n int64, err error) {
160-
return Copy(w.writer, r)
159+
func (c *ExtendedConnWrapper) ReadFrom(r io.Reader) (n int64, err error) {
160+
return Copy(c.writer, r)
161161
}
162162

163-
func (r *ExtendedConnWrapper) WriteTo(w io.Writer) (n int64, err error) {
164-
return Copy(w, r.reader)
163+
func (c *ExtendedConnWrapper) WriteTo(w io.Writer) (n int64, err error) {
164+
return Copy(w, c.reader)
165165
}
166166

167-
func (w *ExtendedConnWrapper) UpstreamReader() any {
168-
return w.reader
167+
func (c *ExtendedConnWrapper) UpstreamReader() any {
168+
return c.reader
169169
}
170170

171-
func (w *ExtendedConnWrapper) ReaderReplaceable() bool {
171+
func (c *ExtendedConnWrapper) ReaderReplaceable() bool {
172172
return true
173173
}
174174

175-
func (w *ExtendedConnWrapper) UpstreamWriter() any {
176-
return w.writer
175+
func (c *ExtendedConnWrapper) UpstreamWriter() any {
176+
return c.writer
177177
}
178178

179-
func (w *ExtendedConnWrapper) WriterReplaceable() bool {
179+
func (c *ExtendedConnWrapper) WriterReplaceable() bool {
180180
return true
181181
}
182182

183-
func (w *ExtendedConnWrapper) Upstream() any {
184-
return w.Conn
183+
func (c *ExtendedConnWrapper) Upstream() any {
184+
return c.Conn
185185
}
186186

187187
func NewExtendedConn(conn net.Conn) N.ExtendedConn {

common/network/conn.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"context"
55
"io"
66
"net"
7+
"syscall"
78
"time"
89

910
"github.com/sagernet/sing/common"
@@ -85,6 +86,15 @@ type BindPacketConn interface {
8586
net.Conn
8687
}
8788

89+
// EXP_UDPConn is a interface used x/net/ipv4 and quic-go
90+
type EXP_UDPConn interface {
91+
net.PacketConn
92+
syscall.Conn
93+
SetReadBuffer(bytes int) error
94+
ReadMsgUDP(b, oob []byte) (n, oobn, flags int, addr *net.UDPAddr, err error)
95+
WriteMsgUDP(b, oob []byte, addr *net.UDPAddr) (n, oobn int, err error)
96+
}
97+
8898
type UDPHandler interface {
8999
NewPacket(ctx context.Context, conn PacketConn, buffer *buf.Buffer, metadata M.Metadata) error
90100
}

0 commit comments

Comments
 (0)