girl 0.71.0 → 0.73.1

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: 5a29bed71df8f50ac316ebd9819b0e32134324700d01752dd7027ed91e51dc35
4
- data.tar.gz: 63dca91494dd3680caa7364db5b6b22c205fa6cc4a55a23d497ec0489f8c1234
3
+ metadata.gz: 33af151d416edee9c887ce27984d09f2dd29f9ab73b2f09beac406bdde96eba4
4
+ data.tar.gz: bd0271ae4f10083e473ec9ec9794becccb2a24f5d2888b94c48e8402ab08f475
5
5
  SHA512:
6
- metadata.gz: 3ce8f9e01aea05d29e5bd8fb91f027eca72ec3f992da8ad767a9845c52ad9e4727bf70ed1408cef2f2a71cf92ce3265564c7789fc95d76c793d8172d0a0da53a
7
- data.tar.gz: 0f5ee9f741065b75f2de0aa9f2ee68cc4e462a5aaffe1f7e9418028a629cf2dd0b116a07b8b6481898dcd3907e691f9bda0f7a88e4d0a2095fb6ffbbc36b0f09
6
+ metadata.gz: 699f24fd304267c96841c882290a47961a3fefcd21bdf8b8bef509b20eaaa7200f5292d58cc10248a251e541cf6a5bb68d43bef1ad7f4d24881b8ef8c994130a
7
+ data.tar.gz: 7c3e71e1c31c9e61f3584b2b1b0a78b505a7e222c61d6b5edd041f7a25a985267ec13bf1432d6bcdfc46c89d9fb0bf32678fda57b47e8a917c40f4451da93e82
@@ -1,17 +1,17 @@
1
1
  module Girl
2
- PACK_SIZE = 1328 # 包大小 1400(console MTU) - 8(PPPoE header) - 40(IPv6 header) - 8(UDP header) - 8(pack id) - 8(src id) = 1328
3
- CHUNK_SIZE = PACK_SIZE * 1000 # 块大小
4
- WBUFFS_LIMIT = 1000 # 写前上限,超过上限结一个块
5
- WMEMS_LIMIT = 100_000 # 写后上限,达到上限暂停写
6
- RESUME_BELOW = 50_000 # 降到多少以下恢复写
7
- EXPIRE_NEW = 10 # 创建之后多久没有流量进来,过期
8
- EXPIRE_AFTER = 300 # 多久没有新流量,过期
9
- CHECK_EXPIRE_INTERVAL = 30 # 检查过期间隔
10
- STATUS_INTERVAL = 0.5 # 发送状态间隔
11
- SEND_STATUS_UNTIL = 10 # 持续的告之对面状态,直到没有流量往来,持续多少秒
12
- BREAK_SEND_MISS = 10_000 # miss包个数上限,达到上限忽略要后面的段,可控碎片缓存
13
- CONFUSE_UNTIL = 5 # 混淆前几个包
14
- RESOLV_CACHE_EXPIRE = 300 # dns查询结果缓存多久过期
2
+ PACK_SIZE = 1328 # 包大小 1400(console MTU) - 8(PPPoE header) - 40(IPv6 header) - 8(UDP header) - 8(pack id) - 8(src id) = 1328
3
+ CHUNK_SIZE = PACK_SIZE * 1000 # 块大小
4
+ WBUFFS_LIMIT = 1000 # 写前上限,超过上限结一个块
5
+ WMEMS_LIMIT = 100_000 # 写后上限,达到上限暂停写
6
+ RESUME_BELOW = 50_000 # 降到多少以下恢复写
7
+ EXPIRE_NEW = 10 # 创建之后多久没有流量进来,过期
8
+ EXPIRE_AFTER = 300 # 多久没有新流量,过期
9
+ CHECK_EXPIRE_INTERVAL = 30 # 检查过期间隔
10
+ STATUS_INTERVAL = 0.5 # 发送状态间隔
11
+ SEND_STATUS_UNTIL = 10 # 持续的告之对面状态,直到没有流量往来,持续多少秒
12
+ BREAK_SEND_MISS = 10_000 # miss包个数上限,达到上限忽略要后面的段,可控碎片缓存
13
+ CONFUSE_UNTIL = 5 # 混淆前几个包
14
+ RESOLV_CACHE_EXPIRE = 300 # dns查询结果缓存多久过期
15
15
  TUND_PORT = 1
16
16
  HEARTBEAT = 2
17
17
  A_NEW_SOURCE = 3
@@ -23,15 +23,15 @@ require 'socket'
23
23
  #
24
24
  # tun-tund:
25
25
  #
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>: 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
26
+ # Q>: 0 ctlmsg -> C: 2 heartbeat -> C: random char
27
+ # 3 a new source -> Q>: src id -> encoded destination address
28
+ # 4 paired -> Q>: src id -> n: dst port
29
+ # 5 dest status -> n: dst port -> Q>: biggest relayed dst pack id -> Q>: continue src pack id
30
+ # 6 source 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>/n: src id / 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
@@ -129,21 +129,19 @@ module Girl
129
129
  end
130
130
 
131
131
  src_chunk_dir = File.join( proxy_tmp_dir, 'src.chunk' )
132
- dst_chunk_dir = File.join( proxy_tmp_dir, 'dst.chunk' )
133
- tun_chunk_dir = File.join( proxy_tmp_dir, 'tun.chunk' )
134
-
135
- unless Dir.exist?( proxy_tmp_dir )
136
- Dir.mkdir( proxy_tmp_dir )
137
- end
138
132
 
139
133
  unless Dir.exist?( src_chunk_dir )
140
134
  Dir.mkdir( src_chunk_dir )
141
135
  end
142
136
 
137
+ dst_chunk_dir = File.join( proxy_tmp_dir, 'dst.chunk' )
138
+
143
139
  unless Dir.exist?( dst_chunk_dir )
144
140
  Dir.mkdir( dst_chunk_dir )
145
141
  end
146
142
 
143
+ tun_chunk_dir = File.join( proxy_tmp_dir, 'tun.chunk' )
144
+
147
145
  unless Dir.exist?( tun_chunk_dir )
148
146
  Dir.mkdir( tun_chunk_dir )
149
147
  end
@@ -18,7 +18,6 @@ module Girl
18
18
  @writes = []
19
19
  @roles = {} # sock => :dotr / :proxy / :src / :dst / :tun
20
20
  @src_infos = {} # src => {}
21
- @dsts = {} # local_port => dst
22
21
  @dst_infos = {} # dst => {}
23
22
  @resolv_caches = {} # domain => [ ip, created_at ]
24
23
 
@@ -124,9 +123,7 @@ module Girl
124
123
  end
125
124
 
126
125
  @src_infos.each do | src, src_info |
127
- is_expired = src_info[ :last_recv_at ].nil? && ( now - src_info[ :created_at ] > EXPIRE_NEW )
128
-
129
- if is_expired
126
+ if now - src_info[ :last_continue_at ] > EXPIRE_AFTER
130
127
  puts "p#{ Process.pid } #{ Time.new } expire src"
131
128
  set_is_closing( src )
132
129
  need_trigger = true
@@ -134,10 +131,8 @@ module Girl
134
131
  end
135
132
 
136
133
  @dst_infos.each do | dst, dst_info |
137
- is_expired = dst_info[ :last_recv_at ].nil? && ( now - dst_info[ :created_at ] > EXPIRE_NEW )
138
-
139
- if is_expired
140
- puts "p#{ Process.pid } #{ Time.new } expire dst"
134
+ if now - dst_info[ :last_continue_at ] > EXPIRE_AFTER
135
+ puts "p#{ Process.pid } #{ Time.new } expire dst #{ dst_info[ :domain ] }"
141
136
  set_is_closing( dst )
142
137
  need_trigger = true
143
138
  end
@@ -217,12 +212,6 @@ module Girl
217
212
  # resolve domain
218
213
  #
219
214
  def resolve_domain( src, domain )
220
- if ( /\A(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})\Z/ =~ domain ) && domain.split( '.' ).all? { | part | part.to_i < 256 }
221
- # puts "debug1 #{ domain } is a ip"
222
- deal_with_destination_ip( src, domain )
223
- return
224
- end
225
-
226
215
  if @remotes.any? { | remote | ( domain.size >= remote.size ) && ( domain[ ( remote.size * -1 )..-1 ] == remote ) }
227
216
  # puts "debug1 #{ domain } hit remotes"
228
217
  new_a_src_ext( src )
@@ -232,11 +221,11 @@ module Girl
232
221
  resolv_cache = @resolv_caches[ domain ]
233
222
 
234
223
  if resolv_cache
235
- destination_ip, created_at = resolv_cache
224
+ ip_info, created_at = resolv_cache
236
225
 
237
226
  if Time.new - created_at < RESOLV_CACHE_EXPIRE
238
- # puts "debug1 #{ domain } hit resolv cache #{ destination_ip }"
239
- deal_with_destination_ip( src, destination_ip )
227
+ # puts "debug1 #{ domain } hit resolv cache #{ ip_info.inspect }"
228
+ deal_with_destination_ip( src, ip_info )
240
229
  return
241
230
  end
242
231
 
@@ -256,12 +245,11 @@ module Girl
256
245
 
257
246
  @mutex.synchronize do
258
247
  if ip_info
259
- destination_ip = ip_info.ip_address
260
- # puts "debug1 resolved #{ domain } #{ destination_ip }"
261
- @resolv_caches[ domain ] = [ destination_ip, Time.new ]
248
+ @resolv_caches[ domain ] = [ ip_info, Time.new ]
262
249
 
263
250
  unless src.closed?
264
- deal_with_destination_ip( src, destination_ip )
251
+ puts "p#{ Process.pid } #{ Time.new } resolved #{ domain } #{ ip_info.ip_address }"
252
+ deal_with_destination_ip( src, ip_info )
265
253
  end
266
254
  else
267
255
  set_is_closing( src )
@@ -275,11 +263,11 @@ module Girl
275
263
  ##
276
264
  # deal with destination ip
277
265
  #
278
- def deal_with_destination_ip( src, destination_ip )
279
- if @directs.any? { | direct | direct.include?( destination_ip ) }
266
+ def deal_with_destination_ip( src, ip_info )
267
+ if @directs.any? { | direct | direct.include?( ip_info.ip_address ) }
280
268
  # ip命中直连列表,直连
281
- # puts "debug1 #{ destination_ip } hit directs"
282
- new_a_dst( src, destination_ip )
269
+ # puts "debug1 #{ ip_info.inspect } hit directs"
270
+ new_a_dst( src, ip_info )
283
271
  else
284
272
  # 走远端
285
273
  new_a_src_ext( src )
@@ -343,10 +331,11 @@ module Girl
343
331
  ##
344
332
  # new a dst
345
333
  #
346
- def new_a_dst( src, destination_ip )
334
+ def new_a_dst( src, ip_info )
347
335
  src_info = @src_infos[ src ]
348
- destination_addr = Socket.sockaddr_in( src_info[ :destination_port ], destination_ip )
349
- dst = Socket.new( Socket::AF_INET, Socket::SOCK_STREAM, 0 )
336
+ domain = src_info[ :destination_domain ]
337
+ destination_addr = Socket.sockaddr_in( src_info[ :destination_port ], ip_info.ip_address )
338
+ dst = Socket.new( ip_info.ipv4? ? Socket::AF_INET : Socket::AF_INET6, Socket::SOCK_STREAM, 0 )
350
339
 
351
340
  if RUBY_PLATFORM.include?( 'linux' )
352
341
  dst.setsockopt( Socket::SOL_TCP, Socket::TCP_NODELAY, 1 )
@@ -364,17 +353,16 @@ module Girl
364
353
 
365
354
  # puts "debug1 a new dst #{ dst.local_address.inspect }"
366
355
  local_port = dst.local_address.ip_port
367
- @dsts[ local_port ] = dst
368
356
  @dst_infos[ dst ] = {
369
- local_port: local_port, # 本地端口
370
- src: src, # 对应src
371
- wbuff: '', # 写前
372
- cache: '', # 块读出缓存
373
- chunks: [], # 块队列,写前达到块大小时结一个块 filename
374
- spring: 0, # 块后缀,结块时,如果块队列不为空,则自增,为空,则置为0
375
- created_at: Time.new, # 创建时间
376
- last_recv_at: nil, # 上一次收到流量的时间,过期关闭
377
- is_closing: false # 是否准备关闭
357
+ local_port: local_port, # 本地端口
358
+ src: src, # 对应src
359
+ domain: domain, # 域名
360
+ wbuff: '', # 写前
361
+ cache: '', # 块读出缓存
362
+ chunks: [], # 块队列,写前达到块大小时结一个块 filename
363
+ spring: 0, # 块后缀,结块时,如果块队列不为空,则自增,为空,则置为0
364
+ last_continue_at: Time.new, # 上一次发生流量的时间
365
+ is_closing: false # 是否准备关闭
378
366
  }
379
367
 
380
368
  add_read( dst, :dst )
@@ -383,11 +371,9 @@ module Girl
383
371
 
384
372
  if src_info[ :proxy_proto ] == :http
385
373
  if src_info[ :is_connect ]
386
- # CONNECT
387
374
  # puts "debug1 add src wbuff http ok"
388
375
  add_src_wbuff( src, HTTP_OK )
389
376
  else
390
- # not CONNECT
391
377
  # puts "debug1 add src rbuffs to dst wbuff"
392
378
 
393
379
  src_info[ :rbuffs ].each do | _, data |
@@ -418,7 +404,7 @@ module Girl
418
404
  is_dst_closed: false, # dst是否已关闭
419
405
  biggest_dst_pack_id: 0, # dst最大包号码
420
406
  completed_pack_id: 0, # 完成到几(对面收到几)
421
- last_continue_at: Time.new # 创建,或者上一次收到连续流量,或者发出新包的时间
407
+ last_continue_at: Time.new # 上一次发生流量的时间
422
408
  }
423
409
 
424
410
  src_info = @src_infos[ src ]
@@ -666,7 +652,6 @@ module Girl
666
652
  end
667
653
  end
668
654
 
669
- @dsts.delete( dst_info[ :local_port ] )
670
655
  set_is_closing( dst_info[ :src ] )
671
656
  end
672
657
 
@@ -780,6 +765,7 @@ module Girl
780
765
  # puts "debug2 write src #{ written }"
781
766
  data = data[ written..-1 ]
782
767
  src_info[ from ] = data
768
+ src_info[ :last_continue_at ] = Time.new
783
769
  end
784
770
 
785
771
  ##
@@ -831,6 +817,7 @@ module Girl
831
817
  # puts "debug2 write dst #{ written }"
832
818
  data = data[ written..-1 ]
833
819
  dst_info[ from ] = data
820
+ dst_info[ :last_continue_at ] = Time.new
834
821
  end
835
822
 
836
823
  ##
@@ -852,6 +839,10 @@ module Girl
852
839
  tun.sendmsg( data, 0, to_addr )
853
840
  rescue IO::WaitWritable, Errno::EINTR
854
841
  return
842
+ rescue Errno::EHOSTUNREACH, Errno::ENETUNREACH => e
843
+ puts "#{ Time.new } #{ e.class }, close tun"
844
+ close_tun( tun )
845
+ return
855
846
  end
856
847
 
857
848
  @tun_info[ :ctlmsgs ].shift
@@ -870,6 +861,10 @@ module Girl
870
861
  tun.sendmsg( data, 0, @tun_info[ :tund_addr ] )
871
862
  rescue IO::WaitWritable, Errno::EINTR
872
863
  return
864
+ rescue Errno::EHOSTUNREACH, Errno::ENETUNREACH => e
865
+ puts "#{ Time.new } #{ e.class }, close tun"
866
+ close_tun( tun )
867
+ return
873
868
  end
874
869
  end
875
870
  end
@@ -938,6 +933,10 @@ module Girl
938
933
  tun.sendmsg( data, 0, @tun_info[ :tund_addr ] )
939
934
  rescue IO::WaitWritable, Errno::EINTR
940
935
  return
936
+ rescue Errno::EHOSTUNREACH, Errno::ENETUNREACH => e
937
+ puts "#{ Time.new } #{ e.class }, close tun"
938
+ close_tun( tun )
939
+ return
941
940
  end
942
941
 
943
942
  # puts "debug2 written pack #{ pack_id }"
@@ -971,22 +970,21 @@ module Girl
971
970
  # puts "debug1 accept a src #{ addrinfo.inspect } #{ id }"
972
971
 
973
972
  @src_infos[ src ] = {
974
- id: id, # id
975
- proxy_proto: :uncheck, # :uncheck / :http / :socks5
976
- proxy_type: :uncheck, # :uncheck / :checking / :direct / :tunnel / :negotiation
977
- dst: nil, # :direct的场合,对应的dst
978
- destination_domain: nil, # 目的地域名
979
- destination_port: nil, # 目的地端口
980
- biggest_pack_id: 0, # 最大包号码
981
- is_connect: true, # 代理协议是http的场合,是否是CONNECT
982
- rbuffs: [], # 非CONNECT,dst或者远端dst未准备好,暂存流量 [ pack_id, data ]
983
- wbuff: '', # 写前
984
- cache: '', # 块读出缓存
985
- chunks: [], # 块队列,写前达到块大小时结一个块 filename
986
- spring: 0, # 块后缀,结块时,如果块队列不为空,则自增,为空,则置为0
987
- created_at: Time.new, # 创建时间
988
- last_recv_at: nil, # 上一次收到流量的时间,过期关闭
989
- is_closing: false # 是否准备关闭
973
+ id: id, # id
974
+ proxy_proto: :uncheck, # :uncheck / :http / :socks5
975
+ proxy_type: :uncheck, # :uncheck / :checking / :direct / :tunnel / :negotiation
976
+ dst: nil, # :direct的场合,对应的dst
977
+ destination_domain: nil, # 目的地域名
978
+ destination_port: nil, # 目的地端口
979
+ biggest_pack_id: 0, # 最大包号码
980
+ is_connect: true, # 代理协议是http的场合,是否是CONNECT
981
+ rbuffs: [], # 非CONNECT,dst或者远端dst未准备好,暂存流量 [ pack_id, data ]
982
+ wbuff: '', # 写前
983
+ cache: '', # 块读出缓存
984
+ chunks: [], # 块队列,写前达到块大小时结一个块 filename
985
+ spring: 0, # 块后缀,结块时,如果块队列不为空,则自增,为空,则置为0
986
+ last_continue_at: Time.new, # 上一次发生流量的时间
987
+ is_closing: false # 是否准备关闭
990
988
  }
991
989
 
992
990
  add_read( src, :src )
@@ -1008,7 +1006,7 @@ module Girl
1008
1006
 
1009
1007
  # puts "debug2 read src #{ data.inspect }"
1010
1008
  src_info = @src_infos[ src ]
1011
- src_info[ :last_recv_at ] = Time.new
1009
+ src_info[ :last_continue_at ] = Time.new
1012
1010
  proxy_type = src_info[ :proxy_type ]
1013
1011
 
1014
1012
  case proxy_type
@@ -1115,7 +1113,7 @@ module Girl
1115
1113
  src_info[ :destination_domain ] = destination_ip
1116
1114
  src_info[ :destination_port ] = destination_port
1117
1115
  # puts "debug1 IP V4 address #{ destination_addrinfo.inspect }"
1118
- deal_with_destination_ip( src, destination_ip )
1116
+ deal_with_destination_ip( src, destination_addrinfo )
1119
1117
  elsif atyp == 3
1120
1118
  domain_len = data[ 4 ].unpack( 'C' ).first
1121
1119
 
@@ -1198,7 +1196,7 @@ module Girl
1198
1196
 
1199
1197
  # puts "debug2 read dst #{ data.inspect }"
1200
1198
  dst_info = @dst_infos[ dst ]
1201
- dst_info[ :last_recv_at ] = Time.new
1199
+ dst_info[ :last_continue_at ] = Time.new
1202
1200
  src = dst_info[ :src ]
1203
1201
 
1204
1202
  if src.closed?
@@ -1264,11 +1262,9 @@ module Girl
1264
1262
 
1265
1263
  if src_info[ :proxy_proto ] == :http
1266
1264
  if src_info[ :is_connect ]
1267
- # CONNECT
1268
1265
  # puts "debug1 add src wbuff http ok"
1269
1266
  add_src_wbuff( src, HTTP_OK )
1270
1267
  else
1271
- # not CONNECT
1272
1268
  # puts "debug1 add src rbuffs to tun wbuffs"
1273
1269
 
1274
1270
  src_info[ :rbuffs ].each do | pack_id, _data |
@@ -1358,7 +1354,6 @@ module Girl
1358
1354
  src_ext[ :biggest_dst_pack_id ] = biggest_dst_pack_id
1359
1355
  release_wmems( src_ext, continue_src_pack_id )
1360
1356
 
1361
- # 接到对面已关闭,若最后一个包已经进写前,关闭src
1362
1357
  if ( biggest_dst_pack_id == src_ext[ :continue_dst_pack_id ] )
1363
1358
  # puts "debug1 2-1. tun recv fin1 -> all traffic received ? -> close src after write"
1364
1359
  set_is_closing( src_ext[ :src ] )
@@ -37,16 +37,13 @@ module Girl
37
37
  end
38
38
 
39
39
  dst_chunk_dir = File.join( proxyd_tmp_dir, 'dst.chunk' )
40
- tund_chunk_dir = File.join( proxyd_tmp_dir, 'tund.chunk' )
41
-
42
- unless Dir.exist?( proxyd_tmp_dir )
43
- Dir.mkdir( proxyd_tmp_dir )
44
- end
45
40
 
46
41
  unless Dir.exist?( dst_chunk_dir )
47
42
  Dir.mkdir( dst_chunk_dir )
48
43
  end
49
44
 
45
+ tund_chunk_dir = File.join( proxyd_tmp_dir, 'tund.chunk' )
46
+
50
47
  unless Dir.exist?( tund_chunk_dir )
51
48
  Dir.mkdir( tund_chunk_dir )
52
49
  end
@@ -123,10 +123,8 @@ module Girl
123
123
  end
124
124
 
125
125
  @dst_infos.each do | dst, dst_info |
126
- is_expired = dst_info[ :last_recv_at ].nil? && ( now - dst_info[ :created_at ] > EXPIRE_NEW )
127
-
128
- if is_expired
129
- puts "p#{ Process.pid } #{ Time.new } expire dst"
126
+ if now - dst_info[ :last_continue_at ] > EXPIRE_AFTER
127
+ puts "p#{ Process.pid } #{ Time.new } expire dst #{ dst_info[ :domain_port ] }"
130
128
  set_is_closing( dst )
131
129
  need_trigger = true
132
130
  end
@@ -195,7 +193,7 @@ module Girl
195
193
 
196
194
  if Time.new - created_at < RESOLV_CACHE_EXPIRE
197
195
  # puts "debug1 #{ destination_domain_port } hit resolv cache #{ Addrinfo.new( destination_addr ).inspect }"
198
- deal_with_destination_addr( tund, src_id, destination_addr )
196
+ deal_with_destination_addr( tund, src_id, destination_addr, destination_domain_port )
199
197
  return
200
198
  end
201
199
 
@@ -204,13 +202,17 @@ module Girl
204
202
  end
205
203
 
206
204
  Thread.new do
207
- destination_domain, destination_port = destination_domain_port.split( ':' )
208
- destination_port = destination_port.to_i
205
+ colon_idx = destination_domain_port.rindex( ':' )
209
206
 
210
- begin
211
- destination_addr = Socket.sockaddr_in( destination_port, destination_domain )
212
- rescue Exception => e
213
- puts "p#{ Process.pid } #{ Time.new } sockaddr in #{ destination_domain_port } #{ e.class }"
207
+ if colon_idx
208
+ destination_domain = destination_domain_port[ 0...colon_idx ]
209
+ destination_port = destination_domain_port[ ( colon_idx + 1 )..-1 ].to_i
210
+
211
+ begin
212
+ destination_addr = Socket.sockaddr_in( destination_port, destination_domain )
213
+ rescue Exception => e
214
+ puts "p#{ Process.pid } #{ Time.new } sockaddr in #{ destination_domain_port } #{ e.class }"
215
+ end
214
216
  end
215
217
 
216
218
  @mutex.synchronize do
@@ -219,7 +221,7 @@ module Girl
219
221
  @resolv_caches[ destination_domain_port ] = [ destination_addr, Time.new ]
220
222
 
221
223
  unless tund.closed?
222
- if deal_with_destination_addr( tund, src_id, destination_addr )
224
+ if deal_with_destination_addr( tund, src_id, destination_addr, destination_domain_port )
223
225
  next_tick
224
226
  end
225
227
  end
@@ -231,8 +233,8 @@ module Girl
231
233
  ##
232
234
  # deal with destination addr
233
235
  #
234
- def deal_with_destination_addr( tund, src_id, destination_addr )
235
- dst = Socket.new( Socket::AF_INET, Socket::SOCK_STREAM, 0 )
236
+ def deal_with_destination_addr( tund, src_id, destination_addr, destination_domain_port )
237
+ dst = Socket.new( Addrinfo.new( destination_addr ).ipv4? ? Socket::AF_INET : Socket::AF_INET6, Socket::SOCK_STREAM, 0 )
236
238
  dst.setsockopt( Socket::SOL_TCP, Socket::TCP_NODELAY, 1 )
237
239
 
238
240
  begin
@@ -246,16 +248,16 @@ module Girl
246
248
  local_port = dst.local_address.ip_port
247
249
 
248
250
  @dst_infos[ dst ] = {
249
- local_port: local_port, # 本地端口
250
- tund: tund, # 对应tund
251
- biggest_pack_id: 0, # 最大包号码
252
- wbuff: '', # 写前
253
- cache: '', # 块读出缓存
254
- chunks: [], # 块队列,写前达到块大小时结一个块 filename
255
- spring: 0, # 块后缀,结块时,如果块队列不为空,则自增,为空,则置为0
256
- created_at: Time.new, # 创建时间
257
- last_recv_at: nil, # 上一次收到流量的时间,过期关闭
258
- is_closing: false # 是否准备关闭
251
+ local_port: local_port, # 本地端口
252
+ tund: tund, # 对应tund
253
+ domain_port: destination_domain_port, # 域名和端口
254
+ biggest_pack_id: 0, # 最大包号码
255
+ wbuff: '', # 写前
256
+ cache: '', # 块读出缓存
257
+ chunks: [], # 块队列,写前达到块大小时结一个块 filename
258
+ spring: 0, # 块后缀,结块时,如果块队列不为空,则自增,为空,则置为0
259
+ last_continue_at: Time.new, # 上一次发生流量的时间
260
+ is_closing: false # 是否准备关闭
259
261
  }
260
262
  add_read( dst, :dst )
261
263
 
@@ -272,7 +274,7 @@ module Girl
272
274
  is_src_closed: false, # src是否已关闭
273
275
  biggest_src_pack_id: 0, # src最大包号码
274
276
  completed_pack_id: 0, # 完成到几(对面收到几)
275
- last_continue_at: Time.new # 创建,或者上一次收到连续流量,或者发出新包的时间
277
+ last_continue_at: Time.new # 上一次发生流量的时间
276
278
  }
277
279
 
278
280
  data = [ 0, PAIRED, src_id, local_port ].pack( 'Q>CQ>n' )
@@ -582,6 +584,7 @@ module Girl
582
584
  # puts "debug2 write dst #{ written }"
583
585
  data = data[ written..-1 ]
584
586
  dst_info[ from ] = data
587
+ dst_info[ :last_continue_at ] = Time.new
585
588
  end
586
589
 
587
590
  ##
@@ -771,7 +774,7 @@ module Girl
771
774
 
772
775
  # puts "debug2 read dst #{ data.inspect }"
773
776
  dst_info = @dst_infos[ dst ]
774
- dst_info[ :last_recv_at ] = Time.new
777
+ dst_info[ :last_continue_at ] = Time.new
775
778
  tund = dst_info[ :tund ]
776
779
 
777
780
  if tund.closed?
@@ -814,7 +817,6 @@ module Girl
814
817
  when A_NEW_SOURCE
815
818
  src_id = data[ 9, 8 ].unpack( 'Q>' ).first
816
819
  dst_local_port = tund_info[ :dst_local_ports ][ src_id ]
817
- # puts "debug1 got a new source #{ src_id }"
818
820
 
819
821
  if dst_local_port
820
822
  dst_ext = tund_info[ :dst_exts ][ dst_local_port ]
@@ -831,8 +833,8 @@ module Girl
831
833
  end
832
834
 
833
835
  data = data[ 17..-1 ]
834
- # puts "debug1 #{ data }"
835
836
  destination_domain_port = @custom.decode( data )
837
+ puts "p#{ Process.pid } #{ Time.new } a new source #{ src_id } #{ destination_domain_port }"
836
838
  resolve_domain( tund, src_id, destination_domain_port )
837
839
  when SOURCE_STATUS
838
840
  src_id, relay_src_pack_id, continue_dst_pack_id = data[ 9, 24 ].unpack( 'Q>Q>Q>' )
@@ -908,7 +910,6 @@ module Girl
908
910
  dst_ext[ :biggest_src_pack_id ] = biggest_src_pack_id
909
911
  release_wmems( dst_ext, continue_dst_pack_id )
910
912
 
911
- # 接到对面已关闭,若最后一个包已经进写前,关闭dst
912
913
  if biggest_src_pack_id == dst_ext[ :continue_src_pack_id ]
913
914
  # puts "debug1 4-1. tund recv fin1 -> all traffic received ? -> close dst after write"
914
915
  set_is_closing( dst_ext[ :dst ] )
@@ -1,3 +1,3 @@
1
1
  module Girl
2
- VERSION = '0.71.0'.freeze
2
+ VERSION = '0.73.1'.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.71.0
4
+ version: 0.73.1
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-30 00:00:00.000000000 Z
11
+ date: 2020-07-19 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: while internet is evil, here's a girl.
14
14
  email: