girl 3.9.0 → 4.0.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of girl might be problematic. Click here for more details.

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