girl 0.90.0 → 0.95.0

This diff has not been reviewed by any users.
Sign up to get free protection for your applications and to get access to all the features.
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: