girl 0.55.0 → 0.56.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of girl might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/lib/girl/udp.rb +67 -81
- data/lib/girl/udpd.rb +91 -164
- data/lib/girl/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 51cd8eb08b9c349052e54ac302dd4ad2fdfac19b93e80636d20507ab21e1d3b5
|
4
|
+
data.tar.gz: 05d5de915f020e027d938f410a9a875ba92b39cb668a14ad9a3f523ecf5424dd
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0bf9735b27decf69c11b3c2b9701ec6f77f351a95b5ab0585cffbc0d17df0ed0dce0b94cacc5b2b032b9ebf0e7ca13cb2b8ab49ba6c2d300c3a02a0985bbdd21
|
7
|
+
data.tar.gz: a8a5b465ed7ef52108ff56d8ddaf0b5a56e3b10ca1d254f78e069df198d3e3df8d1fe7285ea2e8695e24e9d26d41d72bb803955ad1a90aaa75672c2244aa15e7
|
data/lib/girl/udp.rb
CHANGED
@@ -13,45 +13,6 @@ require 'socket'
|
|
13
13
|
#
|
14
14
|
# iptables -t nat -A PREROUTING -p udp -d game.server.ip -j REDIRECT --to-ports 1313
|
15
15
|
#
|
16
|
-
# p2p flow
|
17
|
-
# =========
|
18
|
-
#
|
19
|
-
# 源地址src发往第二个目的地dst2,iptables会映射一个新的本地端口sport2,用来代理dst2的返程。
|
20
|
-
# 可在nf_conntrack里找到src1和src2,看到映射前的源地址端口是一样的。
|
21
|
-
# 若在sport2没有收到返程30秒过期后,src发往第三个目的地dst3,iptables会把dst3的返程依旧映射在sport2上。因此不能根据映射端口建tun-tund对。
|
22
|
-
#
|
23
|
-
# tund1接到dst2,看作p2p进来,记tund1为src-dst2发送代理。
|
24
|
-
# 取接收者tund1.dst2.receiver,由接收者接数据。
|
25
|
-
# 若接收者为空,据dst2-src找接收者,找到tund2,tund2-tun2传数据,同时tund1发tund2.wmems去dst2。没找到,记tund1.dst2.rbuff。
|
26
|
-
#
|
27
|
-
# src经tun2-tund2发往dst2,记tund2为dst2-src接收者。
|
28
|
-
# 取发送代理tund2.alias_sender,由发送代理发数据。
|
29
|
-
# 若发送代理为空,据src-dst2找发送代理,找到tund1,tund1发数据给dst2,同时tund2转tund1.dst2.rbuffs给tun2。没找到,tund2-dst2,记tund2.wmem。
|
30
|
-
#
|
31
|
-
# 请求匹配服务器:
|
32
|
-
#
|
33
|
-
# redir recv -> src1, dst1, data -> tun1-tund1 data -> set receiver dst1-src: tund1 -> tund1-dst1 data
|
34
|
-
#
|
35
|
-
# 匹配服务器返回:
|
36
|
-
#
|
37
|
-
# tund1 recv -> dst1, data -> tund1-tun1 data -> redir-src1 data
|
38
|
-
#
|
39
|
-
# p1发往p2:
|
40
|
-
#
|
41
|
-
# redir recv -> src2, dst2, data -> tun2-tund2 data -> set receiver dst2-src: tund2 -> alias sender not found -> tund2-dst2 data -> save wmem
|
42
|
-
#
|
43
|
-
# p2后进来:
|
44
|
-
#
|
45
|
-
# tund1 recv -> dst2, data -> set alias sender src-dst2: tund1 -> found receiver tund2 -> tund2-tun2 redir-src2 data -> tund1-dst2 tund2.wmems
|
46
|
-
#
|
47
|
-
# p3进来:
|
48
|
-
#
|
49
|
-
# tund1 recv -> dst3, data -> set alias sender src-dst3: tund1 -> receiver not found -> save data to tund1.dst3.rbuffs
|
50
|
-
#
|
51
|
-
# p1后发往p3:
|
52
|
-
#
|
53
|
-
# redir recv -> src3, dst3, data -> tun3-tund3 data -> set receiver dst3-src: tund3 -> found alias sender tund1 -> tund1-dst3 data -> tund3-tun3 redir-src tund1.dst3.rbuffs
|
54
|
-
#
|
55
16
|
module Girl
|
56
17
|
class Udp
|
57
18
|
|
@@ -83,7 +44,7 @@ module Girl
|
|
83
44
|
# dst_addr: sockaddr
|
84
45
|
# src_addr: sockaddr
|
85
46
|
# tund_addr: sockaddr
|
86
|
-
#
|
47
|
+
# rbuffs: []
|
87
48
|
# wbuffs: []
|
88
49
|
# last_traff_at: now
|
89
50
|
end
|
@@ -136,30 +97,51 @@ module Girl
|
|
136
97
|
def read_redir( redir )
|
137
98
|
data, addrinfo, rflags, *controls = redir.recvmsg
|
138
99
|
src_addr = addrinfo.to_sockaddr
|
139
|
-
|
100
|
+
is_hit_cache = false
|
101
|
+
now = Time.new
|
140
102
|
# puts "debug redir recv #{ data.inspect } from #{ addrinfo.inspect }"
|
141
|
-
# 2 udp 5 src 7 sport 9 [UNREPLIED] 11 dst 13 dport
|
142
|
-
# 2 udp 5 src 7 sport 10 dst 12 dport
|
143
|
-
bin = IO.binread( '/proc/net/nf_conntrack' )
|
144
|
-
rows = bin.split( "\n" ).map { | line | line.split( ' ' ) }
|
145
|
-
row = rows.find { | _row | _row[ 2 ] == 'udp' && ( ( _row[ 9 ] == '[UNREPLIED]' && _row[ 11 ].split( '=' )[ 1 ] == addrinfo.ip_address && _row[ 13 ].split( '=' )[ 1 ].to_i == addrinfo.ip_port ) || ( _row[ 10 ].split( '=' )[ 1 ] == addrinfo.ip_address && _row[ 12 ].split( '=' )[ 1 ].to_i == addrinfo.ip_port ) ) }
|
146
103
|
|
147
|
-
if
|
104
|
+
if @mappings.include?( src_addr )
|
105
|
+
orig_src_addr, dst_addr, timeout, read_at = @mappings[ src_addr ]
|
106
|
+
|
107
|
+
if now - read_at < timeout
|
108
|
+
# puts "debug hit cache #{ addrinfo.inspect }"
|
109
|
+
is_hit_cache = true
|
110
|
+
else
|
111
|
+
# puts "debug cache timeout #{ addrinfo.inspect }"
|
112
|
+
@mappings.delete( src_addr )
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
unless is_hit_cache
|
117
|
+
# 2 udp 4 timeout 5 src 7 sport 9 [UNREPLIED] 11 dst 13 dport
|
118
|
+
# 2 udp 4 timeout 5 src 7 sport 10 dst 12 dport
|
119
|
+
bin = IO.binread( '/proc/net/nf_conntrack' )
|
120
|
+
rows = bin.split( "\n" ).map { | line | line.split( ' ' ) }
|
121
|
+
row = rows.find { | _row | _row[ 2 ] == 'udp' && ( ( _row[ 10 ].split( '=' )[ 1 ] == addrinfo.ip_address && _row[ 12 ].split( '=' )[ 1 ].to_i == addrinfo.ip_port ) || ( _row[ 9 ] == '[UNREPLIED]' && _row[ 11 ].split( '=' )[ 1 ] == addrinfo.ip_address && _row[ 13 ].split( '=' )[ 1 ].to_i == addrinfo.ip_port ) ) }
|
122
|
+
|
123
|
+
unless row
|
124
|
+
puts "miss conntrack #{ addrinfo.inspect } #{ Time.new }"
|
125
|
+
IO.binwrite( '/tmp/nf_conntrack', bin )
|
126
|
+
return
|
127
|
+
end
|
128
|
+
|
129
|
+
timeout = row[ 4 ].to_i
|
148
130
|
orig_src_ip = row[ 5 ].split( '=' )[ 1 ]
|
149
131
|
orig_src_port = row[ 7 ].split( '=' )[ 1 ].to_i
|
150
132
|
dst_ip = row[ 6 ].split( '=' )[ 1 ]
|
151
133
|
dst_port = row[ 8 ].split( '=' )[ 1 ].to_i
|
152
134
|
orig_src_addr = Socket.sockaddr_in( orig_src_port, orig_src_ip )
|
153
135
|
dst_addr = Socket.sockaddr_in( dst_port, dst_ip )
|
154
|
-
|
155
|
-
|
156
|
-
puts "
|
157
|
-
|
136
|
+
|
137
|
+
if Addrinfo.new( dst_addr ).ipv4_private?
|
138
|
+
puts "dst is private? #{ Addrinfo.new( dst_addr ).inspect } #{ Addrinfo.new( src_addr ).inspect } #{ Addrinfo.new( orig_src_addr ).inspect } #{ Time.new }"
|
139
|
+
add_redir_wbuff( redir, dst_addr, data )
|
158
140
|
return
|
159
141
|
end
|
160
142
|
|
161
|
-
puts "
|
162
|
-
orig_src_addr, dst_addr
|
143
|
+
# puts "debug save cache #{ addrinfo.inspect } #{ Addrinfo.new( orig_src_addr ).inspect } #{ Addrinfo.new( dst_addr ).inspect } #{ timeout } #{ now }"
|
144
|
+
@mappings[ src_addr ] = [ orig_src_addr, dst_addr, timeout, now ]
|
163
145
|
end
|
164
146
|
|
165
147
|
tun = @tuns[ [ orig_src_addr, dst_addr ].join ]
|
@@ -169,12 +151,11 @@ module Girl
|
|
169
151
|
|
170
152
|
# puts "debug tun send to udpd #{ Addrinfo.new( orig_src_addr ).inspect } #{ Addrinfo.new( dst_addr ).inspect }"
|
171
153
|
ctlmsg = [ orig_src_addr, dst_addr ].join
|
172
|
-
|
173
|
-
|
174
|
-
@mappings[ src_addr ] = [ orig_src_addr, dst_addr ]
|
154
|
+
add_tun_wbuff( tun, @udpd_addr, ctlmsg )
|
175
155
|
end
|
176
156
|
|
177
|
-
|
157
|
+
tun_info = @tun_infos[ tun ]
|
158
|
+
add_tun_wbuff( tun, tun_info[ :tund_addr ], data )
|
178
159
|
end
|
179
160
|
|
180
161
|
def read_tun( tun )
|
@@ -187,10 +168,15 @@ module Girl
|
|
187
168
|
tund_port = data[ 0, 2 ].unpack( 'n' ).first
|
188
169
|
tund_addr = Socket.sockaddr_in( tund_port, @udpd_host )
|
189
170
|
tun_info[ :tund_addr ] = tund_addr
|
190
|
-
|
171
|
+
|
172
|
+
if tun_info[ :rbuffs ].any?
|
173
|
+
tun_info[ :wbuffs ] += tun_info[ :rbuffs ].map{ | rbuff | [ tund_addr, rbuff ] }
|
174
|
+
tun_info[ :rbuffs ].clear
|
175
|
+
add_write( tun )
|
176
|
+
end
|
177
|
+
|
191
178
|
elsif from_addr == tun_info[ :tund_addr ]
|
192
|
-
@
|
193
|
-
add_write( @redir )
|
179
|
+
add_redir_wbuff( @redir, tun_info[ :src_addr ], data )
|
194
180
|
end
|
195
181
|
end
|
196
182
|
|
@@ -211,34 +197,33 @@ module Girl
|
|
211
197
|
end
|
212
198
|
|
213
199
|
tun_info = @tun_infos[ tun ]
|
214
|
-
ctlmsg = tun_info[ :ctlmsgs ].shift
|
215
|
-
|
216
|
-
if ctlmsg
|
217
|
-
tun.sendmsg( ctlmsg, 0, @udpd_addr )
|
218
|
-
return
|
219
|
-
end
|
220
200
|
|
221
|
-
if tun_info[ :
|
201
|
+
if tun_info[ :wbuffs ].empty?
|
222
202
|
@writes.delete( tun )
|
223
203
|
return
|
224
204
|
end
|
225
205
|
|
226
|
-
data = tun_info[ :wbuffs ].shift
|
227
|
-
tun.sendmsg( data, 0,
|
206
|
+
to_addr, data = tun_info[ :wbuffs ].shift
|
207
|
+
tun.sendmsg( data, 0, to_addr )
|
228
208
|
end
|
229
209
|
|
230
|
-
def
|
231
|
-
|
232
|
-
|
233
|
-
add_write( tun )
|
210
|
+
def add_redir_wbuff( redir, to_addr, data )
|
211
|
+
@redir_wbuffs << [ to_addr, data ]
|
212
|
+
add_write( redir )
|
234
213
|
end
|
235
214
|
|
236
|
-
def
|
237
|
-
|
238
|
-
|
239
|
-
|
215
|
+
def add_tun_wbuff( tun, to_addr, data )
|
216
|
+
tun_info = @tun_infos[ tun ]
|
217
|
+
|
218
|
+
if to_addr
|
219
|
+
tun_info[ :wbuffs ] << [ to_addr, data ]
|
220
|
+
add_write( tun )
|
221
|
+
else
|
222
|
+
tun_info[ :rbuffs ] << data
|
240
223
|
end
|
224
|
+
end
|
241
225
|
|
226
|
+
def add_write( sock )
|
242
227
|
unless @writes.include?( sock )
|
243
228
|
@writes << sock
|
244
229
|
end
|
@@ -262,7 +247,7 @@ module Girl
|
|
262
247
|
@tuns.delete( [ tun_info[ :orig_src_addr ], tun_info[ :dst_addr ] ].join )
|
263
248
|
|
264
249
|
if @mappings.include?( tun_info[ :src_addr ] )
|
265
|
-
orig_src_addr, dst_addr = @mappings[ tun_info[ :src_addr ] ]
|
250
|
+
orig_src_addr, dst_addr, timeout, read_at = @mappings[ tun_info[ :src_addr ] ]
|
266
251
|
|
267
252
|
if orig_src_addr == tun_info[ :orig_src_addr ] && dst_addr == tun_info[ :dst_addr ]
|
268
253
|
@mappings.delete( tun_info[ :src_addr ] )
|
@@ -280,7 +265,7 @@ module Girl
|
|
280
265
|
dst_addr: dst_addr,
|
281
266
|
src_addr: src_addr,
|
282
267
|
tund_addr: nil,
|
283
|
-
|
268
|
+
rbuffs: [],
|
284
269
|
wbuffs: [],
|
285
270
|
last_traff_at: Time.new
|
286
271
|
}
|
@@ -295,13 +280,14 @@ module Girl
|
|
295
280
|
def loop_expire
|
296
281
|
Thread.new do
|
297
282
|
loop do
|
298
|
-
sleep
|
283
|
+
sleep 30
|
299
284
|
|
300
285
|
@mutex.synchronize do
|
301
286
|
now = Time.new
|
302
287
|
|
303
288
|
@tun_infos.values.each do | tun_info |
|
304
|
-
|
289
|
+
# net.netfilter.nf_conntrack_udp_timeout_stream
|
290
|
+
if now - tun_info[ :last_traff_at ] > 180
|
305
291
|
@ctlw.write( [ tun_info[ :orig_src_addr ], tun_info[ :dst_addr ] ].join )
|
306
292
|
end
|
307
293
|
end
|
data/lib/girl/udpd.rb
CHANGED
@@ -22,25 +22,20 @@ module Girl
|
|
22
22
|
@writes = []
|
23
23
|
@closings = []
|
24
24
|
@roles = {
|
25
|
-
ctlr => :ctlr,
|
25
|
+
ctlr => :ctlr, # :ctlr / :udpd / :tund
|
26
26
|
udpd => :udpd
|
27
27
|
}
|
28
|
-
@udpd_wbuffs = []
|
29
|
-
@tunds = {}
|
30
|
-
@
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
# wmems: [] # 写往dst的写后缓存
|
40
|
-
# other_dst_rbuffs: { new_dst_addr => [] }
|
41
|
-
# receivers: { other_dst_addr => other_tund }
|
42
|
-
# last_traff_at: now
|
43
|
-
@od_addr_rbuffs = {}
|
28
|
+
@udpd_wbuffs = [] # [ tun_addr ctlmsg ] ...
|
29
|
+
@tunds = {} # [ tun_ip_addr orig_src_addr ] => tund
|
30
|
+
@tund_infos = {} # tund => {}
|
31
|
+
# port: port
|
32
|
+
# tun_ip_addr: sockaddr
|
33
|
+
# orig_src_addr: sockaddr
|
34
|
+
# wbuffs: [] # [ to_addr, data ] ...
|
35
|
+
# dst_addrs: { tun_addr => dst_addr }
|
36
|
+
# tun_addrs: { dst_addr => tun_addr }
|
37
|
+
# unpaired_dst_rbuffs: { dst_addr => [] }
|
38
|
+
# last_traff_at: now
|
44
39
|
end
|
45
40
|
|
46
41
|
def looping
|
@@ -80,8 +75,8 @@ module Girl
|
|
80
75
|
private
|
81
76
|
|
82
77
|
def read_ctlr( ctlr )
|
83
|
-
|
84
|
-
tund = @tunds[
|
78
|
+
to_addr = ctlr.read( 32 )
|
79
|
+
tund = @tunds[ to_addr ]
|
85
80
|
|
86
81
|
if tund
|
87
82
|
add_closing( tund )
|
@@ -97,14 +92,12 @@ module Girl
|
|
97
92
|
tun_ip_addr = Addrinfo.ip( addrinfo.ip_address ).to_sockaddr
|
98
93
|
|
99
94
|
return unless Addrinfo.new( orig_src_addr ).ipv4?
|
100
|
-
return unless Addrinfo.new( dst_addr ).ipv4?
|
101
95
|
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
tund = new_a_tund( tun_addr, tun_ip_addr, orig_src_addr, dst_addr )
|
106
|
-
end
|
96
|
+
dst_addrinfo = Addrinfo.new( dst_addr )
|
97
|
+
return unless dst_addrinfo.ipv4?
|
98
|
+
return if dst_addrinfo.ipv4_private?
|
107
99
|
|
100
|
+
tund = pair_tund( tun_addr, tun_ip_addr, orig_src_addr, dst_addr )
|
108
101
|
tund_info = @tund_infos[ tund ]
|
109
102
|
tund_port = tund_info[ :port ]
|
110
103
|
|
@@ -119,106 +112,42 @@ module Girl
|
|
119
112
|
from_addr = addrinfo.to_sockaddr
|
120
113
|
tund_info = @tund_infos[ tund ]
|
121
114
|
tund_info[ :last_traff_at ] = Time.new
|
115
|
+
to_addr = tund_info[ :dst_addrs ][ from_addr ]
|
116
|
+
|
117
|
+
if to_addr
|
118
|
+
# 来自tun,发给dst。
|
119
|
+
# 如果对面没来过流量,且在nat里,nat规则是只对去过的目的地做接收,那么,先过去的流量会撞死。
|
120
|
+
# 没关系,撞死的流量通常是打洞数据,撞死在应用掌控之内,打洞数据通常是连发的。
|
121
|
+
# puts "debug #{ data.inspect } from #{ addrinfo.inspect } to #{ Addrinfo.new( to_addr ).inspect }"
|
122
|
+
add_tund_wbuff( tund, to_addr, data )
|
123
|
+
return
|
124
|
+
end
|
122
125
|
|
123
|
-
|
124
|
-
when tund_info[ :tun_addr ]
|
125
|
-
# src经tun2-tund2发往dst2,记tund2为dst2-src接收者。
|
126
|
-
dto_addr = [ tund_info[ :dst_addr ], tund_info[ :tun_ip_addr ], tund_info[ :orig_src_addr ] ].join
|
126
|
+
to_addr = tund_info[ :tun_addrs ][ from_addr ]
|
127
127
|
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
128
|
+
if to_addr
|
129
|
+
# 来自dst,发给tun。
|
130
|
+
# 先发暂存
|
131
|
+
if tund_info[ :unpaired_dst_rbuffs ].include?( from_addr )
|
132
|
+
rbuffs = tund_info[ :unpaired_dst_rbuffs ].delete( from_addr )
|
133
|
+
# puts "debug move tund.dst.rbuffs to tund.wbuffs #{ rbuffs.inspect }"
|
134
|
+
tund_info[ :wbuffs ] += rbuffs.map{ | rbuff | [ to_addr, rbuff ] }
|
135
135
|
end
|
136
136
|
|
137
|
-
#
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
# puts "debug alias sender send #{ data.inspect } to #{ Addrinfo.new( tund_info[ :dst_addr ] ).inspect }"
|
142
|
-
sender.sendmsg( data, 0, tund_info[ :dst_addr ] )
|
143
|
-
else
|
144
|
-
# 若发送代理为空,据src-dst2找发送代理,找到tund1,tund1发数据给dst2,同时tund2转tund1.dst2.rbuffs给tun2。没找到,tund2-dst2,记tund2.wmem。
|
145
|
-
tod_addr = [ tund_info[ :tun_ip_addr ], tund_info[ :orig_src_addr ], tund_info[ :dst_addr ] ].join
|
146
|
-
sender = @alias_senders[ tod_addr ]
|
147
|
-
|
148
|
-
if sender
|
149
|
-
sender.sendmsg( data, 0, tund_info[ :dst_addr ] )
|
150
|
-
tund_info[ :alias_sender ] = sender
|
151
|
-
|
152
|
-
sender_info = @tund_infos[ sender ]
|
153
|
-
rbuffs = sender_info[ :other_dst_rbuffs ].delete( tund_info[ :dst_addr ] )
|
154
|
-
|
155
|
-
if rbuffs
|
156
|
-
# puts "debug move tund1.dst2.rbuffs to tund2.wbuffs #{ rbuffs.inspect }"
|
157
|
-
tund_info[ :wbuffs ] += rbuffs
|
158
|
-
add_write( tund )
|
159
|
-
end
|
160
|
-
else
|
161
|
-
tund.sendmsg( data, 0, tund_info[ :dst_addr ] )
|
162
|
-
|
163
|
-
# 缓存写后,可能是p2p自己先出去,撞死的流量,之后对面进来匹配成对,由发送代理重发。超过5条看做非p2p。
|
164
|
-
if tund_info[ :wmems ].size < 5
|
165
|
-
# puts "debug save wmem #{ data.inspect } #{ Addrinfo.new( tund_info[ :dst_addr ] ).inspect }"
|
166
|
-
tund_info[ :wmems ] << data
|
167
|
-
end
|
168
|
-
end
|
169
|
-
end
|
170
|
-
when tund_info[ :dst_addr ]
|
171
|
-
# puts "debug tund-tun #{ data.inspect } from #{ Addrinfo.new( tund_info[ :dst_addr ] ).inspect }"
|
172
|
-
add_write( tund, data )
|
173
|
-
else
|
174
|
-
# tund1接到dst2,看作p2p进来,记tund1为src-dst2发送代理。
|
175
|
-
# puts "debug tund recv #{ data.inspect } from #{ addrinfo.inspect }"
|
176
|
-
tod_addr = [ tund_info[ :tun_ip_addr ], tund_info[ :orig_src_addr ], from_addr ].join
|
177
|
-
|
178
|
-
if @alias_senders[ tod_addr ]
|
179
|
-
if @alias_senders[ tod_addr ] != tund
|
180
|
-
puts "alias sender not unique? #{ Addrinfo.new( tund_info[ :tun_ip_addr ] ).inspect } #{ Addrinfo.new( tund_info[ :orig_src_addr ] ).inspect } #{ addrinfo.inspect }"
|
181
|
-
return
|
182
|
-
end
|
183
|
-
else
|
184
|
-
@alias_senders[ tod_addr ] = tund
|
185
|
-
end
|
186
|
-
|
187
|
-
# 取接收者tund1.dst2.receiver,由接收者接数据。
|
188
|
-
receiver = tund_info[ :receivers ][ from_addr ]
|
189
|
-
|
190
|
-
if receiver
|
191
|
-
receiver_info = @tund_infos[ receiver ]
|
192
|
-
add_write( receiver, data )
|
193
|
-
else
|
194
|
-
# 若接收者为空,据dst2-src找接收者,找到tund2,tund2-tun2传数据,同时tund1转tund2.wmems给dst2。没找到,记tund1.dst2.rbuff。
|
195
|
-
dto_addr = [ from_addr, tund_info[ :tun_ip_addr ], tund_info[ :orig_src_addr ] ].join
|
196
|
-
receiver = @receivers[ dto_addr ]
|
197
|
-
|
198
|
-
if receiver
|
199
|
-
add_write( receiver, data )
|
200
|
-
|
201
|
-
tund_info[ :receivers ][ from_addr ] = receiver
|
202
|
-
receiver_info = @tund_infos[ receiver ]
|
203
|
-
|
204
|
-
receiver_info[ :wmems ].each do | wmem |
|
205
|
-
# puts "debug send wmem #{ wmem.inspect } to #{ addrinfo.inspect }"
|
206
|
-
tund.sendmsg( wmem, 0, from_addr )
|
207
|
-
end
|
137
|
+
# puts "debug #{ data.inspect } from #{ addrinfo.inspect } to #{ Addrinfo.new( to_addr ).inspect }"
|
138
|
+
add_tund_wbuff( tund, to_addr, data )
|
139
|
+
return
|
140
|
+
end
|
208
141
|
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
end
|
142
|
+
# 来自未知的地方,看做是p2p对面先到。
|
143
|
+
unless tund_info[ :unpaired_dst_rbuffs ][ from_addr ]
|
144
|
+
tund_info[ :unpaired_dst_rbuffs ][ from_addr ] = []
|
145
|
+
end
|
214
146
|
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
end
|
220
|
-
end
|
221
|
-
end
|
147
|
+
# 暂存5条(连发打洞数据,不需要存多)。
|
148
|
+
if tund_info[ :unpaired_dst_rbuffs ][ from_addr ].size < 5
|
149
|
+
# puts "debug save other dst rbuff #{ addrinfo.inspect } #{ data.inspect }"
|
150
|
+
tund_info[ :unpaired_dst_rbuffs ][ from_addr ] << data
|
222
151
|
end
|
223
152
|
end
|
224
153
|
|
@@ -245,16 +174,18 @@ module Girl
|
|
245
174
|
return
|
246
175
|
end
|
247
176
|
|
248
|
-
data = tund_info[ :wbuffs ].shift
|
249
|
-
tund.sendmsg( data, 0,
|
177
|
+
to_addr, data = tund_info[ :wbuffs ].shift
|
178
|
+
tund.sendmsg( data, 0, to_addr )
|
250
179
|
end
|
251
180
|
|
252
|
-
def
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
181
|
+
def add_tund_wbuff( tund, to_addr, data )
|
182
|
+
tund_info = @tund_infos[ tund ]
|
183
|
+
tund_info[ :wbuffs ] << [ to_addr, data ]
|
184
|
+
|
185
|
+
add_write( tund )
|
186
|
+
end
|
257
187
|
|
188
|
+
def add_write( sock )
|
258
189
|
unless @writes.include?( sock )
|
259
190
|
@writes << sock
|
260
191
|
end
|
@@ -275,44 +206,39 @@ module Girl
|
|
275
206
|
@closings.delete( tund )
|
276
207
|
@roles.delete( tund )
|
277
208
|
tund_info = @tund_infos.delete( tund )
|
278
|
-
@tunds.delete( tund_info[ :
|
279
|
-
|
280
|
-
tod_addr = [ tund_info[ :tun_ip_addr ], tund_info[ :orig_src_addr ], tund_info[ :dst_addr ] ].join
|
281
|
-
|
282
|
-
if @alias_senders[ tod_addr ] && @alias_senders[ tod_addr ] == tund
|
283
|
-
@alias_senders.delete( tod_addr )
|
284
|
-
end
|
285
|
-
|
286
|
-
dto_addr = [ tund_info[ :dst_addr ], tund_info[ :tun_ip_addr ], tund_info[ :orig_src_addr ] ].join
|
287
|
-
|
288
|
-
if @receivers[ dto_addr ] && @receivers[ dto_addr ] == tund
|
289
|
-
@receivers.delete( dto_addr )
|
290
|
-
end
|
209
|
+
@tunds.delete( [ tund_info[ :tun_ip_addr ], tund_info[ :orig_src_addr ] ].join )
|
291
210
|
end
|
292
211
|
|
293
|
-
def
|
294
|
-
|
295
|
-
tund
|
296
|
-
tund.setsockopt( Socket::SOL_SOCKET, Socket::SO_BROADCAST, 1 )
|
297
|
-
tund.bind( Socket.sockaddr_in( 0, '0.0.0.0' ) )
|
298
|
-
tund_port = tund.local_address.ip_unpack.last
|
299
|
-
|
300
|
-
@tunds[ tun_addr ] = tund
|
301
|
-
@tund_infos[ tund ] = {
|
302
|
-
port: tund_port,
|
303
|
-
tun_addr: tun_addr,
|
304
|
-
tun_ip_addr: tun_ip_addr,
|
305
|
-
orig_src_addr: orig_src_addr,
|
306
|
-
dst_addr: dst_addr,
|
307
|
-
wbuffs: [],
|
308
|
-
wmems: [],
|
309
|
-
other_dst_rbuffs: {},
|
310
|
-
receivers: {},
|
311
|
-
last_traff_at: Time.new
|
312
|
-
}
|
212
|
+
def pair_tund( tun_addr, tun_ip_addr, orig_src_addr, dst_addr )
|
213
|
+
from_addr = [ tun_ip_addr, orig_src_addr ].join
|
214
|
+
tund = @tunds[ from_addr ]
|
313
215
|
|
314
|
-
|
315
|
-
|
216
|
+
if tund
|
217
|
+
tund_info = @tund_infos[ tund ]
|
218
|
+
tund_info[ :dst_addrs ][ tun_addr ] = dst_addr
|
219
|
+
tund_info[ :tun_addrs ][ dst_addr ] = tun_addr
|
220
|
+
else
|
221
|
+
tund = Socket.new( Socket::AF_INET, Socket::SOCK_DGRAM, 0 )
|
222
|
+
tund.setsockopt( Socket::SOL_SOCKET, Socket::SO_REUSEPORT, 1 )
|
223
|
+
tund.setsockopt( Socket::SOL_SOCKET, Socket::SO_BROADCAST, 1 )
|
224
|
+
tund.bind( Socket.sockaddr_in( 0, '0.0.0.0' ) )
|
225
|
+
tund_port = tund.local_address.ip_unpack.last
|
226
|
+
|
227
|
+
@tund_infos[ tund ] = {
|
228
|
+
port: tund_port,
|
229
|
+
tun_ip_addr: tun_ip_addr,
|
230
|
+
orig_src_addr: orig_src_addr,
|
231
|
+
wbuffs: [],
|
232
|
+
dst_addrs: { tun_addr => dst_addr },
|
233
|
+
tun_addrs: { dst_addr => tun_addr },
|
234
|
+
unpaired_dst_rbuffs: {},
|
235
|
+
last_traff_at: Time.new
|
236
|
+
}
|
237
|
+
|
238
|
+
@roles[ tund ] = :tund
|
239
|
+
@reads << tund
|
240
|
+
@tunds[ from_addr ] = tund
|
241
|
+
end
|
316
242
|
|
317
243
|
tund
|
318
244
|
end
|
@@ -320,14 +246,15 @@ module Girl
|
|
320
246
|
def loop_expire
|
321
247
|
Thread.new do
|
322
248
|
loop do
|
323
|
-
sleep
|
249
|
+
sleep 30
|
324
250
|
|
325
251
|
@mutex.synchronize do
|
326
252
|
now = Time.new
|
327
253
|
|
328
254
|
@tund_infos.values.each do | tund_info |
|
329
|
-
|
330
|
-
|
255
|
+
# net.netfilter.nf_conntrack_udp_timeout_stream
|
256
|
+
if now - tund_info[ :last_traff_at ] > 180
|
257
|
+
@ctlw.write( [ tund_info[ :tun_ip_addr ], tund_info[ :orig_src_addr ] ].join )
|
331
258
|
end
|
332
259
|
end
|
333
260
|
end
|
data/lib/girl/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: girl
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.56.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- takafan
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-04-
|
11
|
+
date: 2020-04-09 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: while internet is evil, here's a girl.
|
14
14
|
email:
|