girl 3.9.0 → 4.4.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,9 +1,12 @@
1
- module Girl
2
- class ProxydCustom
3
-
4
- def check( data, addrinfo )
5
- :success
6
- end
7
-
8
- end
9
- end
1
+ require 'girl/custom'
2
+
3
+ module Girl
4
+ class ProxydCustom
5
+ include Custom
6
+
7
+ def check( data, addrinfo )
8
+ :success
9
+ end
10
+
11
+ end
12
+ end
@@ -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
- 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
301
  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 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,19 +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
- pre_proxyd = Socket.new( Socket::AF_INET, Socket::SOCK_STREAM, 0 )
519
- pre_proxyd.setsockopt( Socket::SOL_SOCKET, Socket::SO_REUSEADDR, 1 )
520
- pre_proxyd.setsockopt( Socket::SOL_SOCKET, Socket::SO_REUSEPORT, 1 )
521
- pre_proxyd.setsockopt( Socket::SOL_TCP, Socket::TCP_NODELAY, 1 )
522
- pre_proxyd.bind( Socket.sockaddr_in( proxyd_port, '0.0.0.0' ) )
523
-
524
- proxyd = OpenSSL::SSL::SSLServer.new pre_proxyd, @context
525
- proxyd.listen( 127 )
526
- puts "p#{ Process.pid } #{ Time.new } proxyd listen on #{ proxyd_port }"
527
- add_read( 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
528
492
  end
529
493
 
530
494
  ##
@@ -534,11 +498,20 @@ module Girl
534
498
  infod = Socket.new( Socket::AF_INET, Socket::SOCK_DGRAM, 0 )
535
499
  infod.setsockopt( Socket::SOL_SOCKET, Socket::SO_REUSEPORT, 1 )
536
500
  infod.bind( Socket.sockaddr_in( infod_port, '127.0.0.1' ) )
537
-
538
501
  puts "p#{ Process.pid } #{ Time.new } infod bind on #{ infod_port }"
539
502
  add_read( infod, :infod )
540
503
  end
541
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
+
542
515
  ##
543
516
  # next tick
544
517
  #
@@ -546,22 +519,30 @@ module Girl
546
519
  @dotw.write( '.' )
547
520
  end
548
521
 
522
+ ##
523
+ # pack a chunk
524
+ #
525
+ def pack_a_chunk( data )
526
+ data = @custom.encode( data )
527
+ "#{ [ data.bytesize ].pack( 'n' ) }#{ data }"
528
+ end
529
+
549
530
  ##
550
531
  # resolve domain
551
532
  #
552
- def resolve_domain( proxy, src_id, domain_port )
533
+ def resolve_domain( ctl_addr, src_id, domain_port )
553
534
  resolv_cache = @resolv_caches[ domain_port ]
554
535
 
555
536
  if resolv_cache then
556
537
  destination_addr, created_at = resolv_cache
557
538
 
558
539
  if Time.new - created_at < RESOLV_CACHE_EXPIRE then
559
- # puts "debug1 #{ domain_port } hit resolv cache #{ Addrinfo.new( destination_addr ).inspect }"
560
- deal_with_destination_addr( proxy, src_id, destination_addr, domain_port )
540
+ # puts "debug #{ domain_port } hit resolv cache #{ Addrinfo.new( destination_addr ).inspect }"
541
+ deal_with_destination_addr( ctl_addr, src_id, destination_addr, domain_port )
561
542
  return
562
543
  end
563
544
 
564
- # puts "debug1 expire #{ domain_port } resolv cache"
545
+ # puts "debug expire #{ domain_port } resolv cache"
565
546
  @resolv_caches.delete( domain_port )
566
547
  end
567
548
 
@@ -580,16 +561,38 @@ module Girl
580
561
  end
581
562
 
582
563
  if destination_addr then
583
- # puts "debug1 resolved #{ domain_port } #{ Addrinfo.new( destination_addr ).inspect }"
564
+ # puts "debug resolved #{ domain_port } #{ Addrinfo.new( destination_addr ).inspect }"
584
565
  @resolv_caches[ domain_port ] = [ destination_addr, Time.new ]
585
-
586
- unless proxy.closed? then
587
- deal_with_destination_addr( proxy, src_id, destination_addr, domain_port )
588
- end
566
+ deal_with_destination_addr( ctl_addr, src_id, destination_addr, domain_port )
589
567
  end
590
568
  end
591
569
  end
592
570
 
571
+ ##
572
+ # send ctlmsg
573
+ #
574
+ def send_ctlmsg( data, to_addr )
575
+ data = @custom.encode( data )
576
+
577
+ begin
578
+ @ctld.sendmsg( data, 0, to_addr )
579
+ rescue Exception => e
580
+ puts "p#{ Process.pid } #{ Time.new } sendmsg #{ e.class }"
581
+ end
582
+ end
583
+
584
+ ##
585
+ # set btun closing
586
+ #
587
+ def set_btun_closing( btun )
588
+ return if btun.closed?
589
+ btun_info = @btun_infos[ btun ]
590
+ return if btun_info[ :closing ]
591
+ # puts "debug set btun closing"
592
+ btun_info[ :closing ] = true
593
+ add_write( btun )
594
+ end
595
+
593
596
  ##
594
597
  # set dst closing write
595
598
  #
@@ -597,31 +600,20 @@ module Girl
597
600
  return if dst.closed? || @closing_dsts.include?( dst )
598
601
  dst_info = @dst_infos[ dst ]
599
602
  return if dst_info[ :closing_write ]
603
+ # puts "debug set dst closing write"
600
604
  dst_info[ :closing_write ] = true
601
605
  add_write( dst )
602
606
  end
603
607
 
604
- ##
605
- # set tun closing write
606
- #
607
- def set_tun_closing_write( tun )
608
- return if tun.closed? || @closing_tuns.include?( tun )
609
- tun_info = @tun_infos[ tun ]
610
- return if tun_info[ :closing_write ]
611
- tun_info[ :closing_write ] = true
612
- add_write( tun )
613
- end
614
-
615
608
  ##
616
609
  # read dotr
617
610
  #
618
611
  def read_dotr( dotr )
619
- dotr.read_nonblock( READ_SIZE )
612
+ dotr.read_nonblock( 65535 )
620
613
 
621
- # 处理关闭
622
- if @closing_proxys.any? then
623
- @closing_proxys.each { | proxy | close_proxy( proxy ) }
624
- @closing_proxys.clear
614
+ if @deleting_ctl_infos.any? then
615
+ @deleting_ctl_infos.each { | ctl_addr | del_ctl_info( ctl_addr ) }
616
+ @deleting_ctl_infos.clear
625
617
  end
626
618
 
627
619
  if @closing_dsts.any? then
@@ -629,11 +621,6 @@ module Girl
629
621
  @closing_dsts.clear
630
622
  end
631
623
 
632
- if @closing_tuns.any? then
633
- @closing_tuns.each { | tun | close_tun( tun ) }
634
- @closing_tuns.clear
635
- end
636
-
637
624
  if @resume_dsts.any? then
638
625
  @resume_dsts.each do | dst |
639
626
  add_read( dst )
@@ -643,81 +630,33 @@ module Girl
643
630
  @resume_dsts.clear
644
631
  end
645
632
 
646
- if @resume_tuns.any? then
647
- @resume_tuns.each do | tun |
648
- add_read( tun )
649
- @paused_tuns.delete( tun )
633
+ if @resume_atuns.any? then
634
+ @resume_atuns.each do | atun |
635
+ add_read( atun )
636
+ @paused_atuns.delete( atun )
650
637
  end
651
638
 
652
- @resume_tuns.clear
639
+ @resume_atuns.clear
653
640
  end
654
641
  end
655
642
 
656
643
  ##
657
- # read proxyd
644
+ # read ctld
658
645
  #
659
- def read_proxyd( proxyd )
660
- begin
661
- proxy = proxyd.accept
662
- rescue IO::WaitReadable, Errno::EINTR
663
- print 'r'
664
- return
665
- rescue Exception => e
666
- puts "p#{ Process.pid } #{ Time.new } proxyd accept #{ e.class }"
667
- return
668
- end
669
-
670
- @proxy_infos[ proxy ] = {
671
- addrinfo: proxy.io.remote_address, # proxy地址
672
- im: nil, # 标识
673
- tund: nil, # 对应tund
674
- tund_port: nil, # tund端口
675
- ctlmsgs: [], # ctlmsg
676
- dsts: ConcurrentHash.new, # dst_id => dst
677
- dst_ids: ConcurrentHash.new, # src_id => dst_id
678
- created_at: Time.new, # 创建时间
679
- last_recv_at: nil # 上一次收到流量的时间
680
- }
681
-
682
- puts "p#{ Process.pid } #{ Time.new } accept a proxy #{ proxy.io.remote_address.inspect } #{ proxy.ssl_version }, #{ @proxy_infos.size } proxys"
683
- add_read( proxy, :proxy )
684
- end
685
-
686
- ##
687
- # read proxy
688
- #
689
- def read_proxy( proxy )
690
- if proxy.closed? then
691
- puts "p#{ Process.pid } #{ Time.new } read proxy but proxy closed?"
692
- return
693
- end
694
-
695
- begin
696
- data = proxy.read_nonblock( READ_SIZE )
697
- rescue IO::WaitReadable
698
- return
699
- rescue Errno::EINTR
700
- puts e.class
701
- return
702
- rescue Exception => e
703
- # puts "debug1 read proxy #{ e.class }"
704
- close_proxy( proxy )
705
- return
706
- end
707
-
708
- proxy_info = @proxy_infos[ proxy ]
709
- proxy_info[ :last_recv_at ] = Time.new
710
-
711
- data.split( SEPARATE ).each do | ctlmsg |
712
- next unless ctlmsg[ 0 ]
713
-
714
- ctl_num = ctlmsg[ 0 ].unpack( 'C' ).first
646
+ def read_ctld( ctld )
647
+ data, addrinfo, rflags, *controls = ctld.recvmsg
648
+ data = @custom.decode( data )
649
+ ctl_num = data[ 0 ].unpack( 'C' ).first
650
+ ctl_addr = addrinfo.to_sockaddr
651
+ ctl_info = @ctl_infos[ ctl_addr ]
715
652
 
716
- case ctl_num
717
- when HELLO then
718
- next if proxy_info[ :tund_port ] || ctlmsg.size <= 1
719
- im = ctlmsg[ 1..-1 ]
720
- addrinfo = proxy_info[ :addrinfo ]
653
+ case ctl_num
654
+ when HELLO then
655
+ if ctl_info then
656
+ atund_port, btund_port = ctl_info[ :atund_port ], ctl_info[ :btund_port ]
657
+ else
658
+ return if data.size <= 1
659
+ im = data[ 1..-1 ]
721
660
  result = @custom.check( im, addrinfo )
722
661
 
723
662
  if result != :success then
@@ -730,63 +669,65 @@ module Girl
730
669
  @traff_outs[ im ] = 0
731
670
  end
732
671
 
733
- pre_tund = Socket.new( Socket::AF_INET, Socket::SOCK_STREAM, 0 )
734
- pre_tund.setsockopt( Socket::SOL_TCP, Socket::TCP_NODELAY, 1 )
735
- pre_tund.bind( Socket.sockaddr_in( 0, '0.0.0.0' ) )
672
+ atund = new_a_tund
673
+ atund_port = atund.local_address.ip_port
674
+ btund = new_a_tund
675
+ btund_port = btund.local_address.ip_port
676
+ add_read( atund, :atund )
677
+ add_read( btund, :btund )
736
678
 
737
- tund_port = pre_tund.local_address.ip_port
738
- tund = OpenSSL::SSL::SSLServer.new pre_tund, @context
739
- tund.listen( 127 )
740
- puts "p#{ Process.pid } #{ Time.new } tund #{ im.inspect } listen on #{ tund_port }"
741
- add_read( tund, :tund )
679
+ @atund_infos[ atund ] = {
680
+ ctl_addr: ctl_addr,
681
+ im: im
682
+ }
742
683
 
743
- @tund_infos[ tund ] = {
744
- proxy: proxy,
745
- close_read: false,
746
- close_write: false
684
+ @btund_infos[ btund ] = {
685
+ ctl_addr: ctl_addr,
686
+ im: im
747
687
  }
748
688
 
749
- proxy_info[ :im ] = im
750
- proxy_info[ :tund ] = tund
751
- proxy_info[ :tund_port ] = tund_port
752
- data2 = [ TUND_PORT, tund_port ].pack( 'Cn' )
753
- add_ctlmsg( proxy, data2 )
754
- when A_NEW_SOURCE then
755
- next if ctlmsg.size <= 9
756
- src_id = ctlmsg[ 1, 8 ].unpack( 'Q>' ).first
757
- dst_id = proxy_info[ :dst_ids ][ src_id ]
758
- next if dst_id
759
- domain_port = ctlmsg[ 9..-1 ]
760
- # puts "debug1 a new source #{ src_id } #{ domain_port }"
761
- resolve_domain( proxy, src_id, domain_port )
762
- when RESOLV then
763
- next if ctlmsg.size <= 9
764
- src_id = ctlmsg[ 1, 8 ].unpack( 'Q>' ).first
765
- domain = ctlmsg[ 9..-1 ]
766
-
767
- Thread.new do
768
- begin
769
- ip_info = Addrinfo.ip( domain )
770
- rescue Exception => e
771
- puts "p#{ Process.pid } #{ Time.new } resolv #{ domain.inspect } #{ e.class }"
772
- end
689
+ @ctl_infos[ ctl_addr ] = {
690
+ addrinfo: addrinfo, # 地址
691
+ im: im, # 标识
692
+ atund: atund, # 对应atund,src->dst
693
+ atund_port: atund_port, # atund端口
694
+ btund: btund, # 对应btund,dst->src
695
+ btund_port: btund_port, # btund端口
696
+ dsts: ConcurrentHash.new, # dst_id => dst
697
+ dst_ids: ConcurrentHash.new, # src_id => dst_id
698
+ last_recv_at: Time.new # 上一次收到流量的时间
699
+ }
773
700
 
774
- if ip_info then
775
- ip = ip_info.ip_address
776
- puts "p#{ Process.pid } #{ Time.new } resolved #{ domain } #{ ip }"
777
- data2 = "#{ [ RESOLVED, src_id ].pack( 'CQ>' ) }#{ ip }"
778
- add_ctlmsg( proxy, data2 )
779
- end
780
- end
781
- when TUN_FIN then
782
- puts "p#{ Process.pid } #{ Time.new } got tun fin"
783
- close_proxy( proxy )
701
+ 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 }"
702
+ end
703
+
704
+ data2 = [ TUND_PORT, atund_port, btund_port ].pack( 'Cnn' )
705
+ send_ctlmsg( data2, ctl_addr )
706
+ when A_NEW_SOURCE then
707
+ unless ctl_info then
708
+ send_ctlmsg( [ UNKNOWN_CTL_ADDR ].pack( 'C' ), addrinfo )
709
+ return
710
+ end
711
+
712
+ return if data.size <= 9
713
+ src_id = data[ 1, 8 ].unpack( 'Q>' ).first
714
+ dst_id = ctl_info[ :dst_ids ][ src_id ]
715
+
716
+ if dst_id then
717
+ data2 = [ PAIRED, src_id, dst_id ].pack( 'CQ>n' )
718
+ # puts "debug dst id exist, send ctlmsg paired #{ src_id } #{ dst_id }"
719
+ send_ctlmsg( data2, ctl_addr )
784
720
  return
785
- when HEARTBEAT
786
- # puts "debug1 #{ Time.new } got heartbeat"
787
- data2 = [ HEARTBEAT ].pack( 'C' )
788
- add_ctlmsg( proxy, data2 )
789
721
  end
722
+
723
+ domain_port = data[ 9..-1 ]
724
+ # puts "debug got a new source #{ src_id } #{ domain_port }"
725
+ resolve_domain( ctl_addr, src_id, domain_port )
726
+ ctl_info[ :last_recv_at ] = Time.new
727
+ when CTL_FIN then
728
+ return unless ctl_info
729
+ # puts "debug got ctl fin #{ addrinfo.inspect }"
730
+ del_ctl_info( ctl_addr )
790
731
  end
791
732
  end
792
733
 
@@ -796,7 +737,7 @@ module Girl
796
737
  def read_infod( infod )
797
738
  data, addrinfo, rflags, *controls = infod.recvmsg
798
739
  ctl_num = data[ 0 ].unpack( 'C' ).first
799
- # puts "debug1 infod got #{ ctl_num } #{ addrinfo.ip_unpack.inspect }"
740
+ # puts "debug infod got #{ ctl_num } #{ addrinfo.ip_unpack.inspect }"
800
741
 
801
742
  case ctl_num
802
743
  when TRAFF_INFOS then
@@ -810,9 +751,9 @@ module Girl
810
751
 
811
752
  begin
812
753
  infod.sendmsg_nonblock( data2, 0, addrinfo )
813
- rescue IO::WaitWritable, Errno::EINTR
754
+ rescue IO::WaitWritable
814
755
  print 'w'
815
- rescue Errno::EHOSTUNREACH, Errno::ENETUNREACH, Errno::ENETDOWN => e
756
+ rescue Exception => e
816
757
  puts "p#{ Process.pid } #{ Time.new } infod sendmsg to #{ addrinfo.ip_unpack.inspect } #{ e.class }"
817
758
  end
818
759
  end
@@ -827,160 +768,293 @@ module Girl
827
768
  return
828
769
  end
829
770
 
771
+ dst_info = @dst_infos[ dst ]
772
+ btun = dst_info[ :btun ]
773
+
830
774
  begin
831
- data = dst.read_nonblock( READ_SIZE )
832
- rescue IO::WaitReadable, Errno::EINTR
775
+ data = dst.read_nonblock( 65535 )
776
+ rescue IO::WaitReadable
833
777
  print 'r'
834
778
  return
835
779
  rescue Exception => e
836
- # puts "debug1 read dst #{ e.class }"
837
- dst_info = close_read_dst( dst )
838
- tun = dst_info[ :tun ]
839
- set_tun_closing_write( tun ) if tun
780
+ # puts "debug read dst #{ e.class }"
781
+ close_read_dst( dst )
782
+
783
+ if btun then
784
+ set_btun_closing( btun )
785
+ end
786
+
840
787
  return
841
788
  end
842
789
 
843
- dst_info = @dst_infos[ dst ]
844
790
  @traff_ins[ dst_info[ :im ] ] += data.bytesize
845
- tun = dst_info[ :tun ]
791
+ # puts "debug read dst #{ data.bytesize }"
846
792
 
847
- if tun then
848
- unless tun.closed? then
849
- tun_info = @tun_infos[ tun ]
850
- # puts "debug2 add tun.wbuff #{ data.bytesize }"
851
- add_tun_wbuff( tun, data )
852
- end
793
+ if btun then
794
+ add_btun_wbuff( btun, pack_a_chunk( data ) )
853
795
  else
796
+ # puts "debug add dst.rbuff #{ data.bytesize }"
854
797
  add_dst_rbuff( dst, data )
855
798
  end
856
799
  end
857
800
 
858
801
  ##
859
- # read tund
802
+ # read atund
860
803
  #
861
- def read_tund( tund )
862
- if tund.closed? then
863
- puts "p#{ Process.pid } #{ Time.new } read tund but tund closed?"
804
+ def read_atund( atund )
805
+ if atund.closed? then
806
+ puts "p#{ Process.pid } #{ Time.new } read atund but atund closed?"
864
807
  return
865
808
  end
866
809
 
810
+ atund_info = @atund_infos[ atund ]
811
+
867
812
  begin
868
- tun = tund.accept
869
- rescue IO::WaitReadable, Errno::EINTR
870
- print 'r'
871
- return
813
+ atun, _ = atund.accept_nonblock
872
814
  rescue Exception => e
873
- puts "p#{ Process.pid } #{ Time.new } tund accept #{ e.class }"
815
+ puts "p#{ Process.pid } #{ Time.new } atund #{ atund_info[ :im ] } accept #{ e.class }"
816
+ puts e.full_message
874
817
  return
875
818
  end
876
819
 
877
- # puts "debug1 accept a tun #{ tun.ssl_version }"
878
- tund_info = @tund_infos[ tund ]
879
- proxy = tund_info[ :proxy ]
880
- proxy_info = @proxy_infos[ proxy ]
881
-
882
- @tun_infos[ tun ] = {
883
- proxy: proxy, # 对应proxy
884
- im: proxy_info[ :im ], # 标识
885
- dst: nil, # 对应dst
886
- domain_port: nil, # dst的目的地和端口
887
- wbuff: '', # 写前
888
- closing_write: false # 准备关闭写
820
+ # puts "debug accept a atun #{ atund_info[ :im ] }"
821
+
822
+ @atun_infos[ atun ] = {
823
+ ctl_addr: atund_info[ :ctl_addr ], # 对应ctl
824
+ im: atund_info[ :im ], # 标识
825
+ dst: nil, # 对应dst
826
+ domain_port: nil, # dst的目的地和端口
827
+ rbuff: '', # 暂存当前块没收全的流量
828
+ wait_bytes: 0, # 还差多少字节收全当前块
829
+ lbuff: '' # 流量截断在长度前缀处
889
830
  }
890
831
 
891
- add_read( tun, :tun )
832
+ add_read( atun, :atun )
892
833
  end
893
834
 
894
835
  ##
895
- # read tun
836
+ # read btund
896
837
  #
897
- def read_tun( tun )
898
- if tun.closed? then
899
- 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?"
900
841
  return
901
842
  end
902
843
 
844
+ btund_info = @btund_infos[ btund ]
845
+
903
846
  begin
904
- data = tun.read_nonblock( READ_SIZE )
905
- 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
906
851
  return
907
- rescue Errno::EINTR
908
- 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?"
909
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 )
910
882
  rescue Exception => e
911
- # puts "debug1 read tun #{ e.class }"
912
- tun_info = close_read_tun( tun )
913
- dst = tun_info[ :dst ]
914
- 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
+
915
890
  return
916
891
  end
917
892
 
918
- tun_info = @tun_infos[ tun ]
919
- @traff_ins[ tun_info[ :im ] ] += data.bytesize
920
- dst = tun_info[ :dst ]
921
-
922
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
+
923
899
  dst_id = data[ 0, 2 ].unpack( 'n' ).first
924
- proxy = tun_info[ :proxy ]
900
+ ctl_addr = atun_info[ :ctl_addr ]
901
+ ctl_info = @ctl_infos[ ctl_addr ]
925
902
 
926
- if proxy.closed? then
927
- close_tun( tun )
903
+ unless ctl_info then
904
+ close_atun( atun )
928
905
  return
929
906
  end
930
907
 
931
- proxy_info = @proxy_infos[ proxy ]
932
- dst = proxy_info[ :dsts ][ dst_id ]
908
+ dst = ctl_info[ :dsts ][ dst_id ]
933
909
 
934
910
  unless dst then
935
- close_tun( tun )
911
+ close_atun( atun )
936
912
  return
937
913
  end
938
914
 
939
- # puts "debug1 set tun.dst #{ dst_id }"
940
- tun_info[ :dst ] = dst
915
+ # puts "debug set atun.dst #{ dst_id }"
916
+ atun_info[ :dst ] = dst
941
917
  dst_info = @dst_infos[ dst ]
942
- tun_info[ :domain_port ] = dst_info[ :domain_port ]
943
-
944
- unless dst_info[ :rbuff ].empty? then
945
- # puts "debug1 move dst.rbuff to tun.wbuff"
946
- add_tun_wbuff( tun, dst_info[ :rbuff ] )
947
- end
918
+ atun_info[ :domain_port ] = dst_info[ :domain_port ]
919
+ dst_info[ :atun ] = atun
948
920
 
949
- dst_info[ :tun ] = tun
950
921
  data = data[ 2..-1 ]
951
- return if data.empty?
952
922
  end
953
923
 
954
- # puts "debug2 add dst.wbuff #{ data.bytesize }"
955
- add_dst_wbuff( dst, data )
924
+ until data.empty? do
925
+ wait_bytes = atun_info[ :wait_bytes ]
926
+
927
+ if wait_bytes > 0 then
928
+ len = wait_bytes
929
+ # puts "debug wait bytes #{ len }"
930
+ else
931
+ lbuff = atun_info[ :lbuff ]
932
+
933
+ if lbuff.empty? then
934
+ # 长度缓存为空,从读到的流量里取长度
935
+ # 两个字节以下,记进长度缓存
936
+ if data.bytesize <= 2 then
937
+ # puts "debug set atun.lbuff #{ data.inspect }"
938
+ atun_info[ :lbuff ] = data
939
+ return
940
+ end
941
+
942
+ len = data[ 0, 2 ].unpack( 'n' ).first
943
+ data = data[ 2..-1 ]
944
+ elsif lbuff.bytesize == 1 then
945
+ # 长度缓存记有一个字节,补一个字节
946
+ lbuff = "#{ lbuff }#{ data[ 0 ] }"
947
+
948
+ if data.bytesize == 1 then
949
+ # puts "debug add atun.lbuff a byte #{ data.inspect }"
950
+ atun_info[ :lbuff ] = lbuff
951
+ return
952
+ end
953
+
954
+ # 使用长度缓存
955
+ len = lbuff.unpack( 'n' ).first
956
+ atun_info[ :lbuff ].clear
957
+ data = data[ 1..-1 ]
958
+ else
959
+ # 使用长度缓存
960
+ len = lbuff.unpack( 'n' ).first
961
+ atun_info[ :lbuff ].clear
962
+ end
963
+ end
964
+
965
+ chunk = data[ 0, len ]
966
+ chunk_size = chunk.bytesize
967
+
968
+ if chunk_size == len then
969
+ # 取完整了
970
+ chunk = @custom.decode( "#{ atun_info[ :rbuff ] }#{ chunk }" )
971
+ # puts "debug decode and add dst.wbuff #{ chunk.bytesize }"
972
+ add_dst_wbuff( dst, chunk )
973
+ atun_info[ :rbuff ].clear
974
+ atun_info[ :wait_bytes ] = 0
975
+ else
976
+ # 暂存
977
+ # puts "debug add atun.rbuff #{ chunk_size } wait bytes #{ len - chunk_size }"
978
+ atun_info[ :rbuff ] << chunk
979
+ atun_info[ :wait_bytes ] = len - chunk_size
980
+ end
981
+
982
+ data = data[ chunk_size..-1 ]
983
+ end
956
984
  end
957
985
 
958
986
  ##
959
- # write proxy
987
+ # read btun
960
988
  #
961
- def write_proxy( proxy )
962
- proxy_info = @proxy_infos[ proxy ]
989
+ def read_btun( btun )
990
+ if btun.closed? then
991
+ puts "p#{ Process.pid } #{ Time.new } read btun but btun closed?"
992
+ return
993
+ end
963
994
 
964
- # 发ctlmsg
965
- while proxy_info[ :ctlmsgs ].any? do
966
- data = proxy_info[ :ctlmsgs ].map{ | ctlmsg | "#{ ctlmsg }#{ SEPARATE }" }.join
995
+ btun_info = @btun_infos[ btun ]
967
996
 
968
- # 写入
969
- begin
970
- written = proxy.write( data )
971
- rescue IO::WaitWritable, Errno::EINTR
972
- print 'w'
973
- return
974
- rescue Exception => e
975
- # puts "debug1 write proxy #{ e.class }"
976
- close_proxy( proxy )
977
- return
997
+ begin
998
+ data = btun.read_nonblock( READ_SIZE )
999
+ rescue Exception => e
1000
+ # puts "debug read btun #{ btun_info[ :im ] } #{ e.class }"
1001
+ close_btun( btun )
1002
+ return
1003
+ end
1004
+
1005
+ if data.bytesize != 2 then
1006
+ close_btun( btun )
1007
+ return
1008
+ end
1009
+
1010
+ # puts "debug read btun #{ data.inspect }"
1011
+ @traff_ins[ btun_info[ :im ] ] += data.bytesize
1012
+ dst = btun_info[ :dst ]
1013
+
1014
+ if dst then
1015
+ # puts "debug unexpect data"
1016
+ close_btun( btun )
1017
+ return
1018
+ end
1019
+
1020
+ dst_id = data.unpack( 'n' ).first
1021
+ ctl_addr = btun_info[ :ctl_addr ]
1022
+ ctl_info = @ctl_infos[ ctl_addr ]
1023
+
1024
+ unless ctl_info then
1025
+ # puts "debug ctl info not found"
1026
+ close_btun( btun )
1027
+ return
1028
+ end
1029
+
1030
+ dst = ctl_info[ :dsts ][ dst_id ]
1031
+
1032
+ unless dst then
1033
+ # puts "debug dst #{ dst_id } not found"
1034
+ close_btun( btun )
1035
+ return
1036
+ end
1037
+
1038
+ # puts "debug set btun.dst #{ dst_id }"
1039
+ btun_info[ :dst ] = dst
1040
+ dst_info = @dst_infos[ dst ]
1041
+ btun_info[ :domain_port ] = dst_info[ :domain_port ]
1042
+
1043
+ unless dst_info[ :rbuff ].empty? then
1044
+ data2 = ''
1045
+
1046
+ until dst_info[ :rbuff ].empty? do
1047
+ _data = dst_info[ :rbuff ][ 0, 65535 ]
1048
+ data_size = _data.bytesize
1049
+ # puts "debug move dst.rbuff to btun.wbuff"
1050
+ data2 << pack_a_chunk( _data )
1051
+ dst_info[ :rbuff ] = dst_info[ :rbuff ][ data_size..-1 ]
978
1052
  end
979
1053
 
980
- proxy_info[ :ctlmsgs ].clear
1054
+ add_btun_wbuff( btun, data2 )
981
1055
  end
982
1056
 
983
- @writes.delete( proxy )
1057
+ dst_info[ :btun ] = btun
984
1058
  end
985
1059
 
986
1060
  ##
@@ -993,7 +1067,7 @@ module Girl
993
1067
  end
994
1068
 
995
1069
  dst_info = @dst_infos[ dst ]
996
- tun = dst_info[ :tun ]
1070
+ atun = dst_info[ :atun ]
997
1071
  data = dst_info[ :wbuff ]
998
1072
 
999
1073
  # 写前为空,处理关闭写
@@ -1010,41 +1084,45 @@ module Girl
1010
1084
  # 写入
1011
1085
  begin
1012
1086
  written = dst.write_nonblock( data )
1013
- rescue IO::WaitWritable, Errno::EINTR
1087
+ rescue IO::WaitWritable
1014
1088
  print 'w'
1015
1089
  return
1016
1090
  rescue Exception => e
1017
- # puts "debug1 write dst #{ e.class }"
1091
+ # puts "debug write dst #{ e.class }"
1018
1092
  close_write_dst( dst )
1019
- close_read_tun( tun ) if tun
1093
+
1094
+ if atun then
1095
+ close_atun( atun )
1096
+ end
1097
+
1020
1098
  return
1021
1099
  end
1022
1100
 
1023
- # puts "debug2 written dst #{ written }"
1101
+ # puts "debug write dst #{ written }"
1024
1102
  data = data[ written..-1 ]
1025
1103
  dst_info[ :wbuff ] = data
1026
1104
  @traff_outs[ dst_info[ :im ] ] += written
1027
1105
  end
1028
1106
 
1029
1107
  ##
1030
- # write tun
1108
+ # write btun
1031
1109
  #
1032
- def write_tun( tun )
1033
- if tun.closed? then
1034
- puts "p#{ Process.pid } #{ Time.new } write tun but tun closed?"
1110
+ def write_btun( btun )
1111
+ if btun.closed? then
1112
+ puts "p#{ Process.pid } #{ Time.new } write btun but btun closed?"
1035
1113
  return
1036
1114
  end
1037
1115
 
1038
- tun_info = @tun_infos[ tun ]
1039
- dst = tun_info[ :dst ]
1040
- data = tun_info[ :wbuff ]
1116
+ btun_info = @btun_infos[ btun ]
1117
+ dst = btun_info[ :dst ]
1118
+ data = btun_info[ :wbuff ]
1041
1119
 
1042
1120
  # 写前为空,处理关闭写
1043
1121
  if data.empty? then
1044
- if tun_info[ :closing_write ] then
1045
- close_write_tun( tun )
1122
+ if btun_info[ :closing ] then
1123
+ close_btun( btun )
1046
1124
  else
1047
- @writes.delete( tun )
1125
+ @writes.delete( btun )
1048
1126
  end
1049
1127
 
1050
1128
  return
@@ -1052,21 +1130,21 @@ module Girl
1052
1130
 
1053
1131
  # 写入
1054
1132
  begin
1055
- written = tun.write_nonblock( data )
1056
- rescue IO::WaitWritable, Errno::EINTR
1133
+ written = btun.write_nonblock( data )
1134
+ rescue IO::WaitWritable
1057
1135
  print 'w'
1058
1136
  return
1059
1137
  rescue Exception => e
1060
- # puts "debug1 write tun #{ e.class }"
1061
- close_write_tun( tun )
1138
+ # puts "debug write btun #{ e.class }"
1139
+ close_btun( btun )
1062
1140
  close_read_dst( dst ) if dst
1063
1141
  return
1064
1142
  end
1065
1143
 
1066
- # puts "debug2 written tun #{ written }"
1144
+ # puts "debug write btun #{ written }"
1067
1145
  data = data[ written..-1 ]
1068
- tun_info[ :wbuff ] = data
1069
- @traff_outs[ tun_info[ :im ] ] += written
1146
+ btun_info[ :wbuff ] = data
1147
+ @traff_outs[ btun_info[ :im ] ] += written
1070
1148
 
1071
1149
  if dst && !dst.closed? then
1072
1150
  dst_info = @dst_infos[ dst ]