girl 0.81.0 → 0.86.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c03f23d6ce85424ec557285d47ce226a1ee91372c24c517d0b15b7391dc13cf6
4
- data.tar.gz: 7219e443eee2a40403d1280ab42154045247080601b71736ddd3af751bb62357
3
+ metadata.gz: 48f438a56f35bb4fd0fbb76e57f08b5ea1a6e8890b8a2b7542881b1f69e89461
4
+ data.tar.gz: 8ad2943b900e91f8a6e29306fe29249d467374f738261daadaaa429961370206
5
5
  SHA512:
6
- metadata.gz: ea3a13ec0c20daec401b2128255c11a5d6c8908e34abc9ebe24f21f410cdffe59ba406f49fba48ca8b3d2b21d69d45d2c7c6a1a098239c708b499948aa768b5a
7
- data.tar.gz: cc448ee54e1f2c98da438f95edb6cacd5d498785633f9c9711a762c7ef48b8faca1a03dd4d5304f34eb1b75a990525e352d81dcc1d7478ce7c052b2116c29c65
6
+ metadata.gz: 98512a3678ebde91bff827995447765c57c558f885313d05ecd8c831e85354a9ea81beb5ff038c18787b1bd0c15fe88317b85a3b6e84458a5709bcf59b027fff
7
+ data.tar.gz: 263aff6f7b79025d5404f6b6e4a68b01dfa899df0af4556b0085f72e9bb3227d6423be77e3c1cd12445fb1c9727c426be9750a9f7cea72d112b72c59702917a7
@@ -10,7 +10,7 @@ Gem::Specification.new do |spec|
10
10
  spec.email = ['qqtakafan@gmail.com']
11
11
 
12
12
  spec.summary = %q{妹子}
13
- spec.description = %q{while internet is evil, here's a girl.}
13
+ spec.description = %q{escape evil.}
14
14
  spec.homepage = 'https://github.com/takafan/girl'
15
15
  spec.license = 'MIT'
16
16
 
@@ -7,9 +7,10 @@ module Girl
7
7
  EXPIRE_NEW = 10 # 创建之后多久没有流量进来,过期
8
8
  EXPIRE_AFTER = 300 # 多久没有新流量,过期
9
9
  CHECK_EXPIRE_INTERVAL = 30 # 检查过期间隔
10
- STATUS_INTERVAL = 0.5 # 发送状态间隔
10
+ CHECK_STATUS_INTERVAL = 0.5 # 发送状态间隔
11
11
  SEND_STATUS_UNTIL = 10 # 持续的告之对面状态,直到没有流量往来,持续多少秒
12
- BREAK_SEND_MISS = 10_000 # miss包个数上限,达到上限忽略要后面的段,可控碎片缓存
12
+ MISS_RANGE_LIMIT = 500 # miss段上限,达到上限忽略要后面的段
13
+ RESENDING_LIMIT = 5000 # 重传队列上限
13
14
  CONFUSE_UNTIL = 5 # 混淆前几个包
14
15
  RESOLV_CACHE_EXPIRE = 300 # dns查询结果缓存多久过期
15
16
  TUND_PORT = 1
@@ -108,7 +108,7 @@ module Girl
108
108
  raise "not found direct file #{ direct_path }"
109
109
  end
110
110
 
111
- directs = ( [ Addrinfo.ip( proxyd_host ).ip_address ] + RESERVED_ROUTE.split( "\n" ) + IO.binread( direct_path ).split( "\n" ) ).map { | line | IPAddr.new( line.strip ) }
111
+ directs = ( RESERVED_ROUTE.split( "\n" ) + IO.binread( direct_path ).split( "\n" ) ).map { | line | IPAddr.new( line.strip ) }
112
112
  end
113
113
 
114
114
  remotes = []
@@ -170,6 +170,29 @@ module Girl
170
170
  puts "im #{ im }"
171
171
  puts "worker count #{ worker_count }"
172
172
 
173
+ names = %w[
174
+ PACK_SIZE
175
+ CHUNK_SIZE
176
+ WBUFFS_LIMIT
177
+ WMEMS_LIMIT
178
+ RESUME_BELOW
179
+ EXPIRE_NEW
180
+ EXPIRE_AFTER
181
+ CHECK_EXPIRE_INTERVAL
182
+ CHECK_STATUS_INTERVAL
183
+ SEND_STATUS_UNTIL
184
+ MISS_RANGE_LIMIT
185
+ RESENDING_LIMIT
186
+ CONFUSE_UNTIL
187
+ RESOLV_CACHE_EXPIRE
188
+ ]
189
+
190
+ len = names.map{ | name | name.size }.max
191
+
192
+ names.each do | name |
193
+ puts "#{ name.gsub( '_', ' ' ).ljust( len ) } #{ Girl.const_get( name ) }"
194
+ end
195
+
173
196
  if RUBY_PLATFORM.include?( 'linux' )
174
197
  $0 = title
175
198
  workers = []
@@ -152,7 +152,7 @@ module Girl
152
152
  def loop_check_status
153
153
  Thread.new do
154
154
  loop do
155
- sleep STATUS_INTERVAL
155
+ sleep CHECK_STATUS_INTERVAL
156
156
 
157
157
  @mutex.synchronize do
158
158
  if @tun && !@tun.closed? && @tun_info[ :tund_addr ]
@@ -264,8 +264,10 @@ module Girl
264
264
  # deal with destination ip
265
265
  #
266
266
  def deal_with_destination_ip( src, ip_info )
267
- if @directs.any? { | direct | direct.include?( ip_info.ip_address ) }
268
- # ip命中直连列表,直连
267
+ src_info = @src_infos[ src ]
268
+
269
+ if ( @directs.any? { | direct | direct.include?( ip_info.ip_address ) } ) || ( ( src_info[ :destination_domain ] == @proxyd_host ) && ![ 80, 443 ].include?( src_info[ :destination_port ] ) )
270
+ # ip命中直连列表,或者访问远端非80/443端口,直连
269
271
  # puts "debug1 #{ ip_info.inspect } hit directs"
270
272
  new_a_dst( src, ip_info )
271
273
  else
@@ -1224,7 +1226,7 @@ module Girl
1224
1226
 
1225
1227
  tund_port = data[ 9, 2 ].unpack( 'n' ).first
1226
1228
 
1227
- # puts "debug1 got tund port #{ tund_port }"
1229
+ puts "p#{ Process.pid } #{ Time.new } got tund port #{ tund_port }"
1228
1230
  tund_addr = Socket.sockaddr_in( tund_port, @proxyd_host )
1229
1231
  @tun_info[ :tund_addr ] = tund_addr
1230
1232
 
@@ -1289,36 +1291,36 @@ module Girl
1289
1291
  # 发miss
1290
1292
  if !src_ext[ :src ].closed? && ( src_ext[ :continue_dst_pack_id ] < relay_dst_pack_id )
1291
1293
  ranges = []
1294
+ ignored = false
1292
1295
  curr_pack_id = src_ext[ :continue_dst_pack_id ] + 1
1293
1296
 
1294
1297
  src_ext[ :pieces ].keys.sort.each do | pack_id |
1295
1298
  if pack_id > curr_pack_id
1296
1299
  ranges << [ curr_pack_id, pack_id - 1 ]
1300
+
1301
+ if ranges.size >= MISS_RANGE_LIMIT
1302
+ puts "p#{ Process.pid } #{ Time.new } break add miss range at #{ pack_id }"
1303
+ ignored = true
1304
+ break
1305
+ end
1297
1306
  end
1298
1307
 
1299
1308
  curr_pack_id = pack_id + 1
1300
1309
  end
1301
1310
 
1302
- if curr_pack_id <= relay_dst_pack_id
1311
+ if !ignored && ( curr_pack_id <= relay_dst_pack_id )
1303
1312
  ranges << [ curr_pack_id, relay_dst_pack_id ]
1304
1313
  end
1305
1314
 
1306
- pack_count = 0
1307
1315
  # puts "debug1 continue/relay #{ src_ext[ :continue_dst_pack_id ] }/#{ relay_dst_pack_id } send MISS #{ ranges.size }"
1308
1316
 
1309
1317
  ranges.each do | pack_id_begin, pack_id_end |
1310
- if pack_count >= BREAK_SEND_MISS
1311
- puts "p#{ Process.pid } #{ Time.new } break send miss at #{ pack_id_begin }"
1312
- break
1313
- end
1314
-
1315
1318
  data2 = [ 0, MISS, dst_port, pack_id_begin, pack_id_end ].pack( 'Q>CnQ>Q>' )
1316
1319
  add_tun_ctlmsg( data2 )
1317
- pack_count += ( pack_id_end - pack_id_begin + 1 )
1318
1320
  end
1319
1321
  end
1320
1322
  when MISS
1321
- return if from_addr != @tun_info[ :tund_addr ]
1323
+ return if ( from_addr != @tun_info[ :tund_addr ] ) || ( @tun_info[ :resendings ].size >= RESENDING_LIMIT )
1322
1324
 
1323
1325
  src_id, pack_id_begin, pack_id_end = data[ 9, 24 ].unpack( 'Q>Q>Q>' )
1324
1326
 
@@ -1329,7 +1331,7 @@ module Girl
1329
1331
  send_at = src_ext[ :send_ats ][ pack_id ]
1330
1332
 
1331
1333
  if send_at
1332
- break if now - send_at < STATUS_INTERVAL
1334
+ break if now - send_at < CHECK_STATUS_INTERVAL
1333
1335
  @tun_info[ :resendings ] << [ src_id, pack_id ]
1334
1336
  end
1335
1337
  end
@@ -144,7 +144,7 @@ module Girl
144
144
  def loop_check_status
145
145
  Thread.new do
146
146
  loop do
147
- sleep STATUS_INTERVAL
147
+ sleep CHECK_STATUS_INTERVAL
148
148
 
149
149
  if @tunds.any?
150
150
  @mutex.synchronize do
@@ -418,15 +418,17 @@ module Girl
418
418
  ##
419
419
  # send data
420
420
  #
421
- def send_data( tund, data, to_addr )
421
+ def send_data( sock, data, to_addr )
422
422
  begin
423
- tund.sendmsg( data, 0, to_addr )
423
+ sock.sendmsg( data, 0, to_addr )
424
424
  rescue IO::WaitWritable, Errno::EINTR
425
425
  return false
426
426
  rescue Errno::EHOSTUNREACH, Errno::ENETUNREACH, Errno::ENETDOWN => e
427
- puts "#{ Time.new } #{ e.class }, close tund"
428
- close_tund( tund )
429
- return false
427
+ if @roles[ sock ] == :tund
428
+ puts "#{ Time.new } #{ e.class }, close tund"
429
+ close_tund( sock )
430
+ return false
431
+ end
430
432
  end
431
433
 
432
434
  true
@@ -541,9 +543,7 @@ module Girl
541
543
  while @proxyd_ctlmsgs.any?
542
544
  to_addr, data = @proxyd_ctlmsgs.first
543
545
 
544
- begin
545
- proxyd.sendmsg( data, 0, to_addr )
546
- rescue IO::WaitWritable, Errno::EINTR
546
+ unless send_data( proxyd, data, to_addr )
547
547
  return
548
548
  end
549
549
 
@@ -866,35 +866,37 @@ module Girl
866
866
  # 发miss
867
867
  if !dst_ext[ :dst ].closed? && ( dst_ext[ :continue_src_pack_id ] < relay_src_pack_id )
868
868
  ranges = []
869
+ ignored = false
869
870
  curr_pack_id = dst_ext[ :continue_src_pack_id ] + 1
870
871
 
871
872
  dst_ext[ :pieces ].keys.sort.each do | pack_id |
872
873
  if pack_id > curr_pack_id
873
874
  ranges << [ curr_pack_id, pack_id - 1 ]
875
+
876
+ if ranges.size >= MISS_RANGE_LIMIT
877
+ puts "p#{ Process.pid } #{ Time.new } break add miss range at #{ pack_id }"
878
+ ignored = true
879
+ break
880
+ end
874
881
  end
875
882
 
876
883
  curr_pack_id = pack_id + 1
877
884
  end
878
885
 
879
- if curr_pack_id <= relay_src_pack_id
886
+ if !ignored && ( curr_pack_id <= relay_src_pack_id )
880
887
  ranges << [ curr_pack_id, relay_src_pack_id ]
881
888
  end
882
889
 
883
- pack_count = 0
884
890
  # puts "debug1 continue/relay #{ dst_ext[ :continue_src_pack_id ] }/#{ relay_src_pack_id } send MISS #{ ranges.size }"
885
891
 
886
892
  ranges.each do | pack_id_begin, pack_id_end |
887
- if pack_count >= BREAK_SEND_MISS
888
- puts "p#{ Process.pid } #{ Time.new } break send miss at #{ pack_id_begin }"
889
- break
890
- end
891
-
892
893
  data2 = [ 0, MISS, src_id, pack_id_begin, pack_id_end ].pack( 'Q>CQ>Q>Q>' )
893
894
  add_tund_ctlmsg( tund, data2 )
894
- pack_count += ( pack_id_end - pack_id_begin + 1 )
895
895
  end
896
896
  end
897
897
  when MISS
898
+ return if tund_info[ :resendings ].size >= RESENDING_LIMIT
899
+
898
900
  dst_local_port, pack_id_begin, pack_id_end = data[ 9, 18 ].unpack( 'nQ>Q>' )
899
901
 
900
902
  dst_ext = tund_info[ :dst_exts ][ dst_local_port ]
@@ -904,7 +906,7 @@ module Girl
904
906
  send_at = dst_ext[ :send_ats ][ pack_id ]
905
907
 
906
908
  if send_at
907
- break if now - send_at < STATUS_INTERVAL
909
+ break if now - send_at < CHECK_STATUS_INTERVAL
908
910
  tund_info[ :resendings ] << [ dst_local_port, pack_id ]
909
911
  end
910
912
  end
@@ -17,25 +17,12 @@ module Girl
17
17
  class Udp
18
18
 
19
19
  def initialize( udpd_host, udpd_port = 3030, redir_port = 1313 )
20
- ctlr, ctlw = IO.pipe
21
-
22
- redir = Socket.new( Socket::AF_INET, Socket::SOCK_DGRAM, 0 )
23
- redir.setsockopt( Socket::SOL_SOCKET, Socket::SO_REUSEPORT, 1 )
24
- redir.bind( Socket.sockaddr_in( redir_port, '0.0.0.0' ) )
25
- puts "redir bound on #{ redir_port } #{ Time.new }"
26
-
27
- @mutex = Mutex.new
28
20
  @udpd_host = udpd_host
29
21
  @udpd_addr = Socket.sockaddr_in( udpd_port, udpd_host )
30
- @ctlw = ctlw
31
- @redir = redir
32
- @reads = [ ctlr, redir ]
22
+ @mutex = Mutex.new
23
+ @reads = []
33
24
  @writes = []
34
- @closings = []
35
- @roles = {
36
- ctlr => :ctlr, # :ctlr / :redir / :tun
37
- redir => :redir
38
- }
25
+ @roles = {} # :dotr / :redir / :tun
39
26
  @redir_wbuffs = [] # [ src_addr data ] ...
40
27
  @tuns = {} # [ orig_src_addr dst_addr ]=> tun
41
28
  @mappings = {} # src_addr => [ orig_src_addr dst_addr ]
@@ -47,6 +34,10 @@ module Girl
47
34
  # rbuffs: []
48
35
  # wbuffs: []
49
36
  # last_traff_at: now
37
+ dotr, dotw = IO.pipe
38
+ @dotw = dotw
39
+ add_read( dotr, :dotr )
40
+ new_a_redir( redir_port )
50
41
  end
51
42
 
52
43
  def looping
@@ -56,23 +47,23 @@ module Girl
56
47
  rs, ws = IO.select( @reads, @writes )
57
48
 
58
49
  @mutex.synchronize do
59
- rs.each do | sock |
50
+ ws.each do | sock |
60
51
  case @roles[ sock ]
61
- when :ctlr
62
- read_ctlr( sock )
63
52
  when :redir
64
- read_redir( sock )
53
+ write_redir( sock )
65
54
  when :tun
66
- read_tun( sock )
55
+ write_tun( sock )
67
56
  end
68
57
  end
69
58
 
70
- ws.each do | sock |
59
+ rs.each do | sock |
71
60
  case @roles[ sock ]
61
+ when :dotr
62
+ read_dotr( sock )
72
63
  when :redir
73
- write_redir( sock )
64
+ read_redir( sock )
74
65
  when :tun
75
- write_tun( sock )
66
+ read_tun( sock )
76
67
  end
77
68
  end
78
69
  end
@@ -85,15 +76,176 @@ module Girl
85
76
 
86
77
  private
87
78
 
88
- def read_ctlr( ctlr )
89
- od_addr = ctlr.read( 32 )
90
- tun = @tuns[ od_addr ]
79
+ def loop_expire
80
+ Thread.new do
81
+ loop do
82
+ sleep 30
91
83
 
92
- if tun
93
- add_closing( tun )
84
+ @mutex.synchronize do
85
+ need_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
91
+ set_is_closing( tun )
92
+ need_trigger = true
93
+ end
94
+ end
95
+
96
+ if need_trigger
97
+ next_tick
98
+ end
99
+ end
100
+ end
94
101
  end
95
102
  end
96
103
 
104
+ def new_a_redir( redir_port )
105
+ redir = Socket.new( Socket::AF_INET, Socket::SOCK_DGRAM, 0 )
106
+ redir.setsockopt( Socket::SOL_SOCKET, Socket::SO_REUSEPORT, 1 )
107
+ redir.bind( Socket.sockaddr_in( redir_port, '0.0.0.0' ) )
108
+ puts "redir bound on #{ redir_port } #{ Time.new }"
109
+ @redir = redir
110
+ add_read( redir, :redir )
111
+ end
112
+
113
+ def new_a_tun( orig_src_addr, dst_addr, src_addr )
114
+ tun = Socket.new( Socket::AF_INET, Socket::SOCK_DGRAM, 0 )
115
+ tun.setsockopt( Socket::SOL_SOCKET, Socket::SO_REUSEPORT, 1 )
116
+ tun.bind( Socket.sockaddr_in( 0, '0.0.0.0' ) )
117
+
118
+ @tun_infos[ tun ] = {
119
+ orig_src_addr: orig_src_addr,
120
+ dst_addr: dst_addr,
121
+ src_addr: src_addr,
122
+ tund_addr: nil,
123
+ rbuffs: [],
124
+ wbuffs: [],
125
+ last_traff_at: Time.new,
126
+ is_closing: false
127
+ }
128
+
129
+ @tuns[ [ orig_src_addr, dst_addr ].join ] = tun
130
+ add_read( tun, :tun )
131
+
132
+ tun
133
+ end
134
+
135
+ def add_redir_wbuff( redir, to_addr, data )
136
+ @redir_wbuffs << [ to_addr, data ]
137
+ add_write( redir )
138
+ end
139
+
140
+ def add_tun_wbuff( tun, to_addr, data )
141
+ tun_info = @tun_infos[ tun ]
142
+
143
+ if to_addr
144
+ tun_info[ :wbuffs ] << [ to_addr, data ]
145
+ add_write( tun )
146
+ else
147
+ tun_info[ :rbuffs ] << data
148
+ end
149
+ end
150
+
151
+ def add_read( sock, role )
152
+ unless @reads.include?( sock )
153
+ @reads << sock
154
+ end
155
+
156
+ @roles[ sock ] = role
157
+ end
158
+
159
+ def add_write( sock )
160
+ unless @writes.include?( sock )
161
+ @writes << sock
162
+ end
163
+ end
164
+
165
+ def set_is_closing( tun )
166
+ if tun && !tun.closed?
167
+ # puts "debug1 set tun is closing"
168
+
169
+ tun_info = @tun_infos[ tun ]
170
+ tun_info[ :is_closing ] = true
171
+
172
+ @reads.delete( tun )
173
+ add_write( tun )
174
+ end
175
+ end
176
+
177
+ def send_data( sock, data, to_addr )
178
+ begin
179
+ sock.sendmsg( data, 0, to_addr )
180
+ rescue IO::WaitWritable, Errno::EINTR
181
+ return false
182
+ rescue Errno::EHOSTUNREACH, Errno::ENETUNREACH, Errno::ENETDOWN => e
183
+ if @roles[ sock ] == :tun
184
+ puts "#{ Time.new } #{ e.class }, close tun"
185
+ close_tun( sock )
186
+ return false
187
+ end
188
+ end
189
+
190
+ true
191
+ end
192
+
193
+ def close_tun( tun )
194
+ tun.close
195
+ @reads.delete( tun )
196
+ @writes.delete( tun )
197
+ @roles.delete( tun )
198
+ tun_info = @tun_infos.delete( tun )
199
+ @tuns.delete( [ tun_info[ :orig_src_addr ], tun_info[ :dst_addr ] ].join )
200
+
201
+ if @mappings.include?( tun_info[ :src_addr ] )
202
+ orig_src_addr, dst_addr, timeout, read_at = @mappings[ tun_info[ :src_addr ] ]
203
+
204
+ if orig_src_addr == tun_info[ :orig_src_addr ] && dst_addr == tun_info[ :dst_addr ]
205
+ @mappings.delete( tun_info[ :src_addr ] )
206
+ end
207
+ end
208
+ end
209
+
210
+ def write_redir( redir )
211
+ while @redir_wbuffs.any?
212
+ to_addr, data = @redir_wbuffs.first
213
+
214
+ unless send_data( redir, data, to_addr )
215
+ return
216
+ end
217
+
218
+ @redir_wbuffs.shift
219
+ end
220
+
221
+ @writes.delete( redir )
222
+ end
223
+
224
+ def write_tun( tun )
225
+ tun_info = @tun_infos[ tun ]
226
+
227
+ if tun_info[ :is_closing ]
228
+ close_tun( tun )
229
+ return
230
+ end
231
+
232
+ while tun_info[ :wbuffs ].any?
233
+ to_addr, data = tun_info[ :wbuffs ].first
234
+
235
+ unless send_data( tun, data, to_addr )
236
+ return
237
+ end
238
+
239
+ tun_info[ :wbuffs ].shift
240
+ end
241
+
242
+ @writes.delete( tun )
243
+ end
244
+
245
+ def read_dotr( dotr )
246
+ dotr.read( 1 )
247
+ end
248
+
97
249
  def read_redir( redir )
98
250
  data, addrinfo, rflags, *controls = redir.recvmsg
99
251
  src_addr = addrinfo.to_sockaddr
@@ -180,121 +332,5 @@ module Girl
180
332
  end
181
333
  end
182
334
 
183
- def write_redir( redir )
184
- if @redir_wbuffs.empty?
185
- @writes.delete( redir )
186
- return
187
- end
188
-
189
- src_addr, data = @redir_wbuffs.shift
190
- redir.sendmsg( data, 0, src_addr )
191
- end
192
-
193
- def write_tun( tun )
194
- if @closings.include?( tun )
195
- close_tun( tun )
196
- return
197
- end
198
-
199
- tun_info = @tun_infos[ tun ]
200
-
201
- if tun_info[ :wbuffs ].empty?
202
- @writes.delete( tun )
203
- return
204
- end
205
-
206
- to_addr, data = tun_info[ :wbuffs ].shift
207
- tun.sendmsg( data, 0, to_addr )
208
- end
209
-
210
- def add_redir_wbuff( redir, to_addr, data )
211
- @redir_wbuffs << [ to_addr, data ]
212
- add_write( redir )
213
- end
214
-
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
223
- end
224
- end
225
-
226
- def add_write( sock )
227
- unless @writes.include?( sock )
228
- @writes << sock
229
- end
230
- end
231
-
232
- def add_closing( tun )
233
- unless @closings.include?( tun )
234
- @closings << tun
235
- end
236
-
237
- add_write( tun )
238
- end
239
-
240
- def close_tun( tun )
241
- tun.close
242
- @reads.delete( tun )
243
- @writes.delete( tun )
244
- @closings.delete( tun )
245
- @roles.delete( tun )
246
- tun_info = @tun_infos.delete( tun )
247
- @tuns.delete( [ tun_info[ :orig_src_addr ], tun_info[ :dst_addr ] ].join )
248
-
249
- if @mappings.include?( tun_info[ :src_addr ] )
250
- orig_src_addr, dst_addr, timeout, read_at = @mappings[ tun_info[ :src_addr ] ]
251
-
252
- if orig_src_addr == tun_info[ :orig_src_addr ] && dst_addr == tun_info[ :dst_addr ]
253
- @mappings.delete( tun_info[ :src_addr ] )
254
- end
255
- end
256
- end
257
-
258
- def new_a_tun( orig_src_addr, dst_addr, src_addr )
259
- tun = Socket.new( Socket::AF_INET, Socket::SOCK_DGRAM, 0 )
260
- tun.setsockopt( Socket::SOL_SOCKET, Socket::SO_REUSEPORT, 1 )
261
- tun.bind( Socket.sockaddr_in( 0, '0.0.0.0' ) )
262
-
263
- @tun_infos[ tun ] = {
264
- orig_src_addr: orig_src_addr,
265
- dst_addr: dst_addr,
266
- src_addr: src_addr,
267
- tund_addr: nil,
268
- rbuffs: [],
269
- wbuffs: [],
270
- last_traff_at: Time.new
271
- }
272
-
273
- @tuns[ [ orig_src_addr, dst_addr ].join ] = tun
274
- @roles[ tun ] = :tun
275
- @reads << tun
276
-
277
- tun
278
- end
279
-
280
- def loop_expire
281
- Thread.new do
282
- loop do
283
- sleep 30
284
-
285
- @mutex.synchronize do
286
- now = Time.new
287
-
288
- @tun_infos.values.each do | tun_info |
289
- # net.netfilter.nf_conntrack_udp_timeout_stream
290
- if now - tun_info[ :last_traff_at ] > 180
291
- @ctlw.write( [ tun_info[ :orig_src_addr ], tun_info[ :dst_addr ] ].join )
292
- end
293
- end
294
- end
295
- end
296
- end
297
- end
298
-
299
335
  end
300
336
  end
@@ -8,23 +8,10 @@ module Girl
8
8
  class Udpd
9
9
 
10
10
  def initialize( port = 3030 )
11
- ctlr, ctlw = IO.pipe
12
-
13
- udpd = Socket.new( Socket::AF_INET, Socket::SOCK_DGRAM, 0 )
14
- udpd.setsockopt( Socket::SOL_SOCKET, Socket::SO_REUSEPORT, 1 )
15
- udpd.bind( Socket.sockaddr_in( port, '0.0.0.0' ) )
16
- puts "udpd bound on #{ port } #{ Time.new }"
17
-
18
11
  @mutex = Mutex.new
19
- @ctlw = ctlw
20
- @udpd = udpd
21
- @reads = [ ctlr, udpd ]
12
+ @reads = []
22
13
  @writes = []
23
- @closings = []
24
- @roles = {
25
- ctlr => :ctlr, # :ctlr / :udpd / :tund
26
- udpd => :udpd
27
- }
14
+ @roles = {} # :dotr / :udpd / :tund
28
15
  @udpd_wbuffs = [] # [ tun_addr ctlmsg ] ...
29
16
  @tunds = {} # [ tun_ip_addr orig_src_addr ] => tund
30
17
  @tund_infos = {} # tund => {}
@@ -37,6 +24,10 @@ module Girl
37
24
  # is_tunneleds: { [ tun_addr dst_addr ] => false }
38
25
  # unpaired_dst_rbuffs: { dst_addr => [] }
39
26
  # last_traff_at: now
27
+ dotr, dotw = IO.pipe
28
+ @dotw = dotw
29
+ add_read( dotr, :dotr )
30
+ new_a_udpd( port )
40
31
  end
41
32
 
42
33
  def looping
@@ -46,23 +37,23 @@ module Girl
46
37
  rs, ws = IO.select( @reads, @writes )
47
38
 
48
39
  @mutex.synchronize do
49
- rs.each do | sock |
40
+ ws.each do | sock |
50
41
  case @roles[ sock ]
51
- when :ctlr
52
- read_ctlr( sock )
53
42
  when :udpd
54
- read_udpd( sock )
43
+ write_udpd( sock )
55
44
  when :tund
56
- read_tund( sock )
45
+ write_tund( sock )
57
46
  end
58
47
  end
59
48
 
60
- ws.each do | sock |
49
+ rs.each do | sock |
61
50
  case @roles[ sock ]
51
+ when :dotr
52
+ read_dotr( sock )
62
53
  when :udpd
63
- write_udpd( sock )
54
+ read_udpd( sock )
64
55
  when :tund
65
- write_tund( sock )
56
+ read_tund( sock )
66
57
  end
67
58
  end
68
59
  end
@@ -75,13 +66,176 @@ module Girl
75
66
 
76
67
  private
77
68
 
78
- def read_ctlr( ctlr )
79
- to_addr = ctlr.read( 32 )
80
- tund = @tunds[ to_addr ]
69
+ def loop_expire
70
+ Thread.new do
71
+ loop do
72
+ sleep 30
73
+
74
+ @mutex.synchronize do
75
+ need_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
81
+ set_is_closing( tund )
82
+ need_trigger = true
83
+ end
84
+ end
85
+
86
+ if need_trigger
87
+ next_tick
88
+ end
89
+ end
90
+ end
91
+ end
92
+ end
93
+
94
+ def new_a_udpd( port )
95
+ udpd = Socket.new( Socket::AF_INET, Socket::SOCK_DGRAM, 0 )
96
+ udpd.setsockopt( Socket::SOL_SOCKET, Socket::SO_REUSEPORT, 1 )
97
+ udpd.bind( Socket.sockaddr_in( port, '0.0.0.0' ) )
98
+ puts "udpd bound on #{ port } #{ Time.new }"
99
+ @udpd = udpd
100
+ add_read( udpd, :udpd )
101
+ end
102
+
103
+ def pair_tund( tun_addr, tun_ip_addr, orig_src_addr, dst_addr )
104
+ from_addr = [ tun_ip_addr, orig_src_addr ].join
105
+ td_addr = [ tun_addr, dst_addr ].join
106
+ tund = @tunds[ from_addr ]
81
107
 
82
108
  if tund
83
- add_closing( tund )
109
+ tund_info = @tund_infos[ tund ]
110
+ tund_info[ :dst_addrs ][ tun_addr ] = dst_addr
111
+ tund_info[ :tun_addrs ][ dst_addr ] = tun_addr
112
+ tund_info[ :is_tunneleds ][ td_addr ] = false
113
+ else
114
+ tund = Socket.new( Socket::AF_INET, Socket::SOCK_DGRAM, 0 )
115
+ tund.setsockopt( Socket::SOL_SOCKET, Socket::SO_REUSEPORT, 1 )
116
+ tund.setsockopt( Socket::SOL_SOCKET, Socket::SO_BROADCAST, 1 )
117
+ tund.bind( Socket.sockaddr_in( 0, '0.0.0.0' ) )
118
+ tund_port = tund.local_address.ip_unpack.last
119
+
120
+ @tund_infos[ tund ] = {
121
+ port: tund_port,
122
+ tun_ip_addr: tun_ip_addr,
123
+ orig_src_addr: orig_src_addr,
124
+ wbuffs: [],
125
+ dst_addrs: { tun_addr => dst_addr },
126
+ tun_addrs: { dst_addr => tun_addr },
127
+ is_tunneleds: { td_addr => false },
128
+ unpaired_dst_rbuffs: {},
129
+ last_traff_at: Time.new,
130
+ is_closing: false
131
+ }
132
+
133
+ @tunds[ from_addr ] = tund
134
+ add_read( tund, :tund )
135
+ end
136
+
137
+ tund
138
+ end
139
+
140
+ def add_tund_wbuff( tund, to_addr, data )
141
+ tund_info = @tund_infos[ tund ]
142
+ tund_info[ :wbuffs ] << [ to_addr, data ]
143
+
144
+ add_write( tund )
145
+ end
146
+
147
+ def add_read( sock, role )
148
+ unless @reads.include?( sock )
149
+ @reads << sock
150
+ end
151
+
152
+ @roles[ sock ] = role
153
+ end
154
+
155
+ def add_write( sock )
156
+ unless @writes.include?( sock )
157
+ @writes << sock
158
+ end
159
+ end
160
+
161
+ def set_is_closing( tund )
162
+ if tund && !tund.closed?
163
+ # puts "debug1 set tund is closing"
164
+
165
+ tund_info = @tund_infos[ tund ]
166
+ tund_info[ :is_closing ] = true
167
+
168
+ @reads.delete( tund )
169
+ add_write( tund )
170
+ end
171
+ end
172
+
173
+ def send_data( sock, data, to_addr )
174
+ begin
175
+ sock.sendmsg( data, 0, to_addr )
176
+ rescue IO::WaitWritable, Errno::EINTR
177
+ return false
178
+ rescue Errno::EHOSTUNREACH, Errno::ENETUNREACH, Errno::ENETDOWN => e
179
+ if @roles[ sock ] == :tund
180
+ puts "#{ Time.new } #{ e.class }, close tund"
181
+ close_tund( sock )
182
+ return false
183
+ end
184
+ end
185
+
186
+ true
187
+ end
188
+
189
+ def close_tund( tund )
190
+ tund.close
191
+ @reads.delete( tund )
192
+ @writes.delete( tund )
193
+ @roles.delete( tund )
194
+ tund_info = @tund_infos.delete( tund )
195
+ @tunds.delete( [ tund_info[ :tun_ip_addr ], tund_info[ :orig_src_addr ] ].join )
196
+ end
197
+
198
+ def next_tick
199
+ @dotw.write( '.' )
200
+ end
201
+
202
+ def write_udpd( udpd )
203
+ while @udpd_wbuffs.any?
204
+ to_addr, data = @udpd_wbuffs.first
205
+
206
+ unless send_data( udpd, data, to_addr )
207
+ return
208
+ end
209
+
210
+ @udpd_wbuffs.shift
211
+ end
212
+
213
+ @writes.delete( udpd )
214
+ end
215
+
216
+ def write_tund( tund )
217
+ tund_info = @tund_infos[ tund ]
218
+
219
+ if tund_info[ :is_closing ]
220
+ close_tund( tund )
221
+ return
222
+ end
223
+
224
+ while tund_info[ :wbuffs ].any?
225
+ to_addr, data = tund_info[ :wbuffs ].first
226
+
227
+ unless send_data( tund, data, to_addr )
228
+ return
229
+ end
230
+
231
+ tund_info[ :wbuffs ].shift
84
232
  end
233
+
234
+ @writes.delete( tund )
235
+ end
236
+
237
+ def read_dotr( dotr )
238
+ dotr.read( 1 )
85
239
  end
86
240
 
87
241
  def read_udpd( udpd )
@@ -168,119 +322,5 @@ module Girl
168
322
  end
169
323
  end
170
324
 
171
- def write_udpd( udpd )
172
- if @udpd_wbuffs.empty?
173
- @writes.delete( udpd )
174
- return
175
- end
176
-
177
- tun_addr, ctlmsg = @udpd_wbuffs.shift
178
- udpd.sendmsg( ctlmsg, 0, tun_addr )
179
- end
180
-
181
- def write_tund( tund )
182
- if @closings.include?( tund )
183
- close_tund( tund )
184
- return
185
- end
186
-
187
- tund_info = @tund_infos[ tund ]
188
-
189
- if tund_info[ :wbuffs ].empty?
190
- @writes.delete( tund )
191
- return
192
- end
193
-
194
- to_addr, data = tund_info[ :wbuffs ].shift
195
- tund.sendmsg( data, 0, to_addr )
196
- end
197
-
198
- def add_tund_wbuff( tund, to_addr, data )
199
- tund_info = @tund_infos[ tund ]
200
- tund_info[ :wbuffs ] << [ to_addr, data ]
201
-
202
- add_write( tund )
203
- end
204
-
205
- def add_write( sock )
206
- unless @writes.include?( sock )
207
- @writes << sock
208
- end
209
- end
210
-
211
- def add_closing( tund )
212
- unless @closings.include?( tund )
213
- @closings << tund
214
- end
215
-
216
- add_write( tund )
217
- end
218
-
219
- def close_tund( tund )
220
- tund.close
221
- @reads.delete( tund )
222
- @writes.delete( tund )
223
- @closings.delete( tund )
224
- @roles.delete( tund )
225
- tund_info = @tund_infos.delete( tund )
226
- @tunds.delete( [ tund_info[ :tun_ip_addr ], tund_info[ :orig_src_addr ] ].join )
227
- end
228
-
229
- def pair_tund( tun_addr, tun_ip_addr, orig_src_addr, dst_addr )
230
- from_addr = [ tun_ip_addr, orig_src_addr ].join
231
- td_addr = [ tun_addr, dst_addr ].join
232
- tund = @tunds[ from_addr ]
233
-
234
- if tund
235
- tund_info = @tund_infos[ tund ]
236
- tund_info[ :dst_addrs ][ tun_addr ] = dst_addr
237
- tund_info[ :tun_addrs ][ dst_addr ] = tun_addr
238
- tund_info[ :is_tunneleds ][ td_addr ] = false
239
- else
240
- tund = Socket.new( Socket::AF_INET, Socket::SOCK_DGRAM, 0 )
241
- tund.setsockopt( Socket::SOL_SOCKET, Socket::SO_REUSEPORT, 1 )
242
- tund.setsockopt( Socket::SOL_SOCKET, Socket::SO_BROADCAST, 1 )
243
- tund.bind( Socket.sockaddr_in( 0, '0.0.0.0' ) )
244
- tund_port = tund.local_address.ip_unpack.last
245
-
246
- @tund_infos[ tund ] = {
247
- port: tund_port,
248
- tun_ip_addr: tun_ip_addr,
249
- orig_src_addr: orig_src_addr,
250
- wbuffs: [],
251
- dst_addrs: { tun_addr => dst_addr },
252
- tun_addrs: { dst_addr => tun_addr },
253
- is_tunneleds: { td_addr => false },
254
- unpaired_dst_rbuffs: {},
255
- last_traff_at: Time.new
256
- }
257
-
258
- @roles[ tund ] = :tund
259
- @reads << tund
260
- @tunds[ from_addr ] = tund
261
- end
262
-
263
- tund
264
- end
265
-
266
- def loop_expire
267
- Thread.new do
268
- loop do
269
- sleep 30
270
-
271
- @mutex.synchronize do
272
- now = Time.new
273
-
274
- @tund_infos.values.each do | tund_info |
275
- # net.netfilter.nf_conntrack_udp_timeout_stream
276
- if now - tund_info[ :last_traff_at ] > 180
277
- @ctlw.write( [ tund_info[ :tun_ip_addr ], tund_info[ :orig_src_addr ] ].join )
278
- end
279
- end
280
- end
281
- end
282
- end
283
- end
284
-
285
325
  end
286
326
  end
@@ -1,3 +1,3 @@
1
1
  module Girl
2
- VERSION = '0.81.0'.freeze
2
+ VERSION = '0.86.0'.freeze
3
3
  end
metadata CHANGED
@@ -1,16 +1,16 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: girl
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.81.0
4
+ version: 0.86.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-08-27 00:00:00.000000000 Z
11
+ date: 2020-09-18 00:00:00.000000000 Z
12
12
  dependencies: []
13
- description: while internet is evil, here's a girl.
13
+ description: escape evil.
14
14
  email:
15
15
  - qqtakafan@gmail.com
16
16
  executables: []