girl 0.99.0 → 1.0.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/girl.gemspec +0 -2
- data/lib/girl/proxy_worker.rb +114 -112
- data/lib/girl/proxyd_worker.rb +6 -5
- data/lib/girl/version.rb +1 -1
- metadata +2 -4
- data/lib/girl/udp.rb +0 -326
- data/lib/girl/udpd.rb +0 -316
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0c0254d6f9509721f13f14148087071820ae5ad13a3a7a87884d5372e7d93035
|
4
|
+
data.tar.gz: 2e718e248d7b3967e350a0dd4b6266c2a396a7eb5193a2fcd419222606b9ac19
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f9546abfd9b420cf80fa128670ba0db60e95bf54ed88466e1309820bb247ced3e7aa552d6afb93db12388a35b3d432d6994dfe2ea9a5f80580c82dce8655ff66
|
7
|
+
data.tar.gz: 7e3b2c573cd03bb284cc5d51a44b0c4aa882f7c069759f63075216759cf5abdab44f80babe5f3dbe81c126a05d9e1449c9e65bab0d34e3a9f184a417e922d326
|
data/girl.gemspec
CHANGED
data/lib/girl/proxy_worker.rb
CHANGED
@@ -121,12 +121,17 @@ module Girl
|
|
121
121
|
end
|
122
122
|
|
123
123
|
##
|
124
|
-
# add
|
124
|
+
# add dst wbuff
|
125
125
|
#
|
126
|
-
def
|
127
|
-
|
128
|
-
|
129
|
-
|
126
|
+
def add_dst_wbuff( dst, data )
|
127
|
+
dst_info = @dst_infos[ dst ]
|
128
|
+
dst_info[ :wbuff ] << data
|
129
|
+
add_write( dst )
|
130
|
+
|
131
|
+
if dst_info[ :wbuff ].bytesize >= WBUFF_LIMIT then
|
132
|
+
puts "p#{ Process.pid } #{ Time.new } pause direct src #{ dst_info[ :domain ] }"
|
133
|
+
add_paused_src( dst_info[ :src ] )
|
134
|
+
end
|
130
135
|
end
|
131
136
|
|
132
137
|
##
|
@@ -138,6 +143,15 @@ module Girl
|
|
138
143
|
@paused_dsts << dst
|
139
144
|
end
|
140
145
|
|
146
|
+
##
|
147
|
+
# add paused src
|
148
|
+
#
|
149
|
+
def add_paused_src( src )
|
150
|
+
return if src.closed? || @paused_srcs.include?( src )
|
151
|
+
@reads.delete( src )
|
152
|
+
@paused_srcs << src
|
153
|
+
end
|
154
|
+
|
141
155
|
##
|
142
156
|
# add paused stream
|
143
157
|
#
|
@@ -161,20 +175,20 @@ module Girl
|
|
161
175
|
end
|
162
176
|
|
163
177
|
##
|
164
|
-
# add resume
|
178
|
+
# add resume dst
|
165
179
|
#
|
166
|
-
def
|
167
|
-
return if @
|
168
|
-
@
|
180
|
+
def add_resume_dst( dst )
|
181
|
+
return if @resume_dsts.include?( dst )
|
182
|
+
@resume_dsts << dst
|
169
183
|
next_tick
|
170
184
|
end
|
171
185
|
|
172
186
|
##
|
173
|
-
# add resume
|
187
|
+
# add resume src
|
174
188
|
#
|
175
|
-
def
|
176
|
-
return if @
|
177
|
-
@
|
189
|
+
def add_resume_src( src )
|
190
|
+
return if @resume_srcs.include?( src )
|
191
|
+
@resume_srcs << src
|
178
192
|
next_tick
|
179
193
|
end
|
180
194
|
|
@@ -187,20 +201,6 @@ module Girl
|
|
187
201
|
next_tick
|
188
202
|
end
|
189
203
|
|
190
|
-
##
|
191
|
-
# add dst wbuff
|
192
|
-
#
|
193
|
-
def add_dst_wbuff( dst, data )
|
194
|
-
dst_info = @dst_infos[ dst ]
|
195
|
-
dst_info[ :wbuff ] << data
|
196
|
-
add_write( dst )
|
197
|
-
|
198
|
-
if dst_info[ :wbuff ].bytesize >= WBUFF_LIMIT then
|
199
|
-
puts "p#{ Process.pid } #{ Time.new } pause direct src #{ dst_info[ :domain ] }"
|
200
|
-
add_paused_src( dst_info[ :src ] )
|
201
|
-
end
|
202
|
-
end
|
203
|
-
|
204
204
|
##
|
205
205
|
# add src rbuff
|
206
206
|
#
|
@@ -241,20 +241,6 @@ module Girl
|
|
241
241
|
end
|
242
242
|
end
|
243
243
|
|
244
|
-
##
|
245
|
-
# add stream wbuff
|
246
|
-
#
|
247
|
-
def add_stream_wbuff( stream, data )
|
248
|
-
stream_info = @stream_infos[ stream ]
|
249
|
-
stream_info[ :wbuff ] << data
|
250
|
-
add_write( stream )
|
251
|
-
|
252
|
-
if stream_info[ :wbuff ].bytesize >= WBUFF_LIMIT then
|
253
|
-
puts "p#{ Process.pid } #{ Time.new } pause tunnel src #{ stream_info[ :domain ] }"
|
254
|
-
add_paused_src( stream_info[ :src ] )
|
255
|
-
end
|
256
|
-
end
|
257
|
-
|
258
244
|
##
|
259
245
|
# add src wbuff socks5 conn reply
|
260
246
|
#
|
@@ -270,6 +256,20 @@ module Girl
|
|
270
256
|
add_src_wbuff( src, data )
|
271
257
|
end
|
272
258
|
|
259
|
+
##
|
260
|
+
# add stream wbuff
|
261
|
+
#
|
262
|
+
def add_stream_wbuff( stream, data )
|
263
|
+
stream_info = @stream_infos[ stream ]
|
264
|
+
stream_info[ :wbuff ] << data
|
265
|
+
add_write( stream )
|
266
|
+
|
267
|
+
if stream_info[ :wbuff ].bytesize >= WBUFF_LIMIT then
|
268
|
+
puts "p#{ Process.pid } #{ Time.new } pause tunnel src #{ stream_info[ :domain ] }"
|
269
|
+
add_paused_src( stream_info[ :src ] )
|
270
|
+
end
|
271
|
+
end
|
272
|
+
|
273
273
|
##
|
274
274
|
# add write
|
275
275
|
#
|
@@ -280,13 +280,23 @@ module Girl
|
|
280
280
|
end
|
281
281
|
|
282
282
|
##
|
283
|
-
# close
|
283
|
+
# close read dst
|
284
284
|
#
|
285
|
-
def
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
@
|
285
|
+
def close_read_dst( dst )
|
286
|
+
return if dst.closed?
|
287
|
+
# puts "debug1 close read dst"
|
288
|
+
dst.close_read
|
289
|
+
@reads.delete( dst )
|
290
|
+
|
291
|
+
if dst.closed? then
|
292
|
+
# puts "debug1 delete dst info"
|
293
|
+
@roles.delete( dst )
|
294
|
+
dst_info = @dst_infos.delete( dst )
|
295
|
+
else
|
296
|
+
dst_info = @dst_infos[ dst ]
|
297
|
+
end
|
298
|
+
|
299
|
+
dst_info
|
290
300
|
end
|
291
301
|
|
292
302
|
##
|
@@ -309,26 +319,6 @@ module Girl
|
|
309
319
|
src_info
|
310
320
|
end
|
311
321
|
|
312
|
-
##
|
313
|
-
# close read dst
|
314
|
-
#
|
315
|
-
def close_read_dst( dst )
|
316
|
-
return if dst.closed?
|
317
|
-
# puts "debug1 close read dst"
|
318
|
-
dst.close_read
|
319
|
-
@reads.delete( dst )
|
320
|
-
|
321
|
-
if dst.closed? then
|
322
|
-
# puts "debug1 delete dst info"
|
323
|
-
@roles.delete( dst )
|
324
|
-
dst_info = @dst_infos.delete( dst )
|
325
|
-
else
|
326
|
-
dst_info = @dst_infos[ dst ]
|
327
|
-
end
|
328
|
-
|
329
|
-
dst_info
|
330
|
-
end
|
331
|
-
|
332
322
|
##
|
333
323
|
# close read stream
|
334
324
|
#
|
@@ -349,6 +339,16 @@ module Girl
|
|
349
339
|
stream_info
|
350
340
|
end
|
351
341
|
|
342
|
+
##
|
343
|
+
# close sock
|
344
|
+
#
|
345
|
+
def close_sock( sock )
|
346
|
+
sock.close
|
347
|
+
@reads.delete( sock )
|
348
|
+
@writes.delete( sock )
|
349
|
+
@roles.delete( sock )
|
350
|
+
end
|
351
|
+
|
352
352
|
##
|
353
353
|
# close src
|
354
354
|
#
|
@@ -360,14 +360,14 @@ module Girl
|
|
360
360
|
dst = src_info[ :dst ]
|
361
361
|
|
362
362
|
if dst then
|
363
|
-
|
364
|
-
|
363
|
+
close_sock( dst )
|
364
|
+
@dst_infos.delete( dst )
|
365
365
|
else
|
366
366
|
stream = src_info[ :stream ]
|
367
367
|
|
368
368
|
if stream then
|
369
|
-
|
370
|
-
|
369
|
+
close_sock( stream )
|
370
|
+
@stream_infos.delete( stream )
|
371
371
|
end
|
372
372
|
end
|
373
373
|
end
|
@@ -382,26 +382,6 @@ module Girl
|
|
382
382
|
@tun_info[ :srcs ].each{ | _, src | close_src( src ) }
|
383
383
|
end
|
384
384
|
|
385
|
-
##
|
386
|
-
# close write src
|
387
|
-
#
|
388
|
-
def close_write_src( src )
|
389
|
-
return if src.closed?
|
390
|
-
# puts "debug1 close write src"
|
391
|
-
src.close_write
|
392
|
-
@writes.delete( src )
|
393
|
-
|
394
|
-
if src.closed? then
|
395
|
-
# puts "debug1 delete src info"
|
396
|
-
@roles.delete( src )
|
397
|
-
src_info = del_src_info( src )
|
398
|
-
else
|
399
|
-
src_info = @src_infos[ src ]
|
400
|
-
end
|
401
|
-
|
402
|
-
src_info
|
403
|
-
end
|
404
|
-
|
405
385
|
##
|
406
386
|
# close write dst
|
407
387
|
#
|
@@ -422,6 +402,26 @@ module Girl
|
|
422
402
|
dst_info
|
423
403
|
end
|
424
404
|
|
405
|
+
##
|
406
|
+
# close write src
|
407
|
+
#
|
408
|
+
def close_write_src( src )
|
409
|
+
return if src.closed?
|
410
|
+
# puts "debug1 close write src"
|
411
|
+
src.close_write
|
412
|
+
@writes.delete( src )
|
413
|
+
|
414
|
+
if src.closed? then
|
415
|
+
# puts "debug1 delete src info"
|
416
|
+
@roles.delete( src )
|
417
|
+
src_info = del_src_info( src )
|
418
|
+
else
|
419
|
+
src_info = @src_infos[ src ]
|
420
|
+
end
|
421
|
+
|
422
|
+
src_info
|
423
|
+
end
|
424
|
+
|
425
425
|
##
|
426
426
|
# close write stream
|
427
427
|
#
|
@@ -628,6 +628,7 @@ module Girl
|
|
628
628
|
# connect nonblock 必抛 wait writable
|
629
629
|
rescue Exception => e
|
630
630
|
puts "p#{ Process.pid } #{ Time.new } dst connect destination #{ domain } #{ src_info[ :destination_port ] } #{ ip_info.ip_address } #{ e.class }, close src"
|
631
|
+
dst.close
|
631
632
|
add_closing_src( src )
|
632
633
|
return
|
633
634
|
end
|
@@ -659,6 +660,25 @@ module Girl
|
|
659
660
|
end
|
660
661
|
end
|
661
662
|
|
663
|
+
##
|
664
|
+
# new a proxy
|
665
|
+
#
|
666
|
+
def new_a_proxy( proxy_port )
|
667
|
+
proxy = Socket.new( Socket::AF_INET, Socket::SOCK_STREAM, 0 )
|
668
|
+
proxy.setsockopt( Socket::SOL_SOCKET, Socket::SO_REUSEADDR, 1 )
|
669
|
+
|
670
|
+
if RUBY_PLATFORM.include?( 'linux' ) then
|
671
|
+
proxy.setsockopt( Socket::SOL_SOCKET, Socket::SO_REUSEPORT, 1 )
|
672
|
+
proxy.setsockopt( Socket::SOL_TCP, Socket::TCP_NODELAY, 1 )
|
673
|
+
end
|
674
|
+
|
675
|
+
proxy.bind( Socket.sockaddr_in( proxy_port, '0.0.0.0' ) )
|
676
|
+
proxy.listen( 127 )
|
677
|
+
puts "p#{ Process.pid } #{ Time.new } proxy listen on #{ proxy_port }"
|
678
|
+
add_read( proxy, :proxy )
|
679
|
+
@proxy_local_address = proxy.local_address
|
680
|
+
end
|
681
|
+
|
662
682
|
##
|
663
683
|
# new a stream
|
664
684
|
#
|
@@ -683,6 +703,7 @@ module Girl
|
|
683
703
|
rescue IO::WaitWritable
|
684
704
|
rescue Exception => e
|
685
705
|
puts "p#{ Process.pid } #{ Time.new } connect tcpd #{ e.class }"
|
706
|
+
stream.close
|
686
707
|
return
|
687
708
|
end
|
688
709
|
|
@@ -717,25 +738,6 @@ module Girl
|
|
717
738
|
end
|
718
739
|
end
|
719
740
|
|
720
|
-
##
|
721
|
-
# new a proxy
|
722
|
-
#
|
723
|
-
def new_a_proxy( proxy_port )
|
724
|
-
proxy = Socket.new( Socket::AF_INET, Socket::SOCK_STREAM, 0 )
|
725
|
-
proxy.setsockopt( Socket::SOL_SOCKET, Socket::SO_REUSEADDR, 1 )
|
726
|
-
|
727
|
-
if RUBY_PLATFORM.include?( 'linux' ) then
|
728
|
-
proxy.setsockopt( Socket::SOL_SOCKET, Socket::SO_REUSEPORT, 1 )
|
729
|
-
proxy.setsockopt( Socket::SOL_TCP, Socket::TCP_NODELAY, 1 )
|
730
|
-
end
|
731
|
-
|
732
|
-
proxy.bind( Socket.sockaddr_in( proxy_port, '0.0.0.0' ) )
|
733
|
-
proxy.listen( 127 )
|
734
|
-
puts "p#{ Process.pid } #{ Time.new } proxy listen on #{ proxy_port }"
|
735
|
-
add_read( proxy, :proxy )
|
736
|
-
@proxy_local_address = proxy.local_address
|
737
|
-
end
|
738
|
-
|
739
741
|
##
|
740
742
|
# new a tun
|
741
743
|
#
|
@@ -793,7 +795,7 @@ module Girl
|
|
793
795
|
#
|
794
796
|
def resolve_domain( src, domain )
|
795
797
|
if @remotes.any? { | remote | ( domain.size >= remote.size ) && ( domain[ ( remote.size * -1 )..-1 ] == remote ) } then
|
796
|
-
|
798
|
+
puts "p#{ Process.pid } #{ Time.new } #{ domain } hit remotes"
|
797
799
|
set_src_proxy_type_tunnel( src )
|
798
800
|
return
|
799
801
|
end
|
@@ -1012,7 +1014,7 @@ module Girl
|
|
1012
1014
|
#
|
1013
1015
|
def read_tun( tun )
|
1014
1016
|
return if tun.closed?
|
1015
|
-
|
1017
|
+
|
1016
1018
|
begin
|
1017
1019
|
data, addrinfo, rflags, *controls = tun.recvmsg_nonblock
|
1018
1020
|
rescue IO::WaitReadable, Errno::EINTR
|
data/lib/girl/proxyd_worker.rb
CHANGED
@@ -262,8 +262,8 @@ module Girl
|
|
262
262
|
streamd = dst_info[ :streamd ]
|
263
263
|
|
264
264
|
if streamd then
|
265
|
-
|
266
|
-
|
265
|
+
close_sock( streamd )
|
266
|
+
@streamd_infos.delete( streamd )
|
267
267
|
end
|
268
268
|
end
|
269
269
|
|
@@ -328,8 +328,8 @@ module Girl
|
|
328
328
|
dst = streamd_info[ :dst ]
|
329
329
|
|
330
330
|
if dst then
|
331
|
-
|
332
|
-
|
331
|
+
close_sock( dst )
|
332
|
+
del_dst_info( dst )
|
333
333
|
end
|
334
334
|
end
|
335
335
|
|
@@ -399,6 +399,7 @@ module Girl
|
|
399
399
|
rescue IO::WaitWritable
|
400
400
|
rescue Exception => e
|
401
401
|
puts "p#{ Process.pid } #{ Time.new } connect destination #{ domain_port } #{ e.class }"
|
402
|
+
dst.close
|
402
403
|
return false
|
403
404
|
end
|
404
405
|
|
@@ -443,7 +444,7 @@ module Girl
|
|
443
444
|
tund_info[ :dsts ].delete( dst_info[ :id ] )
|
444
445
|
tund_info[ :dst_ids ].delete( dst_info[ :src_id ] )
|
445
446
|
end
|
446
|
-
|
447
|
+
|
447
448
|
dst_info
|
448
449
|
end
|
449
450
|
|
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: 1.0.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-
|
11
|
+
date: 2020-11-21 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: escape evil.
|
14
14
|
email:
|
@@ -27,8 +27,6 @@ files:
|
|
27
27
|
- lib/girl/proxyd.rb
|
28
28
|
- lib/girl/proxyd_custom.rb
|
29
29
|
- lib/girl/proxyd_worker.rb
|
30
|
-
- lib/girl/udp.rb
|
31
|
-
- lib/girl/udpd.rb
|
32
30
|
- lib/girl/version.rb
|
33
31
|
homepage: https://github.com/takafan/girl
|
34
32
|
licenses:
|
data/lib/girl/udp.rb
DELETED
@@ -1,326 +0,0 @@
|
|
1
|
-
require 'girl/version'
|
2
|
-
require 'socket'
|
3
|
-
|
4
|
-
##
|
5
|
-
# Girl::Udp - udp透明转发,近端。
|
6
|
-
#
|
7
|
-
# usage
|
8
|
-
# ======
|
9
|
-
#
|
10
|
-
# Girl::Udpd.new( 3030 ).looping # 远端
|
11
|
-
#
|
12
|
-
# Girl::Udp.new( 'your.server.ip', 3030, 1313 ).looping # 近端
|
13
|
-
#
|
14
|
-
# iptables -t nat -A PREROUTING -p udp -d game.server.ip -j REDIRECT --to-ports 1313
|
15
|
-
#
|
16
|
-
module Girl
|
17
|
-
class Udp
|
18
|
-
|
19
|
-
def initialize( udpd_host, udpd_port = 3030, redir_port = 1313 )
|
20
|
-
@udpd_host = udpd_host
|
21
|
-
@udpd_addr = Socket.sockaddr_in( udpd_port, udpd_host )
|
22
|
-
@mutex = Mutex.new
|
23
|
-
@reads = []
|
24
|
-
@writes = []
|
25
|
-
@roles = {} # :dotr / :redir / :tun
|
26
|
-
@redir_wbuffs = [] # [ src_addr data ] ...
|
27
|
-
@tuns = {} # [ orig_src_addr dst_addr ]=> tun
|
28
|
-
@mappings = {} # src_addr => [ orig_src_addr dst_addr ]
|
29
|
-
@tun_infos = {} # tun => {}
|
30
|
-
# orig_src_addr: sockaddr
|
31
|
-
# dst_addr: sockaddr
|
32
|
-
# src_addr: sockaddr
|
33
|
-
# tund_addr: sockaddr
|
34
|
-
# rbuffs: []
|
35
|
-
# wbuffs: []
|
36
|
-
# last_traff_at: now
|
37
|
-
dotr, dotw = IO.pipe
|
38
|
-
@dotw = dotw
|
39
|
-
add_read( dotr, :dotr )
|
40
|
-
new_a_redir( redir_port )
|
41
|
-
end
|
42
|
-
|
43
|
-
def looping
|
44
|
-
loop_expire
|
45
|
-
|
46
|
-
loop do
|
47
|
-
rs, ws = IO.select( @reads, @writes )
|
48
|
-
|
49
|
-
@mutex.synchronize do
|
50
|
-
rs.each do | sock |
|
51
|
-
case @roles[ sock ]
|
52
|
-
when :dotr then
|
53
|
-
read_dotr( sock )
|
54
|
-
when :redir then
|
55
|
-
read_redir( sock )
|
56
|
-
when :tun then
|
57
|
-
read_tun( sock )
|
58
|
-
end
|
59
|
-
end
|
60
|
-
|
61
|
-
ws.each do | sock |
|
62
|
-
case @roles[ sock ]
|
63
|
-
when :redir then
|
64
|
-
write_redir( sock )
|
65
|
-
when :tun then
|
66
|
-
write_tun( sock )
|
67
|
-
end
|
68
|
-
end
|
69
|
-
end
|
70
|
-
end
|
71
|
-
end
|
72
|
-
|
73
|
-
def quit!
|
74
|
-
exit
|
75
|
-
end
|
76
|
-
|
77
|
-
private
|
78
|
-
|
79
|
-
def loop_expire
|
80
|
-
Thread.new do
|
81
|
-
loop do
|
82
|
-
sleep 30
|
83
|
-
|
84
|
-
@mutex.synchronize do
|
85
|
-
trigger = false
|
86
|
-
now = Time.new
|
87
|
-
|
88
|
-
@tun_infos.each do | tun, tun_info |
|
89
|
-
# net.netfilter.nf_conntrack_udp_timeout_stream
|
90
|
-
if now - tun_info[ :last_traff_at ] > 180 then
|
91
|
-
set_is_closing( tun )
|
92
|
-
trigger = true
|
93
|
-
end
|
94
|
-
end
|
95
|
-
|
96
|
-
next_tick if trigger
|
97
|
-
end
|
98
|
-
end
|
99
|
-
end
|
100
|
-
end
|
101
|
-
|
102
|
-
def new_a_redir( redir_port )
|
103
|
-
redir = Socket.new( Socket::AF_INET, Socket::SOCK_DGRAM, 0 )
|
104
|
-
redir.setsockopt( Socket::SOL_SOCKET, Socket::SO_REUSEPORT, 1 )
|
105
|
-
redir.bind( Socket.sockaddr_in( redir_port, '0.0.0.0' ) )
|
106
|
-
puts "redir bound on #{ redir_port } #{ Time.new }"
|
107
|
-
@redir = redir
|
108
|
-
add_read( redir, :redir )
|
109
|
-
end
|
110
|
-
|
111
|
-
def new_a_tun( orig_src_addr, dst_addr, src_addr )
|
112
|
-
tun = Socket.new( Socket::AF_INET, Socket::SOCK_DGRAM, 0 )
|
113
|
-
tun.setsockopt( Socket::SOL_SOCKET, Socket::SO_REUSEPORT, 1 )
|
114
|
-
tun.bind( Socket.sockaddr_in( 0, '0.0.0.0' ) )
|
115
|
-
|
116
|
-
@tun_infos[ tun ] = {
|
117
|
-
orig_src_addr: orig_src_addr,
|
118
|
-
dst_addr: dst_addr,
|
119
|
-
src_addr: src_addr,
|
120
|
-
tund_addr: nil,
|
121
|
-
rbuffs: [],
|
122
|
-
wbuffs: [],
|
123
|
-
last_traff_at: Time.new,
|
124
|
-
is_closing: false
|
125
|
-
}
|
126
|
-
|
127
|
-
@tuns[ [ orig_src_addr, dst_addr ].join ] = tun
|
128
|
-
add_read( tun, :tun )
|
129
|
-
|
130
|
-
tun
|
131
|
-
end
|
132
|
-
|
133
|
-
def add_redir_wbuff( redir, to_addr, data )
|
134
|
-
@redir_wbuffs << [ to_addr, data ]
|
135
|
-
add_write( redir )
|
136
|
-
end
|
137
|
-
|
138
|
-
def add_tun_wbuff( tun, to_addr, data )
|
139
|
-
tun_info = @tun_infos[ tun ]
|
140
|
-
|
141
|
-
if to_addr then
|
142
|
-
tun_info[ :wbuffs ] << [ to_addr, data ]
|
143
|
-
add_write( tun )
|
144
|
-
else
|
145
|
-
tun_info[ :rbuffs ] << data
|
146
|
-
end
|
147
|
-
end
|
148
|
-
|
149
|
-
def add_read( sock, role )
|
150
|
-
unless @reads.include?( sock ) then
|
151
|
-
@reads << sock
|
152
|
-
end
|
153
|
-
|
154
|
-
@roles[ sock ] = role
|
155
|
-
end
|
156
|
-
|
157
|
-
def add_write( sock )
|
158
|
-
unless @writes.include?( sock ) then
|
159
|
-
@writes << sock
|
160
|
-
end
|
161
|
-
end
|
162
|
-
|
163
|
-
def set_is_closing( tun )
|
164
|
-
if tun && !tun.closed? then
|
165
|
-
# puts "debug1 set tun is closing"
|
166
|
-
|
167
|
-
tun_info = @tun_infos[ tun ]
|
168
|
-
tun_info[ :is_closing ] = true
|
169
|
-
|
170
|
-
@reads.delete( tun )
|
171
|
-
add_write( tun )
|
172
|
-
end
|
173
|
-
end
|
174
|
-
|
175
|
-
def send_data( sock, data, to_addr )
|
176
|
-
begin
|
177
|
-
sock.sendmsg( data, 0, to_addr )
|
178
|
-
rescue IO::WaitWritable, Errno::EINTR
|
179
|
-
return false
|
180
|
-
rescue Errno::EHOSTUNREACH, Errno::ENETUNREACH, Errno::ENETDOWN => e
|
181
|
-
if @roles[ sock ] == :tun then
|
182
|
-
puts "#{ Time.new } #{ e.class }, close tun"
|
183
|
-
close_tun( sock )
|
184
|
-
return false
|
185
|
-
end
|
186
|
-
end
|
187
|
-
|
188
|
-
true
|
189
|
-
end
|
190
|
-
|
191
|
-
def close_tun( tun )
|
192
|
-
tun.close
|
193
|
-
@reads.delete( tun )
|
194
|
-
@writes.delete( tun )
|
195
|
-
@roles.delete( tun )
|
196
|
-
tun_info = @tun_infos.delete( tun )
|
197
|
-
@tuns.delete( [ tun_info[ :orig_src_addr ], tun_info[ :dst_addr ] ].join )
|
198
|
-
|
199
|
-
if @mappings.include?( tun_info[ :src_addr ] ) then
|
200
|
-
orig_src_addr, dst_addr, timeout, read_at = @mappings[ tun_info[ :src_addr ] ]
|
201
|
-
|
202
|
-
if orig_src_addr == tun_info[ :orig_src_addr ] && dst_addr == tun_info[ :dst_addr ] then
|
203
|
-
@mappings.delete( tun_info[ :src_addr ] )
|
204
|
-
end
|
205
|
-
end
|
206
|
-
end
|
207
|
-
|
208
|
-
def write_redir( redir )
|
209
|
-
while @redir_wbuffs.any? do
|
210
|
-
to_addr, data = @redir_wbuffs.first
|
211
|
-
return unless send_data( redir, data, to_addr )
|
212
|
-
@redir_wbuffs.shift
|
213
|
-
end
|
214
|
-
|
215
|
-
@writes.delete( redir )
|
216
|
-
end
|
217
|
-
|
218
|
-
def write_tun( tun )
|
219
|
-
tun_info = @tun_infos[ tun ]
|
220
|
-
|
221
|
-
if tun_info[ :is_closing ] then
|
222
|
-
close_tun( tun )
|
223
|
-
return
|
224
|
-
end
|
225
|
-
|
226
|
-
while tun_info[ :wbuffs ].any? do
|
227
|
-
to_addr, data = tun_info[ :wbuffs ].first
|
228
|
-
return unless send_data( tun, data, to_addr )
|
229
|
-
tun_info[ :wbuffs ].shift
|
230
|
-
end
|
231
|
-
|
232
|
-
@writes.delete( tun )
|
233
|
-
end
|
234
|
-
|
235
|
-
def read_dotr( dotr )
|
236
|
-
dotr.read( 1 )
|
237
|
-
end
|
238
|
-
|
239
|
-
def read_redir( redir )
|
240
|
-
data, addrinfo, rflags, *controls = redir.recvmsg
|
241
|
-
src_addr = addrinfo.to_sockaddr
|
242
|
-
is_hit_cache = false
|
243
|
-
now = Time.new
|
244
|
-
# puts "debug redir recv #{ data.inspect } from #{ addrinfo.inspect }"
|
245
|
-
|
246
|
-
if @mappings.include?( src_addr ) then
|
247
|
-
orig_src_addr, dst_addr, timeout, read_at = @mappings[ src_addr ]
|
248
|
-
|
249
|
-
if now - read_at < timeout then
|
250
|
-
# puts "debug hit cache #{ addrinfo.inspect }"
|
251
|
-
is_hit_cache = true
|
252
|
-
else
|
253
|
-
# puts "debug cache timeout #{ addrinfo.inspect }"
|
254
|
-
@mappings.delete( src_addr )
|
255
|
-
end
|
256
|
-
end
|
257
|
-
|
258
|
-
unless is_hit_cache then
|
259
|
-
# 2 udp 4 timeout 5 src 7 sport 9 [UNREPLIED] 11 dst 13 dport
|
260
|
-
# 2 udp 4 timeout 5 src 7 sport 10 dst 12 dport
|
261
|
-
bin = IO.binread( '/proc/net/nf_conntrack' )
|
262
|
-
rows = bin.split( "\n" ).map { | line | line.split( ' ' ) }
|
263
|
-
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 ) ) }
|
264
|
-
|
265
|
-
unless row then
|
266
|
-
puts "miss conntrack #{ addrinfo.inspect } #{ Time.new }"
|
267
|
-
IO.binwrite( '/tmp/nf_conntrack', bin )
|
268
|
-
return
|
269
|
-
end
|
270
|
-
|
271
|
-
timeout = row[ 4 ].to_i
|
272
|
-
orig_src_ip = row[ 5 ].split( '=' )[ 1 ]
|
273
|
-
orig_src_port = row[ 7 ].split( '=' )[ 1 ].to_i
|
274
|
-
dst_ip = row[ 6 ].split( '=' )[ 1 ]
|
275
|
-
dst_port = row[ 8 ].split( '=' )[ 1 ].to_i
|
276
|
-
orig_src_addr = Socket.sockaddr_in( orig_src_port, orig_src_ip )
|
277
|
-
dst_addr = Socket.sockaddr_in( dst_port, dst_ip )
|
278
|
-
|
279
|
-
if Addrinfo.new( dst_addr ).ipv4_private? then
|
280
|
-
puts "dst is private? #{ Addrinfo.new( dst_addr ).inspect } #{ Addrinfo.new( src_addr ).inspect } #{ Addrinfo.new( orig_src_addr ).inspect } #{ Time.new }"
|
281
|
-
add_redir_wbuff( redir, dst_addr, data )
|
282
|
-
return
|
283
|
-
end
|
284
|
-
|
285
|
-
# puts "debug save cache #{ addrinfo.inspect } #{ Addrinfo.new( orig_src_addr ).inspect } #{ Addrinfo.new( dst_addr ).inspect } #{ timeout } #{ now }"
|
286
|
-
@mappings[ src_addr ] = [ orig_src_addr, dst_addr, timeout, now ]
|
287
|
-
end
|
288
|
-
|
289
|
-
tun = @tuns[ [ orig_src_addr, dst_addr ].join ]
|
290
|
-
|
291
|
-
unless tun then
|
292
|
-
tun = new_a_tun( orig_src_addr, dst_addr, src_addr )
|
293
|
-
|
294
|
-
# puts "debug tun send to udpd #{ Addrinfo.new( orig_src_addr ).inspect } #{ Addrinfo.new( dst_addr ).inspect }"
|
295
|
-
ctlmsg = [ orig_src_addr, dst_addr ].join
|
296
|
-
add_tun_wbuff( tun, @udpd_addr, ctlmsg )
|
297
|
-
end
|
298
|
-
|
299
|
-
tun_info = @tun_infos[ tun ]
|
300
|
-
add_tun_wbuff( tun, tun_info[ :tund_addr ], data )
|
301
|
-
end
|
302
|
-
|
303
|
-
def read_tun( tun )
|
304
|
-
data, addrinfo, rflags, *controls = tun.recvmsg
|
305
|
-
from_addr = addrinfo.to_sockaddr
|
306
|
-
tun_info = @tun_infos[ tun ]
|
307
|
-
tun_info[ :last_traff_at ] = Time.new
|
308
|
-
|
309
|
-
if from_addr == @udpd_addr then
|
310
|
-
tund_port = data[ 0, 2 ].unpack( 'n' ).first
|
311
|
-
tund_addr = Socket.sockaddr_in( tund_port, @udpd_host )
|
312
|
-
tun_info[ :tund_addr ] = tund_addr
|
313
|
-
|
314
|
-
if tun_info[ :rbuffs ].any? then
|
315
|
-
tun_info[ :wbuffs ] += tun_info[ :rbuffs ].map{ | rbuff | [ tund_addr, rbuff ] }
|
316
|
-
tun_info[ :rbuffs ].clear
|
317
|
-
add_write( tun )
|
318
|
-
end
|
319
|
-
|
320
|
-
elsif from_addr == tun_info[ :tund_addr ] then
|
321
|
-
add_redir_wbuff( @redir, tun_info[ :src_addr ], data )
|
322
|
-
end
|
323
|
-
end
|
324
|
-
|
325
|
-
end
|
326
|
-
end
|
data/lib/girl/udpd.rb
DELETED
@@ -1,316 +0,0 @@
|
|
1
|
-
require 'girl/version'
|
2
|
-
require 'socket'
|
3
|
-
|
4
|
-
##
|
5
|
-
# Girl::Udpd - udp透明转发,远端。
|
6
|
-
#
|
7
|
-
module Girl
|
8
|
-
class Udpd
|
9
|
-
|
10
|
-
def initialize( port = 3030 )
|
11
|
-
@mutex = Mutex.new
|
12
|
-
@reads = []
|
13
|
-
@writes = []
|
14
|
-
@roles = {} # :dotr / :udpd / :tund
|
15
|
-
@udpd_wbuffs = [] # [ tun_addr ctlmsg ] ...
|
16
|
-
@tunds = {} # [ tun_ip_addr orig_src_addr ] => tund
|
17
|
-
@tund_infos = {} # tund => {}
|
18
|
-
# port: port
|
19
|
-
# tun_ip_addr: sockaddr
|
20
|
-
# orig_src_addr: sockaddr
|
21
|
-
# wbuffs: [] # [ to_addr, data ] ...
|
22
|
-
# dst_addrs: { tun_addr => dst_addr }
|
23
|
-
# tun_addrs: { dst_addr => tun_addr }
|
24
|
-
# is_tunneleds: { [ tun_addr dst_addr ] => false }
|
25
|
-
# unpaired_dst_rbuffs: { dst_addr => [] }
|
26
|
-
# last_traff_at: now
|
27
|
-
dotr, dotw = IO.pipe
|
28
|
-
@dotw = dotw
|
29
|
-
add_read( dotr, :dotr )
|
30
|
-
new_a_udpd( port )
|
31
|
-
end
|
32
|
-
|
33
|
-
def looping
|
34
|
-
loop_expire
|
35
|
-
|
36
|
-
loop do
|
37
|
-
rs, ws = IO.select( @reads, @writes )
|
38
|
-
|
39
|
-
@mutex.synchronize do
|
40
|
-
ws.each do | sock |
|
41
|
-
case @roles[ sock ]
|
42
|
-
when :udpd then
|
43
|
-
write_udpd( sock )
|
44
|
-
when :tund then
|
45
|
-
write_tund( sock )
|
46
|
-
end
|
47
|
-
end
|
48
|
-
|
49
|
-
rs.each do | sock |
|
50
|
-
case @roles[ sock ]
|
51
|
-
when :dotr then
|
52
|
-
read_dotr( sock )
|
53
|
-
when :udpd then
|
54
|
-
read_udpd( sock )
|
55
|
-
when :tund then
|
56
|
-
read_tund( sock )
|
57
|
-
end
|
58
|
-
end
|
59
|
-
end
|
60
|
-
end
|
61
|
-
end
|
62
|
-
|
63
|
-
def quit!
|
64
|
-
exit
|
65
|
-
end
|
66
|
-
|
67
|
-
private
|
68
|
-
|
69
|
-
def loop_expire
|
70
|
-
Thread.new do
|
71
|
-
loop do
|
72
|
-
sleep 30
|
73
|
-
|
74
|
-
@mutex.synchronize do
|
75
|
-
trigger = false
|
76
|
-
now = Time.new
|
77
|
-
|
78
|
-
@tund_infos.each do | tund, tund_info |
|
79
|
-
# net.netfilter.nf_conntrack_udp_timeout_stream
|
80
|
-
if now - tund_info[ :last_traff_at ] > 180 then
|
81
|
-
set_is_closing( tund )
|
82
|
-
trigger = true
|
83
|
-
end
|
84
|
-
end
|
85
|
-
|
86
|
-
next_tick if trigger
|
87
|
-
end
|
88
|
-
end
|
89
|
-
end
|
90
|
-
end
|
91
|
-
|
92
|
-
def new_a_udpd( port )
|
93
|
-
udpd = Socket.new( Socket::AF_INET, Socket::SOCK_DGRAM, 0 )
|
94
|
-
udpd.setsockopt( Socket::SOL_SOCKET, Socket::SO_REUSEPORT, 1 )
|
95
|
-
udpd.bind( Socket.sockaddr_in( port, '0.0.0.0' ) )
|
96
|
-
puts "udpd bound on #{ port } #{ Time.new }"
|
97
|
-
@udpd = udpd
|
98
|
-
add_read( udpd, :udpd )
|
99
|
-
end
|
100
|
-
|
101
|
-
def pair_tund( tun_addr, tun_ip_addr, orig_src_addr, dst_addr )
|
102
|
-
from_addr = [ tun_ip_addr, orig_src_addr ].join
|
103
|
-
td_addr = [ tun_addr, dst_addr ].join
|
104
|
-
tund = @tunds[ from_addr ]
|
105
|
-
|
106
|
-
if tund then
|
107
|
-
tund_info = @tund_infos[ tund ]
|
108
|
-
tund_info[ :dst_addrs ][ tun_addr ] = dst_addr
|
109
|
-
tund_info[ :tun_addrs ][ dst_addr ] = tun_addr
|
110
|
-
tund_info[ :is_tunneleds ][ td_addr ] = false
|
111
|
-
else
|
112
|
-
tund = Socket.new( Socket::AF_INET, Socket::SOCK_DGRAM, 0 )
|
113
|
-
tund.setsockopt( Socket::SOL_SOCKET, Socket::SO_REUSEPORT, 1 )
|
114
|
-
tund.setsockopt( Socket::SOL_SOCKET, Socket::SO_BROADCAST, 1 )
|
115
|
-
tund.bind( Socket.sockaddr_in( 0, '0.0.0.0' ) )
|
116
|
-
tund_port = tund.local_address.ip_unpack.last
|
117
|
-
|
118
|
-
@tund_infos[ tund ] = {
|
119
|
-
port: tund_port,
|
120
|
-
tun_ip_addr: tun_ip_addr,
|
121
|
-
orig_src_addr: orig_src_addr,
|
122
|
-
wbuffs: [],
|
123
|
-
dst_addrs: { tun_addr => dst_addr },
|
124
|
-
tun_addrs: { dst_addr => tun_addr },
|
125
|
-
is_tunneleds: { td_addr => false },
|
126
|
-
unpaired_dst_rbuffs: {},
|
127
|
-
last_traff_at: Time.new,
|
128
|
-
is_closing: false
|
129
|
-
}
|
130
|
-
|
131
|
-
@tunds[ from_addr ] = tund
|
132
|
-
add_read( tund, :tund )
|
133
|
-
end
|
134
|
-
|
135
|
-
tund
|
136
|
-
end
|
137
|
-
|
138
|
-
def add_tund_wbuff( tund, to_addr, data )
|
139
|
-
tund_info = @tund_infos[ tund ]
|
140
|
-
tund_info[ :wbuffs ] << [ to_addr, data ]
|
141
|
-
|
142
|
-
add_write( tund )
|
143
|
-
end
|
144
|
-
|
145
|
-
def add_read( sock, role )
|
146
|
-
unless @reads.include?( sock ) then
|
147
|
-
@reads << sock
|
148
|
-
end
|
149
|
-
|
150
|
-
@roles[ sock ] = role
|
151
|
-
end
|
152
|
-
|
153
|
-
def add_write( sock )
|
154
|
-
unless @writes.include?( sock ) then
|
155
|
-
@writes << sock
|
156
|
-
end
|
157
|
-
end
|
158
|
-
|
159
|
-
def set_is_closing( tund )
|
160
|
-
if tund && !tund.closed? then
|
161
|
-
# puts "debug1 set tund is closing"
|
162
|
-
|
163
|
-
tund_info = @tund_infos[ tund ]
|
164
|
-
tund_info[ :is_closing ] = true
|
165
|
-
|
166
|
-
@reads.delete( tund )
|
167
|
-
add_write( tund )
|
168
|
-
end
|
169
|
-
end
|
170
|
-
|
171
|
-
def send_data( sock, data, to_addr )
|
172
|
-
begin
|
173
|
-
sock.sendmsg( data, 0, to_addr )
|
174
|
-
rescue IO::WaitWritable, Errno::EINTR
|
175
|
-
return false
|
176
|
-
rescue Errno::EHOSTUNREACH, Errno::ENETUNREACH, Errno::ENETDOWN => e
|
177
|
-
if @roles[ sock ] == :tund then
|
178
|
-
puts "#{ Time.new } #{ e.class }, close tund"
|
179
|
-
close_tund( sock )
|
180
|
-
return false
|
181
|
-
end
|
182
|
-
end
|
183
|
-
|
184
|
-
true
|
185
|
-
end
|
186
|
-
|
187
|
-
def close_tund( tund )
|
188
|
-
tund.close
|
189
|
-
@reads.delete( tund )
|
190
|
-
@writes.delete( tund )
|
191
|
-
@roles.delete( tund )
|
192
|
-
tund_info = @tund_infos.delete( tund )
|
193
|
-
@tunds.delete( [ tund_info[ :tun_ip_addr ], tund_info[ :orig_src_addr ] ].join )
|
194
|
-
end
|
195
|
-
|
196
|
-
def next_tick
|
197
|
-
@dotw.write( '.' )
|
198
|
-
end
|
199
|
-
|
200
|
-
def write_udpd( udpd )
|
201
|
-
while @udpd_wbuffs.any? do
|
202
|
-
to_addr, data = @udpd_wbuffs.first
|
203
|
-
return unless send_data( udpd, data, to_addr )
|
204
|
-
@udpd_wbuffs.shift
|
205
|
-
end
|
206
|
-
|
207
|
-
@writes.delete( udpd )
|
208
|
-
end
|
209
|
-
|
210
|
-
def write_tund( tund )
|
211
|
-
tund_info = @tund_infos[ tund ]
|
212
|
-
|
213
|
-
if tund_info[ :is_closing ] then
|
214
|
-
close_tund( tund )
|
215
|
-
return
|
216
|
-
end
|
217
|
-
|
218
|
-
while tund_info[ :wbuffs ].any? do
|
219
|
-
to_addr, data = tund_info[ :wbuffs ].first
|
220
|
-
return unless send_data( tund, data, to_addr )
|
221
|
-
tund_info[ :wbuffs ].shift
|
222
|
-
end
|
223
|
-
|
224
|
-
@writes.delete( tund )
|
225
|
-
end
|
226
|
-
|
227
|
-
def read_dotr( dotr )
|
228
|
-
dotr.read( 1 )
|
229
|
-
end
|
230
|
-
|
231
|
-
def read_udpd( udpd )
|
232
|
-
data, addrinfo, rflags, *controls = udpd.recvmsg
|
233
|
-
# puts "debug udpd recv #{ data.inspect } from #{ addrinfo.inspect }"
|
234
|
-
orig_src_addr = data[ 0, 16 ]
|
235
|
-
dst_addr = data[ 16, 16 ]
|
236
|
-
tun_addr = addrinfo.to_sockaddr
|
237
|
-
tun_ip_addr = Addrinfo.ip( addrinfo.ip_address ).to_sockaddr
|
238
|
-
|
239
|
-
return unless Addrinfo.new( orig_src_addr ).ipv4?
|
240
|
-
|
241
|
-
dst_addrinfo = Addrinfo.new( dst_addr )
|
242
|
-
return unless dst_addrinfo.ipv4?
|
243
|
-
return if dst_addrinfo.ipv4_private?
|
244
|
-
|
245
|
-
tund = pair_tund( tun_addr, tun_ip_addr, orig_src_addr, dst_addr )
|
246
|
-
tund_info = @tund_infos[ tund ]
|
247
|
-
tund_port = tund_info[ :port ]
|
248
|
-
|
249
|
-
# puts "debug udpd send to tun #{ tund_port } #{ addrinfo.inspect }"
|
250
|
-
ctlmsg = [ tund_port ].pack( 'n' )
|
251
|
-
@udpd_wbuffs << [ tun_addr, ctlmsg ]
|
252
|
-
add_write( udpd )
|
253
|
-
end
|
254
|
-
|
255
|
-
def read_tund( tund )
|
256
|
-
data, addrinfo, rflags, *controls = tund.recvmsg
|
257
|
-
from_addr = addrinfo.to_sockaddr
|
258
|
-
tund_info = @tund_infos[ tund ]
|
259
|
-
tund_info[ :last_traff_at ] = Time.new
|
260
|
-
to_addr = tund_info[ :dst_addrs ][ from_addr ]
|
261
|
-
|
262
|
-
if to_addr then
|
263
|
-
# 来自tun,发给dst。
|
264
|
-
td_addr = [ from_addr, to_addr ].join
|
265
|
-
is_tunneled = tund_info[ :is_tunneleds ][ td_addr ]
|
266
|
-
|
267
|
-
unless is_tunneled then
|
268
|
-
# puts "debug first traffic from tun #{ addrinfo.inspect } to #{ Addrinfo.new( to_addr ).inspect }"
|
269
|
-
# 发暂存
|
270
|
-
if tund_info[ :unpaired_dst_rbuffs ].include?( to_addr ) then
|
271
|
-
rbuffs = tund_info[ :unpaired_dst_rbuffs ].delete( to_addr )
|
272
|
-
# puts "debug move tund.dst.rbuffs to tund.wbuffs #{ rbuffs.inspect }"
|
273
|
-
tund_info[ :wbuffs ] += rbuffs.map{ | rbuff | [ from_addr, rbuff ] }
|
274
|
-
end
|
275
|
-
|
276
|
-
tund_info[ :is_tunneleds ][ td_addr ] = true
|
277
|
-
end
|
278
|
-
|
279
|
-
# 如果对面没来过流量,且在nat里,nat规则是只对去过的目的地做接收,那么,先过去的流量会撞死。
|
280
|
-
# 没关系,撞死的流量通常是打洞数据,在应用计算之内,打洞数据通常是连发的。
|
281
|
-
# puts "debug #{ data.inspect } from #{ addrinfo.inspect } to #{ Addrinfo.new( to_addr ).inspect }"
|
282
|
-
add_tund_wbuff( tund, to_addr, data )
|
283
|
-
return
|
284
|
-
end
|
285
|
-
|
286
|
-
to_addr = tund_info[ :tun_addrs ][ from_addr ]
|
287
|
-
|
288
|
-
if to_addr then
|
289
|
-
# 来自dst,发给tun。
|
290
|
-
# puts "debug #{ data.inspect } from #{ addrinfo.inspect } to #{ Addrinfo.new( to_addr ).inspect }"
|
291
|
-
|
292
|
-
td_addr = [ to_addr, from_addr ].join
|
293
|
-
is_tunneled = tund_info[ :is_tunneleds ][ td_addr ]
|
294
|
-
|
295
|
-
if is_tunneled then
|
296
|
-
add_tund_wbuff( tund, to_addr, data )
|
297
|
-
return
|
298
|
-
end
|
299
|
-
|
300
|
-
# puts "debug #{ Addrinfo.new( to_addr ).inspect } #{ addrinfo.inspect } not tunneled"
|
301
|
-
end
|
302
|
-
|
303
|
-
# 来自未知的地方,或者对应的tun还没来流量,记暂存
|
304
|
-
unless tund_info[ :unpaired_dst_rbuffs ][ from_addr ] then
|
305
|
-
tund_info[ :unpaired_dst_rbuffs ][ from_addr ] = []
|
306
|
-
end
|
307
|
-
|
308
|
-
# 暂存5条(连发打洞数据,不需要存多)。
|
309
|
-
if tund_info[ :unpaired_dst_rbuffs ][ from_addr ].size < 5 then
|
310
|
-
# puts "debug save other dst rbuff #{ addrinfo.inspect } #{ data.inspect }"
|
311
|
-
tund_info[ :unpaired_dst_rbuffs ][ from_addr ] << data
|
312
|
-
end
|
313
|
-
end
|
314
|
-
|
315
|
-
end
|
316
|
-
end
|