girl 0.66.0 → 0.71.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: 1b2ece41d566cc27562dff36a48b1c53c53000390587b5e424bc38e78636e74c
4
- data.tar.gz: c3d80d9b98804d0f1f37cf479052fc5c68b7cf907c800813cf3dd0d9a1691855
3
+ metadata.gz: 5a29bed71df8f50ac316ebd9819b0e32134324700d01752dd7027ed91e51dc35
4
+ data.tar.gz: 63dca91494dd3680caa7364db5b6b22c205fa6cc4a55a23d497ec0489f8c1234
5
5
  SHA512:
6
- metadata.gz: c2c0d92f7dbd582f04a8d49e5285d863e790070a3ffd2c08313695f66388df436fa59441b9fef992600e1611a39053ea3df8b3f453004e2bcbc0ad126c4e257e
7
- data.tar.gz: e4baabb1843d03f27101e43407927febdf0dd3a1917a30ae017297c75cb5336a32f1fb033bc484ffc0f6cf053a4b3ea63ed8726b4aece5ae662bd72767ff730d
6
+ metadata.gz: 3ce8f9e01aea05d29e5bd8fb91f027eca72ec3f992da8ad767a9845c52ad9e4727bf70ed1408cef2f2a71cf92ce3265564c7789fc95d76c793d8172d0a0da53a
7
+ data.tar.gz: 0f5ee9f741065b75f2de0aa9f2ee68cc4e462a5aaffe1f7e9418028a629cf2dd0b116a07b8b6481898dcd3907e691f9bda0f7a88e4d0a2095fb6ffbbc36b0f09
@@ -19,17 +19,12 @@ girl.gemspec
19
19
  lib/girl.rb
20
20
  lib/girl/custom.rb
21
21
  lib/girl/head.rb
22
- lib/girl/hex.rb
23
22
  lib/girl/proxy_custom.rb
24
23
  lib/girl/proxy_worker.rb
25
24
  lib/girl/proxy.rb
26
25
  lib/girl/proxyd_custom.rb
27
26
  lib/girl/proxyd_worker.rb
28
27
  lib/girl/proxyd.rb
29
- lib/girl/resolv.rb
30
- lib/girl/resolvd.rb
31
- lib/girl/tun.rb
32
- lib/girl/tund.rb
33
28
  lib/girl/udp.rb
34
29
  lib/girl/udpd.rb
35
30
  lib/girl/version.rb
@@ -7,7 +7,6 @@ module Girl
7
7
  EXPIRE_NEW = 10 # 创建之后多久没有流量进来,过期
8
8
  EXPIRE_AFTER = 300 # 多久没有新流量,过期
9
9
  CHECK_EXPIRE_INTERVAL = 30 # 检查过期间隔
10
- HEARTBEAT_INTERVAL = 30 # 心跳间隔
11
10
  STATUS_INTERVAL = 0.5 # 发送状态间隔
12
11
  SEND_STATUS_UNTIL = 10 # 持续的告之对面状态,直到没有流量往来,持续多少秒
13
12
  BREAK_SEND_MISS = 10_000 # miss包个数上限,达到上限忽略要后面的段,可控碎片缓存
@@ -26,8 +25,6 @@ module Girl
26
25
  GOT_FIN2 = 11
27
26
  TUND_FIN = 12
28
27
  TUN_FIN = 13
29
- CTL_CLOSE = 1
30
- CTL_RESUME = 2
31
28
  HTTP_OK = "HTTP/1.1 200 OK\r\n\r\n"
32
29
  # https://www.iana.org/assignments/iana-ipv4-special-registry/iana-ipv4-special-registry.xhtml
33
30
  RESERVED_ROUTE = <<EOF
@@ -24,28 +24,36 @@ require 'socket'
24
24
  # tun-tund:
25
25
  #
26
26
  # Q>: 0 ctlmsg -> C: 2 heartbeat -> C: random char
27
- # 3 a new src -> Q>: src_id -> encoded destination address
28
- # 4 paired -> Q>: src_id -> n: dst_port
29
- # 5 dst status -> n: dst_port -> Q>Q>: 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
27
+ # 3 a new src -> Q>: src id -> encoded destination address
28
+ # 4 paired -> Q>: src id -> n: dst port
29
+ # 5 dst status -> n: dst port -> Q>: biggest relayed dst pack id -> Q>: continue src pack id
30
+ # 6 src status -> Q>: src id -> Q>: biggest relayed src pack id -> Q>: continue dst pack id
31
+ # 7 miss -> Q>/n: src id / dst port -> Q>: pack id begin -> Q>: pack id end
32
+ # 8 fin1 -> Q>/n: src id / dst port -> Q>: biggest src pack id / biggest dst pack id -> Q>: continue dst pack id / continue src pack id
33
33
  # 9 not use
34
- # 10 fin2 -> Q>: src_id/n: dst_port
34
+ # 10 fin2 -> Q>/n: src id / dst port
35
35
  # 11 not use
36
36
  # 12 tund fin
37
37
  # 13 tun fin
38
38
  #
39
- # Q>: 1+ pack_id -> Q>: src_id/n: dst_port -> traffic
39
+ # Q>: 1+ pack_id -> Q>/n: src id / dst port -> traffic
40
40
  #
41
41
  # close logic
42
42
  # ===========
43
43
  #
44
44
  # 1-1. after close src -> dst closed ? no -> send fin1
45
- # 1-2. recv fin2 -> del src ext
45
+ # 1-2. tun recv fin2 -> del src ext
46
46
  #
47
- # 2-1. recv traffic/fin1/dst status -> dst closed and all traffic received ? -> close src after write
48
- # 2-2. after close src -> dst closed ? yes -> del src ext -> send fin2
47
+ # 2-1. tun recv fin1 -> all traffic received ? -> close src after write
48
+ # 2-2. tun recv traffic -> dst closed and all traffic received ? -> close src after write
49
+ # 2-3. after close src -> dst closed ? yes -> del src ext -> send fin2
50
+ #
51
+ # 3-1. after close dst -> src closed ? no -> send fin1
52
+ # 3-2. tund recv fin2 -> del dst ext
53
+ #
54
+ # 4-1. tund recv fin1 -> all traffic received ? -> close dst after write
55
+ # 4-2. tund recv traffic -> src closed and all traffic received ? -> close dst after write
56
+ # 4-3. after close dst -> src closed ? yes -> del dst ext -> send fin2
49
57
  #
50
58
  module Girl
51
59
  class Proxy
@@ -168,8 +168,7 @@ module Girl
168
168
 
169
169
  @tun_info[ :src_exts ].each do | src_id, src_ext |
170
170
  if src_ext[ :dst_port ] && ( now - src_ext[ :last_continue_at ] < SEND_STATUS_UNTIL )
171
- # puts "debug2 ctl send status biggest #{ src_ext[ :biggest_pack_id ] } continue dst #{ src_ext[ :continue_dst_pack_id ] }"
172
- data = [ 0, SOURCE_STATUS, src_id, src_ext[ :biggest_pack_id ], src_ext[ :continue_dst_pack_id ] ].pack( 'Q>CQ>Q>Q>' )
171
+ data = [ 0, SOURCE_STATUS, src_id, src_ext[ :relay_pack_id ], src_ext[ :continue_dst_pack_id ] ].pack( 'Q>CQ>Q>Q>' )
173
172
  add_tun_ctlmsg( data )
174
173
  need_trigger = true
175
174
  end
@@ -317,8 +316,8 @@ module Girl
317
316
  port: port, # 端口
318
317
  ctlmsg_rbuffs: [], # 还没配上tund,暂存的ctlmsg
319
318
  ctlmsgs: [], # [ to_addr, data ]
320
- wbuffs: [], # 写前缓存 [ src_id, data ]
321
- caches: [], # 块读出缓存 [ src_id, data ]
319
+ wbuffs: [], # 写前缓存 [ src_id, pack_id, data ]
320
+ caches: [], # 块读出缓存 [ src_id, pack_id, data ]
322
321
  chunks: [], # 块队列 filename
323
322
  spring: 0, # 块后缀,结块时,如果块队列不为空,则自增,为空,则置为0
324
323
  tund_addr: nil, # tund地址
@@ -383,9 +382,7 @@ module Girl
383
382
  src_info[ :dst ] = dst
384
383
 
385
384
  if src_info[ :proxy_proto ] == :http
386
- datas = src_info[ :rbuffs ]
387
-
388
- if datas.empty?
385
+ if src_info[ :is_connect ]
389
386
  # CONNECT
390
387
  # puts "debug1 add src wbuff http ok"
391
388
  add_src_wbuff( src, HTTP_OK )
@@ -393,7 +390,7 @@ module Girl
393
390
  # not CONNECT
394
391
  # puts "debug1 add src rbuffs to dst wbuff"
395
392
 
396
- datas.each do | data |
393
+ src_info[ :rbuffs ].each do | _, data |
397
394
  add_dst_wbuff( dst, data )
398
395
  end
399
396
  end
@@ -415,11 +412,11 @@ module Girl
415
412
  dst_port: nil, # 远端dst端口
416
413
  wmems: {}, # 写后 pack_id => data
417
414
  send_ats: {}, # 上一次发出时间 pack_id => send_at
418
- biggest_pack_id: 0, # 发到几
415
+ relay_pack_id: 0, # 转发到几
419
416
  continue_dst_pack_id: 0, # 收到几
420
417
  pieces: {}, # 跳号包 dst_pack_id => data
421
- is_dst_closed: false, # 对面是否已关闭
422
- biggest_dst_pack_id: 0, # 对面发到几
418
+ is_dst_closed: false, # dst是否已关闭
419
+ biggest_dst_pack_id: 0, # dst最大包号码
423
420
  completed_pack_id: 0, # 完成到几(对面收到几)
424
421
  last_continue_at: Time.new # 创建,或者上一次收到连续流量,或者发出新包的时间
425
422
  }
@@ -491,17 +488,17 @@ module Girl
491
488
  ##
492
489
  # add tun wbuff
493
490
  #
494
- def add_tun_wbuff( src_id, data )
495
- @tun_info[ :wbuffs ] << [ src_id, data ]
491
+ def add_tun_wbuff( src_id, pack_id, data )
492
+ @tun_info[ :wbuffs ] << [ src_id, pack_id, data ]
496
493
 
497
494
  if @tun_info[ :wbuffs ].size >= WBUFFS_LIMIT
498
495
  spring = @tun_info[ :chunks ].size > 0 ? ( @tun_info[ :spring ] + 1 ) : 0
499
496
  filename = "#{ Process.pid }-#{ @tun_info[ :port ] }.#{ spring }"
500
497
  chunk_path = File.join( @tun_chunk_dir, filename )
501
- wbuffs = @tun_info[ :wbuffs ].map{ | _src_id, _data | [ [ _src_id, _data.bytesize ].pack( 'Q>n' ), _data ].join }
498
+ datas = @tun_info[ :wbuffs ].map{ | _src_id, _pack_id, _data | [ [ _src_id, _pack_id, _data.bytesize ].pack( 'Q>Q>n' ), _data ].join }
502
499
 
503
500
  begin
504
- IO.binwrite( chunk_path, wbuffs.join )
501
+ IO.binwrite( chunk_path, datas.join )
505
502
  rescue Errno::ENOSPC => e
506
503
  puts "p#{ Process.pid } #{ Time.new } #{ e.class }, close tun"
507
504
  set_is_closing( @tun )
@@ -587,7 +584,7 @@ module Girl
587
584
  # add write
588
585
  #
589
586
  def add_write( sock )
590
- unless @writes.include?( sock )
587
+ if sock && !sock.closed? && !@writes.include?( sock )
591
588
  @writes << sock
592
589
  end
593
590
  end
@@ -640,13 +637,13 @@ module Girl
640
637
  return if src_ext.nil? || src_ext[ :dst_port ].nil?
641
638
 
642
639
  if src_ext[ :is_dst_closed ]
643
- # puts "debug1 2-2. after close src -> dst closed ? yes -> del src ext -> send fin2"
640
+ # puts "debug1 2-3. after close src -> dst closed ? yes -> del src ext -> send fin2"
644
641
  del_src_ext( src_id )
645
642
  data = [ 0, FIN2, src_id ].pack( 'Q>CQ>' )
646
643
  add_tun_ctlmsg( data )
647
644
  else
648
645
  # puts "debug1 1-1. after close src -> dst closed ? no -> send fin1"
649
- data = [ 0, FIN1, src_id, src_ext[ :biggest_pack_id ], src_ext[ :continue_dst_pack_id ] ].pack( 'Q>CQ>Q>Q>' )
646
+ data = [ 0, FIN1, src_id, src_info[ :biggest_pack_id ], src_ext[ :continue_dst_pack_id ] ].pack( 'Q>CQ>Q>Q>' )
650
647
  add_tun_ctlmsg( data )
651
648
  end
652
649
  elsif src_info[ :proxy_type ] == :direct
@@ -894,7 +891,7 @@ module Girl
894
891
 
895
892
  # 取写前
896
893
  if @tun_info[ :caches ].any?
897
- src_id, data = @tun_info[ :caches ].first
894
+ src_id, pack_id, data = @tun_info[ :caches ].first
898
895
  from = :caches
899
896
  elsif @tun_info[ :chunks ].any?
900
897
  path = File.join( @tun_chunk_dir, @tun_info[ :chunks ].shift )
@@ -911,16 +908,16 @@ module Girl
911
908
  caches = []
912
909
 
913
910
  until data.empty?
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 ]
911
+ _src_id, _pack_id, pack_size = data[ 0, 18 ].unpack( 'Q>Q>n' )
912
+ caches << [ _src_id, _pack_id, data[ 18, pack_size ] ]
913
+ data = data[ ( 18 + pack_size )..-1 ]
917
914
  end
918
915
 
919
916
  @tun_info[ :caches ] = caches
920
- src_id, data = caches.first
917
+ src_id, pack_id, data = caches.first
921
918
  from = :caches
922
919
  elsif @tun_info[ :wbuffs ].any?
923
- src_id, data = @tun_info[ :wbuffs ].first
920
+ src_id, pack_id, data = @tun_info[ :wbuffs ].first
924
921
  from = :wbuffs
925
922
  else
926
923
  @writes.delete( tun )
@@ -930,8 +927,6 @@ module Girl
930
927
  src_ext = @tun_info[ :src_exts ][ src_id ]
931
928
 
932
929
  if src_ext
933
- pack_id = src_ext[ :biggest_pack_id ] + 1
934
-
935
930
  if pack_id <= CONFUSE_UNTIL
936
931
  data = @custom.encode( data )
937
932
  # puts "debug1 encoded pack #{ pack_id }"
@@ -946,7 +941,7 @@ module Girl
946
941
  end
947
942
 
948
943
  # puts "debug2 written pack #{ pack_id }"
949
- src_ext[ :biggest_pack_id ] = pack_id
944
+ src_ext[ :relay_pack_id ] = pack_id
950
945
  src_ext[ :wmems ][ pack_id ] = data
951
946
  src_ext[ :send_ats ][ pack_id ] = now
952
947
  src_ext[ :last_continue_at ] = now
@@ -982,7 +977,9 @@ module Girl
982
977
  dst: nil, # :direct的场合,对应的dst
983
978
  destination_domain: nil, # 目的地域名
984
979
  destination_port: nil, # 目的地端口
985
- rbuffs: [], # 非CONNECT,dst或者远端dst未准备好,暂存流量
980
+ biggest_pack_id: 0, # 最大包号码
981
+ is_connect: true, # 代理协议是http的场合,是否是CONNECT
982
+ rbuffs: [], # 非CONNECT,dst或者远端dst未准备好,暂存流量 [ pack_id, data ]
986
983
  wbuff: '', # 写前
987
984
  cache: '', # 块读出缓存
988
985
  chunks: [], # 块队列,写前达到块大小时结一个块 filename
@@ -1079,7 +1076,10 @@ module Girl
1079
1076
  end
1080
1077
  end
1081
1078
 
1082
- src_info[ :rbuffs ] << data
1079
+ src_info[ :is_connect ] = false
1080
+ pack_id = src_info[ :biggest_pack_id ] + 1
1081
+ src_info[ :biggest_pack_id ] = pack_id
1082
+ src_info[ :rbuffs ] << [ pack_id, data ]
1083
1083
  end
1084
1084
 
1085
1085
  domain, port = domain_and_port.split( ':' )
@@ -1092,7 +1092,9 @@ module Girl
1092
1092
  resolve_domain( src, domain )
1093
1093
  when :checking
1094
1094
  # puts "debug1 add src rbuff while checking #{ data.inspect }"
1095
- src_info[ :rbuffs ] << data
1095
+ pack_id = src_info[ :biggest_pack_id ] + 1
1096
+ src_info[ :biggest_pack_id ] = pack_id
1097
+ src_info[ :rbuffs ] << [ pack_id, data ]
1096
1098
  when :negotiation
1097
1099
  # +----+-----+-------+------+----------+----------+
1098
1100
  # |VER | CMD | RSV | ATYP | DST.ADDR | DST.PORT |
@@ -1139,6 +1141,9 @@ module Girl
1139
1141
  return
1140
1142
  end
1141
1143
 
1144
+ pack_id = src_info[ :biggest_pack_id ] + 1
1145
+ src_info[ :biggest_pack_id ] = pack_id
1146
+
1142
1147
  if src_ext[ :dst_port ]
1143
1148
  if @tun.closed?
1144
1149
  # puts "debug1 tun closed, close src"
@@ -1146,14 +1151,14 @@ module Girl
1146
1151
  return
1147
1152
  end
1148
1153
 
1149
- if src_info[ :rbuffs ].any?
1154
+ unless src_info[ :is_connect ]
1150
1155
  data, _ = sub_http_request( data )
1151
1156
  end
1152
1157
 
1153
- add_tun_wbuff( src_id, data )
1158
+ add_tun_wbuff( src_id, pack_id, data )
1154
1159
  else
1155
1160
  # puts "debug1 remote dst not ready, save data to src rbuff"
1156
- src_info[ :rbuffs ] << data
1161
+ src_info[ :rbuffs ] << [ pack_id, data ]
1157
1162
  end
1158
1163
  when :direct
1159
1164
  dst = src_info[ :dst ]
@@ -1165,14 +1170,14 @@ module Girl
1165
1170
  return
1166
1171
  end
1167
1172
 
1168
- if src_info[ :rbuffs ].any?
1173
+ unless src_info[ :is_connect ]
1169
1174
  data, _ = sub_http_request( data )
1170
1175
  end
1171
1176
 
1172
1177
  add_dst_wbuff( dst, data )
1173
1178
  else
1174
1179
  # puts "debug1 dst not ready, save data to src rbuff"
1175
- src_info[ :rbuffs ] << data
1180
+ src_info[ :rbuffs ] << [ nil, data ]
1176
1181
  end
1177
1182
  end
1178
1183
  end
@@ -1258,9 +1263,7 @@ module Girl
1258
1263
  src_info = @src_infos[ src ]
1259
1264
 
1260
1265
  if src_info[ :proxy_proto ] == :http
1261
- datas = src_info[ :rbuffs ]
1262
-
1263
- if datas.empty?
1266
+ if src_info[ :is_connect ]
1264
1267
  # CONNECT
1265
1268
  # puts "debug1 add src wbuff http ok"
1266
1269
  add_src_wbuff( src, HTTP_OK )
@@ -1268,8 +1271,8 @@ module Girl
1268
1271
  # not CONNECT
1269
1272
  # puts "debug1 add src rbuffs to tun wbuffs"
1270
1273
 
1271
- datas.each do | _data |
1272
- add_tun_wbuff( src_id, _data )
1274
+ src_info[ :rbuffs ].each do | pack_id, _data |
1275
+ add_tun_wbuff( src_id, pack_id, _data )
1273
1276
  end
1274
1277
  end
1275
1278
  elsif src_info[ :proxy_proto ] == :socks5
@@ -1278,7 +1281,7 @@ module Girl
1278
1281
  when DEST_STATUS
1279
1282
  return if from_addr != @tun_info[ :tund_addr ]
1280
1283
 
1281
- dst_port, biggest_dst_pack_id, continue_src_pack_id = data[ 9, 18 ].unpack( 'nQ>Q>' )
1284
+ dst_port, relay_dst_pack_id, continue_src_pack_id = data[ 9, 18 ].unpack( 'nQ>Q>' )
1282
1285
 
1283
1286
  src_id = @tun_info[ :src_ids ][ dst_port ]
1284
1287
  return unless src_id
@@ -1288,22 +1291,10 @@ module Girl
1288
1291
 
1289
1292
  # puts "debug2 got dest status"
1290
1293
 
1291
- # 更新对面发到几
1292
- if biggest_dst_pack_id > src_ext[ :biggest_dst_pack_id ]
1293
- # puts "debug2 update biggest dst pack #{ biggest_dst_pack_id }"
1294
- src_ext[ :biggest_dst_pack_id ] = biggest_dst_pack_id
1295
-
1296
- # 接到对面状态,若对面已关闭,且最后一个包已经进写前,关闭src
1297
- if src_ext[ :is_dst_closed ] && ( biggest_dst_pack_id == src_ext[ :continue_dst_pack_id ] )
1298
- # puts "debug1 2-1. recv traffic/fin1/dst status -> dst closed and all traffic received ? -> close src after write"
1299
- set_is_closing( src_ext[ :src ] )
1300
- end
1301
- end
1302
-
1303
1294
  release_wmems( src_ext, continue_src_pack_id )
1304
1295
 
1305
1296
  # 发miss
1306
- if !src_ext[ :src ].closed? && ( src_ext[ :continue_dst_pack_id ] < src_ext[ :biggest_dst_pack_id ] )
1297
+ if !src_ext[ :src ].closed? && ( src_ext[ :continue_dst_pack_id ] < relay_dst_pack_id )
1307
1298
  ranges = []
1308
1299
  curr_pack_id = src_ext[ :continue_dst_pack_id ] + 1
1309
1300
 
@@ -1315,12 +1306,12 @@ module Girl
1315
1306
  curr_pack_id = pack_id + 1
1316
1307
  end
1317
1308
 
1318
- if curr_pack_id <= src_ext[ :biggest_dst_pack_id ]
1319
- ranges << [ curr_pack_id, src_ext[ :biggest_dst_pack_id ] ]
1309
+ if curr_pack_id <= relay_dst_pack_id
1310
+ ranges << [ curr_pack_id, relay_dst_pack_id ]
1320
1311
  end
1321
1312
 
1322
1313
  pack_count = 0
1323
- # puts "debug1 continue/biggest #{ src_ext[ :continue_dst_pack_id ] }/#{ src_ext[ :biggest_dst_pack_id ] } send MISS #{ ranges.size }"
1314
+ # puts "debug1 continue/relay #{ src_ext[ :continue_dst_pack_id ] }/#{ relay_dst_pack_id } send MISS #{ ranges.size }"
1324
1315
 
1325
1316
  ranges.each do | pack_id_begin, pack_id_end |
1326
1317
  if pack_count >= BREAK_SEND_MISS
@@ -1369,7 +1360,7 @@ module Girl
1369
1360
 
1370
1361
  # 接到对面已关闭,若最后一个包已经进写前,关闭src
1371
1362
  if ( biggest_dst_pack_id == src_ext[ :continue_dst_pack_id ] )
1372
- # puts "debug1 2-1. recv fin1 -> set dst closed -> all traffic received ? -> close src after write"
1363
+ # puts "debug1 2-1. tun recv fin1 -> all traffic received ? -> close src after write"
1373
1364
  set_is_closing( src_ext[ :src ] )
1374
1365
  end
1375
1366
  when FIN2
@@ -1380,7 +1371,7 @@ module Girl
1380
1371
  src_id = @tun_info[ :src_ids ][ dst_port ]
1381
1372
  return unless src_id
1382
1373
 
1383
- # puts "debug1 1-2. recv fin2 -> del src ext"
1374
+ # puts "debug1 1-2. tun recv fin2 -> del src ext"
1384
1375
  del_src_ext( src_id )
1385
1376
  when TUND_FIN
1386
1377
  return if from_addr != @tun_info[ :tund_addr ]
@@ -1426,7 +1417,7 @@ module Girl
1426
1417
 
1427
1418
  # 接到流量,若对面已关闭,且流量正好收全,关闭src
1428
1419
  if src_ext[ :is_dst_closed ] && ( pack_id == src_ext[ :biggest_dst_pack_id ] )
1429
- # puts "debug1 2-1. recv traffic/fin1/dst status -> dst closed and all traffic received ? -> close src after write"
1420
+ # puts "debug1 2-2. tun recv traffic -> dst closed and all traffic received ? -> close src after write"
1430
1421
  set_is_closing( src_ext[ :src ] )
1431
1422
  end
1432
1423
  else
@@ -9,15 +9,6 @@ require 'socket'
9
9
  ##
10
10
  # Girl::Proxyd - 代理服务,远端。
11
11
  #
12
- # close logic
13
- # ===========
14
- #
15
- # 1-1. after close dst -> src closed ? no -> send fin1
16
- # 1-2. recv fin2 -> del dst ext
17
- #
18
- # 2-1. recv traffic/fin1/src status -> src closed and all traffic received ? -> close dst after write
19
- # 2-2. after close dst -> src closed ? yes -> del dst ext -> send fin2
20
- #
21
12
  module Girl
22
13
  class Proxyd
23
14
 
@@ -160,7 +160,7 @@ module Girl
160
160
 
161
161
  tund_info[ :dst_exts ].each do | dst_local_port, dst_ext |
162
162
  if now - dst_ext[ :last_continue_at ] < SEND_STATUS_UNTIL
163
- data = [ 0, DEST_STATUS, dst_local_port, dst_ext[ :biggest_pack_id ], dst_ext[ :continue_src_pack_id ] ].pack( 'Q>CnQ>Q>' )
163
+ data = [ 0, DEST_STATUS, dst_local_port, dst_ext[ :relay_pack_id ], dst_ext[ :continue_src_pack_id ] ].pack( 'Q>CnQ>Q>' )
164
164
  add_tund_ctlmsg( tund, data )
165
165
  need_trigger = true
166
166
  end
@@ -248,6 +248,7 @@ module Girl
248
248
  @dst_infos[ dst ] = {
249
249
  local_port: local_port, # 本地端口
250
250
  tund: tund, # 对应tund
251
+ biggest_pack_id: 0, # 最大包号码
251
252
  wbuff: '', # 写前
252
253
  cache: '', # 块读出缓存
253
254
  chunks: [], # 块队列,写前达到块大小时结一个块 filename
@@ -265,11 +266,11 @@ module Girl
265
266
  src_id: src_id, # 近端src id
266
267
  wmems: {}, # 写后 pack_id => data
267
268
  send_ats: {}, # 上一次发出时间 pack_id => send_at
268
- biggest_pack_id: 0, # 发到几
269
+ relay_pack_id: 0, # 转发到几
269
270
  continue_src_pack_id: 0, # 收到几
270
271
  pieces: {}, # 跳号包 src_pack_id => data
271
- is_src_closed: false, # 对面是否已关闭
272
- biggest_src_pack_id: 0, # 对面发到几
272
+ is_src_closed: false, # src是否已关闭
273
+ biggest_src_pack_id: 0, # src最大包号码
273
274
  completed_pack_id: 0, # 完成到几(对面收到几)
274
275
  last_continue_at: Time.new # 创建,或者上一次收到连续流量,或者发出新包的时间
275
276
  }
@@ -315,18 +316,18 @@ module Girl
315
316
  ##
316
317
  # add tund wbuff
317
318
  #
318
- def add_tund_wbuff( tund, dst_local_port, data )
319
+ def add_tund_wbuff( tund, dst_local_port, pack_id, data )
319
320
  tund_info = @tund_infos[ tund ]
320
- tund_info[ :wbuffs ] << [ dst_local_port, data ]
321
+ tund_info[ :wbuffs ] << [ dst_local_port, pack_id, data ]
321
322
 
322
323
  if tund_info[ :wbuffs ].size >= WBUFFS_LIMIT
323
324
  spring = tund_info[ :chunks ].size > 0 ? ( tund_info[ :spring ] + 1 ) : 0
324
325
  filename = "#{ Process.pid }-#{ tund_info[ :port ] }.#{ spring }"
325
326
  chunk_path = File.join( @tund_chunk_dir, filename )
326
- wbuffs = tund_info[ :wbuffs ].map{ | _dst_local_port, _data | [ [ _dst_local_port, _data.bytesize ].pack( 'nn' ), _data ].join }
327
+ datas = tund_info[ :wbuffs ].map{ | _dst_local_port, _pack_id, _data | [ [ _dst_local_port, _pack_id, _data.bytesize ].pack( 'nQ>n' ), _data ].join }
327
328
 
328
329
  begin
329
- IO.binwrite( chunk_path, wbuffs.join )
330
+ IO.binwrite( chunk_path, datas.join )
330
331
  rescue Errno::ENOSPC => e
331
332
  puts "p#{ Process.pid } #{ Time.new } #{ e.class }, close tund"
332
333
  set_is_closing( tund )
@@ -384,7 +385,7 @@ module Girl
384
385
  # add write
385
386
  #
386
387
  def add_write( sock )
387
- unless @writes.include?( sock )
388
+ if sock && !sock.closed? && !@writes.include?( sock )
388
389
  @writes << sock
389
390
  end
390
391
  end
@@ -435,13 +436,13 @@ module Girl
435
436
  return unless dst_ext
436
437
 
437
438
  if dst_ext[ :is_src_closed ]
438
- # puts "debug1 2-2. after close dst -> src closed ? yes -> del dst ext -> send fin2"
439
+ # puts "debug1 4-3. after close dst -> src closed ? yes -> del dst ext -> send fin2"
439
440
  del_dst_ext( tund, local_port )
440
441
  data = [ 0, FIN2, local_port ].pack( 'Q>Cn' )
441
442
  add_tund_ctlmsg( tund, data )
442
443
  else
443
- # puts "debug1 1-1. after close dst -> src closed ? no -> send fin1"
444
- data = [ 0, FIN1, local_port, dst_ext[ :biggest_pack_id ], dst_ext[ :continue_src_pack_id ] ].pack( 'Q>CnQ>Q>' )
444
+ # puts "debug1 3-1. after close dst -> src closed ? no -> send fin1"
445
+ data = [ 0, FIN1, local_port, dst_info[ :biggest_pack_id ], dst_ext[ :continue_src_pack_id ] ].pack( 'Q>CnQ>Q>' )
445
446
  add_tund_ctlmsg( tund, data )
446
447
  end
447
448
  end
@@ -641,7 +642,7 @@ module Girl
641
642
 
642
643
  # 取写前
643
644
  if tund_info[ :caches ].any?
644
- dst_local_port, data = tund_info[ :caches ].first
645
+ dst_local_port, pack_id, data = tund_info[ :caches ].first
645
646
  from = :caches
646
647
  elsif tund_info[ :chunks ].any?
647
648
  path = File.join( @tund_chunk_dir, tund_info[ :chunks ].shift )
@@ -658,16 +659,16 @@ module Girl
658
659
  caches = []
659
660
 
660
661
  until data.empty?
661
- _dst_local_port, pack_size = data[ 0, 4 ].unpack( 'nn' )
662
- caches << [ _dst_local_port, data[ 4, pack_size ] ]
663
- data = data[ ( 4 + pack_size )..-1 ]
662
+ _dst_local_port, _pack_id, pack_size = data[ 0, 12 ].unpack( 'nQ>n' )
663
+ caches << [ _dst_local_port, _pack_id, data[ 12, pack_size ] ]
664
+ data = data[ ( 12 + pack_size )..-1 ]
664
665
  end
665
666
 
666
667
  tund_info[ :caches ] = caches
667
- dst_local_port, data = caches.first
668
+ dst_local_port, pack_id, data = caches.first
668
669
  from = :caches
669
670
  elsif tund_info[ :wbuffs ].any?
670
- dst_local_port, data = tund_info[ :wbuffs ].first
671
+ dst_local_port, pack_id, data = tund_info[ :wbuffs ].first
671
672
  from = :wbuffs
672
673
  else
673
674
  @writes.delete( tund )
@@ -677,8 +678,6 @@ module Girl
677
678
  dst_ext = tund_info[ :dst_exts ][ dst_local_port ]
678
679
 
679
680
  if dst_ext
680
- pack_id = dst_ext[ :biggest_pack_id ] + 1
681
-
682
681
  if pack_id <= CONFUSE_UNTIL
683
682
  data = @custom.encode( data )
684
683
  # puts "debug1 encoded pack #{ pack_id }"
@@ -694,7 +693,7 @@ module Girl
694
693
 
695
694
  # puts "debug2 written pack #{ pack_id }"
696
695
  now = Time.new
697
- dst_ext[ :biggest_pack_id ] = pack_id
696
+ dst_ext[ :relay_pack_id ] = pack_id
698
697
  dst_ext[ :wmems ][ pack_id ] = data
699
698
  dst_ext[ :send_ats ][ pack_id ] = now
700
699
  dst_ext[ :last_continue_at ] = now
@@ -735,15 +734,15 @@ module Girl
735
734
  @tund_infos[ tund ] = {
736
735
  port: port, # 端口
737
736
  ctlmsgs: [], # data
738
- wbuffs: [], # 写前缓存 [ src_dst_addr, data ]
739
- caches: [], # 块读出缓存 [ src_dst_addr, data ]
737
+ wbuffs: [], # 写前缓存 [ dst_local_port, pack_id, data ]
738
+ caches: [], # 块读出缓存 [ dst_local_port, pack_id, data ]
740
739
  chunks: [], # 块队列 filename
741
740
  spring: 0, # 块后缀,结块时,如果块队列不为空,则自增,为空,则置为0
742
741
  tun_addr: from_addr, # tun地址
743
- dst_exts: {}, # dst额外信息 dst_addr => {}
742
+ dst_exts: {}, # dst额外信息 dst_local_port => {}
744
743
  dst_local_ports: {}, # src_id => dst_local_port
745
744
  paused: false, # 是否暂停写
746
- resendings: [], # 重传队列 [ dst_addr, pack_id ]
745
+ resendings: [], # 重传队列 [ dst_local_port, pack_id ]
747
746
  created_at: Time.new, # 创建时间
748
747
  last_recv_at: nil, # 上一次收到流量的时间,过期关闭
749
748
  is_closing: false # 是否准备关闭
@@ -781,7 +780,9 @@ module Girl
781
780
  return
782
781
  end
783
782
 
784
- add_tund_wbuff( tund, dst_info[ :local_port ], data )
783
+ pack_id = dst_info[ :biggest_pack_id ] + 1
784
+ dst_info[ :biggest_pack_id ] = pack_id
785
+ add_tund_wbuff( tund, dst_info[ :local_port ], pack_id, data )
785
786
  end
786
787
 
787
788
  ##
@@ -834,7 +835,7 @@ module Girl
834
835
  destination_domain_port = @custom.decode( data )
835
836
  resolve_domain( tund, src_id, destination_domain_port )
836
837
  when SOURCE_STATUS
837
- src_id, biggest_src_pack_id, continue_dst_pack_id = data[ 9, 24 ].unpack( 'Q>Q>Q>' )
838
+ src_id, relay_src_pack_id, continue_dst_pack_id = data[ 9, 24 ].unpack( 'Q>Q>Q>' )
838
839
 
839
840
  dst_local_port = tund_info[ :dst_local_ports ][ src_id ]
840
841
  return unless dst_local_port
@@ -844,22 +845,10 @@ module Girl
844
845
 
845
846
  # puts "debug2 got source status"
846
847
 
847
- # 更新对面发到几
848
- if biggest_src_pack_id > dst_ext[ :biggest_src_pack_id ]
849
- # puts "debug2 update biggest src pack #{ biggest_src_pack_id }"
850
- dst_ext[ :biggest_src_pack_id ] = biggest_src_pack_id
851
-
852
- # 接到对面状态,若对面已关闭,且最后一个包已经进写前,关闭dst
853
- if dst_ext[ :is_src_closed ] && ( biggest_src_pack_id == dst_ext[ :continue_src_pack_id ] )
854
- # puts "debug1 2-1. recv traffic/fin1/src status -> src closed and all traffic received ? -> close dst after write"
855
- set_is_closing( dst_ext[ :dst ] )
856
- end
857
- end
858
-
859
848
  release_wmems( dst_ext, continue_dst_pack_id )
860
849
 
861
850
  # 发miss
862
- if !dst_ext[ :dst ].closed? && ( dst_ext[ :continue_src_pack_id ] < dst_ext[ :biggest_src_pack_id ] )
851
+ if !dst_ext[ :dst ].closed? && ( dst_ext[ :continue_src_pack_id ] < relay_src_pack_id )
863
852
  ranges = []
864
853
  curr_pack_id = dst_ext[ :continue_src_pack_id ] + 1
865
854
 
@@ -871,12 +860,12 @@ module Girl
871
860
  curr_pack_id = pack_id + 1
872
861
  end
873
862
 
874
- if curr_pack_id <= dst_ext[ :biggest_src_pack_id ]
875
- ranges << [ curr_pack_id, dst_ext[ :biggest_src_pack_id ] ]
863
+ if curr_pack_id <= relay_src_pack_id
864
+ ranges << [ curr_pack_id, relay_src_pack_id ]
876
865
  end
877
866
 
878
867
  pack_count = 0
879
- # puts "debug1 continue/biggest #{ dst_ext[ :continue_src_pack_id ] }/#{ dst_ext[ :biggest_src_pack_id ] } send MISS #{ ranges.size }"
868
+ # puts "debug1 continue/relay #{ dst_ext[ :continue_src_pack_id ] }/#{ relay_src_pack_id } send MISS #{ ranges.size }"
880
869
 
881
870
  ranges.each do | pack_id_begin, pack_id_end |
882
871
  if pack_count >= BREAK_SEND_MISS
@@ -921,7 +910,7 @@ module Girl
921
910
 
922
911
  # 接到对面已关闭,若最后一个包已经进写前,关闭dst
923
912
  if biggest_src_pack_id == dst_ext[ :continue_src_pack_id ]
924
- # puts "debug1 2-1. recv traffic/fin1/src status -> src closed and all traffic received ? -> close dst after write"
913
+ # puts "debug1 4-1. tund recv fin1 -> all traffic received ? -> close dst after write"
925
914
  set_is_closing( dst_ext[ :dst ] )
926
915
  end
927
916
  when FIN2
@@ -930,7 +919,7 @@ module Girl
930
919
  dst_local_port = tund_info[ :dst_local_ports ][ src_id ]
931
920
  return unless dst_local_port
932
921
 
933
- # puts "debug1 1-2. recv fin2 -> del dst ext"
922
+ # puts "debug1 3-2. tund recv fin2 -> del dst ext"
934
923
  del_dst_ext( tund, dst_local_port )
935
924
  when TUN_FIN
936
925
  puts "p#{ Process.pid } #{ Time.new } recv tun fin"
@@ -972,7 +961,7 @@ module Girl
972
961
 
973
962
  # 接到流量,若对面已关闭,且流量正好收全,关闭dst
974
963
  if dst_ext[ :is_src_closed ] && ( pack_id == dst_ext[ :biggest_src_pack_id ] )
975
- # puts "debug1 2-1. recv traffic/fin1/src status -> src closed and all traffic received ? -> close dst after write"
964
+ # puts "debug1 4-2. tund recv traffic -> src closed and all traffic received ? -> close dst after write"
976
965
  set_is_closing( dst_ext[ :dst ] )
977
966
  return
978
967
  end