@@ -43,14 +43,15 @@ func newNatTable() *natTable {
43
43
return & natTable {conns : map [string ]net.PacketConn {}}
44
44
}
45
45
46
- func (table * natTable ) DeleteAndClose (index string ) {
46
+ func (table * natTable ) Delete (index string ) net. PacketConn {
47
47
table .Lock ()
48
48
defer table .Unlock ()
49
49
c , ok := table .conns [index ]
50
50
if ok {
51
- c .Close ()
52
51
delete (table .conns , index )
52
+ return c
53
53
}
54
+ return nil
54
55
}
55
56
56
57
func (table * natTable ) Get (index string ) (c net.PacketConn , ok bool , err error ) {
@@ -67,13 +68,13 @@ func (table *natTable) Get(index string) (c net.PacketConn, ok bool, err error)
67
68
return
68
69
}
69
70
70
- type ReqList struct {
71
+ type requestHeaderList struct {
71
72
sync.Mutex
72
73
List map [string ]([]byte )
73
74
}
74
75
75
- func newReqList () * ReqList {
76
- ret := & ReqList {List : map [string ]([]byte ){}}
76
+ func newReqList () * requestHeaderList {
77
+ ret := & requestHeaderList {List : map [string ]([]byte ){}}
77
78
go func () {
78
79
for {
79
80
time .Sleep (reqListRefreshTime )
@@ -83,29 +84,29 @@ func newReqList() *ReqList {
83
84
return ret
84
85
}
85
86
86
- func (r * ReqList ) Refresh () {
87
+ func (r * requestHeaderList ) Refresh () {
87
88
r .Lock ()
88
89
defer r .Unlock ()
89
90
for k , _ := range r .List {
90
91
delete (r .List , k )
91
92
}
92
93
}
93
94
94
- func (r * ReqList ) Get (dstaddr string ) (req []byte , ok bool ) {
95
+ func (r * requestHeaderList ) Get (dstaddr string ) (req []byte , ok bool ) {
95
96
r .Lock ()
96
97
defer r .Unlock ()
97
98
req , ok = r .List [dstaddr ]
98
99
return
99
100
}
100
101
101
- func (r * ReqList ) Put (dstaddr string , req []byte ) {
102
+ func (r * requestHeaderList ) Put (dstaddr string , req []byte ) {
102
103
r .Lock ()
103
104
defer r .Unlock ()
104
105
r .List [dstaddr ] = req
105
106
return
106
107
}
107
108
108
- func ParseHeader (addr net.Addr ) ([]byte , int ) {
109
+ func parseHeaderFromAddr (addr net.Addr ) ([]byte , int ) {
109
110
// if the request address type is domain, it cannot be reverselookuped
110
111
ip , port , err := net .SplitHostPort (addr .String ())
111
112
if err != nil {
@@ -129,13 +130,13 @@ func ParseHeader(addr net.Addr) ([]byte, int) {
129
130
return buf [:1 + iplen + 2 ], 1 + iplen + 2
130
131
}
131
132
132
- func Pipeloop (ss * SecurePacketConn , addr net.Addr , in net.PacketConn , compatiblemode bool ) {
133
+ func Pipeloop (write net. PacketConn , writeAddr net.Addr , readClose net.PacketConn ) {
133
134
buf := leakyBuf .Get ()
134
135
defer leakyBuf .Put (buf )
135
- defer in .Close ()
136
+ defer readClose .Close ()
136
137
for {
137
- in .SetDeadline (time .Now ().Add (udpTimeout ))
138
- n , raddr , err := in .ReadFrom (buf )
138
+ readClose .SetDeadline (time .Now ().Add (udpTimeout ))
139
+ n , raddr , err := readClose .ReadFrom (buf )
139
140
if err != nil {
140
141
if ne , ok := err .(* net.OpError ); ok {
141
142
if ne .Err == syscall .EMFILE || ne .Err == syscall .ENFILE {
@@ -144,24 +145,15 @@ func Pipeloop(ss *SecurePacketConn, addr net.Addr, in net.PacketConn, compatible
144
145
Debug .Println ("[udp]read error:" , err )
145
146
}
146
147
}
147
- Debug .Printf ("[udp]closed pipe %s<-%s\n " , addr , in .LocalAddr ())
148
+ Debug .Printf ("[udp]closed pipe %s<-%s\n " , writeAddr , readClose .LocalAddr ())
148
149
return
149
150
}
150
151
// need improvement here
151
152
if req , ok := reqList .Get (raddr .String ()); ok {
152
- if compatiblemode {
153
- ss .ForceOTAWriteTo (append (req , buf [:n ]... ), addr )
154
- } else {
155
- ss .WriteTo (append (req , buf [:n ]... ), addr )
156
- }
153
+ write .WriteTo (append (req , buf [:n ]... ), writeAddr )
157
154
} else {
158
- header , hlen := ParseHeader (raddr )
159
- if compatiblemode {
160
- ss .ForceOTAWriteTo (append (header [:hlen ], buf [:n ]... ), addr )
161
- } else {
162
- ss .WriteTo (append (header [:hlen ], buf [:n ]... ), addr )
163
- }
164
-
155
+ header , hlen := parseHeaderFromAddr (raddr )
156
+ write .WriteTo (append (header [:hlen ], buf [:n ]... ), writeAddr )
165
157
}
166
158
}
167
159
}
@@ -176,6 +168,7 @@ func handleUDPConnection(handle *SecurePacketConn, n int, src net.Addr, receive
176
168
if addrType & OneTimeAuthMask > 0 {
177
169
ota = true
178
170
}
171
+ receive [idType ] &= ^ OneTimeAuthMask
179
172
compatiblemode := ! handle .IsOta () && ota
180
173
181
174
switch addrType & AddrMask {
@@ -229,8 +222,13 @@ func handleUDPConnection(handle *SecurePacketConn, n int, src net.Addr, receive
229
222
if ! exist {
230
223
Debug .Printf ("[udp]new client %s->%s via %s ota=%v\n " , src , dst , remote .LocalAddr (), ota )
231
224
go func () {
232
- Pipeloop (handle , src , remote , compatiblemode )
233
- natlist .DeleteAndClose (src .String ())
225
+ if compatiblemode {
226
+ Pipeloop (handle .ForceOTA (), src , remote )
227
+ } else {
228
+ Pipeloop (handle , src , remote )
229
+ }
230
+
231
+ natlist .Delete (src .String ())
234
232
}()
235
233
} else {
236
234
Debug .Printf ("[udp]using cached client %s->%s via %s ota=%v\n " , src , dst , remote .LocalAddr (), ota )
@@ -248,7 +246,9 @@ func handleUDPConnection(handle *SecurePacketConn, n int, src net.Addr, receive
248
246
} else {
249
247
Debug .Println ("[udp]error connecting to:" , dst , err )
250
248
}
251
- natlist .DeleteAndClose (src .String ())
249
+ if conn := natlist .Delete (src .String ()); conn != nil {
250
+ conn .Close ()
251
+ }
252
252
}
253
253
// Pipeloop
254
254
return
0 commit comments