girl 0.90.0 → 0.95.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: 2e1916068595360e4ab83189c93759e2c6ed05979d4a4128ff83f95390e91dce
4
- data.tar.gz: 9f39d67731002186f66f04e4bb463834980a243fc0d6322b5e35f749fa356f95
3
+ metadata.gz: 995e842429be7063ce5e29248927b336029f2e4dc864e4855979770d18ff7766
4
+ data.tar.gz: 83b4619a2b8cf5f99058282345478eee57a2b7638cefafa5a15d1d0170abfb96
5
5
  SHA512:
6
- metadata.gz: 18e61543e05ae79c31ee76a8504cfcfef1271aa1419430ae667b46c8291dcc790630aa1123bc662ce817117a26b68ac343f5c7679134a3205548f32ba28cfb31
7
- data.tar.gz: 797fa163ab50c3ace753ac833381bdeb040876c12de7d2b5570dbe0f3a799a91b18fa220ca5ea4ecbc8cfad69aabbd1dd245ad1bcd404b92423020890f5d38d1
6
+ metadata.gz: 349a7012c29fd90bae97816b1af481d25623f580969f3ec354c0b747c43aea805bba0b02f8ebb8e653427b12fa5af07584fc3566ddb67bd48fd04947b4386fcf
7
+ data.tar.gz: c078531bb08ed0568e28170336c2a10b8b22896b2138bfdc149d9f61758cae938816ea623f7b4e7bab89e48620c855c731c4c3fdb2485573f2706125e9602b7c
@@ -1,9 +1,12 @@
1
1
  module Girl
2
2
  READ_SIZE = 1024 * 1024 # 一次读多少
3
- WBUFF_LIMIT = 100 * 1024 * 1024 # 写前上限,超过上限暂停读src/dst
3
+ WBUFF_LIMIT = 100 * 1024 * 1024 # 写前上限,超过上限暂停读
4
4
  RESUME_BELOW = WBUFF_LIMIT / 2 # 降到多少以下恢复读
5
- SEND_HELLO_COUNT = 10 # hello最多发几次
5
+ SEND_HELLO_COUNT = 10 # hello/a new source最多发几次
6
+ SEND_HELLO_INTERVAL = 0.5 # 发送hello/a new source间隔
6
7
  EXPIRE_AFTER = 300 # 多久没有新流量,过期
8
+ RESET_TRAFF_DAY = 1 # 流量计数重置日,0为不重置
9
+ CHECK_TRAFF_INTERVAL = 86400 # 检查今天是否是流量计数重置日间隔
7
10
  CHECK_EXPIRE_INTERVAL = 30 # 检查过期间隔
8
11
  CHECK_RESUME_INTERVAL = 1 # 检查恢复读间隔
9
12
  RESOLV_CACHE_EXPIRE = 300 # dns查询结果缓存多久过期
@@ -26,6 +29,7 @@ module Girl
26
29
  CONTINUE = 17
27
30
  IS_RESEND_READY = 18
28
31
  RESEND_READY = 19
32
+ TRAFF_INFOS = 101
29
33
  HTTP_OK = "HTTP/1.1 200 OK\r\n\r\n"
30
34
  # https://www.iana.org/assignments/iana-ipv4-special-registry/iana-ipv4-special-registry.xhtml
31
35
  RESERVED_ROUTE = <<EOF
@@ -42,6 +46,7 @@ EOF
42
46
  WBUFF_LIMIT
43
47
  RESUME_BELOW
44
48
  SEND_HELLO_COUNT
49
+ SEND_HELLO_INTERVAL
45
50
  EXPIRE_AFTER
46
51
  CHECK_EXPIRE_INTERVAL
47
52
  CHECK_RESUME_INTERVAL
@@ -20,21 +20,34 @@ proxyd-tun:
20
20
 
21
21
  Q>: 0 ctlmsg -> C: 1 tund port -> n: tund port -> n: tcpd port
22
22
 
23
+ local-infod:
24
+
25
+ C: 101 traff infos
26
+
27
+ infod-local:
28
+
29
+ C: 101 traff infos -> [ C: im len -> im -> Q>: traff in -> Q>: traff out ]
30
+
23
31
  tun-tund:
24
32
 
25
- Q>: 0 ctlmsg -> C: 2 heartbeat [not use]
33
+ Q>: 0 ctlmsg -> C: 2 heartbeat
26
34
  3 a new source -> Q>: src id -> encoded destination address
27
35
  4 paired -> Q>: src id -> n: dst id
28
- 5 dest status [not use]
29
- 6 source status [not use]
30
- 7 miss [not use]
31
- 8 fin1 [not use]
32
- 9 confirm fin1 [not use]
33
- 10 fin2 [not use]
34
- 11 confirm fin2 [not use]
36
+ 5 dest status NOT USE
37
+ 6 source status NOT USE
38
+ 7 miss NOT USE
39
+ 8 fin1 NOT USE
40
+ 9 confirm fin1 NOT USE
41
+ 10 fin2 NOT USE
42
+ 11 confirm fin2 NOT USE
35
43
  12 tund fin
36
44
  13 tun fin
37
45
  14 tun ip changed
46
+ 15 single miss NOT USE
47
+ 16 range miss NOT USE
48
+ 17 continue NOT USE
49
+ 18 is resend ready NOT USE
50
+ 19 resend ready NOT USE
38
51
  =end
39
52
 
40
53
  module Girl
@@ -109,6 +122,10 @@ module Girl
109
122
  puts "im #{ im }"
110
123
  puts "worker count #{ worker_count }"
111
124
 
125
+ Girl::Custom.constants.each do | name |
126
+ puts "#{ name } #{ Girl::Custom.const_get( name ).inspect }"
127
+ end
128
+
112
129
  len = CONSTS.map{ | name | name.size }.max
113
130
 
114
131
  CONSTS.each do | name |
@@ -124,8 +124,28 @@ module Girl
124
124
  return if src.closed?
125
125
  src_info = @src_infos[ src ]
126
126
  src_info[ :wbuff ] << data
127
- add_write( src )
128
127
  src_info[ :last_recv_at ] = Time.new
128
+ add_write( src )
129
+
130
+ if src_info[ :wbuff ].bytesize >= WBUFF_LIMIT then
131
+ dst = src_info[ :dst ]
132
+
133
+ if dst then
134
+ dst_info = @dst_infos[ dst ]
135
+ puts "p#{ Process.pid } #{ Time.new } pause dst #{ dst_info[ :domain ] }"
136
+ dst_info[ :paused ] = true
137
+ @reads.delete( dst )
138
+ else
139
+ stream = src_info[ :stream ]
140
+
141
+ if stream then
142
+ stream_info = @stream_infos[ stream ]
143
+ puts "p#{ Process.pid } #{ Time.new } pause stream #{ stream_info[ :domain ] }"
144
+ stream_info[ :paused ] = true
145
+ @reads.delete( stream )
146
+ end
147
+ end
148
+ end
129
149
  end
130
150
 
131
151
  ##
@@ -168,7 +188,10 @@ module Girl
168
188
  def close_dst( dst )
169
189
  # puts "debug1 close dst"
170
190
  close_sock( dst )
171
- @dst_infos.delete( dst )
191
+ dst_info = @dst_infos.delete( dst )
192
+ src = dst_info[ :src ]
193
+ close_read_src( src )
194
+ set_src_closing_write( src )
172
195
  end
173
196
 
174
197
  ##
@@ -238,7 +261,32 @@ module Girl
238
261
  def close_src( src )
239
262
  # puts "debug1 close src"
240
263
  close_sock( src )
241
- del_src_info( src )
264
+ src_info = del_src_info( src )
265
+ dst = src_info[ :dst ]
266
+
267
+ if dst then
268
+ close_read_dst( dst )
269
+ set_dst_closing_write( dst )
270
+ else
271
+ stream = src_info[ :stream ]
272
+
273
+ if stream then
274
+ close_read_stream( stream )
275
+ set_stream_closing_write( stream )
276
+ end
277
+ end
278
+ end
279
+
280
+ ##
281
+ # close stream
282
+ #
283
+ def close_stream( stream )
284
+ # puts "debug1 close stream"
285
+ close_sock( stream )
286
+ stream_info = @stream_infos.delete( stream )
287
+ src = stream_info[ :src ]
288
+ close_read_src( src )
289
+ set_src_closing_write( src )
242
290
  end
243
291
 
244
292
  ##
@@ -267,6 +315,7 @@ module Girl
267
315
  src_info = @src_infos[ src ]
268
316
  end
269
317
 
318
+ src_info[ :closed_write ] = true
270
319
  src_info
271
320
  end
272
321
 
@@ -287,6 +336,7 @@ module Girl
287
336
  dst_info = @dst_infos[ dst ]
288
337
  end
289
338
 
339
+ dst_info[ :closed_write ] = true
290
340
  dst_info
291
341
  end
292
342
 
@@ -307,6 +357,7 @@ module Girl
307
357
  stream_info = @stream_infos[ stream ]
308
358
  end
309
359
 
360
+ stream_info[ :closed_write ] = true
310
361
  stream_info
311
362
  end
312
363
 
@@ -333,7 +384,7 @@ module Girl
333
384
  def del_src_info( src )
334
385
  src_info = @src_infos.delete( src )
335
386
 
336
- if src_info[ :stream ] && @tun && !@tun.closed? then
387
+ if ( src_info[ :proxy_type ] == :tunnel ) && @tun && !@tun.closed? then
337
388
  @tun_info[ :srcs ].delete( src_info[ :id ] )
338
389
  end
339
390
 
@@ -354,13 +405,17 @@ module Girl
354
405
 
355
406
  if @tun && !@tun.closed? then
356
407
  last_recv_at = @tun_info[ :last_recv_at ] || @tun_info[ :created_at ]
357
- last_sent_at = @tun_info[ :last_sent_at ] || @tun_info[ :created_at ]
358
408
 
359
- if @tun_info[ :srcs ].empty? && ( now - last_recv_at >= EXPIRE_AFTER ) && ( now - last_sent_at >= EXPIRE_AFTER ) then
409
+ if @tun_info[ :srcs ].empty? && ( now - last_recv_at >= EXPIRE_AFTER ) then
360
410
  puts "p#{ Process.pid } #{ Time.new } expire tun"
361
411
  set_tun_closing
362
- trigger = true
412
+ else
413
+ # puts "debug1 #{ Time.new } heartbeat"
414
+ data = [ 0, HEARTBEAT ].pack( 'Q>C' )
415
+ add_ctlmsg( data )
363
416
  end
417
+
418
+ trigger = true
364
419
  end
365
420
 
366
421
  @src_infos.each do | src, src_info |
@@ -414,6 +469,30 @@ module Girl
414
469
  end
415
470
  end
416
471
 
472
+ @dst_infos.select{ | _, dst_info | dst_info[ :paused ] }.each do | dst, dst_info |
473
+ src = dst_info[ :src ]
474
+ src_info = @src_infos[ src ]
475
+
476
+ if src_info[ :wbuff ].size < RESUME_BELOW then
477
+ puts "p#{ Process.pid } #{ Time.new } src.wbuff below #{ RESUME_BELOW }, resume dst #{ dst_info[ :domain ] }"
478
+ dst_info[ :paused ] = false
479
+ add_read( dst )
480
+ trigger = true
481
+ end
482
+ end
483
+
484
+ @stream_infos.select{ | _, stream_info | stream_info[ :paused ] }.each do | stream, stream_info |
485
+ src = stream_info[ :src ]
486
+ src_info = @src_infos[ src ]
487
+
488
+ if src_info[ :wbuff ].size < RESUME_BELOW then
489
+ puts "p#{ Process.pid } #{ Time.new } src.wbuff below #{ RESUME_BELOW }, resume stream #{ stream_info[ :domain ] }"
490
+ stream_info[ :paused ] = false
491
+ add_read( stream )
492
+ trigger = true
493
+ end
494
+ end
495
+
417
496
  next_tick if trigger
418
497
  end
419
498
  end
@@ -448,7 +527,7 @@ module Girl
448
527
  next_tick
449
528
  end
450
529
 
451
- sleep 1
530
+ sleep SEND_HELLO_INTERVAL
452
531
  end
453
532
  end
454
533
  end
@@ -469,7 +548,7 @@ module Girl
469
548
  rescue IO::WaitWritable
470
549
  # connect nonblock 必抛 wait writable
471
550
  rescue Exception => e
472
- puts "p#{ Process.pid } #{ Time.new } dst connect destination #{ e.class }, close src"
551
+ puts "p#{ Process.pid } #{ Time.new } dst connect destination #{ domain } #{ src_info[ :destination_port ] } #{ ip_info.ip_address } #{ e.class }, close src"
473
552
  set_src_closing( src )
474
553
  return
475
554
  end
@@ -479,11 +558,12 @@ module Girl
479
558
  dst_info = {
480
559
  local_port: local_port, # 本地端口
481
560
  src: src, # 对应src
482
- domain: domain, # 域名
561
+ domain: domain, # 目的地
483
562
  wbuff: '', # 写前,从src读到的流量
563
+ paused: false, # 是否已暂停读
484
564
  closing: false, # 准备关闭
485
- closing_read: false, # 准备关闭读
486
- closing_write: false # 准备关闭写
565
+ closing_write: false, # 准备关闭写
566
+ closed_write: false # 已关闭写
487
567
  }
488
568
 
489
569
  @dst_infos[ dst ] = dst_info
@@ -540,9 +620,15 @@ module Girl
540
620
  data << @custom.encode( src_info[ :rbuff ] )
541
621
  end
542
622
 
623
+ domain = src_info[ :destination_domain ]
543
624
  @stream_infos[ stream ] = {
544
- src: src, # 对应src
545
- wbuff: data # 写前,写往远端streamd
625
+ src: src, # 对应src
626
+ domain: domain, # 目的地
627
+ wbuff: data, # 写前,写往远端streamd
628
+ paused: false, # 是否已暂停读
629
+ closing: false, # 准备关闭
630
+ closing_write: false, # 准备关闭写
631
+ closed_write: false # 已关闭写
546
632
  }
547
633
 
548
634
  src_info[ :dst_id ] = dst_id
@@ -595,7 +681,6 @@ module Girl
595
681
  srcs: {}, # src_id => src
596
682
  created_at: Time.new, # 创建时间
597
683
  last_recv_at: nil, # 上一次收到流量的时间
598
- last_sent_at: nil, # 上一次发出流量的时间
599
684
  closing: false # 是否准备关闭
600
685
  }
601
686
 
@@ -621,7 +706,7 @@ module Girl
621
706
  next_tick
622
707
  end
623
708
 
624
- sleep 1
709
+ sleep SEND_HELLO_INTERVAL
625
710
  end
626
711
  end
627
712
  end
@@ -701,8 +786,13 @@ module Girl
701
786
  return if dst.closed?
702
787
  dst_info = @dst_infos[ dst ]
703
788
  dst_info[ :closing ] = true
704
- @reads.delete( dst )
705
- add_write( dst )
789
+
790
+ if dst_info[ :closed_write ] then
791
+ add_read( dst )
792
+ else
793
+ @reads.delete( dst )
794
+ add_write( dst )
795
+ end
706
796
  end
707
797
 
708
798
  ##
@@ -710,7 +800,10 @@ module Girl
710
800
  #
711
801
  def set_dst_closing_write( dst )
712
802
  return if dst.closed?
803
+
713
804
  dst_info = @dst_infos[ dst ]
805
+ return if dst_info[ :closed_write ]
806
+
714
807
  dst_info[ :closing_write ] = true
715
808
  add_write( dst )
716
809
  end
@@ -720,10 +813,15 @@ module Girl
720
813
  #
721
814
  def set_src_closing( src )
722
815
  return if src.closed?
723
- @reads.delete( src )
724
816
  src_info = @src_infos[ src ]
725
817
  src_info[ :closing ] = true
726
- add_write( src )
818
+
819
+ if src_info[ :closed_write ] then
820
+ add_read( src )
821
+ else
822
+ @reads.delete( src )
823
+ add_write( src )
824
+ end
727
825
  end
728
826
 
729
827
  ##
@@ -731,7 +829,10 @@ module Girl
731
829
  #
732
830
  def set_src_closing_write( src )
733
831
  return if src.closed?
832
+
734
833
  src_info = @src_infos[ src ]
834
+ return if src_info[ :closed_write ]
835
+
735
836
  src_info[ :closing_write ] = true
736
837
  add_write( src )
737
838
  end
@@ -756,23 +857,15 @@ module Girl
756
857
  end
757
858
  end
758
859
 
759
- ##
760
- # set stream closing
761
- #
762
- def set_stream_closing( stream )
763
- return if stream.closed?
764
- stream_info = @stream_infos[ stream ]
765
- stream_info[ :closing ] = true
766
- @reads.delete( stream )
767
- add_write( stream )
768
- end
769
-
770
860
  ##
771
861
  # set stream closing write
772
862
  #
773
863
  def set_stream_closing_write( stream )
774
864
  return if stream.closed?
865
+
775
866
  stream_info = @stream_infos[ stream ]
867
+ return if stream_info[ :closed_write ]
868
+
776
869
  stream_info[ :closing_write ] = true
777
870
  add_write( stream )
778
871
  end
@@ -842,10 +935,10 @@ module Girl
842
935
  created_at: Time.new, # 创建时间
843
936
  last_recv_at: nil, # 上一次收到新流量(由dst收到,或者由stream收到)的时间
844
937
  last_sent_at: nil, # 上一次发出流量(由dst发出,或者由stream发出)的时间
845
- paused: false, # 是否已暂停
938
+ paused: false, # 是否已暂停读
846
939
  closing: false, # 准备关闭
847
- closing_read: false, # 准备关闭读
848
- closing_write: false # 准备关闭写
940
+ closing_write: false, # 准备关闭写
941
+ closed_write: false # 已关闭写
849
942
  }
850
943
 
851
944
  add_read( src, :src )
@@ -863,10 +956,10 @@ module Girl
863
956
  end
864
957
 
865
958
  from_addr = addrinfo.to_sockaddr
866
- @tun_info[ :last_recv_at ] = Time.new
867
959
  pack_id = data[ 0, 8 ].unpack( 'Q>' ).first
868
960
  return if pack_id != 0
869
961
 
962
+ @tun_info[ :last_recv_at ] = Time.new
870
963
  ctl_num = data[ 8 ].unpack( 'C' ).first
871
964
 
872
965
  case ctl_num
@@ -912,6 +1005,8 @@ module Girl
912
1005
  # read src
913
1006
  #
914
1007
  def read_src( src )
1008
+ return if src.closed?
1009
+
915
1010
  begin
916
1011
  data = src.read_nonblock( READ_SIZE )
917
1012
  rescue IO::WaitReadable, Errno::EINTR
@@ -933,6 +1028,13 @@ module Girl
933
1028
  end
934
1029
 
935
1030
  src_info = @src_infos[ src ]
1031
+
1032
+ # 处理关闭
1033
+ if src_info[ :closing ] then
1034
+ close_src( src )
1035
+ return
1036
+ end
1037
+
936
1038
  proxy_type = src_info[ :proxy_type ]
937
1039
 
938
1040
  case proxy_type
@@ -1065,7 +1167,7 @@ module Girl
1065
1167
  add_write( stream )
1066
1168
 
1067
1169
  if stream_info[ :wbuff ].bytesize >= WBUFF_LIMIT then
1068
- puts "p#{ Process.pid } #{ Time.new } pause tunnel src #{ src_info[ :id ] } #{ src_info[ :destination_domain ] }"
1170
+ puts "p#{ Process.pid } #{ Time.new } pause tunnel src #{ src_info[ :destination_domain ] }"
1069
1171
  src_info[ :paused ] = true
1070
1172
  @reads.delete( src )
1071
1173
  end
@@ -1094,7 +1196,7 @@ module Girl
1094
1196
  add_write( dst )
1095
1197
 
1096
1198
  if dst_info[ :wbuff ].bytesize >= WBUFF_LIMIT then
1097
- puts "p#{ Process.pid } #{ Time.new } pause direct src #{ src_info[ :id ] } #{ src_info[ :destination_domain ] }"
1199
+ puts "p#{ Process.pid } #{ Time.new } pause direct src #{ src_info[ :destination_domain ] }"
1098
1200
  src_info[ :paused ] = true
1099
1201
  @reads.delete( src )
1100
1202
  end
@@ -1115,6 +1217,8 @@ module Girl
1115
1217
  # read dst
1116
1218
  #
1117
1219
  def read_dst( dst )
1220
+ return if dst.closed?
1221
+
1118
1222
  begin
1119
1223
  data = dst.read_nonblock( READ_SIZE )
1120
1224
  rescue IO::WaitReadable, Errno::EINTR
@@ -1129,6 +1233,13 @@ module Girl
1129
1233
  end
1130
1234
 
1131
1235
  dst_info = @dst_infos[ dst ]
1236
+
1237
+ # 处理关闭
1238
+ if dst_info[ :closing ] then
1239
+ close_dst( dst )
1240
+ return
1241
+ end
1242
+
1132
1243
  src = dst_info[ :src ]
1133
1244
  add_src_wbuff( src, data )
1134
1245
  end
@@ -1137,6 +1248,8 @@ module Girl
1137
1248
  # read stream
1138
1249
  #
1139
1250
  def read_stream( stream )
1251
+ return if stream.closed?
1252
+
1140
1253
  begin
1141
1254
  data = stream.read_nonblock( READ_SIZE )
1142
1255
  rescue IO::WaitReadable, Errno::EINTR
@@ -1177,7 +1290,6 @@ module Girl
1177
1290
  @tun.sendmsg_nonblock( data, 0, to_addr )
1178
1291
  rescue IO::WaitWritable, Errno::EINTR
1179
1292
  puts "p#{ Process.pid } #{ Time.new } wait send ctlmsg, left #{ @tun_info[ :ctlmsgs ].size }"
1180
- @tun_info[ :last_sent_at ] = now
1181
1293
  return
1182
1294
  rescue Errno::EHOSTUNREACH, Errno::ENETUNREACH, Errno::ENETDOWN => e
1183
1295
  puts "p#{ Process.pid } #{ Time.new } sendmsg #{ e.class }, close tun"
@@ -1188,7 +1300,6 @@ module Girl
1188
1300
  @tun_info[ :ctlmsgs ].shift
1189
1301
  end
1190
1302
 
1191
- @tun_info[ :last_sent_at ] = now
1192
1303
  @writes.delete( tun )
1193
1304
  end
1194
1305
 
@@ -1203,19 +1314,6 @@ module Girl
1203
1314
  # 处理关闭
1204
1315
  if src_info[ :closing ] then
1205
1316
  close_src( src )
1206
-
1207
- if dst then
1208
- close_read_dst( dst )
1209
- set_dst_closing_write( dst )
1210
- else
1211
- stream = src_info[ :stream ]
1212
-
1213
- if stream then
1214
- close_read_stream( stream )
1215
- set_stream_closing_write( stream )
1216
- end
1217
- end
1218
-
1219
1317
  return
1220
1318
  end
1221
1319
 
@@ -1269,12 +1367,6 @@ module Girl
1269
1367
  # 处理关闭
1270
1368
  if dst_info[ :closing ] then
1271
1369
  close_dst( dst )
1272
-
1273
- if src then
1274
- close_read_src( src )
1275
- set_src_closing_write( src )
1276
- end
1277
-
1278
1370
  return
1279
1371
  end
1280
1372
 
@@ -1324,8 +1416,6 @@ module Girl
1324
1416
  # 处理关闭
1325
1417
  if stream_info[ :closing ] then
1326
1418
  close_stream( stream )
1327
- close_read_src( src )
1328
- set_src_closing_write( src )
1329
1419
  return
1330
1420
  end
1331
1421
 
@@ -17,6 +17,7 @@ module Girl
17
17
  raise "not found config file #{ config_path }" unless File.exist?( config_path )
18
18
  conf = JSON.parse( IO.binread( config_path ), symbolize_names: true )
19
19
  proxyd_port = conf[ :proxyd_port ]
20
+ infod_port = conf[ :infod_port ]
20
21
  worker_count = conf[ :worker_count ]
21
22
  end
22
23
 
@@ -24,6 +25,10 @@ module Girl
24
25
  proxyd_port = 6060
25
26
  end
26
27
 
28
+ unless infod_port then
29
+ infod_port = 6070
30
+ end
31
+
27
32
  nprocessors = Etc.nprocessors
28
33
 
29
34
  if worker_count.nil? || worker_count <= 0 || worker_count > nprocessors then
@@ -33,8 +38,13 @@ module Girl
33
38
  title = "girl proxyd #{ Girl::VERSION }"
34
39
  puts title
35
40
  puts "proxyd port #{ proxyd_port }"
41
+ puts "infod port #{ infod_port }"
36
42
  puts "worker count #{ worker_count }"
37
43
 
44
+ Girl::Custom.constants.each do | name |
45
+ puts "#{ name } #{ Girl::Custom.const_get( name ).inspect }"
46
+ end
47
+
38
48
  len = CONSTS.map{ | name | name.size }.max
39
49
 
40
50
  CONSTS.each do | name |
@@ -47,7 +57,7 @@ module Girl
47
57
  worker_count.times do | i |
48
58
  workers << fork do
49
59
  $0 = 'girl proxyd worker'
50
- worker = Girl::ProxydWorker.new( proxyd_port )
60
+ worker = Girl::ProxydWorker.new( proxyd_port, infod_port )
51
61
 
52
62
  Signal.trap( :TERM ) do
53
63
  puts "w#{ i } exit"
@@ -4,23 +4,26 @@ module Girl
4
4
  ##
5
5
  # initialize
6
6
  #
7
- def initialize( proxyd_port )
7
+ def initialize( proxyd_port, infod_port )
8
8
  @custom = Girl::ProxydCustom.new
9
9
  @mutex = Mutex.new
10
10
  @reads = []
11
11
  @writes = []
12
- @roles = {} # sock => :dotr / :proxyd / :dst / :tund / :tcpd / :streamd
12
+ @roles = {} # sock => :dotr / :proxyd / :infod / :dst / :tund / :tcpd / :streamd
13
13
  @tund_infos = {} # tund => {}
14
14
  @tcpd_infos = {} # tcpd => {}
15
15
  @dst_infos = {} # dst => {}
16
16
  @streamd_infos = {} # streamd => {}
17
17
  @tunneling_tunds = {} # tunneling_addr => tund
18
18
  @resolv_caches = {} # domain => [ ip, created_at ]
19
+ @traff_ins = {} # im => 0
20
+ @traff_outs = {} # im => 0
19
21
 
20
22
  dotr, dotw = IO.pipe
21
23
  @dotw = dotw
22
24
  add_read( dotr, :dotr )
23
25
  new_a_proxyd( proxyd_port )
26
+ new_a_infod( infod_port )
24
27
  end
25
28
 
26
29
  ##
@@ -30,6 +33,7 @@ module Girl
30
33
  puts "p#{ Process.pid } #{ Time.new } looping"
31
34
  loop_check_expire
32
35
  loop_check_resume
36
+ loop_check_traff
33
37
 
34
38
  loop do
35
39
  rs, ws = IO.select( @reads, @writes )
@@ -42,6 +46,8 @@ module Girl
42
46
  read_dotr( sock )
43
47
  when :proxyd then
44
48
  read_proxyd( sock )
49
+ when :infod then
50
+ read_infod( sock )
45
51
  when :tund then
46
52
  read_tund( sock )
47
53
  when :tcpd then
@@ -137,7 +143,13 @@ module Girl
137
143
  def close_dst( dst )
138
144
  # puts "debug1 close dst"
139
145
  close_sock( dst )
140
- del_dst_info( dst )
146
+ dst_info = del_dst_info( dst )
147
+ streamd = dst_info[ :streamd ]
148
+
149
+ if streamd then
150
+ close_read_streamd( streamd )
151
+ set_streamd_closing_write( streamd )
152
+ end
141
153
  end
142
154
 
143
155
  ##
@@ -197,7 +209,13 @@ module Girl
197
209
  def close_streamd( streamd )
198
210
  # puts "debug1 close streamd"
199
211
  close_sock( streamd )
200
- @streamd_infos.delete( streamd )
212
+ streamd_info = @streamd_infos.delete( streamd )
213
+ dst = streamd_info[ :dst ]
214
+
215
+ if dst then
216
+ close_read_dst( dst )
217
+ set_dst_closing_write( dst )
218
+ end
201
219
  end
202
220
 
203
221
  ##
@@ -231,6 +249,7 @@ module Girl
231
249
  dst_info = @dst_infos[ dst ]
232
250
  end
233
251
 
252
+ dst_info[ :closed_write ] = true
234
253
  dst_info
235
254
  end
236
255
 
@@ -251,6 +270,7 @@ module Girl
251
270
  streamd_info = @streamd_infos[ streamd ]
252
271
  end
253
272
 
273
+ streamd_info[ :closed_write ] = true
254
274
  streamd_info
255
275
  end
256
276
 
@@ -265,16 +285,18 @@ module Girl
265
285
  dst.connect_nonblock( destination_addr )
266
286
  rescue IO::WaitWritable
267
287
  rescue Exception => e
268
- puts "p#{ Process.pid } #{ Time.new } connect destination #{ e.class }"
288
+ puts "p#{ Process.pid } #{ Time.new } connect destination #{ domain_port } #{ e.class }"
269
289
  return false
270
290
  end
271
291
 
272
292
  dst_id = dst.local_address.ip_port
293
+ tund_info = @tund_infos[ tund ]
273
294
 
274
295
  @dst_infos[ dst ] = {
275
296
  id: dst_id, # id
276
297
  tund: tund, # 对应tund
277
- domain_port: domain_port, # 域名和端口
298
+ im: tund_info[ :im ], # 标识
299
+ domain_port: domain_port, # 目的地和端口
278
300
  rbuff: '', # 对应的streamd没准备好,暂存读到的流量
279
301
  streamd: nil, # 对应的streamd
280
302
  wbuff: '', # 从streamd读到的流量
@@ -282,15 +304,14 @@ module Girl
282
304
  created_at: Time.new, # 创建时间
283
305
  last_recv_at: nil, # 上一次收到新流量(由streamd收到)的时间
284
306
  last_sent_at: nil, # 上一次发出流量(由streamd发出)的时间
285
- paused: false, # 是否已暂停
307
+ paused: false, # 是否已暂停读
286
308
  closing: false, # 准备关闭
287
- closing_read: false, # 准备关闭读
288
- closing_write: false # 准备关闭写
309
+ closing_write: false, # 准备关闭写
310
+ closed_write: false # 已关闭写
289
311
  }
290
312
 
291
313
  add_read( dst, :dst )
292
314
 
293
- tund_info = @tund_infos[ tund ]
294
315
  tund_info[ :dst_ids ][ src_id ] = dst_id
295
316
  tund_info[ :dsts ][ dst_id ] = dst
296
317
 
@@ -330,9 +351,8 @@ module Girl
330
351
 
331
352
  @tund_infos.each do | tund, tund_info |
332
353
  last_recv_at = tund_info[ :last_recv_at ] || tund_info[ :created_at ]
333
- last_sent_at = tund_info[ :last_sent_at ] || tund_info[ :created_at ]
334
354
 
335
- if tund_info[ :dsts ].empty? && ( now - last_recv_at >= EXPIRE_AFTER ) && ( now - last_sent_at >= EXPIRE_AFTER ) then
355
+ if tund_info[ :dsts ].empty? && ( now - last_recv_at >= EXPIRE_AFTER ) then
336
356
  puts "p#{ Process.pid } #{ Time.new } expire tund #{ tund_info[ :port ] }"
337
357
  set_tund_closing( tund )
338
358
  trigger = true
@@ -379,12 +399,45 @@ module Girl
379
399
  end
380
400
  end
381
401
 
402
+ @streamd_infos.select{ | _, streamd_info | streamd_info[ :paused ] }.each do | streamd, streamd_info |
403
+ dst = streamd_info[ :dst ]
404
+ dst_info = @dst_infos[ dst ]
405
+
406
+ if dst_info[ :wbuff ].size < RESUME_BELOW then
407
+ puts "p#{ Process.pid } #{ Time.new } resume streamd #{ streamd_info[ :domain_port ] }"
408
+ streamd_info[ :paused ] = false
409
+ add_read( streamd )
410
+ trigger = true
411
+ end
412
+ end
413
+
382
414
  next_tick if trigger
383
415
  end
384
416
  end
385
417
  end
386
418
  end
387
419
 
420
+ ##
421
+ # loop check traff
422
+ #
423
+ def loop_check_traff
424
+ if RESET_TRAFF_DAY > 0 then
425
+ Thread.new do
426
+ loop do
427
+ sleep CHECK_TRAFF_INTERVAL
428
+
429
+ @mutex.synchronize do
430
+ if Time.new.day == RESET_TRAFF_DAY then
431
+ puts "p#{ Process.pid } #{ Time.new } reset traffs"
432
+ @traff_ins.transform_values!{ | _ | 0 }
433
+ @traff_outs.transform_values!{ | _ | 0 }
434
+ end
435
+ end
436
+ end
437
+ end
438
+ end
439
+ end
440
+
388
441
  ##
389
442
  # new a proxyd
390
443
  #
@@ -402,6 +455,18 @@ module Girl
402
455
  add_read( proxyd, :proxyd )
403
456
  end
404
457
 
458
+ ##
459
+ # new a infod
460
+ #
461
+ def new_a_infod( infod_port )
462
+ infod = Socket.new( Socket::AF_INET, Socket::SOCK_DGRAM, 0 )
463
+ infod.setsockopt( Socket::SOL_SOCKET, Socket::SO_REUSEPORT, 1 )
464
+ infod.bind( Socket.sockaddr_in( infod_port, '127.0.0.1' ) )
465
+
466
+ puts "p#{ Process.pid } #{ Time.new } infod bind on #{ infod_port }"
467
+ add_read( infod, :infod )
468
+ end
469
+
405
470
  ##
406
471
  # next tick
407
472
  #
@@ -480,8 +545,13 @@ module Girl
480
545
  return if dst.closed?
481
546
  dst_info = @dst_infos[ dst ]
482
547
  dst_info[ :closing ] = true
483
- @reads.delete( dst )
484
- add_write( dst )
548
+
549
+ if dst_info[ :closed_write ] then
550
+ add_read( dst )
551
+ else
552
+ @reads.delete( dst )
553
+ add_write( dst )
554
+ end
485
555
  end
486
556
 
487
557
  ##
@@ -489,7 +559,10 @@ module Girl
489
559
  #
490
560
  def set_dst_closing_write( dst )
491
561
  return if dst.closed?
562
+
492
563
  dst_info = @dst_infos[ dst ]
564
+ return if dst_info[ :closed_write ]
565
+
493
566
  dst_info[ :closing_write ] = true
494
567
  add_write( dst )
495
568
  end
@@ -501,8 +574,13 @@ module Girl
501
574
  return if streamd.closed?
502
575
  streamd_info = @streamd_infos[ streamd ]
503
576
  streamd_info[ :closing ] = true
504
- @reads.delete( streamd )
505
- add_write( streamd )
577
+
578
+ if streamd_info[ :closed_write ] then
579
+ add_read( streamd )
580
+ else
581
+ @reads.delete( streamd )
582
+ add_write( streamd )
583
+ end
506
584
  end
507
585
 
508
586
  ##
@@ -510,7 +588,10 @@ module Girl
510
588
  #
511
589
  def set_streamd_closing_write( streamd )
512
590
  return if streamd.closed?
591
+
513
592
  streamd_info = @streamd_infos[ streamd ]
593
+ return if streamd_info[ :closed_write ]
594
+
514
595
  streamd_info[ :closing_write ] = true
515
596
  add_write( streamd )
516
597
  end
@@ -555,6 +636,13 @@ module Girl
555
636
  return
556
637
  end
557
638
 
639
+ im = data
640
+
641
+ unless @traff_ins.include?( im ) then
642
+ @traff_ins[ im ] = 0
643
+ @traff_outs[ im ] = 0
644
+ end
645
+
558
646
  tund = Socket.new( Socket::AF_INET, Socket::SOCK_DGRAM, 0 )
559
647
  tund.bind( Socket.sockaddr_in( 0, '0.0.0.0' ) )
560
648
  tund_port = tund.local_address.ip_port
@@ -568,6 +656,7 @@ module Girl
568
656
  add_read( tcpd, :tcpd )
569
657
 
570
658
  tund_info = {
659
+ im: im, # 标识
571
660
  port: tund_port, # 端口
572
661
  tcpd: tcpd, # 对应的tcpd
573
662
  tcpd_port: tcpd_port, # tcpd端口
@@ -577,10 +666,7 @@ module Girl
577
666
  dst_ids: {}, # src_id => dst_id
578
667
  created_at: Time.new, # 创建时间
579
668
  last_recv_at: nil, # 上一次收到流量的时间
580
- last_sent_at: nil, # 上一次发出流量的时间
581
669
  closing: false, # 准备关闭
582
- closing_read: false, # 准备关闭读
583
- closing_write: false, # 准备关闭写
584
670
  changed_tun_addr: nil # 记录到和tun addr不符的来源地址
585
671
  }
586
672
 
@@ -594,6 +680,28 @@ module Girl
594
680
  add_proxyd_ctlmsg_tund_port( tund_info )
595
681
  end
596
682
 
683
+ ##
684
+ # read infod
685
+ #
686
+ def read_infod( infod )
687
+ data, addrinfo, rflags, *controls = infod.recvmsg
688
+ ctl_num = data[ 0 ].unpack( 'C' ).first
689
+ # puts "debug1 infod recv #{ ctl_num } #{ addrinfo.inspect }"
690
+
691
+ case ctl_num
692
+ when TRAFF_INFOS then
693
+ data2 = [ TRAFF_INFOS ].pack( 'C' )
694
+
695
+ @traff_ins.keys.sort.each do | im |
696
+ traff_in = @traff_ins[ im ]
697
+ traff_out = @traff_outs[ im ]
698
+ data2 << [ [ im.bytesize ].pack( 'C' ), im, [ traff_in, traff_out ].pack( 'Q>Q>' ) ].join
699
+ end
700
+
701
+ send_data( infod, data2, addrinfo )
702
+ end
703
+ end
704
+
597
705
  ##
598
706
  # read tund
599
707
  #
@@ -616,10 +724,10 @@ module Girl
616
724
  return
617
725
  end
618
726
 
619
- tund_info[ :last_recv_at ] = Time.new
620
727
  pack_id = data[ 0, 8 ].unpack( 'Q>' ).first
621
728
  return if pack_id != 0
622
729
 
730
+ tund_info[ :last_recv_at ] = Time.new
623
731
  ctl_num = data[ 8 ].unpack( 'C' ).first
624
732
 
625
733
  case ctl_num
@@ -665,11 +773,18 @@ module Girl
665
773
  # puts "debug1 accept a streamd"
666
774
  tcpd_info = @tcpd_infos[ tcpd ]
667
775
  tund = tcpd_info[ :tund ]
776
+ tund_info = @tund_infos[ tund ]
668
777
 
669
778
  @streamd_infos[ streamd ] = {
670
- tund: tund, # 对应tund
671
- dst: nil, # 对应dst
672
- wbuff: '' # 写前,写往近端stream
779
+ tund: tund, # 对应tund
780
+ im: tund_info[ :im ], # 标识
781
+ dst: nil, # 对应dst
782
+ domain_port: nil, # dst的目的地和端口
783
+ wbuff: '', # 写前,写往近端stream
784
+ paused: false, # 是否已暂停读
785
+ closing: false, # 准备关闭
786
+ closing_write: false, # 准备关闭写
787
+ closed_write: false # 已关闭写
673
788
  }
674
789
 
675
790
  add_read( streamd, :streamd )
@@ -679,6 +794,8 @@ module Girl
679
794
  # read dst
680
795
  #
681
796
  def read_dst( dst )
797
+ return if dst.closed?
798
+
682
799
  begin
683
800
  data = dst.read_nonblock( READ_SIZE )
684
801
  rescue IO::WaitReadable, Errno::EINTR
@@ -693,6 +810,14 @@ module Girl
693
810
  end
694
811
 
695
812
  dst_info = @dst_infos[ dst ]
813
+
814
+ # 处理关闭
815
+ if dst_info[ :closing ] then
816
+ close_dst( dst )
817
+ return
818
+ end
819
+
820
+ @traff_ins[ dst_info[ :im ] ] += data.bytesize
696
821
  streamd = dst_info[ :streamd ]
697
822
 
698
823
  if streamd then
@@ -704,7 +829,7 @@ module Girl
704
829
  add_write( streamd )
705
830
 
706
831
  if streamd_info[ :wbuff ].bytesize >= WBUFF_LIMIT then
707
- puts "p#{ Process.pid } #{ Time.new } pause dst #{ dst_info[ :id ] } #{ dst_info[ :domain_port ] }"
832
+ puts "p#{ Process.pid } #{ Time.new } pause dst #{ dst_info[ :domain_port ] }"
708
833
  dst_info[ :paused ] = true
709
834
  @reads.delete( dst )
710
835
  end
@@ -723,6 +848,8 @@ module Girl
723
848
  # read streamd
724
849
  #
725
850
  def read_streamd( streamd )
851
+ return if streamd.closed?
852
+
726
853
  begin
727
854
  data = streamd.read_nonblock( READ_SIZE )
728
855
  rescue IO::WaitReadable, Errno::EINTR
@@ -737,6 +864,14 @@ module Girl
737
864
  end
738
865
 
739
866
  streamd_info = @streamd_infos[ streamd ]
867
+
868
+ # 处理关闭
869
+ if streamd_info[ :closing ] then
870
+ close_streamd( streamd )
871
+ return
872
+ end
873
+
874
+ @traff_ins[ streamd_info[ :im ] ] += data.bytesize
740
875
  dst = streamd_info[ :dst ]
741
876
 
742
877
  unless dst then
@@ -759,6 +894,7 @@ module Girl
759
894
  # puts "debug1 set streamd.dst #{ dst_id }"
760
895
  streamd_info[ :dst ] = dst
761
896
  dst_info = @dst_infos[ dst ]
897
+ streamd_info[ :domain_port ] = dst_info[ :domain_port ]
762
898
 
763
899
  unless dst_info[ :rbuff ].empty? then
764
900
  # puts "debug1 encode and move dst.rbuff to streamd.wbuff"
@@ -778,6 +914,12 @@ module Girl
778
914
  dst_info[ :wbuff ] << data
779
915
  dst_info[ :last_recv_at ] = Time.new
780
916
  add_write( dst )
917
+
918
+ if dst_info[ :wbuff ].bytesize >= WBUFF_LIMIT then
919
+ puts "p#{ Process.pid } #{ Time.new } pause streamd #{ streamd_info[ :domain_port ] }"
920
+ streamd_info[ :paused ] = true
921
+ @reads.delete( streamd )
922
+ end
781
923
  end
782
924
  end
783
925
 
@@ -830,14 +972,12 @@ module Girl
830
972
  return
831
973
  elsif sent == :wait then
832
974
  puts "p#{ Process.pid } #{ Time.new } wait tund #{ tund_info[ :port ] } send ctlmsg, left #{ tund_info[ :ctlmsgs ].size }"
833
- tund_info[ :last_sent_at ] = now
834
975
  return
835
976
  end
836
977
 
837
978
  tund_info[ :ctlmsgs ].shift
838
979
  end
839
980
 
840
- tund_info[ :last_sent_at ] = now
841
981
  @writes.delete( tund )
842
982
  end
843
983
 
@@ -852,12 +992,6 @@ module Girl
852
992
  # 处理关闭
853
993
  if dst_info[ :closing ] then
854
994
  close_dst( dst )
855
-
856
- if streamd then
857
- close_read_streamd( streamd )
858
- set_streamd_closing_write( streamd )
859
- end
860
-
861
995
  return
862
996
  end
863
997
 
@@ -890,6 +1024,7 @@ module Girl
890
1024
  # puts "debug2 written dst #{ written }"
891
1025
  data = data[ written..-1 ]
892
1026
  dst_info[ :wbuff ] = data
1027
+ @traff_outs[ dst_info[ :im ] ] += written
893
1028
  end
894
1029
 
895
1030
  ##
@@ -903,12 +1038,6 @@ module Girl
903
1038
  # 处理关闭
904
1039
  if streamd_info[ :closing ] then
905
1040
  close_streamd( streamd )
906
-
907
- if dst then
908
- close_read_dst( dst )
909
- set_dst_closing_write( dst )
910
- end
911
-
912
1041
  return
913
1042
  end
914
1043
 
@@ -941,6 +1070,7 @@ module Girl
941
1070
  # puts "debug2 written streamd #{ written }"
942
1071
  data = data[ written..-1 ]
943
1072
  streamd_info[ :wbuff ] = data
1073
+ @traff_outs[ streamd_info[ :im ] ] += written
944
1074
 
945
1075
  if dst && !dst.closed? then
946
1076
  dst_info = @dst_infos[ dst ]
@@ -1,3 +1,3 @@
1
1
  module Girl
2
- VERSION = '0.90.0'.freeze
2
+ VERSION = '0.95.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.90.0
4
+ version: 0.95.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-10-11 00:00:00.000000000 Z
11
+ date: 2020-10-15 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: escape evil.
14
14
  email: