@@ -12,68 +12,55 @@ import (
1212)
1313
1414func 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