girl 3.9.0 → 4.0.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.

@@ -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 ) }
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,16 @@ 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
241
-
242
- src_info
243
237
  end
244
238
 
245
239
  ##
@@ -257,14 +251,14 @@ module Girl
257
251
  #
258
252
  def close_src( src )
259
253
  return if src.closed?
260
- # puts "debug1 close src"
254
+ # puts "debug close src"
261
255
  close_sock( src )
262
- src_info = @src_infos.delete( src )
256
+ src_info = del_src_info( src )
263
257
  dst = src_info[ :dst ]
264
258
 
265
259
  if dst then
266
260
  close_sock( dst )
267
- @dst_infos.delete( dst )
261
+ del_dst_info( dst )
268
262
  end
269
263
  end
270
264
 
@@ -273,20 +267,15 @@ module Girl
273
267
  #
274
268
  def close_write_dst( dst )
275
269
  return if dst.closed?
276
- # puts "debug1 close write dst"
270
+ # puts "debug close write dst"
277
271
  dst.close_write
278
272
  @writes.delete( dst )
279
273
 
280
274
  if dst.closed? then
281
- # puts "debug1 delete dst info"
282
275
  @reads.delete( dst )
283
276
  @roles.delete( dst )
284
- dst_info = @dst_infos.delete( dst )
285
- else
286
- dst_info = @dst_infos[ dst ]
277
+ del_dst_info( dst )
287
278
  end
288
-
289
- dst_info
290
279
  end
291
280
 
292
281
  ##
@@ -294,18 +283,37 @@ module Girl
294
283
  #
295
284
  def close_write_src( src )
296
285
  return if src.closed?
297
- # puts "debug1 close write src"
286
+ # puts "debug close write src"
298
287
  src_info = @src_infos[ src ]
299
288
  src_info[ :close_write ] = true
300
289
 
301
290
  if src_info[ :close_read ] then
302
- # puts "debug1 delete src info"
303
291
  close_sock( src )
304
- src_info = @src_infos.delete( src )
292
+ del_src_info( src )
305
293
  else
306
294
  @writes.delete( src )
307
295
  end
296
+ end
308
297
 
298
+ ##
299
+ # del dst info
300
+ #
301
+ def del_dst_info( dst )
302
+ # puts "debug delete dst info"
303
+ dst_info = @dst_infos.delete( dst )
304
+ @paused_dsts.delete( dst )
305
+ @resume_dsts.delete( dst )
306
+ dst_info
307
+ end
308
+
309
+ ##
310
+ # del src info
311
+ #
312
+ def del_src_info( src )
313
+ # puts "debug delete src info"
314
+ src_info = @src_infos.delete( src )
315
+ @paused_srcs.delete( src )
316
+ @resume_srcs.delete( src )
309
317
  src_info
310
318
  end
311
319
 
@@ -324,7 +332,7 @@ module Girl
324
332
  expire_after = src_info[ :dst ] ? EXPIRE_AFTER : EXPIRE_NEW
325
333
 
326
334
  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 ] }"
335
+ puts "p#{ Process.pid } #{ Time.new } expire src #{ expire_after } #{ src_info[ :id ] } #{ src_info[ :destination_domain ] }"
328
336
  add_closing_src( src )
329
337
 
330
338
  unless src_info[ :rbuff ].empty? then
@@ -345,35 +353,27 @@ module Girl
345
353
  sleep CHECK_RESUME_INTERVAL
346
354
 
347
355
  @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 ]
353
-
354
- if dst then
355
- dst_info = @dst_infos[ dst ]
356
-
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
356
+ src_info = @src_infos[ src ]
357
+ dst = src_info[ :dst ]
358
+
359
+ if dst then
360
+ dst_info = @dst_infos[ dst ]
361
+
362
+ if dst_info[ :wbuff ].size < RESUME_BELOW then
363
+ puts "p#{ Process.pid } #{ Time.new } resume direct src #{ src_info[ :destination_domain ] }"
364
+ add_resume_src( src )
361
365
  end
362
366
  end
363
367
  end
364
368
 
365
369
  @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 ]
371
- src_info = @src_infos[ src ]
370
+ dst_info = @dst_infos[ dst ]
371
+ src = dst_info[ :src ]
372
+ src_info = @src_infos[ src ]
372
373
 
373
- if src_info[ :wbuff ].size < RESUME_BELOW then
374
- puts "p#{ Process.pid } #{ Time.new } resume dst #{ dst_info[ :domain ] }"
375
- add_resume_dst( dst )
376
- end
374
+ if src_info[ :wbuff ].size < RESUME_BELOW then
375
+ puts "p#{ Process.pid } #{ Time.new } resume dst #{ dst_info[ :domain ] }"
376
+ add_resume_dst( dst )
377
377
  end
378
378
  end
379
379
  end
@@ -389,7 +389,6 @@ module Girl
389
389
  domain = src_info[ :destination_domain ]
390
390
  destination_addr = Socket.sockaddr_in( src_info[ :destination_port ], ip_info.ip_address )
391
391
  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
392
 
394
393
  begin
395
394
  dst.connect_nonblock( destination_addr )
@@ -402,7 +401,7 @@ module Girl
402
401
  return
403
402
  end
404
403
 
405
- # puts "debug1 a new dst #{ dst.local_address.inspect }"
404
+ # puts "debug a new dst #{ dst.local_address.inspect }"
406
405
  dst_info = {
407
406
  src: src, # 对应src
408
407
  domain: domain, # 目的地
@@ -420,19 +419,32 @@ module Girl
420
419
  ##
421
420
  # new a redir
422
421
  #
423
- def new_a_redir( redir_port, cert, key )
424
- pre_redir = Socket.new( Socket::AF_INET, Socket::SOCK_STREAM, 0 )
425
- pre_redir.setsockopt( Socket::SOL_SOCKET, Socket::SO_REUSEADDR, 1 )
426
- pre_redir.setsockopt( Socket::SOL_SOCKET, Socket::SO_REUSEPORT, 1 )
427
- pre_redir.setsockopt( Socket::SOL_TCP, Socket::TCP_NODELAY, 1 )
428
- pre_redir.bind( Socket.sockaddr_in( redir_port, '0.0.0.0' ) )
429
-
430
- @redir_local_address = pre_redir.local_address
422
+ def new_a_redir
423
+ pre = Socket.new( Socket::AF_INET, Socket::SOCK_STREAM, 0 )
424
+ pre.setsockopt( Socket::SOL_SOCKET, Socket::SO_REUSEADDR, 1 )
425
+ pre.setsockopt( Socket::SOL_SOCKET, Socket::SO_REUSEPORT, 1 )
426
+ pre.bind( Socket.sockaddr_in( @redir_port, '0.0.0.0' ) )
427
+ @redir_local_address = pre.local_address
428
+ puts "p#{ Process.pid } #{ Time.new } pre bind on #{ @redir_port } local address #{ pre.local_address.inspect }"
429
+
430
+ now = Time.new
431
+ name = OpenSSL::X509::Name.new
432
+ key = OpenSSL::PKey::RSA.new 1024
433
+ cert = OpenSSL::X509::Certificate.new
434
+ cert.version = 2
435
+ cert.serial = 0
436
+ cert.not_before = now
437
+ cert.not_after = now + 365 * 24 * 60 * 60
438
+ cert.public_key = key.public_key
439
+ cert.subject = name
440
+ cert.issuer = name
441
+ cert.sign key, OpenSSL::Digest.new('SHA1')
431
442
  context = OpenSSL::SSL::SSLContext.new
443
+ context.security_level = 1
432
444
  context.add_certificate( cert, key )
433
- redir = OpenSSL::SSL::SSLServer.new pre_redir, context
445
+ redir = OpenSSL::SSL::SSLServer.new pre, context
434
446
  redir.listen( 127 )
435
- puts "p#{ Process.pid } #{ Time.new } redir listen on #{ redir_port }"
447
+ puts "p#{ Process.pid } #{ Time.new } redir listening"
436
448
  add_read( redir, :redir )
437
449
  end
438
450
 
@@ -453,12 +465,12 @@ module Girl
453
465
  ip_info, created_at = resolv_cache
454
466
 
455
467
  if Time.new - created_at < RESOLV_CACHE_EXPIRE then
456
- # puts "debug1 #{ domain } hit resolv cache #{ ip_info.inspect }"
468
+ # puts "debug #{ domain } hit resolv cache #{ ip_info.inspect }"
457
469
  new_a_dst( src, ip_info )
458
470
  return
459
471
  end
460
472
 
461
- # puts "debug1 expire #{ domain } resolv cache"
473
+ # puts "debug expire #{ domain } resolv cache"
462
474
  @resolv_caches.delete( domain )
463
475
  end
464
476
 
@@ -508,7 +520,7 @@ module Girl
508
520
  # read dotr
509
521
  #
510
522
  def read_dotr( dotr )
511
- dotr.read_nonblock( READ_SIZE )
523
+ dotr.read_nonblock( 65535 )
512
524
 
513
525
  if @closing_srcs.any? then
514
526
  @closing_srcs.each { | src | close_src( src ) }
@@ -538,17 +550,30 @@ module Girl
538
550
  # read redir
539
551
  #
540
552
  def read_redir( redir )
553
+ accepted = false
554
+
555
+ Thread.new do
556
+ sleep 1
557
+
558
+ unless accepted then
559
+ puts "p#{ Process.pid } #{ Time.new } accept timeout"
560
+ redir.close
561
+ @roles.delete( redir )
562
+ @reads.delete( redir )
563
+ new_a_redir
564
+ end
565
+ end
566
+
541
567
  begin
542
568
  src = redir.accept
543
- rescue IO::WaitReadable, Errno::EINTR
544
- print 'r'
545
- return
546
569
  rescue Exception => e
547
570
  puts "p#{ Process.pid } #{ Time.new } redir accept #{ e.class }"
571
+ puts e.full_message
548
572
  return
549
573
  end
550
574
 
551
- # puts "debug1 accept a src"
575
+ accepted = true
576
+ # puts "debug accept a src"
552
577
 
553
578
  @src_infos[ src ] = {
554
579
  proxy_proto: :uncheck, # :uncheck / :socks5
@@ -579,17 +604,19 @@ module Girl
579
604
  return
580
605
  end
581
606
 
607
+ src_info = @src_infos[ src ]
608
+
582
609
  begin
583
- data = src.read_nonblock( READ_SIZE )
610
+ data = src.read_nonblock( 65535 )
584
611
  rescue IO::WaitReadable
585
612
  return
586
613
  rescue Errno::EINTR => e
587
614
  puts e.class
588
615
  return
589
616
  rescue Exception => e
590
- # puts "debug1 read src #{ e.class }"
591
- src_info = close_read_src( src )
617
+ # puts "debug read src #{ e.class }"
592
618
  dst = src_info[ :dst ]
619
+ close_read_src( src )
593
620
 
594
621
  if dst then
595
622
  set_dst_closing_write( dst )
@@ -607,7 +634,7 @@ module Girl
607
634
  "p#{ Process.pid } #{ Time.new } unknown data #{ data.inspect }"
608
635
  end
609
636
 
610
- # puts "debug1 socks5 #{ data.inspect }"
637
+ # puts "debug socks5 #{ data.inspect }"
611
638
 
612
639
  # https://tools.ietf.org/html/rfc1928
613
640
  #
@@ -635,7 +662,7 @@ module Girl
635
662
  src_info[ :proxy_proto ] = :socks5
636
663
  src_info[ :proxy_type ] = :negotiation
637
664
  when :checking then
638
- # puts "debug1 add src rbuff before resolved #{ data.inspect }"
665
+ # puts "debug add src rbuff before resolved #{ data.inspect }"
639
666
  src_info[ :rbuff ] << data
640
667
  when :negotiation then
641
668
  # +----+-----+-------+------+----------+----------+
@@ -643,11 +670,11 @@ module Girl
643
670
  # +----+-----+-------+------+----------+----------+
644
671
  # | 1 | 1 | X'00' | 1 | Variable | 2 |
645
672
  # +----+-----+-------+------+----------+----------+
646
- # puts "debug1 negotiation #{ data.inspect }"
673
+ # puts "debug negotiation #{ data.inspect }"
647
674
  ver, cmd, rsv, atyp = data[ 0, 4 ].unpack( 'C4' )
648
675
 
649
676
  if cmd == 1 then
650
- # puts "debug1 socks5 CONNECT"
677
+ # puts "debug socks5 CONNECT"
651
678
 
652
679
  if atyp == 1 then
653
680
  destination_host, destination_port = data[ 4, 6 ].unpack( 'Nn' )
@@ -656,7 +683,7 @@ module Girl
656
683
  destination_ip = destination_addrinfo.ip_address
657
684
  src_info[ :destination_domain ] = destination_ip
658
685
  src_info[ :destination_port ] = destination_port
659
- # puts "debug1 IP V4 address #{ destination_addrinfo.ip_unpack.inspect }"
686
+ # puts "debug IP V4 address #{ destination_addrinfo.ip_unpack.inspect }"
660
687
  new_a_dst( src, destination_addrinfo )
661
688
  elsif atyp == 3 then
662
689
  domain_len = data[ 4 ].unpack( 'C' ).first
@@ -666,7 +693,7 @@ module Girl
666
693
  port = data[ ( 5 + domain_len ), 2 ].unpack( 'n' ).first
667
694
  src_info[ :destination_domain ] = domain
668
695
  src_info[ :destination_port ] = port
669
- # puts "debug1 DOMAINNAME #{ domain } #{ port }"
696
+ # puts "debug DOMAINNAME #{ domain } #{ port }"
670
697
  resolve_domain( src, domain )
671
698
  end
672
699
  end
@@ -677,12 +704,9 @@ module Girl
677
704
  dst = src_info[ :dst ]
678
705
 
679
706
  if dst then
680
- unless dst.closed? then
681
- # puts "debug2 add dst.wbuff #{ data.bytesize }"
682
- add_dst_wbuff( dst, data )
683
- end
707
+ add_dst_wbuff( dst, data )
684
708
  else
685
- # puts "debug1 dst not ready, save data to src.rbuff"
709
+ # puts "debug add src.rbuff #{ data.bytesize }"
686
710
  add_src_rbuff( src, data )
687
711
  end
688
712
  end
@@ -697,21 +721,22 @@ module Girl
697
721
  return
698
722
  end
699
723
 
724
+ dst_info = @dst_infos[ dst ]
725
+ src = dst_info[ :src ]
726
+
700
727
  begin
701
- data = dst.read_nonblock( READ_SIZE )
728
+ data = dst.read_nonblock( 65535 )
702
729
  rescue IO::WaitReadable, Errno::EINTR
703
730
  print 'r'
704
731
  return
705
732
  rescue Exception => e
706
- # puts "debug1 read dst #{ e.class }"
707
- dst_info = close_read_dst( dst )
708
- src = dst_info[ :src ]
733
+ # puts "debug read dst #{ e.class }"
734
+ close_read_dst( dst )
709
735
  set_src_closing_write( src )
710
736
  return
711
737
  end
712
738
 
713
- dst_info = @dst_infos[ dst ]
714
- src = dst_info[ :src ]
739
+ # puts "debug read dst #{ data.bytesize }"
715
740
  add_src_wbuff( src, data )
716
741
  end
717
742
 
@@ -746,7 +771,7 @@ module Girl
746
771
  print 'w'
747
772
  return
748
773
  rescue Exception => e
749
- # puts "debug1 write src #{ e.class }"
774
+ # puts "debug write src #{ e.class }"
750
775
  close_write_src( src )
751
776
 
752
777
  if dst then
@@ -756,7 +781,6 @@ module Girl
756
781
  return
757
782
  end
758
783
 
759
- # puts "debug2 written src #{ written }"
760
784
  data = data[ written..-1 ]
761
785
  src_info[ :wbuff ] = data
762
786
  end
@@ -792,7 +816,7 @@ module Girl
792
816
  print 'w'
793
817
  return
794
818
  rescue Exception => e
795
- # puts "debug1 write dst #{ e.class }"
819
+ # puts "debug write dst #{ e.class }"
796
820
  close_write_dst( dst )
797
821
  close_read_src( src )
798
822
  return