Skip to content

Commit b60cf02

Browse files
authored
Optimize TPROXY Inbound UDP write back
Enhanced stability.
1 parent ae98dc7 commit b60cf02

File tree

2 files changed

+30
-43
lines changed

2 files changed

+30
-43
lines changed

proxy/dokodemo/dokodemo.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -277,17 +277,17 @@ func (w *PacketWriter) WriteMultiBuffer(mb buf.MultiBuffer) error {
277277
w.mark,
278278
)
279279
if err != nil {
280+
newError(err).WriteToLog()
280281
b.Release()
281-
buf.ReleaseMulti(mb)
282-
return err
282+
continue
283283
}
284284
w.conns[*b.UDP] = conn
285285
}
286286
_, err = conn.WriteTo(b.Bytes(), w.back)
287287
if err != nil {
288-
conn.Close()
289-
w.conns[*b.UDP] = nil
290288
newError(err).WriteToLog()
289+
w.conns[*b.UDP] = nil
290+
conn.Close()
291291
}
292292
b.Release()
293293
} else {

proxy/dokodemo/fakeudp_linux.go

Lines changed: 26 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -12,68 +12,55 @@ import (
1212
)
1313

1414
func FakeUDP(addr *net.UDPAddr, mark int) (net.PacketConn, error) {
15-
16-
localSocketAddress, af, err := udpAddrToSocketAddr(addr)
17-
if err != nil {
18-
return nil, &net.OpError{Op: "fake", Err: fmt.Errorf("build local socket address: %s", err)}
15+
var af int
16+
var sockaddr syscall.Sockaddr
17+
18+
if len(addr.IP) == 4 {
19+
af = syscall.AF_INET
20+
sockaddr = &syscall.SockaddrInet4{Port: addr.Port}
21+
copy(sockaddr.(*syscall.SockaddrInet4).Addr[:], addr.IP)
22+
} else {
23+
af = syscall.AF_INET6
24+
sockaddr = &syscall.SockaddrInet6{Port: addr.Port}
25+
copy(sockaddr.(*syscall.SockaddrInet6).Addr[:], addr.IP)
1926
}
2027

21-
fileDescriptor, err := syscall.Socket(af, syscall.SOCK_DGRAM, 0)
22-
if err != nil {
28+
var fd int
29+
var err error
30+
31+
if fd, err = syscall.Socket(af, syscall.SOCK_DGRAM, 0); err != nil {
2332
return nil, &net.OpError{Op: "fake", Err: fmt.Errorf("socket open: %s", err)}
2433
}
2534

2635
if mark != 0 {
27-
if err = syscall.SetsockoptInt(fileDescriptor, syscall.SOL_SOCKET, syscall.SO_MARK, mark); err != nil {
28-
syscall.Close(fileDescriptor)
36+
if err = syscall.SetsockoptInt(fd, syscall.SOL_SOCKET, syscall.SO_MARK, mark); err != nil {
37+
syscall.Close(fd)
2938
return nil, &net.OpError{Op: "fake", Err: fmt.Errorf("set socket option: SO_MARK: %s", err)}
3039
}
3140
}
3241

33-
if err = syscall.SetsockoptInt(fileDescriptor, syscall.SOL_SOCKET, syscall.SO_REUSEADDR, 1); err != nil {
34-
syscall.Close(fileDescriptor)
35-
return nil, &net.OpError{Op: "fake", Err: fmt.Errorf("set socket option: SO_REUSEADDR: %s", err)}
42+
if err = syscall.SetsockoptInt(fd, syscall.SOL_IP, syscall.IP_TRANSPARENT, 1); err != nil {
43+
syscall.Close(fd)
44+
return nil, &net.OpError{Op: "fake", Err: fmt.Errorf("set socket option: IP_TRANSPARENT: %s", err)}
3645
}
3746

38-
if err = syscall.SetsockoptInt(fileDescriptor, syscall.SOL_SOCKET, unix.SO_REUSEPORT, 1); err != nil {
39-
syscall.Close(fileDescriptor)
40-
return nil, &net.OpError{Op: "fake", Err: fmt.Errorf("set socket option: SO_REUSEPORT: %s", err)}
41-
}
47+
syscall.SetsockoptInt(fd, syscall.SOL_SOCKET, syscall.SO_REUSEADDR, 1)
4248

43-
if err = syscall.SetsockoptInt(fileDescriptor, syscall.SOL_IP, syscall.IP_TRANSPARENT, 1); err != nil {
44-
syscall.Close(fileDescriptor)
45-
return nil, &net.OpError{Op: "fake", Err: fmt.Errorf("set socket option: IP_TRANSPARENT: %s", err)}
46-
}
49+
syscall.SetsockoptInt(fd, syscall.SOL_SOCKET, unix.SO_REUSEPORT, 1)
4750

48-
if err = syscall.Bind(fileDescriptor, localSocketAddress); err != nil {
49-
syscall.Close(fileDescriptor)
51+
if err = syscall.Bind(fd, sockaddr); err != nil {
52+
syscall.Close(fd)
5053
return nil, &net.OpError{Op: "fake", Err: fmt.Errorf("socket bind: %s", err)}
5154
}
5255

53-
fdFile := os.NewFile(uintptr(fileDescriptor), fmt.Sprintf("net-udp-fake-%s", addr.String()))
56+
fdFile := os.NewFile(uintptr(fd), fmt.Sprintf("net-udp-fake-%s", addr.String()))
5457
defer fdFile.Close()
5558

5659
packetConn, err := net.FilePacketConn(fdFile)
5760
if err != nil {
58-
syscall.Close(fileDescriptor)
61+
syscall.Close(fd)
5962
return nil, &net.OpError{Op: "fake", Err: fmt.Errorf("convert file descriptor to connection: %s", err)}
6063
}
6164

6265
return packetConn, nil
6366
}
64-
65-
func udpAddrToSocketAddr(addr *net.UDPAddr) (syscall.Sockaddr, int, error) {
66-
switch {
67-
case addr.IP.To4() != nil:
68-
ip := [4]byte{}
69-
copy(ip[:], addr.IP.To4())
70-
71-
return &syscall.SockaddrInet4{Addr: ip, Port: addr.Port}, syscall.AF_INET, nil
72-
73-
default:
74-
ip := [16]byte{}
75-
copy(ip[:], addr.IP.To16())
76-
77-
return &syscall.SockaddrInet6{Addr: ip, Port: addr.Port, ZoneId: 0}, syscall.AF_INET6, nil
78-
}
79-
}

0 commit comments

Comments
 (0)