girl 4.0.0 → 4.5.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.

@@ -42,7 +42,6 @@ module Girl
42
42
  loop_check_traff
43
43
 
44
44
  loop do
45
- # puts "debug select"
46
45
  rs, ws = IO.select( @reads, @writes )
47
46
 
48
47
  rs.each do | sock |
@@ -200,9 +199,7 @@ module Girl
200
199
  return if atun.closed?
201
200
  # puts "debug close atun"
202
201
  close_sock( atun )
203
- @atun_infos.delete( atun )
204
- @paused_atuns.delete( atun )
205
- @resume_atuns.delete( atun )
202
+ del_atun_info( atun )
206
203
  end
207
204
 
208
205
  ##
@@ -222,7 +219,12 @@ module Girl
222
219
  return if btun.closed?
223
220
  # puts "debug close btun"
224
221
  close_sock( btun )
225
- @btun_infos.delete( btun )
222
+ btun_info = @btun_infos.delete( btun )
223
+ dst = btun_info[ :dst ]
224
+
225
+ if dst then
226
+ @paused_dsts.delete( dst )
227
+ end
226
228
  end
227
229
 
228
230
  ##
@@ -247,11 +249,13 @@ module Girl
247
249
  btun = dst_info[ :btun ]
248
250
 
249
251
  if atun then
250
- close_atun( atun )
252
+ close_sock( atun )
253
+ del_atun_info( atun )
251
254
  end
252
255
 
253
256
  if btun then
254
- close_btun( btun )
257
+ close_sock( btun )
258
+ @btun_infos.delete( btun )
255
259
  end
256
260
  end
257
261
 
@@ -320,6 +324,7 @@ module Girl
320
324
  ctl_addr: ctl_addr, # 对应ctl
321
325
  im: ctl_info[ :im ], # 标识
322
326
  domain_port: domain_port, # 目的地和端口
327
+ connected: false, # 是否已连接
323
328
  rbuff: '', # 对应的tun没准备好,暂存读到的流量
324
329
  atun: nil, # 对应的atun
325
330
  btun: nil, # 对应的btun
@@ -332,6 +337,7 @@ module Girl
332
337
  }
333
338
 
334
339
  add_read( dst, :dst )
340
+ add_write( dst )
335
341
 
336
342
  ctl_info[ :dst_ids ][ src_id ] = dst_id
337
343
  ctl_info[ :dsts ][ dst_id ] = dst
@@ -341,6 +347,15 @@ module Girl
341
347
  send_ctlmsg( data, ctl_addr )
342
348
  end
343
349
 
350
+ ##
351
+ # del atun info
352
+ #
353
+ def del_atun_info( atun )
354
+ @atun_infos.delete( atun )
355
+ @paused_atuns.delete( atun )
356
+ @resume_atuns.delete( atun )
357
+ end
358
+
344
359
  ##
345
360
  # del ctl info
346
361
  #
@@ -391,11 +406,17 @@ module Girl
391
406
  end
392
407
 
393
408
  @dst_infos.each do | dst, dst_info |
394
- last_recv_at = dst_info[ :last_recv_at ] || dst_info[ :created_at ]
395
- last_sent_at = dst_info[ :last_sent_at ] || dst_info[ :created_at ]
396
- expire_after = dst_info[ :btun ] ? EXPIRE_AFTER : EXPIRE_NEW
409
+ if dst_info[ :connected ] then
410
+ last_recv_at = dst_info[ :last_recv_at ] || dst_info[ :created_at ]
411
+ last_sent_at = dst_info[ :last_sent_at ] || dst_info[ :created_at ]
412
+ expire_after = EXPIRE_AFTER
413
+ is_expire = ( now - last_recv_at >= expire_after ) && ( now - last_sent_at >= expire_after )
414
+ else
415
+ expire_after = EXPIRE_CONNECTING
416
+ is_expire = ( now - dst_info[ :created_at ] >= expire_after )
417
+ end
397
418
 
398
- if ( now - last_recv_at >= expire_after ) && ( now - last_sent_at >= expire_after ) then
419
+ if is_expire then
399
420
  puts "p#{ Process.pid } #{ Time.new } expire dst #{ expire_after } #{ dst_info[ :domain_port ] }"
400
421
 
401
422
  unless @closing_dsts.include?( dst ) then
@@ -419,22 +440,28 @@ module Girl
419
440
  @paused_dsts.each do | dst |
420
441
  dst_info = @dst_infos[ dst ]
421
442
  btun = dst_info[ :btun ]
422
- btun_info = @btun_infos[ btun ]
423
443
 
424
- if btun_info[ :wbuff ].size < RESUME_BELOW then
425
- puts "p#{ Process.pid } #{ Time.new } resume dst #{ dst_info[ :domain_port ] }"
426
- add_resume_dst( dst )
444
+ if btun && !btun.closed? then
445
+ btun_info = @btun_infos[ btun ]
446
+
447
+ if btun_info[ :wbuff ].size < RESUME_BELOW then
448
+ puts "p#{ Process.pid } #{ Time.new } resume dst #{ dst_info[ :domain_port ] }"
449
+ add_resume_dst( dst )
450
+ end
427
451
  end
428
452
  end
429
453
 
430
454
  @paused_atuns.each do | atun |
431
455
  atun_info = @atun_infos[ atun ]
432
456
  dst = atun_info[ :dst ]
433
- dst_info = @dst_infos[ dst ]
434
457
 
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 )
458
+ if dst && !dst.closed? then
459
+ dst_info = @dst_infos[ dst ]
460
+
461
+ if dst_info[ :wbuff ].size < RESUME_BELOW then
462
+ puts "p#{ Process.pid } #{ Time.new } resume atun #{ atun_info[ :domain_port ] }"
463
+ add_resume_atun( atun )
464
+ end
438
465
  end
439
466
  end
440
467
  end
@@ -500,6 +527,14 @@ module Girl
500
527
  @dotw.write( '.' )
501
528
  end
502
529
 
530
+ ##
531
+ # pack a chunk
532
+ #
533
+ def pack_a_chunk( data )
534
+ data = @custom.encode( data )
535
+ "#{ [ data.bytesize ].pack( 'n' ) }#{ data }"
536
+ end
537
+
503
538
  ##
504
539
  # resolve domain
505
540
  #
@@ -545,6 +580,8 @@ module Girl
545
580
  # send ctlmsg
546
581
  #
547
582
  def send_ctlmsg( data, to_addr )
583
+ data = @custom.encode( data )
584
+
548
585
  begin
549
586
  @ctld.sendmsg( data, 0, to_addr )
550
587
  rescue Exception => e
@@ -580,7 +617,7 @@ module Girl
580
617
  # read dotr
581
618
  #
582
619
  def read_dotr( dotr )
583
- dotr.read_nonblock( 65535 )
620
+ dotr.read_nonblock( READ_SIZE )
584
621
 
585
622
  if @deleting_ctl_infos.any? then
586
623
  @deleting_ctl_infos.each { | ctl_addr | del_ctl_info( ctl_addr ) }
@@ -616,6 +653,7 @@ module Girl
616
653
  #
617
654
  def read_ctld( ctld )
618
655
  data, addrinfo, rflags, *controls = ctld.recvmsg
656
+ data = @custom.decode( data )
619
657
  ctl_num = data[ 0 ].unpack( 'C' ).first
620
658
  ctl_addr = addrinfo.to_sockaddr
621
659
  ctl_info = @ctl_infos[ ctl_addr ]
@@ -742,7 +780,7 @@ module Girl
742
780
  btun = dst_info[ :btun ]
743
781
 
744
782
  begin
745
- data = dst.read_nonblock( 65535 )
783
+ data = dst.read_nonblock( CHUNK_SIZE )
746
784
  rescue IO::WaitReadable
747
785
  print 'r'
748
786
  return
@@ -758,12 +796,10 @@ module Girl
758
796
  end
759
797
 
760
798
  @traff_ins[ dst_info[ :im ] ] += data.bytesize
761
- # puts "debug read dst #{ data.bytesize }, encode"
762
- data = @custom.encode( data )
763
- data = "#{ [ data.bytesize ].pack( 'n' ) }#{ data }"
799
+ # puts "debug read dst #{ data.bytesize }"
764
800
 
765
801
  if btun then
766
- add_btun_wbuff( btun, data )
802
+ add_btun_wbuff( btun, pack_a_chunk( data ) )
767
803
  else
768
804
  # puts "debug add dst.rbuff #{ data.bytesize }"
769
805
  add_dst_rbuff( dst, data )
@@ -797,7 +833,8 @@ module Girl
797
833
  dst: nil, # 对应dst
798
834
  domain_port: nil, # dst的目的地和端口
799
835
  rbuff: '', # 暂存当前块没收全的流量
800
- wait_bytes: 0 # 还差多少字节收全当前块
836
+ wait_bytes: 0, # 还差多少字节收全当前块
837
+ lbuff: '' # 流量截断在长度前缀处
801
838
  }
802
839
 
803
840
  add_read( atun, :atun )
@@ -893,22 +930,44 @@ module Girl
893
930
  end
894
931
 
895
932
  until data.empty? do
896
- rbuff = atun_info[ :rbuff ]
897
933
  wait_bytes = atun_info[ :wait_bytes ]
898
934
 
899
935
  if wait_bytes > 0 then
900
936
  len = wait_bytes
901
937
  # puts "debug wait bytes #{ len }"
902
938
  else
903
- if data.bytesize <= 2 then
904
- # puts "debug unexpect data length #{ data.bytesize }"
905
- close_atun( atun )
906
- return
907
- end
939
+ lbuff = atun_info[ :lbuff ]
940
+
941
+ if lbuff.empty? then
942
+ # 长度缓存为空,从读到的流量里取长度
943
+ # 两个字节以下,记进长度缓存
944
+ if data.bytesize <= 2 then
945
+ # puts "debug set atun.lbuff #{ data.inspect }"
946
+ atun_info[ :lbuff ] = data
947
+ return
948
+ end
949
+
950
+ len = data[ 0, 2 ].unpack( 'n' ).first
951
+ data = data[ 2..-1 ]
952
+ elsif lbuff.bytesize == 1 then
953
+ # 长度缓存记有一个字节,补一个字节
954
+ lbuff = "#{ lbuff }#{ data[ 0 ] }"
908
955
 
909
- len = data[ 0, 2 ].unpack( 'n' ).first
910
- # puts "debug read len #{ len }"
911
- data = data[ 2..-1 ]
956
+ if data.bytesize == 1 then
957
+ # puts "debug add atun.lbuff a byte #{ data.inspect }"
958
+ atun_info[ :lbuff ] = lbuff
959
+ return
960
+ end
961
+
962
+ # 使用长度缓存
963
+ len = lbuff.unpack( 'n' ).first
964
+ atun_info[ :lbuff ].clear
965
+ data = data[ 1..-1 ]
966
+ else
967
+ # 使用长度缓存
968
+ len = lbuff.unpack( 'n' ).first
969
+ atun_info[ :lbuff ].clear
970
+ end
912
971
  end
913
972
 
914
973
  chunk = data[ 0, len ]
@@ -916,7 +975,7 @@ module Girl
916
975
 
917
976
  if chunk_size == len then
918
977
  # 取完整了
919
- chunk = @custom.decode( "#{ rbuff }#{ chunk }" )
978
+ chunk = @custom.decode( "#{ atun_info[ :rbuff ] }#{ chunk }" )
920
979
  # puts "debug decode and add dst.wbuff #{ chunk.bytesize }"
921
980
  add_dst_wbuff( dst, chunk )
922
981
  atun_info[ :rbuff ].clear
@@ -990,8 +1049,17 @@ module Girl
990
1049
  btun_info[ :domain_port ] = dst_info[ :domain_port ]
991
1050
 
992
1051
  unless dst_info[ :rbuff ].empty? then
993
- # puts "debug move dst.rbuff to btun.wbuff"
994
- add_btun_wbuff( btun, dst_info[ :rbuff ] )
1052
+ data2 = ''
1053
+
1054
+ until dst_info[ :rbuff ].empty? do
1055
+ _data = dst_info[ :rbuff ][ 0, CHUNK_SIZE ]
1056
+ data_size = _data.bytesize
1057
+ # puts "debug move dst.rbuff to btun.wbuff"
1058
+ data2 << pack_a_chunk( _data )
1059
+ dst_info[ :rbuff ] = dst_info[ :rbuff ][ data_size..-1 ]
1060
+ end
1061
+
1062
+ add_btun_wbuff( btun, data2 )
995
1063
  end
996
1064
 
997
1065
  dst_info[ :btun ] = btun
@@ -1007,6 +1075,7 @@ module Girl
1007
1075
  end
1008
1076
 
1009
1077
  dst_info = @dst_infos[ dst ]
1078
+ dst_info[ :connected ] = true
1010
1079
  atun = dst_info[ :atun ]
1011
1080
  data = dst_info[ :wbuff ]
1012
1081
 
data/lib/girl/relay.rb CHANGED
@@ -3,8 +3,8 @@ require 'girl/concurrent_hash'
3
3
  require 'girl/head'
4
4
  require 'girl/proxy_custom'
5
5
  require 'girl/relay_worker'
6
- require 'girl/resolv_custom'
7
6
  require 'girl/version'
7
+ require 'ipaddr'
8
8
  require 'json'
9
9
  require 'socket'
10
10
 
@@ -13,7 +13,6 @@ module Girl
13
13
  @directs = directs
14
14
  @remotes = remotes
15
15
  @custom = Girl::ProxyCustom.new( im )
16
- @resolv_custom = Girl::ResolvCustom.new
17
16
  @reads = []
18
17
  @writes = []
19
18
  @closing_rsvs = []
@@ -24,7 +23,7 @@ module Girl
24
23
  @resume_srcs = []
25
24
  @resume_dsts = []
26
25
  @resume_btuns = []
27
- @pending_srcs = [] # 还没配到tund,暂存的src
26
+ @pending_srcs = [] # 还没得到atund和btund地址,暂存的src
28
27
  @roles = ConcurrentHash.new # sock => :dotr / :resolv / :rsv / :redir / :proxy / :src / :dst / :atun / :btun
29
28
  @rsv_infos = ConcurrentHash.new # rsv => {}
30
29
  @src_infos = ConcurrentHash.new # src => {}
@@ -298,7 +297,12 @@ module Girl
298
297
  return if atun.closed?
299
298
  # puts "debug close atun"
300
299
  close_sock( atun )
301
- @atun_infos.delete( atun )
300
+ atun_info = @atun_infos.delete( atun )
301
+ src = atun_info[ :src ]
302
+
303
+ if src then
304
+ @paused_srcs.delete( src )
305
+ end
302
306
  end
303
307
 
304
308
  ##
@@ -308,9 +312,7 @@ module Girl
308
312
  return if btun.closed?
309
313
  # puts "debug close btun"
310
314
  close_sock( btun )
311
- @btun_infos.delete( btun )
312
- @paused_btuns.delete( btun )
313
- @resume_btuns.delete( btun )
315
+ del_btun_info( btun )
314
316
  end
315
317
 
316
318
  ##
@@ -392,11 +394,13 @@ module Girl
392
394
  btun = src_info[ :btun ]
393
395
 
394
396
  if atun then
395
- close_atun( atun )
397
+ close_sock( atun )
398
+ @atun_infos.delete( atun )
396
399
  end
397
400
 
398
401
  if btun then
399
- close_btun( btun )
402
+ close_sock( btun )
403
+ del_btun_info( btun )
400
404
  end
401
405
  end
402
406
  end
@@ -440,9 +444,8 @@ module Girl
440
444
  return if src.closed?
441
445
  src_info = @src_infos[ src ]
442
446
 
443
- if ip_info.ipv4_loopback? \
444
- || ip_info.ipv6_loopback? \
445
- || ( ( @ip_address_list.any? { | addrinfo | addrinfo.ip_address == ip_info.ip_address } ) && ( src_info[ :destination_port ] == @redir_port ) ) then
447
+ if ( ( @ip_address_list.any? { | addrinfo | addrinfo.ip_address == ip_info.ip_address } ) && ( src_info[ :destination_port ] == @redir_port ) ) \
448
+ || ( ( ip_info.ip_address == @proxyd_host ) && ( src_info[ :destination_port ] == @proxyd_port ) ) then
446
449
  puts "p#{ Process.pid } #{ Time.new } ignore #{ ip_info.ip_address }:#{ src_info[ :destination_port ] }"
447
450
  add_closing_src( src )
448
451
  return
@@ -459,7 +462,6 @@ module Girl
459
462
  is_direct = @is_direct_caches[ ip_info.ip_address ]
460
463
  else
461
464
  is_direct = @directs.any? { | direct | direct.include?( ip_info.ip_address ) }
462
- # 判断直连耗时较长(树莓派 0.27秒),这里可能切去主线程,回来src可能已关闭
463
465
  puts "p#{ Process.pid } #{ Time.new } cache is direct #{ ip_info.ip_address } #{ is_direct }"
464
466
  @is_direct_caches[ ip_info.ip_address ] = is_direct
465
467
  end
@@ -468,12 +470,20 @@ module Girl
468
470
  # puts "debug #{ ip_info.inspect } hit directs"
469
471
  new_a_dst( src, ip_info )
470
472
  else
471
- # 走远端
472
473
  # puts "debug #{ ip_info.inspect } go tunnel"
473
474
  set_proxy_type_tunnel( src )
474
475
  end
475
476
  end
476
477
 
478
+ ##
479
+ # del btun info
480
+ #
481
+ def del_btun_info( btun )
482
+ @btun_infos.delete( btun )
483
+ @paused_btuns.delete( btun )
484
+ @resume_btuns.delete( btun )
485
+ end
486
+
477
487
  ##
478
488
  # del dst info
479
489
  #
@@ -527,9 +537,24 @@ module Girl
527
537
  @src_infos.each do | src, src_info |
528
538
  last_recv_at = src_info[ :last_recv_at ] || src_info[ :created_at ]
529
539
  last_sent_at = src_info[ :last_sent_at ] || src_info[ :created_at ]
530
- expire_after = ( src_info[ :dst ] || src_info[ :tun ] ) ? EXPIRE_AFTER : EXPIRE_NEW
531
540
 
532
- if ( now - last_recv_at >= expire_after ) && ( now - last_sent_at >= expire_after ) then
541
+ if src_info[ :dst ] then
542
+ if src_info[ :dst_connected ] then
543
+ expire_after = EXPIRE_AFTER
544
+ is_expire = ( now - last_recv_at >= expire_after ) && ( now - last_sent_at >= expire_after )
545
+ else
546
+ expire_after = EXPIRE_CONNECTING
547
+ is_expire = ( now - src_info[ :dst_created_at ] >= expire_after )
548
+ end
549
+ elsif src_info[ :atun ] then
550
+ expire_after = EXPIRE_AFTER
551
+ is_expire = ( now - last_recv_at >= expire_after ) && ( now - last_sent_at >= expire_after )
552
+ else
553
+ expire_after = EXPIRE_NEW
554
+ is_expire = ( now - last_recv_at >= expire_after ) && ( now - last_sent_at >= expire_after )
555
+ end
556
+
557
+ if is_expire then
533
558
  puts "p#{ Process.pid } #{ Time.new } expire src #{ expire_after } #{ src_info[ :id ] } #{ src_info[ :destination_domain ] }"
534
559
  add_closing_src( src )
535
560
 
@@ -555,19 +580,24 @@ module Girl
555
580
  dst = src_info[ :dst ]
556
581
 
557
582
  if dst then
558
- dst_info = @dst_infos[ dst ]
583
+ if !dst.closed? then
584
+ dst_info = @dst_infos[ dst ]
559
585
 
560
- if dst_info[ :wbuff ].size < RESUME_BELOW then
561
- puts "p#{ Process.pid } #{ Time.new } resume direct src #{ src_info[ :destination_domain ] }"
562
- add_resume_src( src )
586
+ if dst_info[ :wbuff ].size < RESUME_BELOW then
587
+ puts "p#{ Process.pid } #{ Time.new } resume direct src #{ src_info[ :destination_domain ] }"
588
+ add_resume_src( src )
589
+ end
563
590
  end
564
591
  else
565
- btun = src_info[ :btun ]
566
- btun_info = @btun_infos[ btun ]
592
+ atun = src_info[ :atun ]
567
593
 
568
- if btun_info[ :wbuff ].size < RESUME_BELOW then
569
- puts "p#{ Process.pid } #{ Time.new } resume tunnel src #{ src_info[ :destination_domain ] }"
570
- add_resume_src( src )
594
+ if atun && !atun.closed? then
595
+ atun_info = @atun_infos[ atun ]
596
+
597
+ if atun_info[ :wbuff ].size < RESUME_BELOW then
598
+ puts "p#{ Process.pid } #{ Time.new } resume tunnel src #{ src_info[ :destination_domain ] }"
599
+ add_resume_src( src )
600
+ end
571
601
  end
572
602
  end
573
603
  end
@@ -575,22 +605,28 @@ module Girl
575
605
  @paused_dsts.each do | dst |
576
606
  dst_info = @dst_infos[ dst ]
577
607
  src = dst_info[ :src ]
578
- src_info = @src_infos[ src ]
579
608
 
580
- if src_info[ :wbuff ].size < RESUME_BELOW then
581
- puts "p#{ Process.pid } #{ Time.new } resume dst #{ dst_info[ :domain ] }"
582
- add_resume_dst( dst )
609
+ if src && !src.closed? then
610
+ src_info = @src_infos[ src ]
611
+
612
+ if src_info[ :wbuff ].size < RESUME_BELOW then
613
+ puts "p#{ Process.pid } #{ Time.new } resume dst #{ dst_info[ :domain ] }"
614
+ add_resume_dst( dst )
615
+ end
583
616
  end
584
617
  end
585
618
 
586
619
  @paused_btuns.each do | btun |
587
620
  btun_info = @btun_infos[ btun ]
588
621
  src = btun_info[ :src ]
589
- src_info = @src_infos[ src ]
590
622
 
591
- if src_info[ :wbuff ].size < RESUME_BELOW then
592
- puts "p#{ Process.pid } #{ Time.new } resume btun #{ btun_info[ :domain ] }"
593
- add_resume_btun( btun )
623
+ if src && !src.closed? then
624
+ src_info = @src_infos[ src ]
625
+
626
+ if src_info[ :wbuff ].size < RESUME_BELOW then
627
+ puts "p#{ Process.pid } #{ Time.new } resume btun #{ btun_info[ :domain ] }"
628
+ add_resume_btun( btun )
629
+ end
594
630
  end
595
631
  end
596
632
  end
@@ -653,15 +689,17 @@ module Girl
653
689
  }
654
690
 
655
691
  @dst_infos[ dst ] = dst_info
656
- add_read( dst, :dst )
657
692
  src_info[ :proxy_type ] = :direct
658
693
  src_info[ :dst ] = dst
694
+ src_info[ :dst_created_at ] = Time.new
659
695
 
660
696
  if src_info[ :rbuff ] then
661
697
  # puts "debug move src.rbuff to dst.wbuff"
662
698
  dst_info[ :wbuff ] << src_info[ :rbuff ]
663
- add_write( dst )
664
699
  end
700
+
701
+ add_read( dst, :dst )
702
+ add_write( dst )
665
703
  end
666
704
 
667
705
  ##
@@ -729,7 +767,7 @@ module Girl
729
767
  rsv.bind( Socket.sockaddr_in( 0, '0.0.0.0' ) )
730
768
 
731
769
  if @qnames.any? { | qname | data.include?( qname ) } then
732
- data = @resolv_custom.encode( data )
770
+ data = @custom.encode( data )
733
771
  to_addr = @resolvd_addr
734
772
  else
735
773
  to_addr = @nameserver_addr
@@ -749,6 +787,7 @@ module Girl
749
787
  # new tuns
750
788
  #
751
789
  def new_tuns( src_id, dst_id )
790
+ return if @ctl_info[ :atund_addr ].nil? || @ctl_info[ :btund_addr ].nil?
752
791
  src = @srcs[ src_id ]
753
792
  return if src.nil? || src.closed?
754
793
  src_info = @src_infos[ src ]
@@ -781,7 +820,7 @@ module Girl
781
820
  atun_wbuff = [ dst_id ].pack( 'n' )
782
821
 
783
822
  until src_info[ :rbuff ].empty? do
784
- data = src_info[ :rbuff ][ 0, 65535 ]
823
+ data = src_info[ :rbuff ][ 0, CHUNK_SIZE ]
785
824
  data_size = data.bytesize
786
825
  # puts "debug move src.rbuff #{ data_size } to atun.wbuff"
787
826
  atun_wbuff << pack_a_chunk( data )
@@ -802,7 +841,8 @@ module Girl
802
841
  domain: domain, # 目的地
803
842
  wbuff: btun_wbuff, # 写前
804
843
  rbuff: '', # 暂存当前块没收全的流量
805
- wait_bytes: 0 # 还差多少字节收全当前块
844
+ wait_bytes: 0, # 还差多少字节收全当前块
845
+ lbuff: '' # 流量截断在长度前缀处
806
846
  }
807
847
 
808
848
  src_info[ :dst_id ] = dst_id
@@ -835,6 +875,7 @@ module Girl
835
875
  #
836
876
  def send_ctlmsg( data )
837
877
  return if @ctl.nil? || @ctl.closed?
878
+ data = @custom.encode( data )
838
879
 
839
880
  begin
840
881
  @ctl.sendmsg( data, 0, @proxyd_addr )
@@ -863,9 +904,7 @@ module Girl
863
904
  def send_data( sock, to_addr, data )
864
905
  begin
865
906
  sock.sendmsg( data, 0, to_addr )
866
- rescue IO::WaitWritable, Errno::EINTR
867
- print 'w'
868
- rescue Errno::EHOSTUNREACH, Errno::ENETUNREACH, Errno::ENETDOWN => e
907
+ rescue Exception => e
869
908
  puts "p#{ Process.pid } #{ Time.new } sendmsg to #{ to_addr.ip_unpack.inspect } #{ e.class }"
870
909
  end
871
910
  end
@@ -908,30 +947,11 @@ module Girl
908
947
  add_write( src )
909
948
  end
910
949
 
911
- ##
912
- # sub http request
913
- #
914
- def sub_http_request( data )
915
- lines = data.split( "\r\n" )
916
-
917
- return [ data, nil ] if lines.empty?
918
-
919
- method, url, proto = lines.first.split( ' ' )
920
-
921
- if proto && url && proto[ 0, 4 ] == 'HTTP' && url[ 0, 7 ] == 'http://' then
922
- domain_port = url.split( '/' )[ 2 ]
923
- data = data.sub( "http://#{ domain_port }", '' )
924
- # puts "debug subed #{ data.inspect } #{ domain_port }"
925
- end
926
-
927
- [ data, domain_port ]
928
- end
929
-
930
950
  ##
931
951
  # read dotr
932
952
  #
933
953
  def read_dotr( dotr )
934
- dotr.read_nonblock( 65535 )
954
+ dotr.read_nonblock( READ_SIZE )
935
955
 
936
956
  if @ctl_info && @ctl_info[ :closing ] then
937
957
  send_ctlmsg( [ CTL_FIN ].pack( 'C' ) )
@@ -993,7 +1013,7 @@ module Girl
993
1013
  # puts "debug rsv recvmsg #{ addrinfo.ip_unpack.inspect } #{ data.inspect }"
994
1014
 
995
1015
  if addrinfo.to_sockaddr == @resolvd_addr then
996
- data = @resolv_custom.decode( data )
1016
+ data = @custom.decode( data )
997
1017
  end
998
1018
 
999
1019
  rsv_info = @rsv_infos[ rsv ]
@@ -1036,6 +1056,8 @@ module Girl
1036
1056
  destination_port: dest_port, # 目的地端口
1037
1057
  rbuff: '', # 读到的流量
1038
1058
  dst: nil, # :direct的场合,对应的dst
1059
+ dst_created_at: nil, # :direct的场合,对应的dst的创建时间
1060
+ dst_connected: false, # :direct的场合,对应的dst是否已连接
1039
1061
  ctl: nil, # :tunnel的场合,对应的ctl
1040
1062
  atun: nil, # :tunnel的场合,对应的atun
1041
1063
  btun: nil, # :tunnel的场合,对应的btun
@@ -1068,6 +1090,7 @@ module Girl
1068
1090
  return
1069
1091
  end
1070
1092
 
1093
+ data = @custom.decode( data )
1071
1094
  ctl_num = data[ 0 ].unpack( 'C' ).first
1072
1095
 
1073
1096
  case ctl_num
@@ -1086,7 +1109,7 @@ module Girl
1086
1109
  @pending_srcs.clear
1087
1110
  end
1088
1111
  when PAIRED then
1089
- return if @ctl_info[ :atund_addr ].nil? || @ctl_info[ :btund_addr ].nil? || data.size != 11
1112
+ return if data.size != 11
1090
1113
  src_id, dst_id = data[ 1, 10 ].unpack( 'Q>n' )
1091
1114
  # puts "debug got paired #{ src_id } #{ dst_id }"
1092
1115
  @ctl_info[ :resends ].delete( [ A_NEW_SOURCE, src_id ].pack( 'CQ>' ) )
@@ -1110,7 +1133,7 @@ module Girl
1110
1133
  src_info = @src_infos[ src ]
1111
1134
 
1112
1135
  begin
1113
- data = src.read_nonblock( 65535 )
1136
+ data = src.read_nonblock( CHUNK_SIZE )
1114
1137
  rescue IO::WaitReadable
1115
1138
  print 'r'
1116
1139
  return
@@ -1172,7 +1195,7 @@ module Girl
1172
1195
  src = dst_info[ :src ]
1173
1196
 
1174
1197
  begin
1175
- data = dst.read_nonblock( 65535 )
1198
+ data = dst.read_nonblock( CHUNK_SIZE )
1176
1199
  rescue IO::WaitReadable
1177
1200
  print 'r'
1178
1201
  return
@@ -1213,22 +1236,44 @@ module Girl
1213
1236
  end
1214
1237
 
1215
1238
  until data.empty? do
1216
- rbuff = btun_info[ :rbuff ]
1217
1239
  wait_bytes = btun_info[ :wait_bytes ]
1218
1240
 
1219
1241
  if wait_bytes > 0 then
1220
1242
  len = wait_bytes
1221
1243
  # puts "debug wait bytes #{ len }"
1222
1244
  else
1223
- if data.bytesize <= 2 then
1224
- # puts "debug unexpect data length #{ data.bytesize }"
1225
- close_btun( btun )
1226
- return
1227
- end
1245
+ lbuff = btun_info[ :lbuff ]
1246
+
1247
+ if lbuff.empty? then
1248
+ # 长度缓存为空,从读到的流量里取长度
1249
+ # 两个字节以下,记进长度缓存
1250
+ if data.bytesize <= 2 then
1251
+ # puts "debug set btun.lbuff #{ data.inspect }"
1252
+ btun_info[ :lbuff ] = data
1253
+ return
1254
+ end
1255
+
1256
+ len = data[ 0, 2 ].unpack( 'n' ).first
1257
+ data = data[ 2..-1 ]
1258
+ elsif lbuff.bytesize == 1 then
1259
+ # 长度缓存记有一个字节,补一个字节
1260
+ lbuff = "#{ lbuff }#{ data[ 0 ] }"
1228
1261
 
1229
- len = data[ 0, 2 ].unpack( 'n' ).first
1230
- # puts "debug read len #{ len }"
1231
- data = data[ 2..-1 ]
1262
+ if data.bytesize == 1 then
1263
+ # puts "debug add btun.lbuff a byte #{ data.inspect }"
1264
+ btun_info[ :lbuff ] = lbuff
1265
+ return
1266
+ end
1267
+
1268
+ # 使用长度缓存
1269
+ len = lbuff.unpack( 'n' ).first
1270
+ btun_info[ :lbuff ].clear
1271
+ data = data[ 1..-1 ]
1272
+ else
1273
+ # 使用长度缓存
1274
+ len = lbuff.unpack( 'n' ).first
1275
+ btun_info[ :lbuff ].clear
1276
+ end
1232
1277
  end
1233
1278
 
1234
1279
  chunk = data[ 0, len ]
@@ -1236,7 +1281,7 @@ module Girl
1236
1281
 
1237
1282
  if chunk_size == len then
1238
1283
  # 取完整了
1239
- chunk = @custom.decode( "#{ rbuff }#{ chunk }" )
1284
+ chunk = @custom.decode( "#{ btun_info[ :rbuff ] }#{ chunk }" )
1240
1285
  # puts "debug read btun decoded #{ chunk.bytesize }"
1241
1286
  add_src_wbuff( src, chunk )
1242
1287
  btun_info[ :rbuff ] = ''
@@ -1315,6 +1360,12 @@ module Girl
1315
1360
 
1316
1361
  dst_info = @dst_infos[ dst ]
1317
1362
  src = dst_info[ :src ]
1363
+ src_info = @src_infos[ src ]
1364
+
1365
+ unless src.closed? then
1366
+ src_info[ :dst_connected ] = true
1367
+ end
1368
+
1318
1369
  data = dst_info[ :wbuff ]
1319
1370
 
1320
1371
  # 写前为空,处理关闭写
@@ -1345,7 +1396,6 @@ module Girl
1345
1396
  dst_info[ :wbuff ] = data
1346
1397
 
1347
1398
  unless src.closed? then
1348
- src_info = @src_infos[ src ]
1349
1399
  src_info[ :last_sent_at ] = Time.new
1350
1400
  end
1351
1401
  end