girl 3.7.0 → 4.2.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.

data/lib/girl/proxyd.rb CHANGED
@@ -5,7 +5,6 @@ require 'girl/proxyd_custom'
5
5
  require 'girl/proxyd_worker'
6
6
  require 'girl/version'
7
7
  require 'json'
8
- require 'openssl'
9
8
  require 'socket'
10
9
 
11
10
  ##
@@ -47,26 +46,13 @@ module Girl
47
46
  puts title
48
47
  puts "proxyd port #{ proxyd_port } infod port #{ infod_port } worker count #{ worker_count }"
49
48
 
50
- now = Time.new
51
- name = OpenSSL::X509::Name.new
52
- key = OpenSSL::PKey::RSA.new 2048
53
- cert = OpenSSL::X509::Certificate.new
54
- cert.version = 2
55
- cert.serial = 0
56
- cert.not_before = now
57
- cert.not_after = now + 365 * 24 * 60 * 60
58
- cert.public_key = key.public_key
59
- cert.subject = name
60
- cert.issuer = name
61
- cert.sign key, OpenSSL::Digest.new('SHA1')
62
-
63
49
  $0 = title
64
50
  workers = []
65
51
 
66
52
  worker_count.times do | i |
67
53
  workers << fork do
68
54
  $0 = 'girl proxyd worker'
69
- worker = Girl::ProxydWorker.new( proxyd_port, infod_port, cert, key )
55
+ worker = Girl::ProxydWorker.new( proxyd_port, infod_port )
70
56
 
71
57
  Signal.trap( :TERM ) do
72
58
  puts "w#{ i } exit"
@@ -1,5 +1,8 @@
1
+ require 'girl/custom'
2
+
1
3
  module Girl
2
4
  class ProxydCustom
5
+ include Custom
3
6
 
4
7
  def check( data, addrinfo )
5
8
  :success
@@ -4,34 +4,31 @@ module Girl
4
4
  ##
5
5
  # initialize
6
6
  #
7
- def initialize( proxyd_port, infod_port, cert, key )
7
+ def initialize( proxyd_port, infod_port )
8
8
  @custom = Girl::ProxydCustom.new
9
9
  @reads = []
10
10
  @writes = []
11
- @closing_proxys = []
11
+ @deleting_ctl_infos = []
12
12
  @closing_dsts = []
13
- @closing_tuns = []
14
13
  @paused_dsts = []
15
- @paused_tuns = []
14
+ @paused_atuns = []
16
15
  @resume_dsts = []
17
- @resume_tuns = []
18
- @roles = ConcurrentHash.new # sock => :dotr / :proxyd / :proxy / :infod / :dst / :tund / :tun
19
- @proxy_infos = ConcurrentHash.new # proxy => {}
16
+ @resume_atuns = []
17
+ @roles = ConcurrentHash.new # sock => :dotr / :ctld / :ctl / :infod / :dst / :atund / :btund / :atun / :btun
18
+ @ctl_infos = ConcurrentHash.new # ctl => {}
20
19
  @dst_infos = ConcurrentHash.new # dst => {}
21
- @tund_infos = ConcurrentHash.new # tund => {}
22
- @tun_infos = ConcurrentHash.new # tun => {}
20
+ @atund_infos = ConcurrentHash.new # atund => {}
21
+ @btund_infos = ConcurrentHash.new # btund => {}
22
+ @atun_infos = ConcurrentHash.new # atun => {}
23
+ @btun_infos = ConcurrentHash.new # btun => {}
23
24
  @resolv_caches = ConcurrentHash.new # domain => [ ip, created_at ]
24
25
  @traff_ins = ConcurrentHash.new # im => 0
25
26
  @traff_outs = ConcurrentHash.new # im => 0
26
27
 
27
- context = OpenSSL::SSL::SSLContext.new
28
- context.add_certificate( cert, key )
29
- @context = context
30
-
31
28
  dotr, dotw = IO.pipe
32
29
  @dotw = dotw
33
30
  add_read( dotr, :dotr )
34
- new_a_proxyd( proxyd_port )
31
+ new_a_ctld( proxyd_port )
35
32
  new_a_infod( infod_port )
36
33
  end
37
34
 
@@ -51,29 +48,29 @@ module Girl
51
48
  case @roles[ sock ]
52
49
  when :dotr then
53
50
  read_dotr( sock )
54
- when :proxyd then
55
- read_proxyd( sock )
56
- when :proxy then
57
- read_proxy( sock )
51
+ when :ctld then
52
+ read_ctld( sock )
58
53
  when :infod then
59
54
  read_infod( sock )
60
55
  when :dst then
61
56
  read_dst( sock )
62
- when :tund then
63
- read_tund( sock )
64
- when :tun then
65
- read_tun( sock )
57
+ when :atund then
58
+ read_atund( sock )
59
+ when :btund then
60
+ read_btund( sock )
61
+ when :atun then
62
+ read_atun( sock )
63
+ when :btun then
64
+ read_btun( sock )
66
65
  end
67
66
  end
68
67
 
69
68
  ws.each do | sock |
70
69
  case @roles[ sock ]
71
- when :proxy then
72
- write_proxy( sock )
73
70
  when :dst then
74
71
  write_dst( sock )
75
- when :tun then
76
- write_tun( sock )
72
+ when :btun then
73
+ write_btun( sock )
77
74
  end
78
75
  end
79
76
  end
@@ -86,26 +83,25 @@ module Girl
86
83
  # quit!
87
84
  #
88
85
  def quit!
89
- @proxy_infos.keys.each do | proxy |
90
- # puts "debug1 send tund fin"
91
- data = [ TUND_FIN ].pack( 'C' )
92
- proxy.write( data )
93
- end
94
-
95
- # puts "debug1 exit"
86
+ # puts "debug exit"
96
87
  exit
97
88
  end
98
89
 
99
90
  private
100
91
 
101
92
  ##
102
- # add ctlmsg
93
+ # add btun wbuff
103
94
  #
104
- def add_ctlmsg( proxy, data )
105
- return if proxy.closed? || @closing_proxys.include?( proxy )
106
- proxy_info = @proxy_infos[ proxy ]
107
- proxy_info[ :ctlmsgs ] << data
108
- add_write( proxy )
95
+ def add_btun_wbuff( btun, data )
96
+ return if btun.closed?
97
+ btun_info = @btun_infos[ btun ]
98
+ btun_info[ :wbuff ] << data
99
+ add_write( btun )
100
+
101
+ if btun_info[ :wbuff ].bytesize >= WBUFF_LIMIT then
102
+ puts "p#{ Process.pid } #{ Time.new } pause dst #{ btun_info[ :domain_port ] }"
103
+ add_paused_dst( btun_info[ :dst ] )
104
+ end
109
105
  end
110
106
 
111
107
  ##
@@ -116,7 +112,7 @@ module Girl
116
112
  dst_info[ :rbuff ] << data
117
113
 
118
114
  if dst_info[ :rbuff ].bytesize >= WBUFF_LIMIT then
119
- # puts "debug1 dst.rbuff full"
115
+ # puts "debug dst.rbuff full"
120
116
  close_dst( dst )
121
117
  end
122
118
  end
@@ -132,11 +128,20 @@ module Girl
132
128
  add_write( dst )
133
129
 
134
130
  if dst_info[ :wbuff ].bytesize >= WBUFF_LIMIT then
135
- puts "p#{ Process.pid } #{ Time.new } pause tun #{ dst_info[ :domain_port ] }"
136
- add_paused_tun( dst_info[ :tun ] )
131
+ puts "p#{ Process.pid } #{ Time.new } pause atun #{ dst_info[ :domain_port ] }"
132
+ add_paused_atun( dst_info[ :atun ] )
137
133
  end
138
134
  end
139
135
 
136
+ ##
137
+ # add paused atun
138
+ #
139
+ def add_paused_atun( atun )
140
+ return if tun.closed? || @paused_atuns.include?( atun )
141
+ @reads.delete( atun )
142
+ @paused_atuns << atun
143
+ end
144
+
140
145
  ##
141
146
  # add paused dst
142
147
  #
@@ -146,15 +151,6 @@ module Girl
146
151
  @paused_dsts << dst
147
152
  end
148
153
 
149
- ##
150
- # add paused tun
151
- #
152
- def add_paused_tun( tun )
153
- return if tun.closed? || @paused_tuns.include?( tun )
154
- @reads.delete( tun )
155
- @paused_tuns << tun
156
- end
157
-
158
154
  ##
159
155
  # add read
160
156
  #
@@ -169,6 +165,15 @@ module Girl
169
165
  next_tick
170
166
  end
171
167
 
168
+ ##
169
+ # add resume atun
170
+ #
171
+ def add_resume_atun( atun )
172
+ return if @resume_atuns.include?( atun )
173
+ @resume_atuns << atun
174
+ next_tick
175
+ end
176
+
172
177
  ##
173
178
  # add resume dst
174
179
  #
@@ -179,36 +184,57 @@ module Girl
179
184
  end
180
185
 
181
186
  ##
182
- # add resume tun
187
+ # add write
183
188
  #
184
- def add_resume_tun( tun )
185
- return if @resume_tuns.include?( tun )
186
- @resume_tuns << tun
189
+ def add_write( sock )
190
+ return if sock.closed? || @writes.include?( sock )
191
+ @writes << sock
187
192
  next_tick
188
193
  end
189
194
 
190
195
  ##
191
- # add tun wbuff
196
+ # close atun
192
197
  #
193
- def add_tun_wbuff( tun, data )
194
- return if tun.closed? || @closing_tuns.include?( tun )
195
- tun_info = @tun_infos[ tun ]
196
- tun_info[ :wbuff ] << data
197
- add_write( tun )
198
-
199
- if tun_info[ :wbuff ].bytesize >= WBUFF_LIMIT then
200
- puts "p#{ Process.pid } #{ Time.new } pause dst #{ tun_info[ :domain_port ] }"
201
- add_paused_dst( tun_info[ :dst ] )
198
+ def close_atun( atun )
199
+ return if atun.closed?
200
+ # puts "debug close atun"
201
+ close_sock( atun )
202
+ del_atun_info( atun )
203
+ end
204
+
205
+ ##
206
+ # close atund
207
+ #
208
+ def close_atund( atund )
209
+ return if atund.closed?
210
+ # puts "debug close atund"
211
+ close_sock( atund )
212
+ @atund_infos.delete( atund )
213
+ end
214
+
215
+ ##
216
+ # close btun
217
+ #
218
+ def close_btun( btun )
219
+ return if btun.closed?
220
+ # puts "debug close btun"
221
+ close_sock( btun )
222
+ btun_info = @btun_infos.delete( btun )
223
+ dst = btun_info[ :dst ]
224
+
225
+ if dst then
226
+ @paused_dsts.delete( dst )
202
227
  end
203
228
  end
204
229
 
205
230
  ##
206
- # add write
231
+ # close btund
207
232
  #
208
- def add_write( sock )
209
- return if sock.closed? || @writes.include?( sock )
210
- @writes << sock
211
- next_tick
233
+ def close_btund( btund )
234
+ return if btund.closed?
235
+ # puts "debug close btund"
236
+ close_sock( btund )
237
+ @btund_infos.delete( btund )
212
238
  end
213
239
 
214
240
  ##
@@ -216,14 +242,20 @@ module Girl
216
242
  #
217
243
  def close_dst( dst )
218
244
  return if dst.closed?
219
- # puts "debug1 close dst"
245
+ # puts "debug close dst"
220
246
  close_sock( dst )
221
247
  dst_info = del_dst_info( dst )
222
- tun = dst_info[ :tun ]
248
+ atun = dst_info[ :atun ]
249
+ btun = dst_info[ :btun ]
250
+
251
+ if atun then
252
+ close_sock( atun )
253
+ del_atun_info( atun )
254
+ end
223
255
 
224
- if tun then
225
- close_sock( tun )
226
- @tun_infos.delete( tun )
256
+ if btun then
257
+ close_sock( btun )
258
+ @btun_infos.delete( btun )
227
259
  end
228
260
  end
229
261
 
@@ -232,40 +264,15 @@ module Girl
232
264
  #
233
265
  def close_read_dst( dst )
234
266
  return if dst.closed?
235
- # puts "debug1 close read dst"
267
+ # puts "debug close read dst"
236
268
  dst.close_read
237
269
  @reads.delete( dst )
238
270
 
239
271
  if dst.closed? then
240
- # puts "debug1 delete dst info"
241
272
  @writes.delete( dst )
242
273
  @roles.delete( dst )
243
- dst_info = del_dst_info( dst )
244
- else
245
- dst_info = @dst_infos[ dst ]
246
- end
247
-
248
- dst_info
249
- end
250
-
251
- ##
252
- # close read tun
253
- #
254
- def close_read_tun( tun )
255
- return if tun.closed?
256
- # puts "debug1 close read tun"
257
- tun_info = @tun_infos[ tun ]
258
- tun_info[ :close_read ] = true
259
-
260
- if tun_info[ :close_write ] then
261
- # puts "debug1 close tun"
262
- close_sock( tun )
263
- tun_info = @tun_infos.delete( tun )
264
- else
265
- @reads.delete( tun )
274
+ del_dst_info( dst )
266
275
  end
267
-
268
- tun_info
269
276
  end
270
277
 
271
278
  ##
@@ -278,85 +285,27 @@ module Girl
278
285
  @roles.delete( sock )
279
286
  end
280
287
 
281
- ##
282
- # close tun
283
- #
284
- def close_tun( tun )
285
- return if tun.closed?
286
- # puts "debug1 close tun"
287
- close_sock( tun )
288
- tun_info = @tun_infos.delete( tun )
289
- dst = tun_info[ :dst ]
290
-
291
- if dst then
292
- close_sock( dst )
293
- del_dst_info( dst )
294
- end
295
- end
296
-
297
- ##
298
- # close proxy
299
- #
300
- def close_proxy( proxy )
301
- return if proxy.closed?
302
- # puts "debug1 close proxy"
303
- close_sock( proxy )
304
- proxy_info = @proxy_infos.delete( proxy )
305
- tund = proxy_info[ :tund ]
306
-
307
- if tund then
308
- close_sock( tund )
309
- @tund_infos.delete( tund )
310
- end
311
- end
312
-
313
288
  ##
314
289
  # close write dst
315
290
  #
316
291
  def close_write_dst( dst )
317
292
  return if dst.closed?
318
- # puts "debug1 close write dst"
293
+ # puts "debug close write dst"
319
294
  dst.close_write
320
295
  @writes.delete( dst )
321
296
 
322
297
  if dst.closed? then
323
- # puts "debug1 delete dst info"
324
298
  @reads.delete( dst )
325
299
  @roles.delete( dst )
326
300
  dst_info = del_dst_info( dst )
327
- else
328
- dst_info = @dst_infos[ dst ]
329
301
  end
330
-
331
- dst_info
332
- end
333
-
334
- ##
335
- # close write tun
336
- #
337
- def close_write_tun( tun )
338
- return if tun.closed?
339
- # puts "debug1 close write tun"
340
- tun_info = @tun_infos[ tun ]
341
- tun_info[ :close_write ] = true
342
-
343
- if tun_info[ :close_read ] then
344
- # puts "debug1 close tun"
345
- close_sock( tun )
346
- tun_info = @tun_infos.delete( tun )
347
- else
348
- @writes.delete( tun )
349
- end
350
-
351
- tun_info
352
302
  end
353
303
 
354
304
  ##
355
305
  # deal with destination addr
356
306
  #
357
- def deal_with_destination_addr( proxy, src_id, destination_addr, domain_port )
307
+ def deal_with_destination_addr( ctl_addr, src_id, destination_addr, domain_port )
358
308
  dst = Socket.new( Addrinfo.new( destination_addr ).ipv4? ? Socket::AF_INET : Socket::AF_INET6, Socket::SOCK_STREAM, 0 )
359
- dst.setsockopt( Socket::SOL_TCP, Socket::TCP_NODELAY, 1 )
360
309
 
361
310
  begin
362
311
  dst.connect_nonblock( destination_addr )
@@ -368,15 +317,16 @@ module Girl
368
317
  end
369
318
 
370
319
  dst_id = dst.local_address.ip_port
371
- proxy_info = @proxy_infos[ proxy ]
320
+ ctl_info = @ctl_infos[ ctl_addr ]
372
321
 
373
322
  @dst_infos[ dst ] = {
374
323
  id: dst_id, # id
375
- proxy: proxy, # 对应proxy
376
- im: proxy_info[ :im ], # 标识
324
+ ctl_addr: ctl_addr, # 对应ctl
325
+ im: ctl_info[ :im ], # 标识
377
326
  domain_port: domain_port, # 目的地和端口
378
327
  rbuff: '', # 对应的tun没准备好,暂存读到的流量
379
- tun: nil, # 对应的tun
328
+ atun: nil, # 对应的atun
329
+ btun: nil, # 对应的btun
380
330
  wbuff: '', # 从tun读到的流量
381
331
  src_id: src_id, # 近端src id
382
332
  created_at: Time.new, # 创建时间
@@ -387,25 +337,47 @@ module Girl
387
337
 
388
338
  add_read( dst, :dst )
389
339
 
390
- proxy_info[ :dst_ids ][ src_id ] = dst_id
391
- proxy_info[ :dsts ][ dst_id ] = dst
340
+ ctl_info[ :dst_ids ][ src_id ] = dst_id
341
+ ctl_info[ :dsts ][ dst_id ] = dst
392
342
 
393
343
  data = [ PAIRED, src_id, dst_id ].pack( 'CQ>n' )
394
- # puts "debug1 add ctlmsg paired #{ src_id } #{ dst_id }"
395
- add_ctlmsg( proxy, data )
344
+ # puts "debug add ctlmsg paired #{ src_id } #{ dst_id }"
345
+ send_ctlmsg( data, ctl_addr )
346
+ end
347
+
348
+ ##
349
+ # del atun info
350
+ #
351
+ def del_atun_info( atun )
352
+ @atun_infos.delete( atun )
353
+ @paused_atuns.delete( atun )
354
+ @resume_atuns.delete( atun )
355
+ end
356
+
357
+ ##
358
+ # del ctl info
359
+ #
360
+ def del_ctl_info( ctl_addr )
361
+ # puts "debug delete ctl info"
362
+ ctl_info = @ctl_infos.delete( ctl_addr )
363
+ close_atund( ctl_info[ :atund ] )
364
+ close_btund( ctl_info[ :btund ] )
396
365
  end
397
366
 
398
367
  ##
399
368
  # del dst info
400
369
  #
401
370
  def del_dst_info( dst )
371
+ # puts "debug delete dst info"
402
372
  dst_info = @dst_infos.delete( dst )
403
- proxy = dst_info[ :proxy ]
404
-
405
- unless proxy.closed? then
406
- proxy_info = @proxy_infos[ proxy ]
407
- proxy_info[ :dsts ].delete( dst_info[ :id ] )
408
- proxy_info[ :dst_ids ].delete( dst_info[ :src_id ] )
373
+ @paused_dsts.delete( dst )
374
+ @resume_dsts.delete( dst )
375
+ ctl_addr = dst_info[ :ctl_addr ]
376
+ ctl_info = @ctl_infos[ ctl_addr ]
377
+
378
+ if ctl_info then
379
+ ctl_info[ :dsts ].delete( dst_info[ :id ] )
380
+ ctl_info[ :dst_ids ].delete( dst_info[ :src_id ] )
409
381
  end
410
382
 
411
383
  dst_info
@@ -420,14 +392,12 @@ module Girl
420
392
  sleep CHECK_EXPIRE_INTERVAL
421
393
  now = Time.new
422
394
 
423
- @proxy_infos.each do | proxy, proxy_info |
424
- last_recv_at = proxy_info[ :last_recv_at ] || proxy_info[ :created_at ]
395
+ @ctl_infos.each do | ctl_addr, ctl_info |
396
+ if now - ctl_info[ :last_recv_at ] >= EXPIRE_CTL
397
+ puts "p#{ Process.pid } #{ Time.new } expire ctl #{ EXPIRE_CTL } #{ ctl_info[ :addrinfo ].inspect } tund ports #{ ctl_info[ :atund_port ] } #{ ctl_info[ :btund_port ] }"
425
398
 
426
- if proxy_info[ :dsts ].empty? && ( now - last_recv_at >= EXPIRE_AFTER ) then
427
- puts "p#{ Process.pid } #{ Time.new } expire proxy #{ proxy_info[ :addrinfo ].inspect }"
428
-
429
- unless @closing_proxys.include?( proxy ) then
430
- @closing_proxys << proxy
399
+ unless @deleting_ctl_infos.include?( ctl_addr ) then
400
+ @deleting_ctl_infos << ctl_addr
431
401
  next_tick
432
402
  end
433
403
  end
@@ -436,7 +406,7 @@ module Girl
436
406
  @dst_infos.each do | dst, dst_info |
437
407
  last_recv_at = dst_info[ :last_recv_at ] || dst_info[ :created_at ]
438
408
  last_sent_at = dst_info[ :last_sent_at ] || dst_info[ :created_at ]
439
- expire_after = dst_info[ :tun ] ? EXPIRE_AFTER : EXPIRE_NEW
409
+ expire_after = dst_info[ :btun ] ? EXPIRE_AFTER : EXPIRE_NEW
440
410
 
441
411
  if ( now - last_recv_at >= expire_after ) && ( now - last_sent_at >= expire_after ) then
442
412
  puts "p#{ Process.pid } #{ Time.new } expire dst #{ expire_after } #{ dst_info[ :domain_port ] }"
@@ -460,31 +430,29 @@ module Girl
460
430
  sleep CHECK_RESUME_INTERVAL
461
431
 
462
432
  @paused_dsts.each do | dst |
463
- if dst.closed? then
464
- add_resume_dst( dst )
465
- else
466
- dst_info = @dst_infos[ dst ]
467
- tun = dst_info[ :tun ]
468
- tun_info = @tun_infos[ tun ]
433
+ dst_info = @dst_infos[ dst ]
434
+ btun = dst_info[ :btun ]
469
435
 
470
- if tun_info[ :wbuff ].size < RESUME_BELOW then
436
+ if btun && !btun.closed? then
437
+ btun_info = @btun_infos[ btun ]
438
+
439
+ if btun_info[ :wbuff ].size < RESUME_BELOW then
471
440
  puts "p#{ Process.pid } #{ Time.new } resume dst #{ dst_info[ :domain_port ] }"
472
441
  add_resume_dst( dst )
473
442
  end
474
443
  end
475
444
  end
476
445
 
477
- @paused_tuns.each do | tun |
478
- if tun.closed? then
479
- add_resume_tun( tun )
480
- else
481
- tun_info = @tun_infos[ tun ]
482
- dst = tun_info[ :dst ]
446
+ @paused_atuns.each do | atun |
447
+ atun_info = @atun_infos[ atun ]
448
+ dst = atun_info[ :dst ]
449
+
450
+ if dst && !dst.closed? then
483
451
  dst_info = @dst_infos[ dst ]
484
452
 
485
453
  if dst_info[ :wbuff ].size < RESUME_BELOW then
486
- puts "p#{ Process.pid } #{ Time.new } resume tun #{ tun_info[ :domain_port ] }"
487
- add_resume_tun( tun )
454
+ puts "p#{ Process.pid } #{ Time.new } resume atun #{ atun_info[ :domain_port ] }"
455
+ add_resume_atun( atun )
488
456
  end
489
457
  end
490
458
  end
@@ -512,18 +480,15 @@ module Girl
512
480
  end
513
481
 
514
482
  ##
515
- # new a proxyd
483
+ # new a ctld
516
484
  #
517
- def new_a_proxyd( proxyd_port )
518
- proxyd = Socket.new( Socket::AF_INET, Socket::SOCK_STREAM, 0 )
519
- proxyd.setsockopt( Socket::SOL_SOCKET, Socket::SO_REUSEADDR, 1 )
520
- proxyd.setsockopt( Socket::SOL_SOCKET, Socket::SO_REUSEPORT, 1 )
521
- proxyd.setsockopt( Socket::SOL_TCP, Socket::TCP_NODELAY, 1 )
522
- proxyd.bind( Socket.sockaddr_in( proxyd_port, '0.0.0.0' ) )
523
- proxyd.listen( 127 )
524
- puts "p#{ Process.pid } #{ Time.new } proxyd bind on #{ proxyd_port }"
525
- ssl_proxyd = OpenSSL::SSL::SSLServer.new proxyd, @context
526
- add_read( ssl_proxyd, :proxyd )
485
+ def new_a_ctld( proxyd_port )
486
+ ctld = Socket.new( Socket::AF_INET, Socket::SOCK_DGRAM, 0 )
487
+ ctld.setsockopt( Socket::SOL_SOCKET, Socket::SO_REUSEPORT, 1 )
488
+ ctld.bind( Socket.sockaddr_in( proxyd_port, '0.0.0.0' ) )
489
+ puts "p#{ Process.pid } #{ Time.new } ctld bind on #{ proxyd_port }"
490
+ add_read( ctld, :ctld )
491
+ @ctld = ctld
527
492
  end
528
493
 
529
494
  ##
@@ -533,11 +498,20 @@ module Girl
533
498
  infod = Socket.new( Socket::AF_INET, Socket::SOCK_DGRAM, 0 )
534
499
  infod.setsockopt( Socket::SOL_SOCKET, Socket::SO_REUSEPORT, 1 )
535
500
  infod.bind( Socket.sockaddr_in( infod_port, '127.0.0.1' ) )
536
-
537
501
  puts "p#{ Process.pid } #{ Time.new } infod bind on #{ infod_port }"
538
502
  add_read( infod, :infod )
539
503
  end
540
504
 
505
+ ##
506
+ # new a tund
507
+ #
508
+ def new_a_tund
509
+ tund = Socket.new( Socket::AF_INET, Socket::SOCK_STREAM, 0 )
510
+ tund.bind( Socket.sockaddr_in( 0, '0.0.0.0' ) )
511
+ tund.listen( 127 )
512
+ tund
513
+ end
514
+
541
515
  ##
542
516
  # next tick
543
517
  #
@@ -545,22 +519,31 @@ module Girl
545
519
  @dotw.write( '.' )
546
520
  end
547
521
 
522
+ ##
523
+ # pack a chunk
524
+ #
525
+ def pack_a_chunk( data )
526
+ # puts "debug pack a chunk"
527
+ data = @custom.encode( data )
528
+ "#{ [ data.bytesize ].pack( 'n' ) }#{ data }"
529
+ end
530
+
548
531
  ##
549
532
  # resolve domain
550
533
  #
551
- def resolve_domain( proxy, src_id, domain_port )
534
+ def resolve_domain( ctl_addr, src_id, domain_port )
552
535
  resolv_cache = @resolv_caches[ domain_port ]
553
536
 
554
537
  if resolv_cache then
555
538
  destination_addr, created_at = resolv_cache
556
539
 
557
540
  if Time.new - created_at < RESOLV_CACHE_EXPIRE then
558
- # puts "debug1 #{ domain_port } hit resolv cache #{ Addrinfo.new( destination_addr ).inspect }"
559
- deal_with_destination_addr( proxy, src_id, destination_addr, domain_port )
541
+ # puts "debug #{ domain_port } hit resolv cache #{ Addrinfo.new( destination_addr ).inspect }"
542
+ deal_with_destination_addr( ctl_addr, src_id, destination_addr, domain_port )
560
543
  return
561
544
  end
562
545
 
563
- # puts "debug1 expire #{ domain_port } resolv cache"
546
+ # puts "debug expire #{ domain_port } resolv cache"
564
547
  @resolv_caches.delete( domain_port )
565
548
  end
566
549
 
@@ -579,16 +562,38 @@ module Girl
579
562
  end
580
563
 
581
564
  if destination_addr then
582
- # puts "debug1 resolved #{ domain_port } #{ Addrinfo.new( destination_addr ).inspect }"
565
+ # puts "debug resolved #{ domain_port } #{ Addrinfo.new( destination_addr ).inspect }"
583
566
  @resolv_caches[ domain_port ] = [ destination_addr, Time.new ]
584
-
585
- unless proxy.closed? then
586
- deal_with_destination_addr( proxy, src_id, destination_addr, domain_port )
587
- end
567
+ deal_with_destination_addr( ctl_addr, src_id, destination_addr, domain_port )
588
568
  end
589
569
  end
590
570
  end
591
571
 
572
+ ##
573
+ # send ctlmsg
574
+ #
575
+ def send_ctlmsg( data, to_addr )
576
+ data = @custom.encode( data )
577
+
578
+ begin
579
+ @ctld.sendmsg( data, 0, to_addr )
580
+ rescue Exception => e
581
+ puts "p#{ Process.pid } #{ Time.new } sendmsg #{ e.class }"
582
+ end
583
+ end
584
+
585
+ ##
586
+ # set btun closing
587
+ #
588
+ def set_btun_closing( btun )
589
+ return if btun.closed?
590
+ btun_info = @btun_infos[ btun ]
591
+ return if btun_info[ :closing ]
592
+ # puts "debug set btun closing"
593
+ btun_info[ :closing ] = true
594
+ add_write( btun )
595
+ end
596
+
592
597
  ##
593
598
  # set dst closing write
594
599
  #
@@ -596,31 +601,20 @@ module Girl
596
601
  return if dst.closed? || @closing_dsts.include?( dst )
597
602
  dst_info = @dst_infos[ dst ]
598
603
  return if dst_info[ :closing_write ]
604
+ # puts "debug set dst closing write"
599
605
  dst_info[ :closing_write ] = true
600
606
  add_write( dst )
601
607
  end
602
608
 
603
- ##
604
- # set tun closing write
605
- #
606
- def set_tun_closing_write( tun )
607
- return if tun.closed? || @closing_tuns.include?( tun )
608
- tun_info = @tun_infos[ tun ]
609
- return if tun_info[ :closing_write ]
610
- tun_info[ :closing_write ] = true
611
- add_write( tun )
612
- end
613
-
614
609
  ##
615
610
  # read dotr
616
611
  #
617
612
  def read_dotr( dotr )
618
- dotr.read_nonblock( READ_SIZE )
613
+ dotr.read_nonblock( 65535 )
619
614
 
620
- # 处理关闭
621
- if @closing_proxys.any? then
622
- @closing_proxys.each { | proxy | close_proxy( proxy ) }
623
- @closing_proxys.clear
615
+ if @deleting_ctl_infos.any? then
616
+ @deleting_ctl_infos.each { | ctl_addr | del_ctl_info( ctl_addr ) }
617
+ @deleting_ctl_infos.clear
624
618
  end
625
619
 
626
620
  if @closing_dsts.any? then
@@ -628,11 +622,6 @@ module Girl
628
622
  @closing_dsts.clear
629
623
  end
630
624
 
631
- if @closing_tuns.any? then
632
- @closing_tuns.each { | tun | close_tun( tun ) }
633
- @closing_tuns.clear
634
- end
635
-
636
625
  if @resume_dsts.any? then
637
626
  @resume_dsts.each do | dst |
638
627
  add_read( dst )
@@ -642,78 +631,33 @@ module Girl
642
631
  @resume_dsts.clear
643
632
  end
644
633
 
645
- if @resume_tuns.any? then
646
- @resume_tuns.each do | tun |
647
- add_read( tun )
648
- @paused_tuns.delete( tun )
634
+ if @resume_atuns.any? then
635
+ @resume_atuns.each do | atun |
636
+ add_read( atun )
637
+ @paused_atuns.delete( atun )
649
638
  end
650
639
 
651
- @resume_tuns.clear
652
- end
653
- end
654
-
655
- ##
656
- # read proxyd
657
- #
658
- def read_proxyd( proxyd )
659
- begin
660
- proxy = proxyd.accept
661
- rescue Exception => e
662
- puts "p#{ Process.pid } #{ Time.new } proxyd accept #{ e.class }"
663
- return
640
+ @resume_atuns.clear
664
641
  end
665
-
666
- @proxy_infos[ proxy ] = {
667
- addrinfo: proxy.io.remote_address, # proxy地址
668
- im: nil, # 标识
669
- tund: nil, # 对应tund
670
- tund_port: nil, # tund端口
671
- ctlmsgs: [], # ctlmsg
672
- dsts: ConcurrentHash.new, # dst_id => dst
673
- dst_ids: ConcurrentHash.new, # src_id => dst_id
674
- created_at: Time.new, # 创建时间
675
- last_recv_at: nil # 上一次收到流量的时间
676
- }
677
-
678
- puts "p#{ Process.pid } #{ Time.new } accept a proxy #{ proxy.io.remote_address.inspect } #{ proxy.ssl_version }, #{ @proxy_infos.size } proxys"
679
- add_read( proxy, :proxy )
680
642
  end
681
643
 
682
644
  ##
683
- # read proxy
645
+ # read ctld
684
646
  #
685
- def read_proxy( proxy )
686
- if proxy.closed? then
687
- puts "p#{ Process.pid } #{ Time.new } read proxy but proxy closed?"
688
- return
689
- end
690
-
691
- begin
692
- data = proxy.read_nonblock( READ_SIZE )
693
- rescue IO::WaitReadable
694
- return
695
- rescue Errno::EINTR
696
- puts e.class
697
- return
698
- rescue Exception => e
699
- # puts "debug1 read proxy #{ e.class }"
700
- close_proxy( proxy )
701
- return
702
- end
703
-
704
- proxy_info = @proxy_infos[ proxy ]
705
- proxy_info[ :last_recv_at ] = Time.new
706
-
707
- data.split( SEPARATE ).each do | ctlmsg |
708
- next unless ctlmsg[ 0 ]
709
-
710
- ctl_num = ctlmsg[ 0 ].unpack( 'C' ).first
647
+ def read_ctld( ctld )
648
+ data, addrinfo, rflags, *controls = ctld.recvmsg
649
+ data = @custom.decode( data )
650
+ ctl_num = data[ 0 ].unpack( 'C' ).first
651
+ ctl_addr = addrinfo.to_sockaddr
652
+ ctl_info = @ctl_infos[ ctl_addr ]
711
653
 
712
- case ctl_num
713
- when HELLO then
714
- next if proxy_info[ :tund_port ] || ctlmsg.size <= 1
715
- im = ctlmsg[ 1..-1 ]
716
- addrinfo = proxy_info[ :addrinfo ]
654
+ case ctl_num
655
+ when HELLO then
656
+ if ctl_info then
657
+ atund_port, btund_port = ctl_info[ :atund_port ], ctl_info[ :btund_port ]
658
+ else
659
+ return if data.size <= 1
660
+ im = data[ 1..-1 ]
717
661
  result = @custom.check( im, addrinfo )
718
662
 
719
663
  if result != :success then
@@ -726,62 +670,65 @@ module Girl
726
670
  @traff_outs[ im ] = 0
727
671
  end
728
672
 
729
- tund = Socket.new( Socket::AF_INET, Socket::SOCK_STREAM, 0 )
730
- tund.setsockopt( Socket::SOL_TCP, Socket::TCP_NODELAY, 1 )
731
- tund.bind( Socket.sockaddr_in( 0, '0.0.0.0' ) )
732
- tund_port = tund.local_address.ip_port
733
- tund.listen( 127 )
734
- puts "p#{ Process.pid } #{ Time.new } tund #{ im.inspect } bind on #{ tund_port }"
735
- ssl_tund = OpenSSL::SSL::SSLServer.new tund, @context
736
- add_read( ssl_tund, :tund )
737
-
738
- @tund_infos[ ssl_tund ] = {
739
- proxy: proxy,
740
- close_read: false,
741
- close_write: false
673
+ atund = new_a_tund
674
+ atund_port = atund.local_address.ip_port
675
+ btund = new_a_tund
676
+ btund_port = btund.local_address.ip_port
677
+ add_read( atund, :atund )
678
+ add_read( btund, :btund )
679
+
680
+ @atund_infos[ atund ] = {
681
+ ctl_addr: ctl_addr,
682
+ im: im
742
683
  }
743
684
 
744
- proxy_info[ :im ] = im
745
- proxy_info[ :tund ] = ssl_tund
746
- proxy_info[ :tund_port ] = tund_port
747
- data2 = [ TUND_PORT, tund_port ].pack( 'Cn' )
748
- add_ctlmsg( proxy, data2 )
749
- when A_NEW_SOURCE then
750
- next if ctlmsg.size <= 9
751
- src_id = ctlmsg[ 1, 8 ].unpack( 'Q>' ).first
752
- dst_id = proxy_info[ :dst_ids ][ src_id ]
753
- next if dst_id
754
- domain_port = ctlmsg[ 9..-1 ]
755
- # puts "debug1 a new source #{ src_id } #{ domain_port }"
756
- resolve_domain( proxy, src_id, domain_port )
757
- when RESOLV then
758
- next if ctlmsg.size <= 9
759
- src_id = ctlmsg[ 1, 8 ].unpack( 'Q>' ).first
760
- domain = ctlmsg[ 9..-1 ]
761
-
762
- Thread.new do
763
- begin
764
- ip_info = Addrinfo.ip( domain )
765
- rescue Exception => e
766
- puts "p#{ Process.pid } #{ Time.new } resolv #{ domain.inspect } #{ e.class }"
767
- end
685
+ @btund_infos[ btund ] = {
686
+ ctl_addr: ctl_addr,
687
+ im: im
688
+ }
768
689
 
769
- if ip_info then
770
- ip = ip_info.ip_address
771
- puts "p#{ Process.pid } #{ Time.new } resolved #{ domain } #{ ip }"
772
- data2 = "#{ [ RESOLVED, src_id ].pack( 'CQ>' ) }#{ ip }"
773
- add_ctlmsg( proxy, data2 )
774
- end
775
- end
776
- when TUN_FIN then
777
- puts "p#{ Process.pid } #{ Time.new } got tun fin"
778
- close_proxy( proxy )
690
+ @ctl_infos[ ctl_addr ] = {
691
+ addrinfo: addrinfo, # 地址
692
+ im: im, # 标识
693
+ atund: atund, # 对应atund,src->dst
694
+ atund_port: atund_port, # atund端口
695
+ btund: btund, # 对应btund,dst->src
696
+ btund_port: btund_port, # btund端口
697
+ dsts: ConcurrentHash.new, # dst_id => dst
698
+ dst_ids: ConcurrentHash.new, # src_id => dst_id
699
+ last_recv_at: Time.new # 上一次收到流量的时间
700
+ }
701
+
702
+ puts "p#{ Process.pid } #{ Time.new } got hello #{ im.inspect }, atund listen on #{ atund_port }, btund listen on #{ btund_port }, ctl infos size #{ @ctl_infos.size }"
703
+ end
704
+
705
+ data2 = [ TUND_PORT, atund_port, btund_port ].pack( 'Cnn' )
706
+ send_ctlmsg( data2, ctl_addr )
707
+ when A_NEW_SOURCE then
708
+ unless ctl_info then
709
+ send_ctlmsg( [ UNKNOWN_CTL_ADDR ].pack( 'C' ), addrinfo )
710
+ return
711
+ end
712
+
713
+ return if data.size <= 9
714
+ src_id = data[ 1, 8 ].unpack( 'Q>' ).first
715
+ dst_id = ctl_info[ :dst_ids ][ src_id ]
716
+
717
+ if dst_id then
718
+ data2 = [ PAIRED, src_id, dst_id ].pack( 'CQ>n' )
719
+ # puts "debug dst id exist, send ctlmsg paired #{ src_id } #{ dst_id }"
720
+ send_ctlmsg( data2, ctl_addr )
779
721
  return
780
- when HEARTBEAT
781
- # puts "debug1 #{ Time.new } got heartbeat"
782
- data2 = [ HEARTBEAT ].pack( 'C' )
783
- add_ctlmsg( proxy, data2 )
784
722
  end
723
+
724
+ domain_port = data[ 9..-1 ]
725
+ # puts "debug got a new source #{ src_id } #{ domain_port }"
726
+ resolve_domain( ctl_addr, src_id, domain_port )
727
+ ctl_info[ :last_recv_at ] = Time.new
728
+ when CTL_FIN then
729
+ return unless ctl_info
730
+ # puts "debug got ctl fin #{ addrinfo.inspect }"
731
+ del_ctl_info( ctl_addr )
785
732
  end
786
733
  end
787
734
 
@@ -791,7 +738,7 @@ module Girl
791
738
  def read_infod( infod )
792
739
  data, addrinfo, rflags, *controls = infod.recvmsg
793
740
  ctl_num = data[ 0 ].unpack( 'C' ).first
794
- # puts "debug1 infod got #{ ctl_num } #{ addrinfo.ip_unpack.inspect }"
741
+ # puts "debug infod got #{ ctl_num } #{ addrinfo.ip_unpack.inspect }"
795
742
 
796
743
  case ctl_num
797
744
  when TRAFF_INFOS then
@@ -805,9 +752,9 @@ module Girl
805
752
 
806
753
  begin
807
754
  infod.sendmsg_nonblock( data2, 0, addrinfo )
808
- rescue IO::WaitWritable, Errno::EINTR
755
+ rescue IO::WaitWritable
809
756
  print 'w'
810
- rescue Errno::EHOSTUNREACH, Errno::ENETUNREACH, Errno::ENETDOWN => e
757
+ rescue Exception => e
811
758
  puts "p#{ Process.pid } #{ Time.new } infod sendmsg to #{ addrinfo.ip_unpack.inspect } #{ e.class }"
812
759
  end
813
760
  end
@@ -822,157 +769,270 @@ module Girl
822
769
  return
823
770
  end
824
771
 
772
+ dst_info = @dst_infos[ dst ]
773
+ btun = dst_info[ :btun ]
774
+
825
775
  begin
826
- data = dst.read_nonblock( READ_SIZE )
827
- rescue IO::WaitReadable, Errno::EINTR
776
+ data = dst.read_nonblock( 65535 )
777
+ rescue IO::WaitReadable
828
778
  print 'r'
829
779
  return
830
780
  rescue Exception => e
831
- # puts "debug1 read dst #{ e.class }"
832
- dst_info = close_read_dst( dst )
833
- tun = dst_info[ :tun ]
834
- set_tun_closing_write( tun ) if tun
781
+ # puts "debug read dst #{ e.class }"
782
+ close_read_dst( dst )
783
+
784
+ if btun then
785
+ set_btun_closing( btun )
786
+ end
787
+
835
788
  return
836
789
  end
837
790
 
838
- dst_info = @dst_infos[ dst ]
839
791
  @traff_ins[ dst_info[ :im ] ] += data.bytesize
840
- tun = dst_info[ :tun ]
792
+ # puts "debug read dst #{ data.bytesize }"
841
793
 
842
- if tun then
843
- unless tun.closed? then
844
- tun_info = @tun_infos[ tun ]
845
- # puts "debug2 add tun.wbuff #{ data.bytesize }"
846
- add_tun_wbuff( tun, data )
847
- end
794
+ if btun then
795
+ add_btun_wbuff( btun, pack_a_chunk( data ) )
848
796
  else
797
+ # puts "debug add dst.rbuff #{ data.bytesize }"
849
798
  add_dst_rbuff( dst, data )
850
799
  end
851
800
  end
852
801
 
853
802
  ##
854
- # read tund
803
+ # read atund
855
804
  #
856
- def read_tund( tund )
857
- if tund.closed? then
858
- puts "p#{ Process.pid } #{ Time.new } read tund but tund closed?"
805
+ def read_atund( atund )
806
+ if atund.closed? then
807
+ puts "p#{ Process.pid } #{ Time.new } read atund but atund closed?"
859
808
  return
860
809
  end
861
810
 
811
+ atund_info = @atund_infos[ atund ]
812
+
862
813
  begin
863
- tun = tund.accept
814
+ atun, _ = atund.accept_nonblock
864
815
  rescue Exception => e
865
- puts "p#{ Process.pid } #{ Time.new } tund accept #{ e.class }"
816
+ puts "p#{ Process.pid } #{ Time.new } atund #{ atund_info[ :im ] } accept #{ e.class }"
817
+ puts e.full_message
866
818
  return
867
819
  end
868
820
 
869
- # puts "debug1 accept a tun #{ tun.ssl_version }"
870
- tund_info = @tund_infos[ tund ]
871
- proxy = tund_info[ :proxy ]
872
- proxy_info = @proxy_infos[ proxy ]
873
-
874
- @tun_infos[ tun ] = {
875
- proxy: proxy, # 对应proxy
876
- im: proxy_info[ :im ], # 标识
877
- dst: nil, # 对应dst
878
- domain_port: nil, # dst的目的地和端口
879
- wbuff: '', # 写前
880
- closing_write: false # 准备关闭写
821
+ # puts "debug accept a atun #{ atund_info[ :im ] }"
822
+
823
+ @atun_infos[ atun ] = {
824
+ ctl_addr: atund_info[ :ctl_addr ], # 对应ctl
825
+ im: atund_info[ :im ], # 标识
826
+ dst: nil, # 对应dst
827
+ domain_port: nil, # dst的目的地和端口
828
+ rbuff: '', # 暂存当前块没收全的流量
829
+ wait_bytes: 0 # 还差多少字节收全当前块
881
830
  }
882
831
 
883
- add_read( tun, :tun )
832
+ add_read( atun, :atun )
884
833
  end
885
834
 
886
835
  ##
887
- # read tun
836
+ # read btund
888
837
  #
889
- def read_tun( tun )
890
- if tun.closed? then
891
- puts "p#{ Process.pid } #{ Time.new } read tun but tun closed?"
838
+ def read_btund( btund )
839
+ if btund.closed? then
840
+ puts "p#{ Process.pid } #{ Time.new } read btund but btund closed?"
892
841
  return
893
842
  end
894
843
 
844
+ btund_info = @btund_infos[ btund ]
845
+
895
846
  begin
896
- data = tun.read_nonblock( READ_SIZE )
897
- rescue IO::WaitReadable
847
+ btun, _ = btund.accept_nonblock
848
+ rescue Exception => e
849
+ puts "p#{ Process.pid } #{ Time.new } btund #{ btund_info[ :im ] } accept #{ e.class }"
850
+ puts e.full_message
898
851
  return
899
- rescue Errno::EINTR
900
- puts e.class
852
+ end
853
+
854
+ # puts "debug accept a btun #{ btund_info[ :im ] }"
855
+
856
+ @btun_infos[ btun ] = {
857
+ ctl_addr: btund_info[ :ctl_addr ], # 对应ctl
858
+ im: btund_info[ :im ], # 标识
859
+ dst: nil, # 对应dst
860
+ domain_port: nil, # dst的目的地和端口
861
+ wbuff: '', # 写前
862
+ closing: false # 准备关闭
863
+ }
864
+
865
+ add_read( btun, :btun )
866
+ end
867
+
868
+ ##
869
+ # read atun
870
+ #
871
+ def read_atun( atun )
872
+ if atun.closed? then
873
+ puts "p#{ Process.pid } #{ Time.new } read atun but atun closed?"
901
874
  return
875
+ end
876
+
877
+ atun_info = @atun_infos[ atun ]
878
+ dst = atun_info[ :dst ]
879
+
880
+ begin
881
+ data = atun.read_nonblock( READ_SIZE )
902
882
  rescue Exception => e
903
- # puts "debug1 read tun #{ e.class }"
904
- tun_info = close_read_tun( tun )
905
- dst = tun_info[ :dst ]
906
- set_dst_closing_write( dst ) if dst
883
+ # puts "debug read atun #{ atun_info[ :im ] } #{ e.class }"
884
+ close_atun( atun )
885
+
886
+ if dst then
887
+ set_dst_closing_write( dst )
888
+ end
889
+
907
890
  return
908
891
  end
909
892
 
910
- tun_info = @tun_infos[ tun ]
911
- @traff_ins[ tun_info[ :im ] ] += data.bytesize
912
- dst = tun_info[ :dst ]
913
-
914
893
  unless dst then
894
+ if data.bytesize < 2 then
895
+ # puts "debug unexpect data length #{ data.bytesize }"
896
+ close_atun( atun )
897
+ end
898
+
915
899
  dst_id = data[ 0, 2 ].unpack( 'n' ).first
916
- proxy = tun_info[ :proxy ]
900
+ ctl_addr = atun_info[ :ctl_addr ]
901
+ ctl_info = @ctl_infos[ ctl_addr ]
917
902
 
918
- if proxy.closed? then
919
- close_tun( tun )
903
+ unless ctl_info then
904
+ close_atun( atun )
920
905
  return
921
906
  end
922
907
 
923
- proxy_info = @proxy_infos[ proxy ]
924
- dst = proxy_info[ :dsts ][ dst_id ]
908
+ dst = ctl_info[ :dsts ][ dst_id ]
925
909
 
926
910
  unless dst then
927
- close_tun( tun )
911
+ close_atun( atun )
928
912
  return
929
913
  end
930
914
 
931
- # puts "debug1 set tun.dst #{ dst_id }"
932
- tun_info[ :dst ] = dst
915
+ # puts "debug set atun.dst #{ dst_id }"
916
+ atun_info[ :dst ] = dst
933
917
  dst_info = @dst_infos[ dst ]
934
- tun_info[ :domain_port ] = dst_info[ :domain_port ]
935
-
936
- unless dst_info[ :rbuff ].empty? then
937
- # puts "debug1 move dst.rbuff to tun.wbuff"
938
- add_tun_wbuff( tun, dst_info[ :rbuff ] )
939
- end
918
+ atun_info[ :domain_port ] = dst_info[ :domain_port ]
919
+ dst_info[ :atun ] = atun
940
920
 
941
- dst_info[ :tun ] = tun
942
921
  data = data[ 2..-1 ]
943
- return if data.empty?
944
922
  end
945
923
 
946
- # puts "debug2 add dst.wbuff #{ data.bytesize }"
947
- add_dst_wbuff( dst, data )
924
+ until data.empty? do
925
+ rbuff = atun_info[ :rbuff ]
926
+ wait_bytes = atun_info[ :wait_bytes ]
927
+
928
+ if wait_bytes > 0 then
929
+ len = wait_bytes
930
+ # puts "debug wait bytes #{ len }"
931
+ else
932
+ if data.bytesize <= 2 then
933
+ # puts "debug unexpect data length #{ data.bytesize }"
934
+ close_atun( atun )
935
+ return
936
+ end
937
+
938
+ len = data[ 0, 2 ].unpack( 'n' ).first
939
+ # puts "debug read len #{ len }"
940
+ data = data[ 2..-1 ]
941
+ end
942
+
943
+ chunk = data[ 0, len ]
944
+ chunk_size = chunk.bytesize
945
+
946
+ if chunk_size == len then
947
+ # 取完整了
948
+ chunk = @custom.decode( "#{ rbuff }#{ chunk }" )
949
+ # puts "debug decode and add dst.wbuff #{ chunk.bytesize }"
950
+ add_dst_wbuff( dst, chunk )
951
+ atun_info[ :rbuff ].clear
952
+ atun_info[ :wait_bytes ] = 0
953
+ else
954
+ # 暂存
955
+ # puts "debug add atun.rbuff #{ chunk_size } wait bytes #{ len - chunk_size }"
956
+ atun_info[ :rbuff ] << chunk
957
+ atun_info[ :wait_bytes ] = len - chunk_size
958
+ end
959
+
960
+ data = data[ chunk_size..-1 ]
961
+ end
948
962
  end
949
963
 
950
964
  ##
951
- # write proxy
965
+ # read btun
952
966
  #
953
- def write_proxy( proxy )
954
- proxy_info = @proxy_infos[ proxy ]
967
+ def read_btun( btun )
968
+ if btun.closed? then
969
+ puts "p#{ Process.pid } #{ Time.new } read btun but btun closed?"
970
+ return
971
+ end
955
972
 
956
- # 发ctlmsg
957
- while proxy_info[ :ctlmsgs ].any? do
958
- data = proxy_info[ :ctlmsgs ].map{ | ctlmsg | "#{ ctlmsg }#{ SEPARATE }" }.join
973
+ btun_info = @btun_infos[ btun ]
959
974
 
960
- # 写入
961
- begin
962
- written = proxy.write( data )
963
- rescue IO::WaitWritable, Errno::EINTR
964
- print 'w'
965
- return
966
- rescue Exception => e
967
- # puts "debug1 write proxy #{ e.class }"
968
- close_proxy( proxy )
969
- return
975
+ begin
976
+ data = btun.read_nonblock( READ_SIZE )
977
+ rescue Exception => e
978
+ # puts "debug read btun #{ btun_info[ :im ] } #{ e.class }"
979
+ close_btun( btun )
980
+ return
981
+ end
982
+
983
+ if data.bytesize != 2 then
984
+ close_btun( btun )
985
+ return
986
+ end
987
+
988
+ # puts "debug read btun #{ data.inspect }"
989
+ @traff_ins[ btun_info[ :im ] ] += data.bytesize
990
+ dst = btun_info[ :dst ]
991
+
992
+ if dst then
993
+ # puts "debug unexpect data"
994
+ close_btun( btun )
995
+ return
996
+ end
997
+
998
+ dst_id = data.unpack( 'n' ).first
999
+ ctl_addr = btun_info[ :ctl_addr ]
1000
+ ctl_info = @ctl_infos[ ctl_addr ]
1001
+
1002
+ unless ctl_info then
1003
+ # puts "debug ctl info not found"
1004
+ close_btun( btun )
1005
+ return
1006
+ end
1007
+
1008
+ dst = ctl_info[ :dsts ][ dst_id ]
1009
+
1010
+ unless dst then
1011
+ # puts "debug dst #{ dst_id } not found"
1012
+ close_btun( btun )
1013
+ return
1014
+ end
1015
+
1016
+ # puts "debug set btun.dst #{ dst_id }"
1017
+ btun_info[ :dst ] = dst
1018
+ dst_info = @dst_infos[ dst ]
1019
+ btun_info[ :domain_port ] = dst_info[ :domain_port ]
1020
+
1021
+ unless dst_info[ :rbuff ].empty? then
1022
+ data2 = ''
1023
+
1024
+ until dst_info[ :rbuff ].empty? do
1025
+ _data = dst_info[ :rbuff ][ 0, 65535 ]
1026
+ data_size = _data.bytesize
1027
+ # puts "debug move dst.rbuff to btun.wbuff"
1028
+ data2 << pack_a_chunk( _data )
1029
+ dst_info[ :rbuff ] = dst_info[ :rbuff ][ data_size..-1 ]
970
1030
  end
971
1031
 
972
- proxy_info[ :ctlmsgs ].clear
1032
+ add_btun_wbuff( btun, data2 )
973
1033
  end
974
1034
 
975
- @writes.delete( proxy )
1035
+ dst_info[ :btun ] = btun
976
1036
  end
977
1037
 
978
1038
  ##
@@ -985,7 +1045,7 @@ module Girl
985
1045
  end
986
1046
 
987
1047
  dst_info = @dst_infos[ dst ]
988
- tun = dst_info[ :tun ]
1048
+ atun = dst_info[ :atun ]
989
1049
  data = dst_info[ :wbuff ]
990
1050
 
991
1051
  # 写前为空,处理关闭写
@@ -1002,41 +1062,45 @@ module Girl
1002
1062
  # 写入
1003
1063
  begin
1004
1064
  written = dst.write_nonblock( data )
1005
- rescue IO::WaitWritable, Errno::EINTR
1065
+ rescue IO::WaitWritable
1006
1066
  print 'w'
1007
1067
  return
1008
1068
  rescue Exception => e
1009
- # puts "debug1 write dst #{ e.class }"
1069
+ # puts "debug write dst #{ e.class }"
1010
1070
  close_write_dst( dst )
1011
- close_read_tun( tun ) if tun
1071
+
1072
+ if atun then
1073
+ close_atun( atun )
1074
+ end
1075
+
1012
1076
  return
1013
1077
  end
1014
1078
 
1015
- # puts "debug2 written dst #{ written }"
1079
+ # puts "debug write dst #{ written }"
1016
1080
  data = data[ written..-1 ]
1017
1081
  dst_info[ :wbuff ] = data
1018
1082
  @traff_outs[ dst_info[ :im ] ] += written
1019
1083
  end
1020
1084
 
1021
1085
  ##
1022
- # write tun
1086
+ # write btun
1023
1087
  #
1024
- def write_tun( tun )
1025
- if tun.closed? then
1026
- puts "p#{ Process.pid } #{ Time.new } write tun but tun closed?"
1088
+ def write_btun( btun )
1089
+ if btun.closed? then
1090
+ puts "p#{ Process.pid } #{ Time.new } write btun but btun closed?"
1027
1091
  return
1028
1092
  end
1029
1093
 
1030
- tun_info = @tun_infos[ tun ]
1031
- dst = tun_info[ :dst ]
1032
- data = tun_info[ :wbuff ]
1094
+ btun_info = @btun_infos[ btun ]
1095
+ dst = btun_info[ :dst ]
1096
+ data = btun_info[ :wbuff ]
1033
1097
 
1034
1098
  # 写前为空,处理关闭写
1035
1099
  if data.empty? then
1036
- if tun_info[ :closing_write ] then
1037
- close_write_tun( tun )
1100
+ if btun_info[ :closing ] then
1101
+ close_btun( btun )
1038
1102
  else
1039
- @writes.delete( tun )
1103
+ @writes.delete( btun )
1040
1104
  end
1041
1105
 
1042
1106
  return
@@ -1044,21 +1108,21 @@ module Girl
1044
1108
 
1045
1109
  # 写入
1046
1110
  begin
1047
- written = tun.write_nonblock( data )
1048
- rescue IO::WaitWritable, Errno::EINTR
1111
+ written = btun.write_nonblock( data )
1112
+ rescue IO::WaitWritable
1049
1113
  print 'w'
1050
1114
  return
1051
1115
  rescue Exception => e
1052
- # puts "debug1 write tun #{ e.class }"
1053
- close_write_tun( tun )
1116
+ # puts "debug write btun #{ e.class }"
1117
+ close_btun( btun )
1054
1118
  close_read_dst( dst ) if dst
1055
1119
  return
1056
1120
  end
1057
1121
 
1058
- # puts "debug2 written tun #{ written }"
1122
+ # puts "debug write btun #{ written }"
1059
1123
  data = data[ written..-1 ]
1060
- tun_info[ :wbuff ] = data
1061
- @traff_outs[ tun_info[ :im ] ] += written
1124
+ btun_info[ :wbuff ] = data
1125
+ @traff_outs[ btun_info[ :im ] ] += written
1062
1126
 
1063
1127
  if dst && !dst.closed? then
1064
1128
  dst_info = @dst_infos[ dst ]