girl 9.1.0 → 9.1.2

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: 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: