girl 0.61.0 → 0.65.0

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

Potentially problematic release.


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

checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c43d66efd27844b45b294a58757f9048b73aec8722d3285a642bb03e02a70ba8
4
- data.tar.gz: f79ac7e41ccda330001c63bce9b20f611ca388f8da374bdfd66fd5c3a773e3e5
3
+ metadata.gz: a6d217fe38a61d01846b2cbf57e0a43a5c456406237007c852d6e4f2d69be3bc
4
+ data.tar.gz: 61641d8b22ee04b1e0daf71d410fe420939e6e6fd6c6ff65c49641a1f502baaf
5
5
  SHA512:
6
- metadata.gz: cead94f72a7167968a5f506d0a1d80e7cf01d95465be839c1e26b63ef69ae9aef044837ef4777a9d352f154a12a7776606ed89bd05650a6030e0c4e849fbc366
7
- data.tar.gz: 70548cfa8185971f22a9f3f1b70e3efd867e3a76c0f430cf466b2af042ef8b5bad5078129dea7d55de4f92f949a7c707581c59e39c85b461e59395b84c0fc8ac
6
+ metadata.gz: cf51f0e222f05a488ca6c5e437bdd3a6231b1ece0aa184b8907d14f0fe1ff2b3c5daa66bca56c376b1e02ca8162744f1156721f8ad48c73b9b4f3118a73a3cf5
7
+ data.tar.gz: b373766e42e420240a47eb5b54f4d3ea6d4c74c630b6a137fc5b91706486635f06717d6e92a1881e92bc841a640f851cb6b8c018e9b2540d16898a8104ae5d24
@@ -1,13 +1,11 @@
1
1
  module Girl
2
- PACK_SIZE = 1328 # 包大小 1400(console MTU) - 8(PPPoE header) - 40(IPv6 header) - 8(UDP header) - 8(source/dest id) - 8(pack id) = 1328
2
+ PACK_SIZE = 1328 # 包大小 1400(console MTU) - 8(PPPoE header) - 40(IPv6 header) - 8(UDP header) - 8(pack id) - 8(src id) = 1328
3
3
  CHUNK_SIZE = PACK_SIZE * 1000 # 块大小
4
- PROXY_PACK_SIZE = 1320 # 1400(console MTU) - 8(PPPoE header) - 40(IPv6 header) - 8(UDP header) - 8(pack id) - 16(src_addr) = 1320
5
- PROXY_CHUNK_SIZE = PROXY_PACK_SIZE * 1000 # proxy块大小
6
4
  WBUFFS_LIMIT = 1000 # 写前上限,超过上限结一个块
7
5
  WMEMS_LIMIT = 100_000 # 写后上限,达到上限暂停写
8
6
  RESUME_BELOW = 50_000 # 降到多少以下恢复写
9
7
  EXPIRE_NEW = 10 # 创建之后多久没有流量进来,过期
10
- EXPIRE_AFTER = 900 # 多久没有新流量进来,过期
8
+ EXPIRE_AFTER = 3600 # 多久没有新流量进来,过期
11
9
  CHECK_EXPIRE_INTERVAL = 30 # 检查过期间隔
12
10
  HEARTBEAT_INTERVAL = 30 # 心跳间隔
13
11
  STATUS_INTERVAL = 0.3 # 发送状态间隔
@@ -24,19 +24,19 @@ require 'socket'
24
24
  # tun-tund:
25
25
  #
26
26
  # Q>: 0 ctlmsg -> C: 2 heartbeat -> C: random char
27
- # 3 a new src -> src_addr -> encoded destination address
28
- # 4 paired -> src_addr -> n: dst_port
27
+ # 3 a new src -> Q>: src_id -> encoded destination address
28
+ # 4 paired -> Q>: src_id -> n: dst_port
29
29
  # 5 dst status -> n: dst_port -> Q>Q>: biggest_dst_pack_id continue_src_pack_id
30
- # 6 src status -> src_addr -> Q>Q>: biggest_src_pack_id continue_dst_pack_id
31
- # 7 miss -> src_addr/n: dst_port -> Q>Q>: pack_id_begin pack_id_end
32
- # 8 fin1 -> src_addr/n: dst_port -> Q>Q>: biggest_src_pack_id continue_dst_pack_id / biggest_dst_pack_id continue_src_pack_id
30
+ # 6 src status -> Q>: src_id -> Q>Q>: biggest_src_pack_id continue_dst_pack_id
31
+ # 7 miss -> Q>: src_id/n: dst_port -> Q>Q>: pack_id_begin pack_id_end
32
+ # 8 fin1 -> Q>: src_id/n: dst_port -> Q>Q>: biggest_src_pack_id continue_dst_pack_id / biggest_dst_pack_id continue_src_pack_id
33
33
  # 9 not use
34
- # 10 fin2 -> src_addr/n: dst_port
34
+ # 10 fin2 -> Q>: src_id/n: dst_port
35
35
  # 11 not use
36
36
  # 12 tund fin
37
37
  # 13 tun fin
38
38
  #
39
- # Q>: 1+ pack_id -> src_addr/n: dst_port -> traffic
39
+ # Q>: 1+ pack_id -> Q>: src_id/n: dst_port -> traffic
40
40
  #
41
41
  # close logic
42
42
  # ===========
@@ -102,7 +102,7 @@ module Girl
102
102
  now = Time.new
103
103
 
104
104
  if @tun && !@tun.closed?
105
- is_expired = @tun_info[ :last_recv_at ] ? ( now - @tun_info[ :last_recv_at ] > EXPIRE_AFTER ) : ( now - @tun_info[ :created_at ] > EXPIRE_NEW )
105
+ is_expired = @tun_info[ :last_recv_at ].nil? && ( now - @tun_info[ :created_at ] > EXPIRE_NEW )
106
106
 
107
107
  if is_expired
108
108
  puts "p#{ Process.pid } #{ Time.new } expire tun"
@@ -111,10 +111,10 @@ module Girl
111
111
  data = [ 0, HEARTBEAT, rand( 128 ) ].pack( 'Q>CC' )
112
112
  add_tun_ctlmsg( data )
113
113
 
114
- @tun_info[ :src_exts ].each do | src_addr, src_ext |
114
+ @tun_info[ :src_exts ].each do | src_id, src_ext |
115
115
  if src_ext[ :src ].closed? && ( now - src_ext[ :last_continue_at ] > EXPIRE_AFTER )
116
- puts "p#{ Process.pid } #{ Time.new } expire src_ext"
117
- del_src_ext( src_addr )
116
+ puts "p#{ Process.pid } #{ Time.new } expire src ext #{ src_id }"
117
+ del_src_ext( src_id )
118
118
  end
119
119
  end
120
120
  end
@@ -165,10 +165,10 @@ module Girl
165
165
  if @tun_info[ :src_exts ].any?
166
166
  now = Time.new
167
167
 
168
- @tun_info[ :src_exts ].each do | src_addr, src_ext |
168
+ @tun_info[ :src_exts ].each do | src_id, src_ext |
169
169
  if src_ext[ :dst_port ] && ( now - src_ext[ :last_continue_at ] < SEND_STATUS_UNTIL )
170
170
  # puts "debug2 ctl send status biggest #{ src_ext[ :biggest_pack_id ] } continue dst #{ src_ext[ :continue_dst_pack_id ] }"
171
- data = [ [ 0, SOURCE_STATUS ].pack( 'Q>C' ), src_addr, [ src_ext[ :biggest_pack_id ], src_ext[ :continue_dst_pack_id ] ].pack( 'Q>Q>' ) ].join
171
+ data = [ 0, SOURCE_STATUS, src_id, src_ext[ :biggest_pack_id ], src_ext[ :continue_dst_pack_id ] ].pack( 'Q>CQ>Q>Q>' )
172
172
  add_tun_ctlmsg( data )
173
173
  need_trigger = true
174
174
  end
@@ -311,20 +311,20 @@ module Girl
311
311
  def new_a_tun
312
312
  tun = Socket.new( Socket::AF_INET, Socket::SOCK_DGRAM, 0 )
313
313
  tun.bind( Socket.sockaddr_in( 0, '0.0.0.0' ) )
314
- port = tun.local_address.ip_unpack.last
314
+ port = tun.local_address.ip_port
315
315
  tun_info = {
316
316
  port: port, # 端口
317
317
  ctlmsg_rbuffs: [], # 还没配上tund,暂存的ctlmsg
318
318
  ctlmsgs: [], # [ to_addr, data ]
319
- wbuffs: [], # 写前缓存 [ src_addr, data ]
320
- caches: [], # 块读出缓存 [ src_addr, data ]
319
+ wbuffs: [], # 写前缓存 [ src_id, data ]
320
+ caches: [], # 块读出缓存 [ src_id, data ]
321
321
  chunks: [], # 块队列 filename
322
322
  spring: 0, # 块后缀,结块时,如果块队列不为空,则自增,为空,则置为0
323
323
  tund_addr: nil, # tund地址
324
- src_exts: {}, # src额外信息 src_addr => {}
325
- src_addrs: {}, # dst_port => src_addr
324
+ src_exts: {}, # src额外信息 src_id => {}
325
+ src_ids: {}, # dst_port => src_id
326
326
  paused: false, # 是否暂停写
327
- resendings: [], # 重传队列 [ src_addr, pack_id ]
327
+ resendings: [], # 重传队列 [ src_id, pack_id ]
328
328
  created_at: Time.new, # 创建时间
329
329
  last_recv_at: nil, # 上一次收到流量的时间,过期关闭
330
330
  is_closing: false # 是否准备关闭
@@ -363,7 +363,7 @@ module Girl
363
363
  end
364
364
 
365
365
  # puts "debug1 a new dst #{ dst.local_address.inspect }"
366
- local_port = dst.local_address.ip_unpack
366
+ local_port = dst.local_address.ip_port
367
367
  @dsts[ local_port ] = dst
368
368
  @dst_infos[ dst ] = {
369
369
  local_port: local_port, # 本地端口
@@ -424,14 +424,14 @@ module Girl
424
424
  }
425
425
 
426
426
  src_info = @src_infos[ src ]
427
- src_addr = src_info[ :src_addr ]
428
- @tun_info[ :src_exts ][ src_addr ] = src_ext
427
+ src_id = src_info[ :id ]
428
+ @tun_info[ :src_exts ][ src_id ] = src_ext
429
429
  src_info[ :proxy_type ] = :tunnel
430
430
 
431
431
  destination_port = src_info[ :destination_port ]
432
432
  destination_domain = src_info[ :destination_domain ]
433
433
  destination_domain_port = [ destination_domain, destination_port ].join( ':' )
434
- data = [ [ 0, A_NEW_SOURCE ].pack( 'Q>C' ), src_addr, @custom.encode( destination_domain_port ) ].join
434
+ data = [ [ 0, A_NEW_SOURCE, src_id ].pack( 'Q>CQ>' ), @custom.encode( destination_domain_port ) ].join
435
435
  loop_send_a_new_source( src_ext, data )
436
436
  end
437
437
 
@@ -454,7 +454,13 @@ module Girl
454
454
  # sub http request
455
455
  #
456
456
  def sub_http_request( data )
457
- method, url, proto = data.split( "\r\n" ).first.split( ' ' )
457
+ lines = data.split( "\r\n" )
458
+
459
+ if lines.empty?
460
+ return [ data, nil ]
461
+ end
462
+
463
+ method, url, proto = lines.first.split( ' ' )
458
464
 
459
465
  if proto && url && proto[ 0, 4 ] == 'HTTP' && url[ 0, 7 ] == 'http://'
460
466
  domain_and_port = url.split( '/' )[ 2 ]
@@ -484,14 +490,14 @@ module Girl
484
490
  ##
485
491
  # add tun wbuff
486
492
  #
487
- def add_tun_wbuff( src_addr, data )
488
- @tun_info[ :wbuffs ] << [ src_addr, data ]
493
+ def add_tun_wbuff( src_id, data )
494
+ @tun_info[ :wbuffs ] << [ src_id, data ]
489
495
 
490
496
  if @tun_info[ :wbuffs ].size >= WBUFFS_LIMIT
491
497
  spring = @tun_info[ :chunks ].size > 0 ? ( @tun_info[ :spring ] + 1 ) : 0
492
498
  filename = "#{ Process.pid }-#{ @tun_info[ :port ] }.#{ spring }"
493
499
  chunk_path = File.join( @tun_chunk_dir, filename )
494
- wbuffs = @tun_info[ :wbuffs ].map{ | _src_addr, _data | [ _src_addr, [ _data.bytesize ].pack( 'n' ), _data ].join }
500
+ wbuffs = @tun_info[ :wbuffs ].map{ | _src_id, _data | [ [ _src_id, _data.bytesize ].pack( 'Q>n' ), _data ].join }
495
501
 
496
502
  begin
497
503
  IO.binwrite( chunk_path, wbuffs.join )
@@ -516,9 +522,9 @@ module Girl
516
522
  src_info = @src_infos[ src ]
517
523
  src_info[ :wbuff ] << data
518
524
 
519
- if src_info[ :wbuff ].bytesize >= PROXY_CHUNK_SIZE
525
+ if src_info[ :wbuff ].bytesize >= CHUNK_SIZE
520
526
  spring = src_info[ :chunks ].size > 0 ? ( src_info[ :spring ] + 1 ) : 0
521
- filename = "#{ Process.pid }-#{ Addrinfo.new( src_info[ :src_addr ] ).ip_unpack.join( '-' ) }.#{ spring }"
527
+ filename = "#{ Process.pid }-#{ src_info[ :id ] }.#{ spring }"
522
528
  chunk_path = File.join( @src_chunk_dir, filename )
523
529
 
524
530
  begin
@@ -544,7 +550,7 @@ module Girl
544
550
  dst_info = @dst_infos[ dst ]
545
551
  dst_info[ :wbuff ] << data
546
552
 
547
- if dst_info[ :wbuff ].bytesize >= PROXY_CHUNK_SIZE
553
+ if dst_info[ :wbuff ].bytesize >= CHUNK_SIZE
548
554
  spring = dst_info[ :chunks ].size > 0 ? ( dst_info[ :spring ] + 1 ) : 0
549
555
  filename = "#{ Process.pid }-#{ dst_info[ :local_port ] }.#{ spring }"
550
556
  chunk_path = File.join( @dst_chunk_dir, filename )
@@ -624,22 +630,22 @@ module Girl
624
630
  end
625
631
  end
626
632
 
627
- src_addr = src_info[ :src_addr ]
633
+ src_id = src_info[ :id ]
628
634
 
629
635
  if src_info[ :proxy_type ] == :tunnel
630
636
  return if @tun.closed?
631
637
 
632
- src_ext = @tun_info[ :src_exts ][ src_addr ]
638
+ src_ext = @tun_info[ :src_exts ][ src_id ]
633
639
  return if src_ext.nil? || src_ext[ :dst_port ].nil?
634
640
 
635
641
  if src_ext[ :is_dst_closed ]
636
642
  # puts "debug1 2-2. after close src -> dst closed ? yes -> del src ext -> send fin2"
637
- del_src_ext( src_addr )
638
- data = [ [ 0, FIN2 ].pack( 'Q>C' ), src_addr ].join
643
+ del_src_ext( src_id )
644
+ data = [ 0, FIN2, src_id ].pack( 'Q>CQ>' )
639
645
  add_tun_ctlmsg( data )
640
646
  else
641
647
  # puts "debug1 1-1. after close src -> dst closed ? no -> send fin1"
642
- data = [ [ 0, FIN1 ].pack( 'Q>C' ), src_addr, [ src_ext[ :biggest_pack_id ], src_ext[ :continue_dst_pack_id ] ].pack( 'Q>Q>' ) ].join
648
+ data = [ 0, FIN1, src_id, src_ext[ :biggest_pack_id ], src_ext[ :continue_dst_pack_id ] ].pack( 'Q>CQ>Q>Q>' )
643
649
  add_tun_ctlmsg( data )
644
650
  end
645
651
  elsif src_info[ :proxy_type ] == :direct
@@ -696,11 +702,11 @@ module Girl
696
702
  ##
697
703
  # del src ext
698
704
  #
699
- def del_src_ext( src_addr )
700
- src_ext = @tun_info[ :src_exts ].delete( src_addr )
705
+ def del_src_ext( src_id )
706
+ src_ext = @tun_info[ :src_exts ].delete( src_id )
701
707
 
702
708
  if src_ext
703
- @tun_info[ :src_addrs ].delete( src_ext[ :dst_port ] )
709
+ @tun_info[ :src_ids ].delete( src_ext[ :dst_port ] )
704
710
  end
705
711
  end
706
712
 
@@ -855,8 +861,8 @@ module Girl
855
861
 
856
862
  # 重传
857
863
  while @tun_info[ :resendings ].any?
858
- src_addr, pack_id = @tun_info[ :resendings ].first
859
- src_ext = @tun_info[ :src_exts ][ src_addr ]
864
+ src_id, pack_id = @tun_info[ :resendings ].first
865
+ src_ext = @tun_info[ :src_exts ][ src_id ]
860
866
 
861
867
  if src_ext
862
868
  data = src_ext[ :wmems ][ pack_id ]
@@ -887,7 +893,7 @@ module Girl
887
893
 
888
894
  # 取写前
889
895
  if @tun_info[ :caches ].any?
890
- src_addr, data = @tun_info[ :caches ].first
896
+ src_id, data = @tun_info[ :caches ].first
891
897
  from = :caches
892
898
  elsif @tun_info[ :chunks ].any?
893
899
  path = File.join( @tun_chunk_dir, @tun_info[ :chunks ].shift )
@@ -904,24 +910,23 @@ module Girl
904
910
  caches = []
905
911
 
906
912
  until data.empty?
907
- _src_addr = data[ 0, 16 ]
908
- pack_size = data[ 16, 2 ].unpack( 'n' ).first
909
- caches << [ _src_addr, data[ 18, pack_size ] ]
910
- data = data[ ( 18 + pack_size )..-1 ]
913
+ _src_id, pack_size = data[ 0, 10 ].unpack( 'Q>n' )
914
+ caches << [ _src_id, data[ 10, pack_size ] ]
915
+ data = data[ ( 10 + pack_size )..-1 ]
911
916
  end
912
917
 
913
918
  @tun_info[ :caches ] = caches
914
- src_addr, data = caches.first
919
+ src_id, data = caches.first
915
920
  from = :caches
916
921
  elsif @tun_info[ :wbuffs ].any?
917
- src_addr, data = @tun_info[ :wbuffs ].first
922
+ src_id, data = @tun_info[ :wbuffs ].first
918
923
  from = :wbuffs
919
924
  else
920
925
  @writes.delete( tun )
921
926
  return
922
927
  end
923
928
 
924
- src_ext = @tun_info[ :src_exts ][ src_addr ]
929
+ src_ext = @tun_info[ :src_exts ][ src_id ]
925
930
 
926
931
  if src_ext
927
932
  pack_id = src_ext[ :biggest_pack_id ] + 1
@@ -931,7 +936,7 @@ module Girl
931
936
  # puts "debug1 encoded pack #{ pack_id }"
932
937
  end
933
938
 
934
- data = [ [ pack_id ].pack( 'Q>' ), src_addr, data ].join
939
+ data = [ [ pack_id, src_id ].pack( 'Q>Q>' ), data ].join
935
940
 
936
941
  begin
937
942
  tun.sendmsg( data, 0, @tun_info[ :tund_addr ] )
@@ -966,10 +971,11 @@ module Girl
966
971
  return
967
972
  end
968
973
 
969
- # puts "debug1 accept a src #{ addrinfo.inspect }"
970
- src_addr = addrinfo.to_sockaddr
974
+ id = rand( ( 2 ** 64 ) - 1 ) + 1
975
+ # puts "debug1 accept a src #{ addrinfo.inspect } #{ id }"
976
+
971
977
  @src_infos[ src ] = {
972
- src_addr: src_addr, # src地址
978
+ id: id, # id
973
979
  proxy_proto: :uncheck, # :uncheck / :http / :socks5
974
980
  proxy_type: :uncheck, # :uncheck / :checking / :direct / :tunnel / :negotiation
975
981
  dst: nil, # :direct的场合,对应的dst
@@ -993,7 +999,7 @@ module Girl
993
999
  #
994
1000
  def read_src( src )
995
1001
  begin
996
- data = src.read_nonblock( PROXY_PACK_SIZE )
1002
+ data = src.read_nonblock( PACK_SIZE )
997
1003
  rescue IO::WaitReadable, Errno::EINTR
998
1004
  return
999
1005
  rescue Exception => e
@@ -1012,6 +1018,12 @@ module Girl
1012
1018
  if data[ 0, 7 ] == 'CONNECT'
1013
1019
  # puts "debug1 CONNECT"
1014
1020
  domain_and_port = data.split( "\r\n" )[ 0 ].split( ' ' )[ 1 ]
1021
+
1022
+ unless domain_and_port
1023
+ puts "p#{ Process.pid } #{ Time.new } CONNECT miss domain"
1024
+ set_is_closing( src )
1025
+ return
1026
+ end
1015
1027
  elsif data[ 0 ].unpack( 'C' ).first == 5
1016
1028
  # puts "debug1 socks5 #{ data.inspect }"
1017
1029
 
@@ -1058,6 +1070,12 @@ module Girl
1058
1070
  unless domain_and_port
1059
1071
  # puts "debug1 not HTTP"
1060
1072
  domain_and_port = host_line.split( ' ' )[ 1 ]
1073
+
1074
+ unless domain_and_port
1075
+ puts "p#{ Process.pid } #{ Time.new } Host line miss domain"
1076
+ set_is_closing( src )
1077
+ return
1078
+ end
1061
1079
  end
1062
1080
 
1063
1081
  src_info[ :rbuffs ] << data
@@ -1111,8 +1129,8 @@ module Girl
1111
1129
  puts "p#{ Process.pid } #{ Time.new } socks5 cmd #{ cmd } not implement"
1112
1130
  end
1113
1131
  when :tunnel
1114
- src_addr = src_info[ :src_addr ]
1115
- src_ext = @tun_info[ :src_exts ][ src_addr ]
1132
+ src_id = src_info[ :id ]
1133
+ src_ext = @tun_info[ :src_exts ][ src_id ]
1116
1134
 
1117
1135
  unless src_ext
1118
1136
  # puts "debug1 not found src ext"
@@ -1131,7 +1149,7 @@ module Girl
1131
1149
  data, _ = sub_http_request( data )
1132
1150
  end
1133
1151
 
1134
- add_tun_wbuff( src_addr, data )
1152
+ add_tun_wbuff( src_id, data )
1135
1153
  else
1136
1154
  # puts "debug1 remote dst not ready, save data to src rbuff"
1137
1155
  src_info[ :rbuffs ] << data
@@ -1163,7 +1181,7 @@ module Girl
1163
1181
  #
1164
1182
  def read_dst( dst )
1165
1183
  begin
1166
- data = dst.read_nonblock( PROXY_PACK_SIZE )
1184
+ data = dst.read_nonblock( PACK_SIZE )
1167
1185
  rescue IO::WaitReadable, Errno::EINTR
1168
1186
  return
1169
1187
  rescue Exception => e
@@ -1194,6 +1212,7 @@ module Girl
1194
1212
  from_addr = addrinfo.to_sockaddr
1195
1213
  now = Time.new
1196
1214
  pack_id = data[ 0, 8 ].unpack( 'Q>' ).first
1215
+ @tun_info[ :last_recv_at ] = now
1197
1216
 
1198
1217
  if pack_id == 0
1199
1218
  ctl_num = data[ 8 ].unpack( 'C' ).first
@@ -1202,7 +1221,6 @@ module Girl
1202
1221
  when TUND_PORT
1203
1222
  return if ( from_addr != @proxyd_addr ) || @tun_info[ :tund_addr ]
1204
1223
 
1205
- @tun_info[ :last_recv_at ] = now
1206
1224
  tund_port = data[ 9, 2 ].unpack( 'n' ).first
1207
1225
 
1208
1226
  # puts "debug1 got tund port #{ tund_port }"
@@ -1218,18 +1236,15 @@ module Girl
1218
1236
  when PAIRED
1219
1237
  return if from_addr != @tun_info[ :tund_addr ]
1220
1238
 
1221
- src_addr = data[ 9, 16 ]
1222
- dst_port = data[ 25, 2 ].unpack( 'n' ).first
1239
+ src_id, dst_port = data[ 9, 10 ].unpack( 'Q>n' )
1223
1240
 
1224
- src_ext = @tun_info[ :src_exts ][ src_addr ]
1241
+ src_ext = @tun_info[ :src_exts ][ src_id ]
1225
1242
  return if src_ext.nil? || src_ext[ :dst_port ]
1226
1243
 
1227
1244
  src = src_ext[ :src ]
1228
1245
  return if src.closed?
1229
1246
 
1230
- @tun_info[ :last_recv_at ] = now
1231
-
1232
- # puts "debug1 got paired #{ Addrinfo.new( src_addr ).inspect } #{ dst_port }"
1247
+ # puts "debug1 got paired #{ src_id } #{ dst_port }"
1233
1248
 
1234
1249
  if dst_port == 0
1235
1250
  set_is_closing( src )
@@ -1237,7 +1252,7 @@ module Girl
1237
1252
  end
1238
1253
 
1239
1254
  src_ext[ :dst_port ] = dst_port
1240
- @tun_info[ :src_addrs ][ dst_port ] = src_addr
1255
+ @tun_info[ :src_ids ][ dst_port ] = src_id
1241
1256
 
1242
1257
  src_info = @src_infos[ src ]
1243
1258
 
@@ -1253,7 +1268,7 @@ module Girl
1253
1268
  # puts "debug1 add src rbuffs to tun wbuffs"
1254
1269
 
1255
1270
  datas.each do | _data |
1256
- add_tun_wbuff( src_addr, _data )
1271
+ add_tun_wbuff( src_id, _data )
1257
1272
  end
1258
1273
  end
1259
1274
  elsif src_info[ :proxy_proto ] == :socks5
@@ -1264,14 +1279,13 @@ module Girl
1264
1279
 
1265
1280
  dst_port, biggest_dst_pack_id, continue_src_pack_id = data[ 9, 18 ].unpack( 'nQ>Q>' )
1266
1281
 
1267
- src_addr = @tun_info[ :src_addrs ][ dst_port ]
1268
- return unless src_addr
1282
+ src_id = @tun_info[ :src_ids ][ dst_port ]
1283
+ return unless src_id
1269
1284
 
1270
- src_ext = @tun_info[ :src_exts ][ src_addr ]
1285
+ src_ext = @tun_info[ :src_exts ][ src_id ]
1271
1286
  return unless src_ext
1272
1287
 
1273
1288
  # puts "debug2 got dest status"
1274
- @tun_info[ :last_recv_at ] = now
1275
1289
 
1276
1290
  # 更新对面发到几
1277
1291
  if biggest_dst_pack_id > src_ext[ :biggest_dst_pack_id ]
@@ -1321,20 +1335,17 @@ module Girl
1321
1335
  when MISS
1322
1336
  return if from_addr != @tun_info[ :tund_addr ]
1323
1337
 
1324
- src_addr = data[ 9, 16 ]
1325
- pack_id_begin, pack_id_end = data[ 25, 16 ].unpack( 'Q>Q>' )
1338
+ src_id, pack_id_begin, pack_id_end = data[ 9, 24 ].unpack( 'Q>Q>Q>' )
1326
1339
 
1327
- src_ext = @tun_info[ :src_exts ][ src_addr ]
1340
+ src_ext = @tun_info[ :src_exts ][ src_id ]
1328
1341
  return unless src_ext
1329
1342
 
1330
- @tun_info[ :last_recv_at ] = now
1331
-
1332
1343
  ( pack_id_begin..pack_id_end ).each do | pack_id |
1333
1344
  send_at = src_ext[ :send_ats ][ pack_id ]
1334
1345
 
1335
1346
  if send_at
1336
1347
  break if now - send_at < STATUS_INTERVAL
1337
- @tun_info[ :resendings ] << [ src_addr, pack_id ]
1348
+ @tun_info[ :resendings ] << [ src_id, pack_id ]
1338
1349
  end
1339
1350
  end
1340
1351
 
@@ -1344,14 +1355,12 @@ module Girl
1344
1355
 
1345
1356
  dst_port, biggest_dst_pack_id, continue_src_pack_id = data[ 9, 18 ].unpack( 'nQ>Q>' )
1346
1357
 
1347
- src_addr = @tun_info[ :src_addrs ][ dst_port ]
1348
- return unless src_addr
1358
+ src_id = @tun_info[ :src_ids ][ dst_port ]
1359
+ return unless src_id
1349
1360
 
1350
- src_ext = @tun_info[ :src_exts ][ src_addr ]
1361
+ src_ext = @tun_info[ :src_exts ][ src_id ]
1351
1362
  return unless src_ext
1352
1363
 
1353
- @tun_info[ :last_recv_at ] = now
1354
-
1355
1364
  # puts "debug1 got fin1 #{ dst_port } biggest dst pack #{ biggest_dst_pack_id } completed src pack #{ continue_src_pack_id }"
1356
1365
  src_ext[ :is_dst_closed ] = true
1357
1366
  src_ext[ :biggest_dst_pack_id ] = biggest_dst_pack_id
@@ -1367,18 +1376,14 @@ module Girl
1367
1376
 
1368
1377
  dst_port = data[ 9, 2 ].unpack( 'n' ).first
1369
1378
 
1370
- src_addr = @tun_info[ :src_addrs ][ dst_port ]
1371
- return unless src_addr
1372
-
1373
- @tun_info[ :last_recv_at ] = now
1379
+ src_id = @tun_info[ :src_ids ][ dst_port ]
1380
+ return unless src_id
1374
1381
 
1375
1382
  # puts "debug1 1-2. recv fin2 -> del src ext"
1376
- del_src_ext( src_addr )
1383
+ del_src_ext( src_id )
1377
1384
  when TUND_FIN
1378
1385
  return if from_addr != @tun_info[ :tund_addr ]
1379
1386
 
1380
- @tun_info[ :last_recv_at ] = now
1381
-
1382
1387
  puts "p#{ Process.pid } #{ Time.new } recv tund fin"
1383
1388
  set_is_closing( tun )
1384
1389
  end
@@ -1390,15 +1395,13 @@ module Girl
1390
1395
 
1391
1396
  dst_port = data[ 8, 2 ].unpack( 'n' ).first
1392
1397
 
1393
- src_addr = @tun_info[ :src_addrs ][ dst_port ]
1394
- return unless src_addr
1398
+ src_id = @tun_info[ :src_ids ][ dst_port ]
1399
+ return unless src_id
1395
1400
 
1396
- src_ext = @tun_info[ :src_exts ][ src_addr ]
1401
+ src_ext = @tun_info[ :src_exts ][ src_id ]
1397
1402
  return if src_ext.nil? || src_ext[ :src ].closed?
1398
1403
  return if ( pack_id <= src_ext[ :continue_dst_pack_id ] ) || src_ext[ :pieces ].include?( pack_id )
1399
1404
 
1400
- @tun_info[ :last_recv_at ] = now
1401
-
1402
1405
  data = data[ 10..-1 ]
1403
1406
  # puts "debug2 got pack #{ pack_id }"
1404
1407
 
@@ -109,7 +109,7 @@ module Girl
109
109
  else
110
110
  tund_info[ :dst_exts ].each do | dst_local_port, dst_ext |
111
111
  if dst_ext[ :dst ].closed? && ( now - dst_ext[ :last_continue_at ] > EXPIRE_AFTER )
112
- puts "p#{ Process.pid } #{ Time.new } expire dst_ext #{ dst_local_port }"
112
+ puts "p#{ Process.pid } #{ Time.new } expire dst ext #{ dst_local_port }"
113
113
  del_dst_ext( tund, dst_local_port )
114
114
  need_trigger = true
115
115
  end
@@ -119,7 +119,7 @@ module Girl
119
119
  end
120
120
 
121
121
  @dst_infos.each do | dst, dst_info |
122
- is_expired = dst_info[ :last_recv_at ] ? ( now - dst_info[ :last_recv_at ] > EXPIRE_AFTER ) : ( now - dst_info[ :created_at ] > EXPIRE_NEW )
122
+ is_expired = dst_info[ :last_recv_at ].nil? && ( now - dst_info[ :created_at ] > EXPIRE_NEW )
123
123
 
124
124
  if is_expired
125
125
  puts "p#{ Process.pid } #{ Time.new } expire dst"
@@ -183,7 +183,7 @@ module Girl
183
183
  ##
184
184
  # resolve domain
185
185
  #
186
- def resolve_domain( tund, src_addr, destination_domain_port )
186
+ def resolve_domain( tund, src_id, destination_domain_port )
187
187
  resolv_cache = @resolv_caches[ destination_domain_port ]
188
188
 
189
189
  if resolv_cache
@@ -191,7 +191,7 @@ module Girl
191
191
 
192
192
  if Time.new - created_at < RESOLV_CACHE_EXPIRE
193
193
  # puts "debug1 #{ destination_domain_port } hit resolv cache #{ Addrinfo.new( destination_addr ).inspect }"
194
- deal_with_destination_addr( tund, src_addr, destination_addr )
194
+ deal_with_destination_addr( tund, src_id, destination_addr )
195
195
  return
196
196
  end
197
197
 
@@ -215,7 +215,7 @@ module Girl
215
215
  @resolv_caches[ destination_domain_port ] = [ destination_addr, Time.new ]
216
216
 
217
217
  unless tund.closed?
218
- if deal_with_destination_addr( tund, src_addr, destination_addr )
218
+ if deal_with_destination_addr( tund, src_id, destination_addr )
219
219
  next_tick
220
220
  end
221
221
  end
@@ -227,7 +227,7 @@ module Girl
227
227
  ##
228
228
  # deal with destination addr
229
229
  #
230
- def deal_with_destination_addr( tund, src_addr, destination_addr )
230
+ def deal_with_destination_addr( tund, src_id, destination_addr )
231
231
  dst = Socket.new( Socket::AF_INET, Socket::SOCK_STREAM, 0 )
232
232
  dst.setsockopt( Socket::SOL_TCP, Socket::TCP_NODELAY, 1 )
233
233
 
@@ -239,7 +239,7 @@ module Girl
239
239
  return false
240
240
  end
241
241
 
242
- local_port = dst.local_address.ip_unpack.last
242
+ local_port = dst.local_address.ip_port
243
243
 
244
244
  @dst_infos[ dst ] = {
245
245
  local_port: local_port, # 本地端口
@@ -255,10 +255,10 @@ module Girl
255
255
  add_read( dst, :dst )
256
256
 
257
257
  tund_info = @tund_infos[ tund ]
258
- tund_info[ :dst_local_ports ][ src_addr ] = local_port
258
+ tund_info[ :dst_local_ports ][ src_id ] = local_port
259
259
  tund_info[ :dst_exts ][ local_port ] = {
260
260
  dst: dst, # dst
261
- src_addr: src_addr, # 近端src地址
261
+ src_id: src_id, # 近端src id
262
262
  wmems: {}, # 写后 pack_id => data
263
263
  send_ats: {}, # 上一次发出时间 pack_id => send_at
264
264
  biggest_pack_id: 0, # 发到几
@@ -270,7 +270,7 @@ module Girl
270
270
  last_continue_at: Time.new # 创建,或者上一次收到连续流量,或者发出新包的时间
271
271
  }
272
272
 
273
- data = [ [ 0, PAIRED ].pack( 'Q>C' ), src_addr, [ local_port ].pack( 'n' ) ].join
273
+ data = [ 0, PAIRED, src_id, local_port ].pack( 'Q>CQ>n' )
274
274
  # puts "debug1 add ctlmsg paired #{ data.inspect }"
275
275
  add_tund_ctlmsg( tund, data )
276
276
 
@@ -344,7 +344,7 @@ module Girl
344
344
  dst_info = @dst_infos[ dst ]
345
345
  dst_info[ :wbuff ] << data
346
346
 
347
- if dst_info[ :wbuff ].bytesize >= PROXY_CHUNK_SIZE
347
+ if dst_info[ :wbuff ].bytesize >= CHUNK_SIZE
348
348
  spring = dst_info[ :chunks ].size > 0 ? ( dst_info[ :spring ] + 1 ) : 0
349
349
  filename = "#{ Process.pid }-#{ dst_info[ :local_port ] }.#{ spring }"
350
350
  chunk_path = File.join( @dst_chunk_dir, filename )
@@ -480,7 +480,7 @@ module Girl
480
480
  dst_ext = tund_info[ :dst_exts ].delete( dst_local_port )
481
481
 
482
482
  if dst_ext
483
- tund_info[ :dst_local_ports ].delete( dst_ext[ :src_addr ] )
483
+ tund_info[ :dst_local_ports ].delete( dst_ext[ :src_id ] )
484
484
  end
485
485
  end
486
486
 
@@ -724,7 +724,7 @@ module Girl
724
724
 
725
725
  tund = Socket.new( Socket::AF_INET, Socket::SOCK_DGRAM, 0 )
726
726
  tund.bind( Socket.sockaddr_in( 0, '0.0.0.0' ) )
727
- port = tund.local_address.ip_unpack.last
727
+ port = tund.local_address.ip_port
728
728
 
729
729
  @tunneling_tunds[ from_addr ] = tund
730
730
  @tunds[ port ] = tund
@@ -738,7 +738,7 @@ module Girl
738
738
  tun_addr: from_addr, # tun地址
739
739
  is_tunneled: false, # 是否已和tun打通
740
740
  dst_exts: {}, # dst额外信息 dst_addr => {}
741
- dst_local_ports: {}, # src_addr => dst_local_port
741
+ dst_local_ports: {}, # src_id => dst_local_port
742
742
  paused: false, # 是否暂停写
743
743
  resendings: [], # 重传队列 [ dst_addr, pack_id ]
744
744
  created_at: Time.new, # 创建时间
@@ -758,7 +758,7 @@ module Girl
758
758
  #
759
759
  def read_dst( dst )
760
760
  begin
761
- data = dst.read_nonblock( PROXY_PACK_SIZE )
761
+ data = dst.read_nonblock( PACK_SIZE )
762
762
  rescue IO::WaitReadable, Errno::EINTR
763
763
  return
764
764
  rescue Exception => e
@@ -791,8 +791,13 @@ module Girl
791
791
  tund_info = @tund_infos[ tund ]
792
792
 
793
793
  if from_addr != tund_info[ :tun_addr ]
794
- puts "p#{ Process.pid } #{ Time.new } #{ addrinfo.inspect } not match #{ Addrinfo.new( tund_info[ :tun_addr ] ).inspect }"
795
- return
794
+ if addrinfo.ip_port == Addrinfo.new( tund_info[ :tun_addr ] ).ip_port
795
+ puts "p#{ Process.pid } #{ Time.new } tun ip changed #{ addrinfo.inspect }"
796
+ tund_info[ :tun_addr ] = from_addr
797
+ else
798
+ puts "p#{ Process.pid } #{ Time.new } #{ addrinfo.inspect } not match #{ Addrinfo.new( tund_info[ :tun_addr ] ).inspect }"
799
+ return
800
+ end
796
801
  end
797
802
 
798
803
  tund_info[ :is_tunneled ] = true
@@ -803,9 +808,9 @@ module Girl
803
808
 
804
809
  case ctl_num
805
810
  when A_NEW_SOURCE
806
- src_addr = data[ 9, 16 ]
807
- dst_local_port = tund_info[ :dst_local_ports ][ src_addr ]
808
- # puts "debug1 got a new source #{ Addrinfo.new( src_addr ).inspect }"
811
+ src_id = data[ 9, 8 ].unpack( 'Q>' ).first
812
+ dst_local_port = tund_info[ :dst_local_ports ][ src_id ]
813
+ # puts "debug1 got a new source #{ src_id }"
809
814
 
810
815
  if dst_local_port
811
816
  dst_ext = tund_info[ :dst_exts ][ dst_local_port ]
@@ -816,22 +821,21 @@ module Girl
816
821
  end
817
822
 
818
823
  # puts "debug1 readd ctlmsg paired #{ dst_local_port }"
819
- data2 = [ [ 0, PAIRED ].pack( 'Q>C' ), src_addr, [ dst_local_port ].pack( 'n' ) ].join
824
+ data2 = [ 0, PAIRED, src_id, dst_local_port ].pack( 'Q>CQ>n' )
820
825
  add_tund_ctlmsg( tund, data2 )
821
826
  return
822
827
  end
823
828
 
824
829
  tund_info[ :last_recv_at ] = now
825
830
 
826
- data = data[ 25..-1 ]
831
+ data = data[ 17..-1 ]
827
832
  # puts "debug1 #{ data }"
828
833
  destination_domain_port = @custom.decode( data )
829
- resolve_domain( tund, src_addr, destination_domain_port )
834
+ resolve_domain( tund, src_id, destination_domain_port )
830
835
  when SOURCE_STATUS
831
- src_addr = data[ 9, 16 ]
832
- biggest_src_pack_id, continue_dst_pack_id = data[ 25, 16 ].unpack( 'Q>Q>' )
836
+ src_id, biggest_src_pack_id, continue_dst_pack_id = data[ 9, 24 ].unpack( 'Q>Q>Q>' )
833
837
 
834
- dst_local_port = tund_info[ :dst_local_ports ][ src_addr ]
838
+ dst_local_port = tund_info[ :dst_local_ports ][ src_id ]
835
839
  return unless dst_local_port
836
840
 
837
841
  dst_ext = tund_info[ :dst_exts ][ dst_local_port ]
@@ -880,7 +884,7 @@ module Girl
880
884
  break
881
885
  end
882
886
 
883
- data2 = [ [ 0, MISS ].pack( 'Q>C' ), src_addr, [ pack_id_begin, pack_id_end ].pack( 'Q>Q>' ) ].join
887
+ data2 = [ 0, MISS, src_id, pack_id_begin, pack_id_end ].pack( 'Q>CQ>Q>Q>' )
884
888
  add_tund_ctlmsg( tund, data2 )
885
889
  pack_count += ( pack_id_end - pack_id_begin + 1 )
886
890
  end
@@ -904,10 +908,9 @@ module Girl
904
908
 
905
909
  add_write( tund )
906
910
  when FIN1
907
- src_addr = data[ 9, 16 ]
908
- biggest_src_pack_id, continue_dst_pack_id = data[ 25, 16 ].unpack( 'Q>Q>' )
911
+ src_id, biggest_src_pack_id, continue_dst_pack_id = data[ 9, 24 ].unpack( 'Q>Q>Q>' )
909
912
 
910
- dst_local_port = tund_info[ :dst_local_ports ][ src_addr ]
913
+ dst_local_port = tund_info[ :dst_local_ports ][ src_id ]
911
914
  return unless dst_local_port
912
915
 
913
916
  dst_ext = tund_info[ :dst_exts ][ dst_local_port ]
@@ -915,7 +918,7 @@ module Girl
915
918
 
916
919
  tund_info[ :last_recv_at ] = now
917
920
 
918
- # puts "debug1 got fin1 #{ Addrinfo.new( src_addr ).inspect } biggest src pack #{ biggest_src_pack_id } completed dst pack #{ continue_dst_pack_id }"
921
+ # puts "debug1 got fin1 #{ src_id } biggest src pack #{ biggest_src_pack_id } completed dst pack #{ continue_dst_pack_id }"
919
922
  dst_ext[ :is_src_closed ] = true
920
923
  dst_ext[ :biggest_src_pack_id ] = biggest_src_pack_id
921
924
  release_wmems( dst_ext, continue_dst_pack_id )
@@ -926,9 +929,9 @@ module Girl
926
929
  set_is_closing( dst_ext[ :dst ] )
927
930
  end
928
931
  when FIN2
929
- src_addr = data[ 9, 16 ]
932
+ src_id = data[ 9, 8 ].unpack( 'Q>' ).first
930
933
 
931
- dst_local_port = tund_info[ :dst_local_ports ][ src_addr ]
934
+ dst_local_port = tund_info[ :dst_local_ports ][ src_id ]
932
935
  return unless dst_local_port
933
936
 
934
937
  tund_info[ :last_recv_at ] = now
@@ -944,9 +947,9 @@ module Girl
944
947
  return
945
948
  end
946
949
 
947
- src_addr = data[ 8, 16 ]
950
+ src_id = data[ 8, 8 ].unpack( 'Q>' ).first
948
951
 
949
- dst_local_port = tund_info[ :dst_local_ports ][ src_addr ]
952
+ dst_local_port = tund_info[ :dst_local_ports ][ src_id ]
950
953
  return unless dst_local_port
951
954
 
952
955
  dst_ext = tund_info[ :dst_exts ][ dst_local_port ]
@@ -955,7 +958,7 @@ module Girl
955
958
 
956
959
  tund_info[ :last_recv_at ] = now
957
960
 
958
- data = data[ 24..-1 ]
961
+ data = data[ 16..-1 ]
959
962
  # puts "debug2 got pack #{ pack_id }"
960
963
 
961
964
  if pack_id <= CONFUSE_UNTIL
@@ -1,3 +1,3 @@
1
1
  module Girl
2
- VERSION = '0.61.0'.freeze
2
+ VERSION = '0.65.0'.freeze
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: girl
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.61.0
4
+ version: 0.65.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - takafan
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-05-27 00:00:00.000000000 Z
11
+ date: 2020-06-23 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: while internet is evil, here's a girl.
14
14
  email: