girl 0.62.0 → 0.66.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: f3597360a30c0ba1226ed9fdeef1faf10687bbfc48ac58c07c063c5e6888dd50
4
- data.tar.gz: 7d7429c890f3090c53b57c61587a4f03351d4e68775e310acd174baf91adfa74
3
+ metadata.gz: 1b2ece41d566cc27562dff36a48b1c53c53000390587b5e424bc38e78636e74c
4
+ data.tar.gz: c3d80d9b98804d0f1f37cf479052fc5c68b7cf907c800813cf3dd0d9a1691855
5
5
  SHA512:
6
- metadata.gz: f0e09919d82be7c07a3342199af626487cdde4527e799609ec561fc9bef29929a616a075dbc10ce31656c00c7c5aab4311223edbf7ea45cf70e9798f0bc5f20e
7
- data.tar.gz: 979e305bb9c5f9e846271ff9d9c1bb01438ca6714e96a95ab7b588493968aa5d25dccfda5ee4d36d288570034e655ac0c113a4e935fcc3410be23d091d74ea56
6
+ metadata.gz: c2c0d92f7dbd582f04a8d49e5285d863e790070a3ffd2c08313695f66388df436fa59441b9fef992600e1611a39053ea3df8b3f453004e2bcbc0ad126c4e257e
7
+ data.tar.gz: e4baabb1843d03f27101e43407927febdf0dd3a1917a30ae017297c75cb5336a32f1fb033bc484ffc0f6cf053a4b3ea63ed8726b4aece5ae662bd72767ff730d
@@ -1,16 +1,14 @@
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 = 300 # 多久没有新流量,过期
11
9
  CHECK_EXPIRE_INTERVAL = 30 # 检查过期间隔
12
10
  HEARTBEAT_INTERVAL = 30 # 心跳间隔
13
- STATUS_INTERVAL = 0.3 # 发送状态间隔
11
+ STATUS_INTERVAL = 0.5 # 发送状态间隔
14
12
  SEND_STATUS_UNTIL = 10 # 持续的告之对面状态,直到没有流量往来,持续多少秒
15
13
  BREAK_SEND_MISS = 10_000 # miss包个数上限,达到上限忽略要后面的段,可控碎片缓存
16
14
  CONFUSE_UNTIL = 5 # 混淆前几个包
@@ -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
  # ===========
@@ -109,12 +109,13 @@ module Girl
109
109
  set_is_closing( @tun )
110
110
  else
111
111
  data = [ 0, HEARTBEAT, rand( 128 ) ].pack( 'Q>CC' )
112
+ # puts "debug1 #{ Time.new } heartbeat"
112
113
  add_tun_ctlmsg( data )
113
114
 
114
- @tun_info[ :src_exts ].each do | src_addr, src_ext |
115
+ @tun_info[ :src_exts ].each do | src_id, src_ext |
115
116
  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 )
117
+ puts "p#{ Process.pid } #{ Time.new } expire src ext #{ src_id }"
118
+ del_src_ext( src_id )
118
119
  end
119
120
  end
120
121
  end
@@ -165,10 +166,10 @@ module Girl
165
166
  if @tun_info[ :src_exts ].any?
166
167
  now = Time.new
167
168
 
168
- @tun_info[ :src_exts ].each do | src_addr, src_ext |
169
+ @tun_info[ :src_exts ].each do | src_id, src_ext |
169
170
  if src_ext[ :dst_port ] && ( now - src_ext[ :last_continue_at ] < SEND_STATUS_UNTIL )
170
171
  # 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
172
+ data = [ 0, SOURCE_STATUS, src_id, src_ext[ :biggest_pack_id ], src_ext[ :continue_dst_pack_id ] ].pack( 'Q>CQ>Q>Q>' )
172
173
  add_tun_ctlmsg( data )
173
174
  need_trigger = true
174
175
  end
@@ -311,20 +312,20 @@ module Girl
311
312
  def new_a_tun
312
313
  tun = Socket.new( Socket::AF_INET, Socket::SOCK_DGRAM, 0 )
313
314
  tun.bind( Socket.sockaddr_in( 0, '0.0.0.0' ) )
314
- port = tun.local_address.ip_unpack.last
315
+ port = tun.local_address.ip_port
315
316
  tun_info = {
316
317
  port: port, # 端口
317
318
  ctlmsg_rbuffs: [], # 还没配上tund,暂存的ctlmsg
318
319
  ctlmsgs: [], # [ to_addr, data ]
319
- wbuffs: [], # 写前缓存 [ src_addr, data ]
320
- caches: [], # 块读出缓存 [ src_addr, data ]
320
+ wbuffs: [], # 写前缓存 [ src_id, data ]
321
+ caches: [], # 块读出缓存 [ src_id, data ]
321
322
  chunks: [], # 块队列 filename
322
323
  spring: 0, # 块后缀,结块时,如果块队列不为空,则自增,为空,则置为0
323
324
  tund_addr: nil, # tund地址
324
- src_exts: {}, # src额外信息 src_addr => {}
325
- src_addrs: {}, # dst_port => src_addr
325
+ src_exts: {}, # src额外信息 src_id => {}
326
+ src_ids: {}, # dst_port => src_id
326
327
  paused: false, # 是否暂停写
327
- resendings: [], # 重传队列 [ src_addr, pack_id ]
328
+ resendings: [], # 重传队列 [ src_id, pack_id ]
328
329
  created_at: Time.new, # 创建时间
329
330
  last_recv_at: nil, # 上一次收到流量的时间,过期关闭
330
331
  is_closing: false # 是否准备关闭
@@ -363,7 +364,7 @@ module Girl
363
364
  end
364
365
 
365
366
  # puts "debug1 a new dst #{ dst.local_address.inspect }"
366
- local_port = dst.local_address.ip_unpack
367
+ local_port = dst.local_address.ip_port
367
368
  @dsts[ local_port ] = dst
368
369
  @dst_infos[ dst ] = {
369
370
  local_port: local_port, # 本地端口
@@ -424,14 +425,14 @@ module Girl
424
425
  }
425
426
 
426
427
  src_info = @src_infos[ src ]
427
- src_addr = src_info[ :src_addr ]
428
- @tun_info[ :src_exts ][ src_addr ] = src_ext
428
+ src_id = src_info[ :id ]
429
+ @tun_info[ :src_exts ][ src_id ] = src_ext
429
430
  src_info[ :proxy_type ] = :tunnel
430
431
 
431
432
  destination_port = src_info[ :destination_port ]
432
433
  destination_domain = src_info[ :destination_domain ]
433
434
  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
435
+ data = [ [ 0, A_NEW_SOURCE, src_id ].pack( 'Q>CQ>' ), @custom.encode( destination_domain_port ) ].join
435
436
  loop_send_a_new_source( src_ext, data )
436
437
  end
437
438
 
@@ -490,14 +491,14 @@ module Girl
490
491
  ##
491
492
  # add tun wbuff
492
493
  #
493
- def add_tun_wbuff( src_addr, data )
494
- @tun_info[ :wbuffs ] << [ src_addr, data ]
494
+ def add_tun_wbuff( src_id, data )
495
+ @tun_info[ :wbuffs ] << [ src_id, data ]
495
496
 
496
497
  if @tun_info[ :wbuffs ].size >= WBUFFS_LIMIT
497
498
  spring = @tun_info[ :chunks ].size > 0 ? ( @tun_info[ :spring ] + 1 ) : 0
498
499
  filename = "#{ Process.pid }-#{ @tun_info[ :port ] }.#{ spring }"
499
500
  chunk_path = File.join( @tun_chunk_dir, filename )
500
- wbuffs = @tun_info[ :wbuffs ].map{ | _src_addr, _data | [ _src_addr, [ _data.bytesize ].pack( 'n' ), _data ].join }
501
+ wbuffs = @tun_info[ :wbuffs ].map{ | _src_id, _data | [ [ _src_id, _data.bytesize ].pack( 'Q>n' ), _data ].join }
501
502
 
502
503
  begin
503
504
  IO.binwrite( chunk_path, wbuffs.join )
@@ -522,9 +523,9 @@ module Girl
522
523
  src_info = @src_infos[ src ]
523
524
  src_info[ :wbuff ] << data
524
525
 
525
- if src_info[ :wbuff ].bytesize >= PROXY_CHUNK_SIZE
526
+ if src_info[ :wbuff ].bytesize >= CHUNK_SIZE
526
527
  spring = src_info[ :chunks ].size > 0 ? ( src_info[ :spring ] + 1 ) : 0
527
- filename = "#{ Process.pid }-#{ Addrinfo.new( src_info[ :src_addr ] ).ip_unpack.join( '-' ) }.#{ spring }"
528
+ filename = "#{ Process.pid }-#{ src_info[ :id ] }.#{ spring }"
528
529
  chunk_path = File.join( @src_chunk_dir, filename )
529
530
 
530
531
  begin
@@ -550,7 +551,7 @@ module Girl
550
551
  dst_info = @dst_infos[ dst ]
551
552
  dst_info[ :wbuff ] << data
552
553
 
553
- if dst_info[ :wbuff ].bytesize >= PROXY_CHUNK_SIZE
554
+ if dst_info[ :wbuff ].bytesize >= CHUNK_SIZE
554
555
  spring = dst_info[ :chunks ].size > 0 ? ( dst_info[ :spring ] + 1 ) : 0
555
556
  filename = "#{ Process.pid }-#{ dst_info[ :local_port ] }.#{ spring }"
556
557
  chunk_path = File.join( @dst_chunk_dir, filename )
@@ -630,22 +631,22 @@ module Girl
630
631
  end
631
632
  end
632
633
 
633
- src_addr = src_info[ :src_addr ]
634
+ src_id = src_info[ :id ]
634
635
 
635
636
  if src_info[ :proxy_type ] == :tunnel
636
637
  return if @tun.closed?
637
638
 
638
- src_ext = @tun_info[ :src_exts ][ src_addr ]
639
+ src_ext = @tun_info[ :src_exts ][ src_id ]
639
640
  return if src_ext.nil? || src_ext[ :dst_port ].nil?
640
641
 
641
642
  if src_ext[ :is_dst_closed ]
642
643
  # puts "debug1 2-2. after close src -> dst closed ? yes -> del src ext -> send fin2"
643
- del_src_ext( src_addr )
644
- data = [ [ 0, FIN2 ].pack( 'Q>C' ), src_addr ].join
644
+ del_src_ext( src_id )
645
+ data = [ 0, FIN2, src_id ].pack( 'Q>CQ>' )
645
646
  add_tun_ctlmsg( data )
646
647
  else
647
648
  # puts "debug1 1-1. after close src -> dst closed ? no -> send fin1"
648
- data = [ [ 0, FIN1 ].pack( 'Q>C' ), src_addr, [ src_ext[ :biggest_pack_id ], src_ext[ :continue_dst_pack_id ] ].pack( 'Q>Q>' ) ].join
649
+ data = [ 0, FIN1, src_id, src_ext[ :biggest_pack_id ], src_ext[ :continue_dst_pack_id ] ].pack( 'Q>CQ>Q>Q>' )
649
650
  add_tun_ctlmsg( data )
650
651
  end
651
652
  elsif src_info[ :proxy_type ] == :direct
@@ -702,11 +703,11 @@ module Girl
702
703
  ##
703
704
  # del src ext
704
705
  #
705
- def del_src_ext( src_addr )
706
- src_ext = @tun_info[ :src_exts ].delete( src_addr )
706
+ def del_src_ext( src_id )
707
+ src_ext = @tun_info[ :src_exts ].delete( src_id )
707
708
 
708
709
  if src_ext
709
- @tun_info[ :src_addrs ].delete( src_ext[ :dst_port ] )
710
+ @tun_info[ :src_ids ].delete( src_ext[ :dst_port ] )
710
711
  end
711
712
  end
712
713
 
@@ -861,8 +862,8 @@ module Girl
861
862
 
862
863
  # 重传
863
864
  while @tun_info[ :resendings ].any?
864
- src_addr, pack_id = @tun_info[ :resendings ].first
865
- src_ext = @tun_info[ :src_exts ][ src_addr ]
865
+ src_id, pack_id = @tun_info[ :resendings ].first
866
+ src_ext = @tun_info[ :src_exts ][ src_id ]
866
867
 
867
868
  if src_ext
868
869
  data = src_ext[ :wmems ][ pack_id ]
@@ -893,7 +894,7 @@ module Girl
893
894
 
894
895
  # 取写前
895
896
  if @tun_info[ :caches ].any?
896
- src_addr, data = @tun_info[ :caches ].first
897
+ src_id, data = @tun_info[ :caches ].first
897
898
  from = :caches
898
899
  elsif @tun_info[ :chunks ].any?
899
900
  path = File.join( @tun_chunk_dir, @tun_info[ :chunks ].shift )
@@ -910,24 +911,23 @@ module Girl
910
911
  caches = []
911
912
 
912
913
  until data.empty?
913
- _src_addr = data[ 0, 16 ]
914
- pack_size = data[ 16, 2 ].unpack( 'n' ).first
915
- caches << [ _src_addr, data[ 18, pack_size ] ]
916
- data = data[ ( 18 + pack_size )..-1 ]
914
+ _src_id, pack_size = data[ 0, 10 ].unpack( 'Q>n' )
915
+ caches << [ _src_id, data[ 10, pack_size ] ]
916
+ data = data[ ( 10 + pack_size )..-1 ]
917
917
  end
918
918
 
919
919
  @tun_info[ :caches ] = caches
920
- src_addr, data = caches.first
920
+ src_id, data = caches.first
921
921
  from = :caches
922
922
  elsif @tun_info[ :wbuffs ].any?
923
- src_addr, data = @tun_info[ :wbuffs ].first
923
+ src_id, data = @tun_info[ :wbuffs ].first
924
924
  from = :wbuffs
925
925
  else
926
926
  @writes.delete( tun )
927
927
  return
928
928
  end
929
929
 
930
- src_ext = @tun_info[ :src_exts ][ src_addr ]
930
+ src_ext = @tun_info[ :src_exts ][ src_id ]
931
931
 
932
932
  if src_ext
933
933
  pack_id = src_ext[ :biggest_pack_id ] + 1
@@ -937,7 +937,7 @@ module Girl
937
937
  # puts "debug1 encoded pack #{ pack_id }"
938
938
  end
939
939
 
940
- data = [ [ pack_id ].pack( 'Q>' ), src_addr, data ].join
940
+ data = [ [ pack_id, src_id ].pack( 'Q>Q>' ), data ].join
941
941
 
942
942
  begin
943
943
  tun.sendmsg( data, 0, @tun_info[ :tund_addr ] )
@@ -972,10 +972,11 @@ module Girl
972
972
  return
973
973
  end
974
974
 
975
- # puts "debug1 accept a src #{ addrinfo.inspect }"
976
- src_addr = addrinfo.to_sockaddr
975
+ id = rand( ( 2 ** 64 ) - 1 ) + 1
976
+ # puts "debug1 accept a src #{ addrinfo.inspect } #{ id }"
977
+
977
978
  @src_infos[ src ] = {
978
- src_addr: src_addr, # src地址
979
+ id: id, # id
979
980
  proxy_proto: :uncheck, # :uncheck / :http / :socks5
980
981
  proxy_type: :uncheck, # :uncheck / :checking / :direct / :tunnel / :negotiation
981
982
  dst: nil, # :direct的场合,对应的dst
@@ -999,7 +1000,7 @@ module Girl
999
1000
  #
1000
1001
  def read_src( src )
1001
1002
  begin
1002
- data = src.read_nonblock( PROXY_PACK_SIZE )
1003
+ data = src.read_nonblock( PACK_SIZE )
1003
1004
  rescue IO::WaitReadable, Errno::EINTR
1004
1005
  return
1005
1006
  rescue Exception => e
@@ -1129,8 +1130,8 @@ module Girl
1129
1130
  puts "p#{ Process.pid } #{ Time.new } socks5 cmd #{ cmd } not implement"
1130
1131
  end
1131
1132
  when :tunnel
1132
- src_addr = src_info[ :src_addr ]
1133
- src_ext = @tun_info[ :src_exts ][ src_addr ]
1133
+ src_id = src_info[ :id ]
1134
+ src_ext = @tun_info[ :src_exts ][ src_id ]
1134
1135
 
1135
1136
  unless src_ext
1136
1137
  # puts "debug1 not found src ext"
@@ -1149,7 +1150,7 @@ module Girl
1149
1150
  data, _ = sub_http_request( data )
1150
1151
  end
1151
1152
 
1152
- add_tun_wbuff( src_addr, data )
1153
+ add_tun_wbuff( src_id, data )
1153
1154
  else
1154
1155
  # puts "debug1 remote dst not ready, save data to src rbuff"
1155
1156
  src_info[ :rbuffs ] << data
@@ -1181,7 +1182,7 @@ module Girl
1181
1182
  #
1182
1183
  def read_dst( dst )
1183
1184
  begin
1184
- data = dst.read_nonblock( PROXY_PACK_SIZE )
1185
+ data = dst.read_nonblock( PACK_SIZE )
1185
1186
  rescue IO::WaitReadable, Errno::EINTR
1186
1187
  return
1187
1188
  rescue Exception => e
@@ -1211,6 +1212,7 @@ module Girl
1211
1212
  data, addrinfo, rflags, *controls = tun.recvmsg
1212
1213
  from_addr = addrinfo.to_sockaddr
1213
1214
  now = Time.new
1215
+ @tun_info[ :last_recv_at ] = now
1214
1216
  pack_id = data[ 0, 8 ].unpack( 'Q>' ).first
1215
1217
 
1216
1218
  if pack_id == 0
@@ -1220,7 +1222,6 @@ module Girl
1220
1222
  when TUND_PORT
1221
1223
  return if ( from_addr != @proxyd_addr ) || @tun_info[ :tund_addr ]
1222
1224
 
1223
- @tun_info[ :last_recv_at ] = now
1224
1225
  tund_port = data[ 9, 2 ].unpack( 'n' ).first
1225
1226
 
1226
1227
  # puts "debug1 got tund port #{ tund_port }"
@@ -1236,18 +1237,15 @@ module Girl
1236
1237
  when PAIRED
1237
1238
  return if from_addr != @tun_info[ :tund_addr ]
1238
1239
 
1239
- src_addr = data[ 9, 16 ]
1240
- dst_port = data[ 25, 2 ].unpack( 'n' ).first
1240
+ src_id, dst_port = data[ 9, 10 ].unpack( 'Q>n' )
1241
1241
 
1242
- src_ext = @tun_info[ :src_exts ][ src_addr ]
1242
+ src_ext = @tun_info[ :src_exts ][ src_id ]
1243
1243
  return if src_ext.nil? || src_ext[ :dst_port ]
1244
1244
 
1245
1245
  src = src_ext[ :src ]
1246
1246
  return if src.closed?
1247
1247
 
1248
- @tun_info[ :last_recv_at ] = now
1249
-
1250
- # puts "debug1 got paired #{ Addrinfo.new( src_addr ).inspect } #{ dst_port }"
1248
+ # puts "debug1 got paired #{ src_id } #{ dst_port }"
1251
1249
 
1252
1250
  if dst_port == 0
1253
1251
  set_is_closing( src )
@@ -1255,7 +1253,7 @@ module Girl
1255
1253
  end
1256
1254
 
1257
1255
  src_ext[ :dst_port ] = dst_port
1258
- @tun_info[ :src_addrs ][ dst_port ] = src_addr
1256
+ @tun_info[ :src_ids ][ dst_port ] = src_id
1259
1257
 
1260
1258
  src_info = @src_infos[ src ]
1261
1259
 
@@ -1271,7 +1269,7 @@ module Girl
1271
1269
  # puts "debug1 add src rbuffs to tun wbuffs"
1272
1270
 
1273
1271
  datas.each do | _data |
1274
- add_tun_wbuff( src_addr, _data )
1272
+ add_tun_wbuff( src_id, _data )
1275
1273
  end
1276
1274
  end
1277
1275
  elsif src_info[ :proxy_proto ] == :socks5
@@ -1282,14 +1280,13 @@ module Girl
1282
1280
 
1283
1281
  dst_port, biggest_dst_pack_id, continue_src_pack_id = data[ 9, 18 ].unpack( 'nQ>Q>' )
1284
1282
 
1285
- src_addr = @tun_info[ :src_addrs ][ dst_port ]
1286
- return unless src_addr
1283
+ src_id = @tun_info[ :src_ids ][ dst_port ]
1284
+ return unless src_id
1287
1285
 
1288
- src_ext = @tun_info[ :src_exts ][ src_addr ]
1286
+ src_ext = @tun_info[ :src_exts ][ src_id ]
1289
1287
  return unless src_ext
1290
1288
 
1291
1289
  # puts "debug2 got dest status"
1292
- @tun_info[ :last_recv_at ] = now
1293
1290
 
1294
1291
  # 更新对面发到几
1295
1292
  if biggest_dst_pack_id > src_ext[ :biggest_dst_pack_id ]
@@ -1339,20 +1336,17 @@ module Girl
1339
1336
  when MISS
1340
1337
  return if from_addr != @tun_info[ :tund_addr ]
1341
1338
 
1342
- src_addr = data[ 9, 16 ]
1343
- pack_id_begin, pack_id_end = data[ 25, 16 ].unpack( 'Q>Q>' )
1339
+ src_id, pack_id_begin, pack_id_end = data[ 9, 24 ].unpack( 'Q>Q>Q>' )
1344
1340
 
1345
- src_ext = @tun_info[ :src_exts ][ src_addr ]
1341
+ src_ext = @tun_info[ :src_exts ][ src_id ]
1346
1342
  return unless src_ext
1347
1343
 
1348
- @tun_info[ :last_recv_at ] = now
1349
-
1350
1344
  ( pack_id_begin..pack_id_end ).each do | pack_id |
1351
1345
  send_at = src_ext[ :send_ats ][ pack_id ]
1352
1346
 
1353
1347
  if send_at
1354
1348
  break if now - send_at < STATUS_INTERVAL
1355
- @tun_info[ :resendings ] << [ src_addr, pack_id ]
1349
+ @tun_info[ :resendings ] << [ src_id, pack_id ]
1356
1350
  end
1357
1351
  end
1358
1352
 
@@ -1362,14 +1356,12 @@ module Girl
1362
1356
 
1363
1357
  dst_port, biggest_dst_pack_id, continue_src_pack_id = data[ 9, 18 ].unpack( 'nQ>Q>' )
1364
1358
 
1365
- src_addr = @tun_info[ :src_addrs ][ dst_port ]
1366
- return unless src_addr
1359
+ src_id = @tun_info[ :src_ids ][ dst_port ]
1360
+ return unless src_id
1367
1361
 
1368
- src_ext = @tun_info[ :src_exts ][ src_addr ]
1362
+ src_ext = @tun_info[ :src_exts ][ src_id ]
1369
1363
  return unless src_ext
1370
1364
 
1371
- @tun_info[ :last_recv_at ] = now
1372
-
1373
1365
  # puts "debug1 got fin1 #{ dst_port } biggest dst pack #{ biggest_dst_pack_id } completed src pack #{ continue_src_pack_id }"
1374
1366
  src_ext[ :is_dst_closed ] = true
1375
1367
  src_ext[ :biggest_dst_pack_id ] = biggest_dst_pack_id
@@ -1385,18 +1377,14 @@ module Girl
1385
1377
 
1386
1378
  dst_port = data[ 9, 2 ].unpack( 'n' ).first
1387
1379
 
1388
- src_addr = @tun_info[ :src_addrs ][ dst_port ]
1389
- return unless src_addr
1390
-
1391
- @tun_info[ :last_recv_at ] = now
1380
+ src_id = @tun_info[ :src_ids ][ dst_port ]
1381
+ return unless src_id
1392
1382
 
1393
1383
  # puts "debug1 1-2. recv fin2 -> del src ext"
1394
- del_src_ext( src_addr )
1384
+ del_src_ext( src_id )
1395
1385
  when TUND_FIN
1396
1386
  return if from_addr != @tun_info[ :tund_addr ]
1397
1387
 
1398
- @tun_info[ :last_recv_at ] = now
1399
-
1400
1388
  puts "p#{ Process.pid } #{ Time.new } recv tund fin"
1401
1389
  set_is_closing( tun )
1402
1390
  end
@@ -1408,15 +1396,13 @@ module Girl
1408
1396
 
1409
1397
  dst_port = data[ 8, 2 ].unpack( 'n' ).first
1410
1398
 
1411
- src_addr = @tun_info[ :src_addrs ][ dst_port ]
1412
- return unless src_addr
1399
+ src_id = @tun_info[ :src_ids ][ dst_port ]
1400
+ return unless src_id
1413
1401
 
1414
- src_ext = @tun_info[ :src_exts ][ src_addr ]
1402
+ src_ext = @tun_info[ :src_exts ][ src_id ]
1415
1403
  return if src_ext.nil? || src_ext[ :src ].closed?
1416
1404
  return if ( pack_id <= src_ext[ :continue_dst_pack_id ] ) || src_ext[ :pieces ].include?( pack_id )
1417
1405
 
1418
- @tun_info[ :last_recv_at ] = now
1419
-
1420
1406
  data = data[ 10..-1 ]
1421
1407
  # puts "debug2 got pack #{ pack_id }"
1422
1408
 
@@ -103,23 +103,27 @@ module Girl
103
103
  is_expired = tund_info[ :last_recv_at ] ? ( now - tund_info[ :last_recv_at ] > EXPIRE_AFTER ) : ( now - tund_info[ :created_at ] > EXPIRE_NEW )
104
104
 
105
105
  if is_expired
106
- puts "p#{ Process.pid } #{ Time.new } expire tund"
106
+ puts "p#{ Process.pid } #{ Time.new } expire tund #{ tund_info[ :port ] }"
107
107
  set_is_closing( tund )
108
- need_trigger = true
109
108
  else
109
+ data = [ 0, HEARTBEAT, rand( 128 ) ].pack( 'Q>CC' )
110
+ # puts "debug1 #{ Time.new } #{ tund_info[ :port ] } heartbeat"
111
+ add_tund_ctlmsg( tund, data )
112
+
110
113
  tund_info[ :dst_exts ].each do | dst_local_port, dst_ext |
111
114
  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 }"
115
+ puts "p#{ Process.pid } #{ Time.new } expire dst ext #{ dst_local_port }"
113
116
  del_dst_ext( tund, dst_local_port )
114
- need_trigger = true
115
117
  end
116
118
  end
117
119
  end
120
+
121
+ need_trigger = true
118
122
  end
119
123
  end
120
124
 
121
125
  @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 )
126
+ is_expired = dst_info[ :last_recv_at ].nil? && ( now - dst_info[ :created_at ] > EXPIRE_NEW )
123
127
 
124
128
  if is_expired
125
129
  puts "p#{ Process.pid } #{ Time.new } expire dst"
@@ -183,7 +187,7 @@ module Girl
183
187
  ##
184
188
  # resolve domain
185
189
  #
186
- def resolve_domain( tund, src_addr, destination_domain_port )
190
+ def resolve_domain( tund, src_id, destination_domain_port )
187
191
  resolv_cache = @resolv_caches[ destination_domain_port ]
188
192
 
189
193
  if resolv_cache
@@ -191,7 +195,7 @@ module Girl
191
195
 
192
196
  if Time.new - created_at < RESOLV_CACHE_EXPIRE
193
197
  # puts "debug1 #{ destination_domain_port } hit resolv cache #{ Addrinfo.new( destination_addr ).inspect }"
194
- deal_with_destination_addr( tund, src_addr, destination_addr )
198
+ deal_with_destination_addr( tund, src_id, destination_addr )
195
199
  return
196
200
  end
197
201
 
@@ -215,7 +219,7 @@ module Girl
215
219
  @resolv_caches[ destination_domain_port ] = [ destination_addr, Time.new ]
216
220
 
217
221
  unless tund.closed?
218
- if deal_with_destination_addr( tund, src_addr, destination_addr )
222
+ if deal_with_destination_addr( tund, src_id, destination_addr )
219
223
  next_tick
220
224
  end
221
225
  end
@@ -227,7 +231,7 @@ module Girl
227
231
  ##
228
232
  # deal with destination addr
229
233
  #
230
- def deal_with_destination_addr( tund, src_addr, destination_addr )
234
+ def deal_with_destination_addr( tund, src_id, destination_addr )
231
235
  dst = Socket.new( Socket::AF_INET, Socket::SOCK_STREAM, 0 )
232
236
  dst.setsockopt( Socket::SOL_TCP, Socket::TCP_NODELAY, 1 )
233
237
 
@@ -239,7 +243,7 @@ module Girl
239
243
  return false
240
244
  end
241
245
 
242
- local_port = dst.local_address.ip_unpack.last
246
+ local_port = dst.local_address.ip_port
243
247
 
244
248
  @dst_infos[ dst ] = {
245
249
  local_port: local_port, # 本地端口
@@ -255,10 +259,10 @@ module Girl
255
259
  add_read( dst, :dst )
256
260
 
257
261
  tund_info = @tund_infos[ tund ]
258
- tund_info[ :dst_local_ports ][ src_addr ] = local_port
262
+ tund_info[ :dst_local_ports ][ src_id ] = local_port
259
263
  tund_info[ :dst_exts ][ local_port ] = {
260
264
  dst: dst, # dst
261
- src_addr: src_addr, # 近端src地址
265
+ src_id: src_id, # 近端src id
262
266
  wmems: {}, # 写后 pack_id => data
263
267
  send_ats: {}, # 上一次发出时间 pack_id => send_at
264
268
  biggest_pack_id: 0, # 发到几
@@ -270,7 +274,7 @@ module Girl
270
274
  last_continue_at: Time.new # 创建,或者上一次收到连续流量,或者发出新包的时间
271
275
  }
272
276
 
273
- data = [ [ 0, PAIRED ].pack( 'Q>C' ), src_addr, [ local_port ].pack( 'n' ) ].join
277
+ data = [ 0, PAIRED, src_id, local_port ].pack( 'Q>CQ>n' )
274
278
  # puts "debug1 add ctlmsg paired #{ data.inspect }"
275
279
  add_tund_ctlmsg( tund, data )
276
280
 
@@ -344,7 +348,7 @@ module Girl
344
348
  dst_info = @dst_infos[ dst ]
345
349
  dst_info[ :wbuff ] << data
346
350
 
347
- if dst_info[ :wbuff ].bytesize >= PROXY_CHUNK_SIZE
351
+ if dst_info[ :wbuff ].bytesize >= CHUNK_SIZE
348
352
  spring = dst_info[ :chunks ].size > 0 ? ( dst_info[ :spring ] + 1 ) : 0
349
353
  filename = "#{ Process.pid }-#{ dst_info[ :local_port ] }.#{ spring }"
350
354
  chunk_path = File.join( @dst_chunk_dir, filename )
@@ -480,7 +484,7 @@ module Girl
480
484
  dst_ext = tund_info[ :dst_exts ].delete( dst_local_port )
481
485
 
482
486
  if dst_ext
483
- tund_info[ :dst_local_ports ].delete( dst_ext[ :src_addr ] )
487
+ tund_info[ :dst_local_ports ].delete( dst_ext[ :src_id ] )
484
488
  end
485
489
  end
486
490
 
@@ -724,7 +728,7 @@ module Girl
724
728
 
725
729
  tund = Socket.new( Socket::AF_INET, Socket::SOCK_DGRAM, 0 )
726
730
  tund.bind( Socket.sockaddr_in( 0, '0.0.0.0' ) )
727
- port = tund.local_address.ip_unpack.last
731
+ port = tund.local_address.ip_port
728
732
 
729
733
  @tunneling_tunds[ from_addr ] = tund
730
734
  @tunds[ port ] = tund
@@ -736,9 +740,8 @@ module Girl
736
740
  chunks: [], # 块队列 filename
737
741
  spring: 0, # 块后缀,结块时,如果块队列不为空,则自增,为空,则置为0
738
742
  tun_addr: from_addr, # tun地址
739
- is_tunneled: false, # 是否已和tun打通
740
743
  dst_exts: {}, # dst额外信息 dst_addr => {}
741
- dst_local_ports: {}, # src_addr => dst_local_port
744
+ dst_local_ports: {}, # src_id => dst_local_port
742
745
  paused: false, # 是否暂停写
743
746
  resendings: [], # 重传队列 [ dst_addr, pack_id ]
744
747
  created_at: Time.new, # 创建时间
@@ -758,7 +761,7 @@ module Girl
758
761
  #
759
762
  def read_dst( dst )
760
763
  begin
761
- data = dst.read_nonblock( PROXY_PACK_SIZE )
764
+ data = dst.read_nonblock( PACK_SIZE )
762
765
  rescue IO::WaitReadable, Errno::EINTR
763
766
  return
764
767
  rescue Exception => e
@@ -791,11 +794,16 @@ module Girl
791
794
  tund_info = @tund_infos[ tund ]
792
795
 
793
796
  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
797
+ if addrinfo.ip_port == Addrinfo.new( tund_info[ :tun_addr ] ).ip_port
798
+ puts "p#{ Process.pid } #{ Time.new } tun ip changed #{ addrinfo.inspect }"
799
+ tund_info[ :tun_addr ] = from_addr
800
+ else
801
+ puts "p#{ Process.pid } #{ Time.new } #{ addrinfo.inspect } not match #{ Addrinfo.new( tund_info[ :tun_addr ] ).inspect }"
802
+ return
803
+ end
796
804
  end
797
805
 
798
- tund_info[ :is_tunneled ] = true
806
+ tund_info[ :last_recv_at ] = now
799
807
  pack_id = data[ 0, 8 ].unpack( 'Q>' ).first
800
808
 
801
809
  if pack_id == 0
@@ -803,9 +811,9 @@ module Girl
803
811
 
804
812
  case ctl_num
805
813
  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 }"
814
+ src_id = data[ 9, 8 ].unpack( 'Q>' ).first
815
+ dst_local_port = tund_info[ :dst_local_ports ][ src_id ]
816
+ # puts "debug1 got a new source #{ src_id }"
809
817
 
810
818
  if dst_local_port
811
819
  dst_ext = tund_info[ :dst_exts ][ dst_local_port ]
@@ -816,29 +824,25 @@ module Girl
816
824
  end
817
825
 
818
826
  # puts "debug1 readd ctlmsg paired #{ dst_local_port }"
819
- data2 = [ [ 0, PAIRED ].pack( 'Q>C' ), src_addr, [ dst_local_port ].pack( 'n' ) ].join
827
+ data2 = [ 0, PAIRED, src_id, dst_local_port ].pack( 'Q>CQ>n' )
820
828
  add_tund_ctlmsg( tund, data2 )
821
829
  return
822
830
  end
823
831
 
824
- tund_info[ :last_recv_at ] = now
825
-
826
- data = data[ 25..-1 ]
832
+ data = data[ 17..-1 ]
827
833
  # puts "debug1 #{ data }"
828
834
  destination_domain_port = @custom.decode( data )
829
- resolve_domain( tund, src_addr, destination_domain_port )
835
+ resolve_domain( tund, src_id, destination_domain_port )
830
836
  when SOURCE_STATUS
831
- src_addr = data[ 9, 16 ]
832
- biggest_src_pack_id, continue_dst_pack_id = data[ 25, 16 ].unpack( 'Q>Q>' )
837
+ src_id, biggest_src_pack_id, continue_dst_pack_id = data[ 9, 24 ].unpack( 'Q>Q>Q>' )
833
838
 
834
- dst_local_port = tund_info[ :dst_local_ports ][ src_addr ]
839
+ dst_local_port = tund_info[ :dst_local_ports ][ src_id ]
835
840
  return unless dst_local_port
836
841
 
837
842
  dst_ext = tund_info[ :dst_exts ][ dst_local_port ]
838
843
  return unless dst_ext
839
844
 
840
845
  # puts "debug2 got source status"
841
- tund_info[ :last_recv_at ] = now
842
846
 
843
847
  # 更新对面发到几
844
848
  if biggest_src_pack_id > dst_ext[ :biggest_src_pack_id ]
@@ -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
@@ -891,8 +895,6 @@ module Girl
891
895
  dst_ext = tund_info[ :dst_exts ][ dst_local_port ]
892
896
  return unless dst_ext
893
897
 
894
- tund_info[ :last_recv_at ] = now
895
-
896
898
  ( pack_id_begin..pack_id_end ).each do | pack_id |
897
899
  send_at = dst_ext[ :send_ats ][ pack_id ]
898
900
 
@@ -904,18 +906,15 @@ module Girl
904
906
 
905
907
  add_write( tund )
906
908
  when FIN1
907
- src_addr = data[ 9, 16 ]
908
- biggest_src_pack_id, continue_dst_pack_id = data[ 25, 16 ].unpack( 'Q>Q>' )
909
+ src_id, biggest_src_pack_id, continue_dst_pack_id = data[ 9, 24 ].unpack( 'Q>Q>Q>' )
909
910
 
910
- dst_local_port = tund_info[ :dst_local_ports ][ src_addr ]
911
+ dst_local_port = tund_info[ :dst_local_ports ][ src_id ]
911
912
  return unless dst_local_port
912
913
 
913
914
  dst_ext = tund_info[ :dst_exts ][ dst_local_port ]
914
915
  return unless dst_ext
915
916
 
916
- tund_info[ :last_recv_at ] = now
917
-
918
- # puts "debug1 got fin1 #{ Addrinfo.new( src_addr ).inspect } biggest src pack #{ biggest_src_pack_id } completed dst pack #{ continue_dst_pack_id }"
917
+ # puts "debug1 got fin1 #{ src_id } biggest src pack #{ biggest_src_pack_id } completed dst pack #{ continue_dst_pack_id }"
919
918
  dst_ext[ :is_src_closed ] = true
920
919
  dst_ext[ :biggest_src_pack_id ] = biggest_src_pack_id
921
920
  release_wmems( dst_ext, continue_dst_pack_id )
@@ -926,36 +925,31 @@ module Girl
926
925
  set_is_closing( dst_ext[ :dst ] )
927
926
  end
928
927
  when FIN2
929
- src_addr = data[ 9, 16 ]
928
+ src_id = data[ 9, 8 ].unpack( 'Q>' ).first
930
929
 
931
- dst_local_port = tund_info[ :dst_local_ports ][ src_addr ]
930
+ dst_local_port = tund_info[ :dst_local_ports ][ src_id ]
932
931
  return unless dst_local_port
933
932
 
934
- tund_info[ :last_recv_at ] = now
935
-
936
933
  # puts "debug1 1-2. recv fin2 -> del dst ext"
937
934
  del_dst_ext( tund, dst_local_port )
938
935
  when TUN_FIN
939
936
  puts "p#{ Process.pid } #{ Time.new } recv tun fin"
940
- tund_info[ :last_recv_at ] = now
941
937
  set_is_closing( tund )
942
938
  end
943
939
 
944
940
  return
945
941
  end
946
942
 
947
- src_addr = data[ 8, 16 ]
943
+ src_id = data[ 8, 8 ].unpack( 'Q>' ).first
948
944
 
949
- dst_local_port = tund_info[ :dst_local_ports ][ src_addr ]
945
+ dst_local_port = tund_info[ :dst_local_ports ][ src_id ]
950
946
  return unless dst_local_port
951
947
 
952
948
  dst_ext = tund_info[ :dst_exts ][ dst_local_port ]
953
949
  return if dst_ext.nil? || dst_ext[ :dst ].closed?
954
950
  return if ( pack_id <= dst_ext[ :continue_src_pack_id ] ) || dst_ext[ :pieces ].include?( pack_id )
955
951
 
956
- tund_info[ :last_recv_at ] = now
957
-
958
- data = data[ 24..-1 ]
952
+ data = data[ 16..-1 ]
959
953
  # puts "debug2 got pack #{ pack_id }"
960
954
 
961
955
  if pack_id <= CONFUSE_UNTIL
@@ -1,3 +1,3 @@
1
1
  module Girl
2
- VERSION = '0.62.0'.freeze
2
+ VERSION = '0.66.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.62.0
4
+ version: 0.66.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-06-09 00:00:00.000000000 Z
11
+ date: 2020-06-26 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: while internet is evil, here's a girl.
14
14
  email: