girl 9.1.0 → 9.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ddce98f59f1102d50d58fd02775ed1305f3babb3a2b7998a4ed86f39438e2599
4
- data.tar.gz: b51d851640addd0acb8d5367b9d6295a67036e720436c6d0bea9ed352222f9bc
3
+ metadata.gz: 673184bfb0785b65e56e4715c2b007481ae91d16620fbc11e3f6e12c50f511b5
4
+ data.tar.gz: 9a37c381bbf266cac12239b479214979202a8b715a1db0c5f443f8ecd3ca046a
5
5
  SHA512:
6
- metadata.gz: 469527cb74ea0a0aab7af6358dcd345852c8c9c25b9adbcb69f70acaa582592b696a2549d92e3970d55b0a607fe400f107c8445e075fffb6c22bc4d82837289a
7
- data.tar.gz: 1ce78e2d003752fb847c11ec505960c82a241d4d0b8ebde1047e7ac788532bb35ad6d985cf76067e20c638a788736336a35a2381b146664d4c391a5e3441d39f
6
+ metadata.gz: d291af3cfc1ff8813e187062a55b93ad9f0c6a52f7bd14e19c4638becd98c96451da21146a167111c5da01d2f20b6fc31711143e71d82e82bf5cf68d8e420efb
7
+ data.tar.gz: 9a6e13e0f756afd3a024f7c7c386fd18e5978488bd1909fd69dbabffacd25e71d8d0c286920ec86665ed69766cee1464ba1d4a8fcab94055fdf82d405392d96b
data/lib/girl/proxy.rb CHANGED
@@ -23,8 +23,12 @@ module Girl
23
23
 
24
24
  conf = JSON.parse( IO.binread( config_path ), symbolize_names: true )
25
25
  puts "load #{ config_path } #{ conf.inspect }"
26
+ redir_host = conf[ :redir_host ]
26
27
  redir_port = conf[ :redir_port ]
27
28
  memd_port = conf[ :memd_port ]
29
+ relayd_host = conf[ :relayd_host ]
30
+ relayd_port = conf[ :relayd_port ]
31
+ tspd_host = conf[ :tspd_host ]
28
32
  tspd_port = conf[ :tspd_port ]
29
33
  proxyd_host = conf[ :proxyd_host ]
30
34
  proxyd_port = conf[ :proxyd_port ]
@@ -54,7 +58,6 @@ module Girl
54
58
  h_src_underhalf = conf[ :h_src_underhalf ] # V
55
59
  h_dst_overflow = conf[ :h_dst_overflow ] # W
56
60
  h_dst_underhalf = conf[ :h_dst_underhalf ] # X
57
-
58
61
  expire_connecting = conf[ :expire_connecting ] # 连接多久没有建成关闭(秒)
59
62
  expire_long_after = conf[ :expire_long_after ] # 长连接多久没有新流量关闭(秒)
60
63
  expire_proxy_after = conf[ :expire_proxy_after ] # proxy多久没有收到流量重建(秒)
@@ -62,8 +65,12 @@ module Girl
62
65
  expire_short_after = conf[ :expire_short_after ] # 短连接创建多久后关闭(秒)
63
66
  is_debug = conf[ :is_debug ]
64
67
 
68
+ redir_host = redir_host ? redir_host.to_s : '0.0.0.0'
65
69
  redir_port = redir_port ? redir_port.to_i : 6666
66
70
  memd_port = memd_port ? memd_port.to_i : redir_port + 1
71
+ relayd_host = relayd_host ? relayd_host.to_s : '0.0.0.0'
72
+ relayd_port = relayd_port ? relayd_port.to_i : redir_port + 2
73
+ tspd_host = tspd_host ? tspd_host.to_s : '0.0.0.0'
67
74
  tspd_port = tspd_port ? tspd_port.to_i : 7777
68
75
  raise "missing proxyd host" unless proxyd_host
69
76
  proxyd_port = proxyd_port ? proxyd_port.to_i : 6060
@@ -128,8 +135,8 @@ module Girl
128
135
  end
129
136
  end
130
137
 
131
- puts "girl proxy #{ Girl::VERSION } #{ im }"
132
- puts "#{ redir_port } #{ tspd_port } #{ proxyd_host } #{ proxyd_port } #{ appd_host } #{ appd_port } #{ nameservers.inspect } #{ is_client_fastopen } #{ is_server_fastopen }"
138
+ puts "girl proxy #{ Girl::VERSION } #{ im } #{ redir_port } #{ relayd_port } #{ tspd_port }"
139
+ puts "#{ proxyd_host } #{ proxyd_port } #{ appd_host } #{ appd_port } #{ nameservers.inspect } #{ is_client_fastopen } #{ is_server_fastopen }"
133
140
  puts "#{ direct_path } #{ directs.size } directs"
134
141
  puts "#{ remote_path } #{ remotes.size } remotes"
135
142
 
@@ -139,8 +146,12 @@ module Girl
139
146
  end
140
147
 
141
148
  worker = Girl::ProxyWorker.new(
149
+ redir_host,
142
150
  redir_port,
143
151
  memd_port,
152
+ relayd_host,
153
+ relayd_port,
154
+ tspd_host,
144
155
  tspd_port,
145
156
  proxyd_host,
146
157
  proxyd_port,
@@ -3,8 +3,12 @@ module Girl
3
3
  include Dns
4
4
 
5
5
  def initialize(
6
+ redir_host,
6
7
  redir_port,
7
8
  memd_port,
9
+ relayd_host,
10
+ relayd_port,
11
+ tspd_host,
8
12
  tspd_port,
9
13
  proxyd_host,
10
14
  proxyd_port,
@@ -51,14 +55,16 @@ module Girl
51
55
  @remotes = remotes
52
56
  @local_ips = Socket.ip_address_list.select{ | info | info.ipv4? }.map{ | info | info.ip_address }
53
57
  @update_roles = [ :dns, :dst, :mem, :p1, :src, :rsv ] # 参与淘汰的角色
54
- @updates_limit = 1008 # 淘汰池上限,1015(mac) - info, infod, memd, proxy, redir, rsvd, tspd
58
+ @updates_limit = 1007 # 淘汰池上限,1015(mac) - info, infod, memd, proxy, redir, relayd, rsvd, tspd
55
59
  @eliminate_count = 0 # 淘汰次数
56
60
  @reads = [] # 读池
57
61
  @writes = [] # 写池
58
- @roles = {} # sock => :dns / :dst / :infod / :mem / :memd / :p1 / :proxy / :redir / :rsv / :rsvd / :src / :tspd
62
+ @roles = {} # sock => :dns / :dst / :girl / :infod / :mem / :memd / :p1 / :proxy / :redir / :relay / :relayd / :rsv / :rsvd / :src / :tspd
59
63
  @updates = {} # sock => updated_at
60
64
  @proxy_infos = {} # proxy => { :is_syn :paused_p1s :paused_srcs :rbuff :recv_at :wbuff }
61
65
  @mem_infos = {} # mem => { :wbuff }
66
+ @relay_infos = {} # relay => { :addrinfo :closing :girl :overflowing :wbuff }
67
+ @girl_infos = {} # girl => { :closing :connected :is_syn :overflowing :relay :wbuff }
62
68
  @src_infos = {} # src => { :addrinfo :closing :destination_domain :destination_port :dst :is_connect :overflowing :proxy_proto :proxy_type :rbuff :src_id :wbuff }
63
69
  @dst_infos = {} # dst => { :closing :connected :domain :ip :overflowing :port :src :wbuff }
64
70
  @dns_infos = {} # dns => { :domain :src }
@@ -100,11 +106,12 @@ module Girl
100
106
  @is_client_fastopen = is_client_fastopen
101
107
  @is_server_fastopen = is_server_fastopen
102
108
 
103
- new_a_redir( redir_port )
109
+ new_a_redir( redir_host, redir_port )
104
110
  new_a_infod( redir_port )
105
111
  new_a_memd( memd_port )
106
- new_a_rsvd( tspd_port )
107
- new_a_tspd( tspd_port )
112
+ new_a_relayd( relayd_host, relayd_port )
113
+ new_a_rsvd( tspd_host, tspd_port )
114
+ new_a_tspd( tspd_host, tspd_port )
108
115
  new_a_proxy
109
116
  end
110
117
 
@@ -123,6 +130,8 @@ module Girl
123
130
  read_dns( sock )
124
131
  when :dst then
125
132
  read_dst( sock )
133
+ when :girl then
134
+ read_girl( sock )
126
135
  when :infod then
127
136
  read_infod( sock )
128
137
  when :mem then
@@ -135,6 +144,10 @@ module Girl
135
144
  read_proxy( sock )
136
145
  when :redir then
137
146
  read_redir( sock )
147
+ when :relay then
148
+ read_relay( sock )
149
+ when :relayd then
150
+ read_relayd( sock )
138
151
  when :rsv then
139
152
  read_rsv( sock )
140
153
  when :rsvd then
@@ -154,12 +167,16 @@ module Girl
154
167
  case role
155
168
  when :dst then
156
169
  write_dst( sock )
170
+ when :girl then
171
+ write_girl( sock )
157
172
  when :mem then
158
173
  write_mem( sock )
159
174
  when :p1 then
160
175
  write_p1( sock )
161
176
  when :proxy then
162
177
  write_proxy( sock )
178
+ when :relay then
179
+ write_relay( sock )
163
180
  when :src then
164
181
  write_src( sock )
165
182
  else
@@ -184,6 +201,12 @@ module Girl
184
201
  dst_info[ :wbuff ] << data
185
202
  bytesize = dst_info[ :wbuff ].bytesize
186
203
 
204
+ if bytesize >= CLOSE_ABOVE then
205
+ puts "close overflow dst #{ dst_info[ :domain ] }"
206
+ close_dst( dst )
207
+ return
208
+ end
209
+
187
210
  if !dst_info[ :overflowing ] && ( bytesize >= WBUFF_LIMIT ) then
188
211
  puts "dst overflow pause src #{ dst_info[ :domain ] }"
189
212
  @reads.delete( dst_info[ :src ] )
@@ -193,6 +216,27 @@ module Girl
193
216
  add_write( dst )
194
217
  end
195
218
 
219
+ def add_girl_wbuff( girl, data )
220
+ return if girl.nil? || girl.closed? || data.nil? || data.empty?
221
+ girl_info = @girl_infos[ girl ]
222
+ girl_info[ :wbuff ] << data
223
+ bytesize = girl_info[ :wbuff ].bytesize
224
+
225
+ if bytesize >= CLOSE_ABOVE then
226
+ puts "close overflow girl"
227
+ close_girl( girl )
228
+ return
229
+ end
230
+
231
+ if !girl_info[ :overflowing ] && ( bytesize >= WBUFF_LIMIT ) then
232
+ puts "girl overflow pause relay"
233
+ @reads.delete( girl_info[ :relay ] )
234
+ girl_info[ :overflowing ] = true
235
+ end
236
+
237
+ add_write( girl )
238
+ end
239
+
196
240
  def add_mem_wbuff( mem, data )
197
241
  return if mem.nil? || mem.closed? || data.nil? || data.empty?
198
242
  mem_info = @mem_infos[ mem ]
@@ -219,7 +263,7 @@ module Girl
219
263
  add_proxy_wbuff( pack_a_chunk( msg ) )
220
264
  p1_info[ :overflowing ] = true
221
265
  end
222
-
266
+
223
267
  add_write( p1 )
224
268
  end
225
269
 
@@ -253,6 +297,27 @@ module Girl
253
297
  end
254
298
  end
255
299
 
300
+ def add_relay_wbuff( relay, data )
301
+ return if relay.nil? || relay.closed? || data.nil? || data.empty?
302
+ relay_info = @relay_infos[ relay ]
303
+ relay_info[ :wbuff ] << data
304
+ bytesize = relay_info[ :wbuff ].bytesize
305
+
306
+ if bytesize >= CLOSE_ABOVE then
307
+ puts "close overflow relay #{ relay_info[ :addrinfo ].ip_unpack.inspect }"
308
+ close_relay( relay )
309
+ return
310
+ end
311
+
312
+ if !relay_info[ :overflowing ] && ( bytesize >= WBUFF_LIMIT ) then
313
+ puts "relay overflow pause girl #{ relay_info[ :addrinfo ].ip_unpack.inspect }"
314
+ @reads.delete( relay_info[ :girl ] )
315
+ relay_info[ :overflowing ] = true
316
+ end
317
+
318
+ add_write( relay )
319
+ end
320
+
256
321
  def add_socks5_conn_reply( src )
257
322
  # +----+-----+-------+------+----------+----------+
258
323
  # |VER | REP | RSV | ATYP | BND.ADDR | BND.PORT |
@@ -334,6 +399,15 @@ module Girl
334
399
  end
335
400
  end
336
401
 
402
+ def check_expire_girls
403
+ now = Time.new
404
+
405
+ @girl_infos.select{ | girl, info | info[ :connected ] ? ( now.to_i - @updates[ girl ].to_i >= @expire_long_after ) : ( now.to_i - @updates[ girl ].to_i >= @expire_connecting ) }.each do | girl, _ |
406
+ puts "expire girl" if @is_debug
407
+ close_girl( girl )
408
+ end
409
+ end
410
+
337
411
  def check_expire_mems
338
412
  now = Time.new
339
413
 
@@ -361,6 +435,15 @@ module Girl
361
435
  end
362
436
  end
363
437
 
438
+ def check_expire_relays
439
+ now = Time.new
440
+
441
+ @relay_infos.select{ | relay, _ | now.to_i - @updates[ relay ].to_i >= @expire_long_after }.each do | relay, info |
442
+ puts "expire relay #{ info[ :addrinfo ].ip_unpack.inspect }" if @is_debug
443
+ close_relay( relay )
444
+ end
445
+ end
446
+
364
447
  def check_expire_rsvs
365
448
  now = Time.new
366
449
 
@@ -396,6 +479,15 @@ module Girl
396
479
  dst_info
397
480
  end
398
481
 
482
+ def close_girl( girl )
483
+ return nil if girl.nil? || girl.closed?
484
+ close_sock( girl )
485
+ girl_info = @girl_infos.delete( girl )
486
+ puts "close girl" if @is_debug
487
+ set_relay_closing( girl_info[ :relay ] ) if girl_info
488
+ girl_info
489
+ end
490
+
399
491
  def close_mem( mem )
400
492
  return nil if mem.nil? || mem.closed?
401
493
  close_sock( mem )
@@ -406,7 +498,7 @@ module Girl
406
498
  return nil if p1.nil? || p1.closed?
407
499
  close_sock( p1 )
408
500
  p1_info = @p1_infos.delete( p1 )
409
-
501
+
410
502
  unless @proxy.closed? then
411
503
  proxy_info = @proxy_infos[ @proxy ]
412
504
  proxy_info[ :paused_p1s ].delete( p1 )
@@ -429,6 +521,15 @@ module Girl
429
521
  proxy_info
430
522
  end
431
523
 
524
+ def close_relay( relay )
525
+ return nil if relay.nil? || relay.closed?
526
+ close_sock( relay )
527
+ relay_info = @relay_infos.delete( relay )
528
+ puts "close relay" if @is_debug
529
+ set_girl_closing( relay_info[ :girl ] ) if relay_info
530
+ relay_info
531
+ end
532
+
432
533
  def close_rsv( rsv )
433
534
  return nil if rsv.nil? || rsv.closed?
434
535
  close_sock( rsv )
@@ -453,7 +554,7 @@ module Girl
453
554
  src_id = src_info[ :src_id ]
454
555
  domain = src_info[ :destination_domain ]
455
556
  puts "close src #{ domain }" if @is_debug
456
-
557
+
457
558
  if src_info[ :proxy_type ] == :direct then
458
559
  set_dst_closing( src_info[ :dst ] )
459
560
  elsif ( src_info[ :proxy_type ] == :remote ) && !@proxy.closed? then
@@ -612,14 +713,14 @@ module Girl
612
713
  domain = src_info[ :destination_domain ]
613
714
  port = src_info[ :destination_port ]
614
715
 
615
- if @local_ips.include?( ip ) && [ @redir_port, @tspd_port ].include?( port ) then
716
+ if @local_ips.include?( ip ) && [ @redir_port, @relayd_port, @tspd_port ].include?( port ) then
616
717
  puts "ignore #{ ip }:#{ port }"
617
718
  close_src( src )
618
719
  return
619
720
  end
620
721
 
621
- if [ domain, ip ].include?( @proxyd_host ) then
622
- # 访问远端,直连
722
+ if [ domain, ip ].include?( @proxyd_host ) && ![ 80, 443 ].include?( port ) then
723
+ # 访问远端非http端口,直连
623
724
  puts "direct #{ ip } #{ port }"
624
725
  new_a_dst( ip, src )
625
726
  return
@@ -709,13 +810,52 @@ module Girl
709
810
  end
710
811
  end
711
812
 
813
+ def new_a_girl( relay )
814
+ return if relay.nil? || relay.closed?
815
+ check_expire_girls
816
+
817
+ begin
818
+ girl = Socket.new( Socket::AF_INET, Socket::SOCK_STREAM, 0 )
819
+ rescue Exception => e
820
+ puts "new a girl #{ e.class }"
821
+ close_girl( girl )
822
+ return
823
+ end
824
+
825
+ girl.setsockopt( Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1 )
826
+
827
+ begin
828
+ girl.connect_nonblock( @proxyd_addr )
829
+ rescue IO::WaitWritable
830
+ rescue Exception => e
831
+ puts "girl connect proxyd #{ e.class }"
832
+ girl.close
833
+ close_girl( girl )
834
+ return
835
+ end
836
+
837
+ girl_info = {
838
+ closing: false,
839
+ connected: false,
840
+ is_syn: @is_client_fastopen,
841
+ overflowing: false,
842
+ relay: relay,
843
+ wbuff: ''
844
+ }
845
+
846
+ @girl_infos[ girl ] = girl_info
847
+ add_read( girl, :girl )
848
+ add_write( girl )
849
+ girl
850
+ end
851
+
712
852
  def new_a_infod( infod_port )
713
- infod_ip = '127.0.0.1'
714
- infod_addr = Socket.sockaddr_in( infod_port, infod_ip )
853
+ infod_host = '127.0.0.1'
854
+ infod_addr = Socket.sockaddr_in( infod_port, infod_host )
715
855
  infod = Socket.new( Socket::AF_INET, Socket::SOCK_DGRAM, 0 )
716
856
  infod.setsockopt( Socket::SOL_SOCKET, Socket::SO_REUSEPORT, 1 ) if RUBY_PLATFORM.include?( 'linux' )
717
857
  infod.bind( infod_addr )
718
- puts "infod bind on #{ infod_ip } #{ infod_port }"
858
+ puts "infod bind on #{ infod_host } #{ infod_port }"
719
859
  add_read( infod, :infod )
720
860
  info = Socket.new( Socket::AF_INET, Socket::SOCK_DGRAM, 0 )
721
861
  @infod_addr = infod_addr
@@ -724,14 +864,14 @@ module Girl
724
864
  end
725
865
 
726
866
  def new_a_memd( memd_port )
727
- memd_ip = '127.0.0.1'
867
+ memd_host = '127.0.0.1'
728
868
  memd = Socket.new( Socket::AF_INET, Socket::SOCK_STREAM, 0 )
729
869
  memd.setsockopt( Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1 )
730
870
  memd.setsockopt( Socket::SOL_SOCKET, Socket::SO_REUSEPORT, 1 ) if RUBY_PLATFORM.include?( 'linux' )
731
871
  memd.setsockopt( Socket::IPPROTO_TCP, Socket::TCP_FASTOPEN, 5 ) if @is_server_fastopen
732
- memd.bind( Socket.sockaddr_in( memd_port, memd_ip ) )
872
+ memd.bind( Socket.sockaddr_in( memd_port, memd_host ) )
733
873
  memd.listen( 5 )
734
- puts "memd listen on #{ memd_ip } #{ memd_port }"
874
+ puts "memd listen on #{ memd_host } #{ memd_port }"
735
875
  add_read( memd, :memd )
736
876
  end
737
877
 
@@ -807,21 +947,33 @@ module Girl
807
947
  proxy_info
808
948
  end
809
949
 
810
- def new_a_redir( redir_port )
811
- redir_ip = '0.0.0.0'
950
+ def new_a_redir( redir_host, redir_port )
812
951
  redir = Socket.new( Socket::AF_INET, Socket::SOCK_STREAM, 0 )
813
952
  redir.setsockopt( Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1 )
814
953
  redir.setsockopt( Socket::SOL_SOCKET, Socket::SO_REUSEADDR, 1 )
815
954
  redir.setsockopt( Socket::SOL_SOCKET, Socket::SO_REUSEPORT, 1 ) if RUBY_PLATFORM.include?( 'linux' )
816
955
  redir.setsockopt( Socket::IPPROTO_TCP, Socket::TCP_FASTOPEN, BACKLOG ) if @is_server_fastopen
817
- redir.bind( Socket.sockaddr_in( redir_port, redir_ip ) )
956
+ redir.bind( Socket.sockaddr_in( redir_port, redir_host ) )
818
957
  redir.listen( BACKLOG )
819
- puts "redir listen on #{ redir_ip } #{ redir_port }"
958
+ puts "redir listen on #{ redir_host } #{ redir_port }"
820
959
  add_read( redir, :redir )
821
960
  @redir_port = redir_port
822
961
  @redir_local_address = redir.local_address
823
962
  end
824
963
 
964
+ def new_a_relayd( relayd_host, relayd_port )
965
+ relayd = Socket.new( Socket::AF_INET, Socket::SOCK_STREAM, 0 )
966
+ relayd.setsockopt( Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1 )
967
+ relayd.setsockopt( Socket::SOL_SOCKET, Socket::SO_REUSEADDR, 1 )
968
+ relayd.setsockopt( Socket::SOL_SOCKET, Socket::SO_REUSEPORT, 1 ) if RUBY_PLATFORM.include?( 'linux' )
969
+ relayd.setsockopt( Socket::IPPROTO_TCP, Socket::TCP_FASTOPEN, BACKLOG ) if @is_server_fastopen
970
+ relayd.bind( Socket.sockaddr_in( relayd_port, relayd_host ) )
971
+ relayd.listen( BACKLOG )
972
+ puts "relayd listen on #{ relayd_host } #{ relayd_port }"
973
+ add_read( relayd, :relayd )
974
+ @relayd_port = relayd_port
975
+ end
976
+
825
977
  def new_a_rsv( data, addrinfo, domain, type )
826
978
  check_expire_rsvs
827
979
  rsv = Socket.new( Socket::AF_INET, Socket::SOCK_DGRAM, 0 )
@@ -844,27 +996,25 @@ module Girl
844
996
  add_read( rsv, :rsv )
845
997
  end
846
998
 
847
- def new_a_rsvd( rsvd_port )
848
- rsvd_ip = '0.0.0.0'
849
- rsvd_addr = Socket.sockaddr_in( rsvd_port, rsvd_ip )
999
+ def new_a_rsvd( rsvd_host, rsvd_port )
1000
+ rsvd_addr = Socket.sockaddr_in( rsvd_port, rsvd_host )
850
1001
  rsvd = Socket.new( Socket::AF_INET, Socket::SOCK_DGRAM, 0 )
851
1002
  rsvd.setsockopt( Socket::SOL_SOCKET, Socket::SO_REUSEPORT, 1 ) if RUBY_PLATFORM.include?( 'linux' )
852
1003
  rsvd.bind( rsvd_addr )
853
- puts "rsvd bind on #{ rsvd_ip } #{ rsvd_port }"
1004
+ puts "rsvd bind on #{ rsvd_host } #{ rsvd_port }"
854
1005
  add_read( rsvd, :rsvd )
855
1006
  @rsvd = rsvd
856
1007
  end
857
1008
 
858
- def new_a_tspd( tspd_port )
859
- tspd_ip = '0.0.0.0'
1009
+ def new_a_tspd( tspd_host, tspd_port )
860
1010
  tspd = Socket.new( Socket::AF_INET, Socket::SOCK_STREAM, 0 )
861
1011
  tspd.setsockopt( Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1 )
862
1012
  tspd.setsockopt( Socket::SOL_SOCKET, Socket::SO_REUSEADDR, 1 )
863
1013
  tspd.setsockopt( Socket::SOL_SOCKET, Socket::SO_REUSEPORT, 1 ) if RUBY_PLATFORM.include?( 'linux' )
864
1014
  tspd.setsockopt( Socket::IPPROTO_TCP, Socket::TCP_FASTOPEN, BACKLOG ) if @is_server_fastopen
865
- tspd.bind( Socket.sockaddr_in( tspd_port, tspd_ip ) )
1015
+ tspd.bind( Socket.sockaddr_in( tspd_port, tspd_host ) )
866
1016
  tspd.listen( BACKLOG )
867
- puts "tspd listen on #{ tspd_ip } #{ tspd_port }"
1017
+ puts "tspd listen on #{ tspd_host } #{ tspd_port }"
868
1018
  add_read( tspd, :tspd )
869
1019
  @tspd_port = tspd_port
870
1020
  end
@@ -955,6 +1105,22 @@ module Girl
955
1105
  add_src_wbuff( src, data )
956
1106
  end
957
1107
 
1108
+ def read_girl( girl )
1109
+ begin
1110
+ data = girl.read_nonblock( READ_SIZE )
1111
+ rescue Errno::ENOTCONN => e
1112
+ return
1113
+ rescue Exception => e
1114
+ close_girl( girl )
1115
+ return
1116
+ end
1117
+
1118
+ set_update( girl )
1119
+ girl_info = @girl_infos[ girl ]
1120
+ relay = girl_info[ :relay ]
1121
+ add_relay_wbuff( relay, data )
1122
+ end
1123
+
958
1124
  def read_infod( infod )
959
1125
  begin
960
1126
  data, addrinfo, rflags, *controls = infod.recvmsg
@@ -1026,6 +1192,8 @@ module Girl
1026
1192
  updates: @updates.size,
1027
1193
  proxy_infos: @proxy_infos.size,
1028
1194
  mem_infos: @mem_infos.size,
1195
+ relay_infos: @relay_infos.size,
1196
+ girl_infos: @girl_infos.size,
1029
1197
  src_infos: @src_infos.size,
1030
1198
  dst_infos: @dst_infos.size,
1031
1199
  dns_infos: @dns_infos.size,
@@ -1148,6 +1316,47 @@ module Girl
1148
1316
  add_read( src, :src )
1149
1317
  end
1150
1318
 
1319
+ def read_relay( relay )
1320
+ begin
1321
+ data = relay.read_nonblock( READ_SIZE )
1322
+ rescue Errno::ENOTCONN => e
1323
+ return
1324
+ rescue Exception => e
1325
+ close_relay( relay )
1326
+ return
1327
+ end
1328
+
1329
+ set_update( relay )
1330
+ relay_info = @relay_infos[ relay ]
1331
+ girl = relay_info[ :girl ]
1332
+ add_girl_wbuff( girl, data )
1333
+ end
1334
+
1335
+ def read_relayd( relayd )
1336
+ check_expire_relays
1337
+
1338
+ begin
1339
+ relay, addrinfo = relayd.accept_nonblock
1340
+ rescue IO::WaitReadable, Errno::EINTR => e
1341
+ puts "relayd accept #{ e.class }"
1342
+ return
1343
+ end
1344
+
1345
+ puts "relayd accept a relay #{ addrinfo.ip_unpack.inspect }"
1346
+
1347
+ relay_info = {
1348
+ addrinfo: addrinfo,
1349
+ closing: false,
1350
+ girl: nil,
1351
+ overflowing: false,
1352
+ wbuff: ''
1353
+ }
1354
+
1355
+ @relay_infos[ relay ] = relay_info
1356
+ add_read( relay, :relay )
1357
+ relay_info[ :girl ] = new_a_girl( relay )
1358
+ end
1359
+
1151
1360
  def read_rsv( rsv )
1152
1361
  begin
1153
1362
  data, addrinfo, rflags, *controls = rsv.recvmsg
@@ -1409,7 +1618,7 @@ module Girl
1409
1618
  unless @proxy.closed? then
1410
1619
  proxy_info = @proxy_infos[ @proxy ]
1411
1620
  bytesize = proxy_info[ :wbuff ].bytesize
1412
-
1621
+
1413
1622
  if ( bytesize >= WBUFF_LIMIT ) && !proxy_info[ :paused_srcs ].include?( src ) then
1414
1623
  puts "proxy overflow pause src #{ src_id } #{ src_info[ :destination_domain ] }"
1415
1624
  @reads.delete( src )
@@ -1477,7 +1686,7 @@ module Girl
1477
1686
  def resolve_domain( domain, src )
1478
1687
  return if src.nil? || src.closed?
1479
1688
 
1480
- unless domain =~ /^[0-9a-zA-Z\-\.]{1,63}$/ then
1689
+ unless domain =~ /^(?=^.{3,255}$)[a-zA-Z0-9][-a-zA-Z0-9]{0,62}(\.[a-zA-Z0-9][-a-zA-Z0-9]{0,62})+$/ then
1481
1690
  # 忽略非法域名
1482
1691
  puts "ignore #{ domain }"
1483
1692
  close_src( src )
@@ -1559,6 +1768,14 @@ module Girl
1559
1768
  add_write( dst )
1560
1769
  end
1561
1770
 
1771
+ def set_girl_closing( girl )
1772
+ return if girl.nil? || girl.closed?
1773
+ girl_info = @girl_infos[ girl ]
1774
+ return if girl_info.nil? || girl_info[ :closing ]
1775
+ girl_info[ :closing ] = true
1776
+ add_write( girl )
1777
+ end
1778
+
1562
1779
  def set_p1_closing( p1 )
1563
1780
  return if p1.nil? || p1.closed?
1564
1781
  p1_info = @p1_infos[ p1 ]
@@ -1567,6 +1784,14 @@ module Girl
1567
1784
  add_write( p1 )
1568
1785
  end
1569
1786
 
1787
+ def set_relay_closing( relay )
1788
+ return if relay.nil? || relay.closed?
1789
+ relay_info = @relay_infos[ relay ]
1790
+ return if relay_info.nil? || relay_info[ :closing ]
1791
+ relay_info[ :closing ] = true
1792
+ add_write( relay )
1793
+ end
1794
+
1570
1795
  def set_remote( src )
1571
1796
  return if src.nil? || src.closed?
1572
1797
 
@@ -1574,7 +1799,7 @@ module Girl
1574
1799
  close_src( src )
1575
1800
  return
1576
1801
  end
1577
-
1802
+
1578
1803
  src_info = @src_infos[ src ]
1579
1804
  src_info[ :proxy_type ] = :remote
1580
1805
 
@@ -1627,10 +1852,14 @@ module Girl
1627
1852
  close_dns( _sock )
1628
1853
  when :dst
1629
1854
  close_dst( _sock )
1855
+ when :girl
1856
+ close_girl( _sock )
1630
1857
  when :mem
1631
1858
  close_mem( _sock )
1632
1859
  when :p1
1633
1860
  close_p1( _sock )
1861
+ when :relay
1862
+ close_relay( _sock )
1634
1863
  when :rsv
1635
1864
  close_rsv( _sock )
1636
1865
  when :src
@@ -1685,6 +1914,52 @@ module Girl
1685
1914
  end
1686
1915
  end
1687
1916
 
1917
+ def write_girl( girl )
1918
+ if girl.closed? then
1919
+ puts "write closed girl?"
1920
+ return
1921
+ end
1922
+
1923
+ girl_info = @girl_infos[ girl ]
1924
+ girl_info[ :connected ] = true
1925
+ data = girl_info[ :wbuff ]
1926
+
1927
+ if data.empty? then
1928
+ if girl_info[ :closing ] then
1929
+ close_girl( girl )
1930
+ else
1931
+ @writes.delete( girl )
1932
+ end
1933
+
1934
+ return
1935
+ end
1936
+
1937
+ begin
1938
+ if girl_info[ :is_syn ] then
1939
+ written = girl.sendmsg_nonblock( data, 536870912, @proxyd_addr )
1940
+ girl_info[ :is_syn ] = false
1941
+ else
1942
+ written = girl.write_nonblock( data )
1943
+ end
1944
+ rescue Errno::EINPROGRESS
1945
+ return
1946
+ rescue Exception => e
1947
+ close_girl( girl )
1948
+ return
1949
+ end
1950
+
1951
+ set_update( girl )
1952
+ data = data[ written..-1 ]
1953
+ girl_info[ :wbuff ] = data
1954
+ bytesize = girl_info[ :wbuff ].bytesize
1955
+
1956
+ if girl_info[ :overflowing ] && ( bytesize < RESUME_BELOW ) then
1957
+ puts "girl underhalf"
1958
+ add_read( girl_info[ :relay ] )
1959
+ girl_info[ :overflowing ] = false
1960
+ end
1961
+ end
1962
+
1688
1963
  def write_mem( mem )
1689
1964
  if mem.closed? then
1690
1965
  puts "write closed mem?"
@@ -1797,7 +2072,7 @@ module Girl
1797
2072
  proxy_info[ :paused_srcs ].each{ | src | add_read( src ) }
1798
2073
  proxy_info[ :paused_srcs ].clear
1799
2074
  end
1800
-
2075
+
1801
2076
  if proxy_info[ :paused_p1s ].any? then
1802
2077
  puts "proxy underhalf resume p1s #{ proxy_info[ :paused_p1s ].size }"
1803
2078
  proxy_info[ :paused_p1s ].each{ | p1 | add_read( p1 ) }
@@ -1838,7 +2113,7 @@ module Girl
1838
2113
  data = data[ written..-1 ]
1839
2114
  src_info[ :wbuff ] = data
1840
2115
  bytesize = src_info[ :wbuff ].bytesize
1841
-
2116
+
1842
2117
  if src_info[ :overflowing ] && ( bytesize < RESUME_BELOW ) then
1843
2118
  src_id = src_info[ :src_id ]
1844
2119
  domain = src_info[ :destination_domain ]
@@ -1856,5 +2131,45 @@ module Girl
1856
2131
  end
1857
2132
  end
1858
2133
 
2134
+ def write_relay( relay )
2135
+ if relay.closed? then
2136
+ puts "write closed relay?"
2137
+ return
2138
+ end
2139
+
2140
+ relay_info = @relay_infos[ relay ]
2141
+ data = relay_info[ :wbuff ]
2142
+
2143
+ if data.empty? then
2144
+ if relay_info[ :closing ] then
2145
+ close_relay( relay )
2146
+ else
2147
+ @writes.delete( relay )
2148
+ end
2149
+
2150
+ return
2151
+ end
2152
+
2153
+ begin
2154
+ written = relay.write_nonblock( data )
2155
+ rescue Errno::EINPROGRESS
2156
+ return
2157
+ rescue Exception => e
2158
+ close_relay( relay )
2159
+ return
2160
+ end
2161
+
2162
+ set_update( relay )
2163
+ data = data[ written..-1 ]
2164
+ relay_info[ :wbuff ] = data
2165
+ bytesize = relay_info[ :wbuff ].bytesize
2166
+
2167
+ if relay_info[ :overflowing ] && ( bytesize < RESUME_BELOW ) then
2168
+ puts "relay underhalf"
2169
+ add_read( relay_info[ :girl ] )
2170
+ relay_info[ :overflowing ] = false
2171
+ end
2172
+ end
2173
+
1859
2174
  end
1860
2175
  end
@@ -170,7 +170,7 @@ module Girl
170
170
  close_dst( dst )
171
171
  return
172
172
  end
173
-
173
+
174
174
  if !dst_info[ :overflowing ] && ( bytesize >= WBUFF_LIMIT ) then
175
175
  proxy = dst_info[ :proxy ]
176
176
  puts "add h_dst_overflow #{ im } #{ src_id } #{ domain }"
@@ -209,7 +209,7 @@ module Girl
209
209
  close_p2( p2 )
210
210
  return
211
211
  end
212
-
212
+
213
213
  if !p2_info[ :overflowing ] && ( bytesize >= WBUFF_LIMIT ) then
214
214
  proxy = im_info[ :proxy ]
215
215
  puts "add h_p2_overflow #{ im } #{ p2_id }"
@@ -641,12 +641,12 @@ module Girl
641
641
  end
642
642
 
643
643
  def new_a_infod( infod_port )
644
- infod_ip = '127.0.0.1'
645
- infod_addr = Socket.sockaddr_in( infod_port, infod_ip )
644
+ infod_host = '127.0.0.1'
645
+ infod_addr = Socket.sockaddr_in( infod_port, infod_host )
646
646
  infod = Socket.new( Socket::AF_INET, Socket::SOCK_DGRAM, 0 )
647
647
  infod.setsockopt( Socket::SOL_SOCKET, Socket::SO_REUSEPORT, 1 ) if RUBY_PLATFORM.include?( 'linux' )
648
648
  infod.bind( infod_addr )
649
- puts "infod bind on #{ infod_ip } #{ infod_port }"
649
+ puts "infod bind on #{ infod_host } #{ infod_port }"
650
650
  add_read( infod, :infod )
651
651
  info = Socket.new( Socket::AF_INET, Socket::SOCK_DGRAM, 0 )
652
652
  @infod_addr = infod_addr
@@ -655,14 +655,14 @@ module Girl
655
655
  end
656
656
 
657
657
  def new_a_memd( memd_port )
658
- memd_ip = '127.0.0.1'
658
+ memd_host = '127.0.0.1'
659
659
  memd = Socket.new( Socket::AF_INET, Socket::SOCK_STREAM, 0 )
660
660
  memd.setsockopt( Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1 )
661
661
  memd.setsockopt( Socket::SOL_SOCKET, Socket::SO_REUSEPORT, 1 ) if RUBY_PLATFORM.include?( 'linux' )
662
662
  memd.setsockopt( Socket::IPPROTO_TCP, Socket::TCP_FASTOPEN, 5 ) if @is_server_fastopen
663
- memd.bind( Socket.sockaddr_in( memd_port, memd_ip ) )
663
+ memd.bind( Socket.sockaddr_in( memd_port, memd_host ) )
664
664
  memd.listen( 5 )
665
- puts "memd listen on #{ memd_ip } #{ memd_port }"
665
+ puts "memd listen on #{ memd_host } #{ memd_port }"
666
666
  add_read( memd, :memd )
667
667
  end
668
668
 
@@ -715,14 +715,14 @@ module Girl
715
715
  end
716
716
 
717
717
  def new_a_proxyd( proxyd_port )
718
- proxyd_ip = '0.0.0.0'
718
+ proxyd_host = '0.0.0.0'
719
719
  proxyd = Socket.new( Socket::AF_INET, Socket::SOCK_STREAM, 0 )
720
720
  proxyd.setsockopt( Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1 )
721
721
  proxyd.setsockopt( Socket::SOL_SOCKET, Socket::SO_REUSEPORT, 1 ) if RUBY_PLATFORM.include?( 'linux' )
722
722
  proxyd.setsockopt( Socket::IPPROTO_TCP, Socket::TCP_FASTOPEN, BACKLOG ) if @is_server_fastopen
723
- proxyd.bind( Socket.sockaddr_in( proxyd_port, proxyd_ip ) )
723
+ proxyd.bind( Socket.sockaddr_in( proxyd_port, proxyd_host ) )
724
724
  proxyd.listen( BACKLOG )
725
- puts "proxyd listen on #{ proxyd_ip } #{ proxyd_port }"
725
+ puts "proxyd listen on #{ proxyd_host } #{ proxyd_port }"
726
726
  add_read( proxyd, :proxyd )
727
727
  end
728
728
 
@@ -1120,7 +1120,7 @@ module Girl
1120
1120
  domain = domain_port[ 0...colon_idx ]
1121
1121
  port = domain_port[ ( colon_idx + 1 )..-1 ].to_i
1122
1122
 
1123
- if ( domain !~ /^[0-9a-zA-Z\-\.]{1,63}$/ ) || ( domain =~ /^((0\.\d{1,3}\.\d{1,3}\.\d{1,3})|(10\.\d{1,3}\.\d{1,3}\.\d{1,3})|(127\.\d{1,3}\.\d{1,3}\.\d{1,3})|(169\.254\.\d{1,3}\.\d{1,3})|(172\.((1[6-9])|(2\d)|(3[01]))\.\d{1,3}\.\d{1,3})|(192\.168\.\d{1,3}\.\d{1,3})|(255\.255\.255\.255)|(localhost))$/ ) then
1123
+ if ( domain !~ /^(?=^.{3,255}$)[a-zA-Z0-9][-a-zA-Z0-9]{0,62}(\.[a-zA-Z0-9][-a-zA-Z0-9]{0,62})+$/ ) || ( domain =~ /^((0\.\d{1,3}\.\d{1,3}\.\d{1,3})|(10\.\d{1,3}\.\d{1,3}\.\d{1,3})|(127\.\d{1,3}\.\d{1,3}\.\d{1,3})|(169\.254\.\d{1,3}\.\d{1,3})|(172\.((1[6-9])|(2\d)|(3[01]))\.\d{1,3}\.\d{1,3})|(192\.168\.\d{1,3}\.\d{1,3})|(255\.255\.255\.255)|(localhost))$/ ) then
1124
1124
  # 忽略非法域名,内网地址
1125
1125
  puts "ignore #{ domain }"
1126
1126
  return
@@ -1348,7 +1348,7 @@ module Girl
1348
1348
  data = data[ written..-1 ]
1349
1349
  p2_info[ :wbuff ] = data
1350
1350
  bytesize = p2_info[ :wbuff ].bytesize
1351
-
1351
+
1352
1352
  if p2_info[ :overflowing ] && ( bytesize < RESUME_BELOW ) then
1353
1353
  proxy = im_info[ :proxy ]
1354
1354
  p2_id = p2_info[ :p2_id ]
@@ -1396,7 +1396,7 @@ module Girl
1396
1396
  proxy_info[ :paused_dsts ].each{ | dst | add_read( dst ) }
1397
1397
  proxy_info[ :paused_dsts ].clear
1398
1398
  end
1399
-
1399
+
1400
1400
  if proxy_info[ :paused_p2s ].any? then
1401
1401
  puts "proxy underhalf resume p2s #{ im } #{ proxy_info[ :paused_p2s ].size }"
1402
1402
  proxy_info[ :paused_p2s ].each{ | p2 | add_read( p2 ) }
data/lib/girl/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Girl
2
- VERSION = '9.1.0'.freeze
2
+ VERSION = '9.1.2'.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: 9.1.0
4
+ version: 9.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - takafan
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-02-18 00:00:00.000000000 Z
11
+ date: 2024-03-12 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: escape evil.
14
14
  email: