girl 3.7.0 → 4.2.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of girl might be problematic. Click here for more details.

@@ -1,7 +1,7 @@
1
- require 'girl/custom_dns_query'
1
+ require 'girl/custom'
2
2
 
3
3
  module Girl
4
4
  class ResolvCustom
5
- include CustomDnsQuery
5
+ include Custom
6
6
  end
7
7
  end
@@ -5,7 +5,7 @@ module Girl
5
5
  # initialize
6
6
  #
7
7
  def initialize( resolvd_port, nameserver )
8
- @resolv_custom = Girl::ResolvCustom.new
8
+ @custom = Girl::ResolvCustom.new
9
9
  @nameserver_addr = Socket.sockaddr_in( 53, nameserver )
10
10
  @roles = ConcurrentHash.new # :resolvd / :dst
11
11
  @reads = []
@@ -162,7 +162,7 @@ module Girl
162
162
  # read dotr
163
163
  #
164
164
  def read_dotr( dotr )
165
- dotr.read_nonblock( READ_SIZE )
165
+ dotr.read_nonblock( 65535 )
166
166
 
167
167
  if @closing_dsts.any? then
168
168
  @closing_dsts.each { | dst | close_dst( dst ) }
@@ -176,7 +176,7 @@ module Girl
176
176
  def read_resolvd( resolvd )
177
177
  data, addrinfo, rflags, *controls = resolvd.recvmsg
178
178
  # puts "debug1 resolvd recvmsg #{ addrinfo.ip_unpack.inspect } #{ data.inspect }"
179
- data = @resolv_custom.decode( data )
179
+ data = @custom.decode( data )
180
180
  new_a_dst( addrinfo.to_sockaddr, data )
181
181
  end
182
182
 
@@ -187,7 +187,7 @@ module Girl
187
187
  data, addrinfo, rflags, *controls = dst.recvmsg
188
188
  # puts "debug1 dst recvmsg #{ addrinfo.ip_unpack.inspect } #{ data.inspect }"
189
189
  dst_info = @dst_infos[ dst ]
190
- data = @resolv_custom.encode( data )
190
+ data = @custom.encode( data )
191
191
  send_data( @resolvd, dst_info[ :src_addr ], data )
192
192
  close_dst( dst )
193
193
  end
data/lib/girl/ssl.rb CHANGED
@@ -44,26 +44,13 @@ module Girl
44
44
  puts title
45
45
  puts "redir port #{ redir_port } worker count #{ worker_count }"
46
46
 
47
- now = Time.new
48
- name = OpenSSL::X509::Name.new
49
- key = OpenSSL::PKey::RSA.new 2048
50
- cert = OpenSSL::X509::Certificate.new
51
- cert.version = 2
52
- cert.serial = 0
53
- cert.not_before = now
54
- cert.not_after = now + 365 * 24 * 60 * 60
55
- cert.public_key = key.public_key
56
- cert.subject = name
57
- cert.issuer = name
58
- cert.sign key, OpenSSL::Digest.new('SHA1')
59
-
60
47
  $0 = title
61
48
  workers = []
62
49
 
63
50
  worker_count.times do | i |
64
51
  workers << fork do
65
52
  $0 = 'girl ssl worker'
66
- worker = Girl::SslWorker.new( redir_port, cert, key )
53
+ worker = Girl::SslWorker.new( redir_port )
67
54
 
68
55
  Signal.trap( :TERM ) do
69
56
  puts "w#{ i } exit"
@@ -4,7 +4,8 @@ module Girl
4
4
  ##
5
5
  # initialize
6
6
  #
7
- def initialize( redir_port, cert, key )
7
+ def initialize( redir_port )
8
+ @redir_port = redir_port
8
9
  @reads = []
9
10
  @writes = []
10
11
  @closing_srcs = []
@@ -12,15 +13,15 @@ module Girl
12
13
  @paused_dsts = []
13
14
  @resume_srcs = []
14
15
  @resume_dsts = []
15
- @roles = ConcurrentHash.new # sock => :dotr / :redir / :src / :dst
16
- @src_infos = ConcurrentHash.new # src => {}
17
- @dst_infos = ConcurrentHash.new # dst => {}
18
- @resolv_caches = ConcurrentHash.new # domain => [ ip, created_at ]
16
+ @roles = ConcurrentHash.new # sock => :dotr / :redir / :src / :dst
17
+ @src_infos = ConcurrentHash.new # src => {}
18
+ @dst_infos = ConcurrentHash.new # dst => {}
19
+ @resolv_caches = ConcurrentHash.new # domain => [ ip, created_at ]
19
20
 
20
21
  dotr, dotw = IO.pipe
21
22
  @dotw = dotw
22
23
  add_read( dotr, :dotr )
23
- new_a_redir( redir_port, cert, key )
24
+ new_a_redir
24
25
  end
25
26
 
26
27
  ##
@@ -65,7 +66,7 @@ module Girl
65
66
  # quit!
66
67
  #
67
68
  def quit!
68
- # puts "debug1 exit"
69
+ # puts "debug exit"
69
70
  exit
70
71
  end
71
72
 
@@ -84,6 +85,7 @@ module Girl
84
85
  # add dst wbuff
85
86
  #
86
87
  def add_dst_wbuff( dst, data )
88
+ return if dst.closed?
87
89
  dst_info = @dst_infos[ dst ]
88
90
  dst_info[ :wbuff ] << data
89
91
  add_write( dst )
@@ -155,7 +157,7 @@ module Girl
155
157
  # +----+-----+-------+------+----------+----------+
156
158
  redir_ip, redir_port = @redir_local_address.ip_unpack
157
159
  data = [ [ 5, 0, 0, 1 ].pack( 'C4' ), IPAddr.new( redir_ip ).hton, [ redir_port ].pack( 'n' ) ].join
158
- # puts "debug1 add src.wbuff socks5 conn reply #{ data.inspect }"
160
+ # puts "debug add src.wbuff socks5 conn reply #{ data.inspect }"
159
161
  add_src_wbuff( src, data )
160
162
  end
161
163
 
@@ -167,7 +169,7 @@ module Girl
167
169
  src_info[ :rbuff ] << data
168
170
 
169
171
  if src_info[ :rbuff ].bytesize >= WBUFF_LIMIT then
170
- # puts "debug1 src.rbuff full"
172
+ # puts "debug src.rbuff full"
171
173
  add_closing_src( src )
172
174
  end
173
175
  end
@@ -206,20 +208,15 @@ module Girl
206
208
  #
207
209
  def close_read_dst( dst )
208
210
  return if dst.closed?
209
- # puts "debug1 close read dst"
211
+ # puts "debug close read dst"
210
212
  dst.close_read
211
213
  @reads.delete( dst )
212
214
 
213
215
  if dst.closed? then
214
- # puts "debug1 delete dst info"
215
216
  @writes.delete( dst )
216
217
  @roles.delete( dst )
217
- dst_info = @dst_infos.delete( dst )
218
- else
219
- dst_info = @dst_infos[ dst ]
218
+ del_dst_info( dst )
220
219
  end
221
-
222
- dst_info
223
220
  end
224
221
 
225
222
  ##
@@ -227,19 +224,27 @@ module Girl
227
224
  #
228
225
  def close_read_src( src )
229
226
  return if src.closed?
230
- # puts "debug1 close read src"
227
+ # puts "debug close read src"
231
228
  src_info = @src_infos[ src ]
232
229
  src_info[ :close_read ] = true
233
230
 
234
231
  if src_info[ :close_write ] then
235
- # puts "debug1 delete src info"
236
232
  close_sock( src )
237
- src_info = @src_infos.delete( src )
233
+ del_src_info( src )
238
234
  else
239
235
  @reads.delete( src )
240
236
  end
237
+ end
241
238
 
242
- src_info
239
+ ##
240
+ # close redir
241
+ #
242
+ def close_redir( redir )
243
+ return if redir.closed?
244
+ redir.close
245
+ @roles.delete( redir )
246
+ @reads.delete( redir )
247
+ @src_infos.each { | src, _ | close_src( src ) }
243
248
  end
244
249
 
245
250
  ##
@@ -257,14 +262,14 @@ module Girl
257
262
  #
258
263
  def close_src( src )
259
264
  return if src.closed?
260
- # puts "debug1 close src"
265
+ # puts "debug close src"
261
266
  close_sock( src )
262
- src_info = @src_infos.delete( src )
267
+ src_info = del_src_info( src )
263
268
  dst = src_info[ :dst ]
264
269
 
265
270
  if dst then
266
271
  close_sock( dst )
267
- @dst_infos.delete( dst )
272
+ del_dst_info( dst )
268
273
  end
269
274
  end
270
275
 
@@ -273,20 +278,15 @@ module Girl
273
278
  #
274
279
  def close_write_dst( dst )
275
280
  return if dst.closed?
276
- # puts "debug1 close write dst"
281
+ # puts "debug close write dst"
277
282
  dst.close_write
278
283
  @writes.delete( dst )
279
284
 
280
285
  if dst.closed? then
281
- # puts "debug1 delete dst info"
282
286
  @reads.delete( dst )
283
287
  @roles.delete( dst )
284
- dst_info = @dst_infos.delete( dst )
285
- else
286
- dst_info = @dst_infos[ dst ]
288
+ del_dst_info( dst )
287
289
  end
288
-
289
- dst_info
290
290
  end
291
291
 
292
292
  ##
@@ -294,18 +294,37 @@ module Girl
294
294
  #
295
295
  def close_write_src( src )
296
296
  return if src.closed?
297
- # puts "debug1 close write src"
297
+ # puts "debug close write src"
298
298
  src_info = @src_infos[ src ]
299
299
  src_info[ :close_write ] = true
300
300
 
301
301
  if src_info[ :close_read ] then
302
- # puts "debug1 delete src info"
303
302
  close_sock( src )
304
- src_info = @src_infos.delete( src )
303
+ del_src_info( src )
305
304
  else
306
305
  @writes.delete( src )
307
306
  end
307
+ end
308
+
309
+ ##
310
+ # del dst info
311
+ #
312
+ def del_dst_info( dst )
313
+ # puts "debug delete dst info"
314
+ dst_info = @dst_infos.delete( dst )
315
+ @paused_dsts.delete( dst )
316
+ @resume_dsts.delete( dst )
317
+ dst_info
318
+ end
308
319
 
320
+ ##
321
+ # del src info
322
+ #
323
+ def del_src_info( src )
324
+ # puts "debug delete src info"
325
+ src_info = @src_infos.delete( src )
326
+ @paused_srcs.delete( src )
327
+ @resume_srcs.delete( src )
309
328
  src_info
310
329
  end
311
330
 
@@ -324,7 +343,7 @@ module Girl
324
343
  expire_after = src_info[ :dst ] ? EXPIRE_AFTER : EXPIRE_NEW
325
344
 
326
345
  if ( now - last_recv_at >= expire_after ) && ( now - last_sent_at >= expire_after ) then
327
- puts "p#{ Process.pid } #{ Time.new } expire src #{ expire_after } #{ src_info[ :destination_domain ] }"
346
+ puts "p#{ Process.pid } #{ Time.new } expire src #{ expire_after } #{ src_info[ :id ] } #{ src_info[ :destination_domain ] }"
328
347
  add_closing_src( src )
329
348
 
330
349
  unless src_info[ :rbuff ].empty? then
@@ -345,29 +364,24 @@ module Girl
345
364
  sleep CHECK_RESUME_INTERVAL
346
365
 
347
366
  @paused_srcs.each do | src |
348
- if src.closed? then
349
- add_resume_src( src )
350
- else
351
- src_info = @src_infos[ src ]
352
- dst = src_info[ :dst ]
367
+ src_info = @src_infos[ src ]
368
+ dst = src_info[ :dst ]
353
369
 
354
- if dst then
355
- dst_info = @dst_infos[ dst ]
370
+ if dst && !dst.closed? then
371
+ dst_info = @dst_infos[ dst ]
356
372
 
357
- if dst_info[ :wbuff ].size < RESUME_BELOW then
358
- puts "p#{ Process.pid } #{ Time.new } resume direct src #{ src_info[ :destination_domain ] }"
359
- add_resume_src( src )
360
- end
373
+ if dst_info[ :wbuff ].size < RESUME_BELOW then
374
+ puts "p#{ Process.pid } #{ Time.new } resume direct src #{ src_info[ :destination_domain ] }"
375
+ add_resume_src( src )
361
376
  end
362
377
  end
363
378
  end
364
379
 
365
380
  @paused_dsts.each do | dst |
366
- if dst.closed? then
367
- add_resume_dst( dst )
368
- else
369
- dst_info = @dst_infos[ dst ]
370
- src = dst_info[ :src ]
381
+ dst_info = @dst_infos[ dst ]
382
+ src = dst_info[ :src ]
383
+
384
+ if src && !src.closed? then
371
385
  src_info = @src_infos[ src ]
372
386
 
373
387
  if src_info[ :wbuff ].size < RESUME_BELOW then
@@ -389,7 +403,6 @@ module Girl
389
403
  domain = src_info[ :destination_domain ]
390
404
  destination_addr = Socket.sockaddr_in( src_info[ :destination_port ], ip_info.ip_address )
391
405
  dst = Socket.new( ip_info.ipv4? ? Socket::AF_INET : Socket::AF_INET6, Socket::SOCK_STREAM, 0 )
392
- dst.setsockopt( Socket::SOL_TCP, Socket::TCP_NODELAY, 1 )
393
406
 
394
407
  begin
395
408
  dst.connect_nonblock( destination_addr )
@@ -402,7 +415,7 @@ module Girl
402
415
  return
403
416
  end
404
417
 
405
- # puts "debug1 a new dst #{ dst.local_address.inspect }"
418
+ # puts "debug a new dst #{ dst.local_address.inspect }"
406
419
  dst_info = {
407
420
  src: src, # 对应src
408
421
  domain: domain, # 目的地
@@ -420,20 +433,32 @@ module Girl
420
433
  ##
421
434
  # new a redir
422
435
  #
423
- def new_a_redir( redir_port, cert, key )
424
- redir = Socket.new( Socket::AF_INET, Socket::SOCK_STREAM, 0 )
425
- redir.setsockopt( Socket::SOL_SOCKET, Socket::SO_REUSEADDR, 1 )
426
- redir.setsockopt( Socket::SOL_SOCKET, Socket::SO_REUSEPORT, 1 )
427
- redir.setsockopt( Socket::SOL_TCP, Socket::TCP_NODELAY, 1 )
428
- redir.bind( Socket.sockaddr_in( redir_port, '0.0.0.0' ) )
429
- redir.listen( 127 )
430
-
431
- @redir_local_address = redir.local_address
436
+ def new_a_redir
437
+ pre = Socket.new( Socket::AF_INET, Socket::SOCK_STREAM, 0 )
438
+ pre.setsockopt( Socket::SOL_SOCKET, Socket::SO_REUSEADDR, 1 )
439
+ pre.setsockopt( Socket::SOL_SOCKET, Socket::SO_REUSEPORT, 1 )
440
+ pre.bind( Socket.sockaddr_in( @redir_port, '0.0.0.0' ) )
441
+ @redir_local_address = pre.local_address
442
+ puts "p#{ Process.pid } #{ Time.new } pre bind on #{ @redir_port } local address #{ pre.local_address.inspect }"
443
+
444
+ now = Time.new
445
+ name = OpenSSL::X509::Name.new
446
+ key = OpenSSL::PKey::RSA.new 1024
447
+ cert = OpenSSL::X509::Certificate.new
448
+ cert.version = 2
449
+ cert.serial = 0
450
+ cert.not_before = now
451
+ cert.not_after = now + 365 * 24 * 60 * 60
452
+ cert.public_key = key.public_key
453
+ cert.subject = name
454
+ cert.issuer = name
455
+ cert.sign key, OpenSSL::Digest.new('SHA1')
432
456
  context = OpenSSL::SSL::SSLContext.new
457
+ context.security_level = 1
433
458
  context.add_certificate( cert, key )
434
- redir = OpenSSL::SSL::SSLServer.new redir, context
435
-
436
- puts "p#{ Process.pid } #{ Time.new } redir listen on #{ redir_port }"
459
+ redir = OpenSSL::SSL::SSLServer.new pre, context
460
+ redir.listen( 127 )
461
+ puts "p#{ Process.pid } #{ Time.new } redir listening"
437
462
  add_read( redir, :redir )
438
463
  end
439
464
 
@@ -454,12 +479,12 @@ module Girl
454
479
  ip_info, created_at = resolv_cache
455
480
 
456
481
  if Time.new - created_at < RESOLV_CACHE_EXPIRE then
457
- # puts "debug1 #{ domain } hit resolv cache #{ ip_info.inspect }"
482
+ # puts "debug #{ domain } hit resolv cache #{ ip_info.inspect }"
458
483
  new_a_dst( src, ip_info )
459
484
  return
460
485
  end
461
486
 
462
- # puts "debug1 expire #{ domain } resolv cache"
487
+ # puts "debug expire #{ domain } resolv cache"
463
488
  @resolv_caches.delete( domain )
464
489
  end
465
490
 
@@ -509,7 +534,7 @@ module Girl
509
534
  # read dotr
510
535
  #
511
536
  def read_dotr( dotr )
512
- dotr.read_nonblock( READ_SIZE )
537
+ dotr.read_nonblock( 65535 )
513
538
 
514
539
  if @closing_srcs.any? then
515
540
  @closing_srcs.each { | src | close_src( src ) }
@@ -539,14 +564,32 @@ module Girl
539
564
  # read redir
540
565
  #
541
566
  def read_redir( redir )
567
+ accepted = false
568
+
569
+ Thread.new do
570
+ sleep 1
571
+
572
+ unless accepted then
573
+ puts "p#{ Process.pid } #{ Time.new } accept timeout"
574
+ close_redir( redir )
575
+ new_a_redir
576
+ end
577
+ end
578
+
542
579
  begin
543
580
  src = redir.accept
581
+ rescue SystemExit => e
582
+ puts "p#{ Process.pid } #{ Time.new } redir accept #{ e.class }"
583
+ close_redir( redir )
584
+ return
544
585
  rescue Exception => e
545
586
  puts "p#{ Process.pid } #{ Time.new } redir accept #{ e.class }"
587
+ puts e.full_message
546
588
  return
547
589
  end
548
590
 
549
- # puts "debug1 accept a src"
591
+ accepted = true
592
+ # puts "debug accept a src"
550
593
 
551
594
  @src_infos[ src ] = {
552
595
  proxy_proto: :uncheck, # :uncheck / :socks5
@@ -577,17 +620,19 @@ module Girl
577
620
  return
578
621
  end
579
622
 
623
+ src_info = @src_infos[ src ]
624
+
580
625
  begin
581
- data = src.read_nonblock( READ_SIZE )
626
+ data = src.read_nonblock( 65535 )
582
627
  rescue IO::WaitReadable
583
628
  return
584
629
  rescue Errno::EINTR => e
585
630
  puts e.class
586
631
  return
587
632
  rescue Exception => e
588
- # puts "debug1 read src #{ e.class }"
589
- src_info = close_read_src( src )
633
+ # puts "debug read src #{ e.class }"
590
634
  dst = src_info[ :dst ]
635
+ close_read_src( src )
591
636
 
592
637
  if dst then
593
638
  set_dst_closing_write( dst )
@@ -605,7 +650,7 @@ module Girl
605
650
  "p#{ Process.pid } #{ Time.new } unknown data #{ data.inspect }"
606
651
  end
607
652
 
608
- # puts "debug1 socks5 #{ data.inspect }"
653
+ # puts "debug socks5 #{ data.inspect }"
609
654
 
610
655
  # https://tools.ietf.org/html/rfc1928
611
656
  #
@@ -633,7 +678,7 @@ module Girl
633
678
  src_info[ :proxy_proto ] = :socks5
634
679
  src_info[ :proxy_type ] = :negotiation
635
680
  when :checking then
636
- # puts "debug1 add src rbuff before resolved #{ data.inspect }"
681
+ # puts "debug add src rbuff before resolved #{ data.inspect }"
637
682
  src_info[ :rbuff ] << data
638
683
  when :negotiation then
639
684
  # +----+-----+-------+------+----------+----------+
@@ -641,11 +686,11 @@ module Girl
641
686
  # +----+-----+-------+------+----------+----------+
642
687
  # | 1 | 1 | X'00' | 1 | Variable | 2 |
643
688
  # +----+-----+-------+------+----------+----------+
644
- # puts "debug1 negotiation #{ data.inspect }"
689
+ # puts "debug negotiation #{ data.inspect }"
645
690
  ver, cmd, rsv, atyp = data[ 0, 4 ].unpack( 'C4' )
646
691
 
647
692
  if cmd == 1 then
648
- # puts "debug1 socks5 CONNECT"
693
+ # puts "debug socks5 CONNECT"
649
694
 
650
695
  if atyp == 1 then
651
696
  destination_host, destination_port = data[ 4, 6 ].unpack( 'Nn' )
@@ -654,7 +699,7 @@ module Girl
654
699
  destination_ip = destination_addrinfo.ip_address
655
700
  src_info[ :destination_domain ] = destination_ip
656
701
  src_info[ :destination_port ] = destination_port
657
- # puts "debug1 IP V4 address #{ destination_addrinfo.ip_unpack.inspect }"
702
+ # puts "debug IP V4 address #{ destination_addrinfo.ip_unpack.inspect }"
658
703
  new_a_dst( src, destination_addrinfo )
659
704
  elsif atyp == 3 then
660
705
  domain_len = data[ 4 ].unpack( 'C' ).first
@@ -664,7 +709,7 @@ module Girl
664
709
  port = data[ ( 5 + domain_len ), 2 ].unpack( 'n' ).first
665
710
  src_info[ :destination_domain ] = domain
666
711
  src_info[ :destination_port ] = port
667
- # puts "debug1 DOMAINNAME #{ domain } #{ port }"
712
+ # puts "debug DOMAINNAME #{ domain } #{ port }"
668
713
  resolve_domain( src, domain )
669
714
  end
670
715
  end
@@ -675,12 +720,9 @@ module Girl
675
720
  dst = src_info[ :dst ]
676
721
 
677
722
  if dst then
678
- unless dst.closed? then
679
- # puts "debug2 add dst.wbuff #{ data.bytesize }"
680
- add_dst_wbuff( dst, data )
681
- end
723
+ add_dst_wbuff( dst, data )
682
724
  else
683
- # puts "debug1 dst not ready, save data to src.rbuff"
725
+ # puts "debug add src.rbuff #{ data.bytesize }"
684
726
  add_src_rbuff( src, data )
685
727
  end
686
728
  end
@@ -695,21 +737,22 @@ module Girl
695
737
  return
696
738
  end
697
739
 
740
+ dst_info = @dst_infos[ dst ]
741
+ src = dst_info[ :src ]
742
+
698
743
  begin
699
- data = dst.read_nonblock( READ_SIZE )
744
+ data = dst.read_nonblock( 65535 )
700
745
  rescue IO::WaitReadable, Errno::EINTR
701
746
  print 'r'
702
747
  return
703
748
  rescue Exception => e
704
- # puts "debug1 read dst #{ e.class }"
705
- dst_info = close_read_dst( dst )
706
- src = dst_info[ :src ]
749
+ # puts "debug read dst #{ e.class }"
750
+ close_read_dst( dst )
707
751
  set_src_closing_write( src )
708
752
  return
709
753
  end
710
754
 
711
- dst_info = @dst_infos[ dst ]
712
- src = dst_info[ :src ]
755
+ # puts "debug read dst #{ data.bytesize }"
713
756
  add_src_wbuff( src, data )
714
757
  end
715
758
 
@@ -744,7 +787,7 @@ module Girl
744
787
  print 'w'
745
788
  return
746
789
  rescue Exception => e
747
- # puts "debug1 write src #{ e.class }"
790
+ # puts "debug write src #{ e.class }"
748
791
  close_write_src( src )
749
792
 
750
793
  if dst then
@@ -754,7 +797,6 @@ module Girl
754
797
  return
755
798
  end
756
799
 
757
- # puts "debug2 written src #{ written }"
758
800
  data = data[ written..-1 ]
759
801
  src_info[ :wbuff ] = data
760
802
  end
@@ -790,7 +832,7 @@ module Girl
790
832
  print 'w'
791
833
  return
792
834
  rescue Exception => e
793
- # puts "debug1 write dst #{ e.class }"
835
+ # puts "debug write dst #{ e.class }"
794
836
  close_write_dst( dst )
795
837
  close_read_src( src )
796
838
  return