girl 4.4.0 → 4.9.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.

data/lib/girl/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Girl
2
- VERSION = '4.4.0'.freeze
2
+ VERSION = '4.9.0'.freeze
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: girl
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.4.0
4
+ version: 4.9.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - takafan
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-04-14 00:00:00.000000000 Z
11
+ date: 2021-05-07 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: escape evil.
14
14
  email:
@@ -33,8 +33,6 @@ files:
33
33
  - lib/girl/resolv_custom.rb
34
34
  - lib/girl/resolvd.rb
35
35
  - lib/girl/resolvd_worker.rb
36
- - lib/girl/ssl.rb
37
- - lib/girl/ssl_worker.rb
38
36
  - lib/girl/version.rb
39
37
  homepage: https://github.com/takafan/girl
40
38
  licenses:
@@ -55,7 +53,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
55
53
  - !ruby/object:Gem::Version
56
54
  version: '0'
57
55
  requirements: []
58
- rubygems_version: 3.2.15
56
+ rubygems_version: 3.2.3
59
57
  signing_key:
60
58
  specification_version: 4
61
59
  summary: 妹子
data/lib/girl/ssl.rb DELETED
@@ -1,79 +0,0 @@
1
- require 'etc'
2
- require 'girl/concurrent_hash'
3
- require 'girl/head'
4
- require 'girl/ssl_worker'
5
- require 'girl/version'
6
- require 'json'
7
- require 'openssl'
8
- require 'socket'
9
-
10
- ##
11
- # Girl::Ssl
12
- #
13
- module Girl
14
- class Ssl
15
-
16
- def initialize( config_path = nil )
17
- unless config_path then
18
- config_path = File.expand_path( '../girl.conf.json', __FILE__ )
19
- end
20
-
21
- raise "missing config file #{ config_path }" unless File.exist?( config_path )
22
-
23
- conf = JSON.parse( IO.binread( config_path ), symbolize_names: true )
24
- redir_port = conf[ :ssl_port ]
25
- worker_count = conf[ :worker_count ]
26
-
27
- unless redir_port then
28
- redir_port = 1080
29
- end
30
-
31
- nprocessors = Etc.nprocessors
32
-
33
- if worker_count.nil? || worker_count <= 0 || worker_count > nprocessors then
34
- worker_count = nprocessors
35
- end
36
-
37
- len = CONSTS.map{ | name | name.size }.max
38
-
39
- CONSTS.each do | name |
40
- puts "#{ name.gsub( '_', ' ' ).ljust( len ) } #{ Girl.const_get( name ) }"
41
- end
42
-
43
- title = "girl ssl #{ Girl::VERSION }"
44
- puts title
45
- puts "redir port #{ redir_port } worker count #{ worker_count }"
46
-
47
- $0 = title
48
- workers = []
49
-
50
- worker_count.times do | i |
51
- workers << fork do
52
- $0 = 'girl ssl worker'
53
- worker = Girl::SslWorker.new( redir_port )
54
-
55
- Signal.trap( :TERM ) do
56
- puts "w#{ i } exit"
57
- worker.quit!
58
- end
59
-
60
- worker.looping
61
- end
62
- end
63
-
64
- Signal.trap( :TERM ) do
65
- puts 'trap TERM'
66
- workers.each do | pid |
67
- begin
68
- Process.kill( :TERM, pid )
69
- rescue Errno::ESRCH => e
70
- puts e.class
71
- end
72
- end
73
- end
74
-
75
- Process.waitall
76
- end
77
-
78
- end
79
- end
@@ -1,851 +0,0 @@
1
- module Girl
2
- class SslWorker
3
-
4
- ##
5
- # initialize
6
- #
7
- def initialize( redir_port )
8
- @redir_port = redir_port
9
- @reads = []
10
- @writes = []
11
- @closing_srcs = []
12
- @paused_srcs = []
13
- @paused_dsts = []
14
- @resume_srcs = []
15
- @resume_dsts = []
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 ]
20
-
21
- dotr, dotw = IO.pipe
22
- @dotw = dotw
23
- add_read( dotr, :dotr )
24
- new_a_redir
25
- end
26
-
27
- ##
28
- # looping
29
- #
30
- def looping
31
- puts "p#{ Process.pid } #{ Time.new } looping"
32
- loop_check_expire
33
- loop_check_resume
34
-
35
- loop do
36
- rs, ws = IO.select( @reads, @writes )
37
-
38
- rs.each do | sock |
39
- case @roles[ sock ]
40
- when :dotr then
41
- read_dotr( sock )
42
- when :redir then
43
- read_redir( sock )
44
- when :src then
45
- read_src( sock )
46
- when :dst then
47
- read_dst( sock )
48
- end
49
- end
50
-
51
- ws.each do | sock |
52
- case @roles[ sock ]
53
- when :src then
54
- write_src( sock )
55
- when :dst then
56
- write_dst( sock )
57
- end
58
- end
59
- end
60
- rescue Interrupt => e
61
- puts e.class
62
- quit!
63
- end
64
-
65
- ##
66
- # quit!
67
- #
68
- def quit!
69
- # puts "debug exit"
70
- exit
71
- end
72
-
73
- private
74
-
75
- ##
76
- # add closing src
77
- #
78
- def add_closing_src( src )
79
- return if src.closed? || @closing_srcs.include?( src )
80
- @closing_srcs << src
81
- next_tick
82
- end
83
-
84
- ##
85
- # add dst wbuff
86
- #
87
- def add_dst_wbuff( dst, data )
88
- return if dst.closed?
89
- dst_info = @dst_infos[ dst ]
90
- dst_info[ :wbuff ] << data
91
- add_write( dst )
92
-
93
- if dst_info[ :wbuff ].bytesize >= WBUFF_LIMIT then
94
- puts "p#{ Process.pid } #{ Time.new } pause direct src #{ dst_info[ :domain ] }"
95
- add_paused_src( dst_info[ :src ] )
96
- end
97
- end
98
-
99
- ##
100
- # add paused dst
101
- #
102
- def add_paused_dst( dst )
103
- return if dst.closed? || @paused_dsts.include?( dst )
104
- @reads.delete( dst )
105
- @paused_dsts << dst
106
- end
107
-
108
- ##
109
- # add paused src
110
- #
111
- def add_paused_src( src )
112
- return if src.closed? || @paused_srcs.include?( src )
113
- @reads.delete( src )
114
- @paused_srcs << src
115
- end
116
-
117
- ##
118
- # add read
119
- #
120
- def add_read( sock, role = nil )
121
- return if sock.closed? || @reads.include?( sock )
122
- @reads << sock
123
-
124
- if role then
125
- @roles[ sock ] = role
126
- end
127
-
128
- next_tick
129
- end
130
-
131
- ##
132
- # add resume dst
133
- #
134
- def add_resume_dst( dst )
135
- return if @resume_dsts.include?( dst )
136
- @resume_dsts << dst
137
- next_tick
138
- end
139
-
140
- ##
141
- # add resume src
142
- #
143
- def add_resume_src( src )
144
- return if @resume_srcs.include?( src )
145
- @resume_srcs << src
146
- next_tick
147
- end
148
-
149
- ##
150
- # add socks5 conn reply
151
- #
152
- def add_socks5_conn_reply( src )
153
- # +----+-----+-------+------+----------+----------+
154
- # |VER | REP | RSV | ATYP | BND.ADDR | BND.PORT |
155
- # +----+-----+-------+------+----------+----------+
156
- # | 1 | 1 | X'00' | 1 | Variable | 2 |
157
- # +----+-----+-------+------+----------+----------+
158
- redir_ip, redir_port = @redir_local_address.ip_unpack
159
- data = [ [ 5, 0, 0, 1 ].pack( 'C4' ), IPAddr.new( redir_ip ).hton, [ redir_port ].pack( 'n' ) ].join
160
- # puts "debug add src.wbuff socks5 conn reply #{ data.inspect }"
161
- add_src_wbuff( src, data )
162
- end
163
-
164
- ##
165
- # add src rbuff
166
- #
167
- def add_src_rbuff( src, data )
168
- src_info = @src_infos[ src ]
169
- src_info[ :rbuff ] << data
170
-
171
- if src_info[ :rbuff ].bytesize >= WBUFF_LIMIT then
172
- # puts "debug src.rbuff full"
173
- add_closing_src( src )
174
- end
175
- end
176
-
177
- ##
178
- # add src wbuff
179
- #
180
- def add_src_wbuff( src, data )
181
- return if src.closed? || @closing_srcs.include?( src )
182
- src_info = @src_infos[ src ]
183
- src_info[ :wbuff ] << data
184
- src_info[ :last_recv_at ] = Time.new
185
- add_write( src )
186
-
187
- if src_info[ :wbuff ].bytesize >= WBUFF_LIMIT then
188
- dst = src_info[ :dst ]
189
-
190
- if dst then
191
- puts "p#{ Process.pid } #{ Time.new } pause dst #{ src_info[ :destination_domain ] }"
192
- add_paused_dst( dst )
193
- end
194
- end
195
- end
196
-
197
- ##
198
- # add write
199
- #
200
- def add_write( sock )
201
- return if sock.closed? || @writes.include?( sock )
202
- @writes << sock
203
- next_tick
204
- end
205
-
206
- ##
207
- # close read dst
208
- #
209
- def close_read_dst( dst )
210
- return if dst.closed?
211
- # puts "debug close read dst"
212
- dst.close_read
213
- @reads.delete( dst )
214
-
215
- if dst.closed? then
216
- @writes.delete( dst )
217
- @roles.delete( dst )
218
- del_dst_info( dst )
219
- end
220
- end
221
-
222
- ##
223
- # close read src
224
- #
225
- def close_read_src( src )
226
- return if src.closed?
227
- # puts "debug close read src"
228
- src_info = @src_infos[ src ]
229
- src_info[ :close_read ] = true
230
-
231
- if src_info[ :close_write ] then
232
- close_sock( src )
233
- del_src_info( src )
234
- else
235
- @reads.delete( src )
236
- end
237
- end
238
-
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 ) }
248
- end
249
-
250
- ##
251
- # close sock
252
- #
253
- def close_sock( sock )
254
- sock.close
255
- @reads.delete( sock )
256
- @writes.delete( sock )
257
- @roles.delete( sock )
258
- end
259
-
260
- ##
261
- # close src
262
- #
263
- def close_src( src )
264
- return if src.closed?
265
- # puts "debug close src"
266
- close_sock( src )
267
- src_info = del_src_info( src )
268
- dst = src_info[ :dst ]
269
-
270
- if dst then
271
- close_sock( dst )
272
- del_dst_info( dst )
273
- end
274
- end
275
-
276
- ##
277
- # close write dst
278
- #
279
- def close_write_dst( dst )
280
- return if dst.closed?
281
- # puts "debug close write dst"
282
- dst.close_write
283
- @writes.delete( dst )
284
-
285
- if dst.closed? then
286
- @reads.delete( dst )
287
- @roles.delete( dst )
288
- del_dst_info( dst )
289
- end
290
- end
291
-
292
- ##
293
- # close write src
294
- #
295
- def close_write_src( src )
296
- return if src.closed?
297
- # puts "debug close write src"
298
- src_info = @src_infos[ src ]
299
- src_info[ :close_write ] = true
300
-
301
- if src_info[ :close_read ] then
302
- close_sock( src )
303
- del_src_info( src )
304
- else
305
- @writes.delete( src )
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
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 )
328
- src_info
329
- end
330
-
331
- ##
332
- # loop check expire
333
- #
334
- def loop_check_expire
335
- Thread.new do
336
- loop do
337
- sleep CHECK_EXPIRE_INTERVAL
338
- now = Time.new
339
-
340
- @src_infos.each do | src, src_info |
341
- last_recv_at = src_info[ :last_recv_at ] || src_info[ :created_at ]
342
- last_sent_at = src_info[ :last_sent_at ] || src_info[ :created_at ]
343
- expire_after = src_info[ :dst ] ? EXPIRE_AFTER : EXPIRE_NEW
344
-
345
- if ( now - last_recv_at >= expire_after ) && ( now - last_sent_at >= expire_after ) then
346
- puts "p#{ Process.pid } #{ Time.new } expire src #{ expire_after } #{ src_info[ :id ] } #{ src_info[ :destination_domain ] }"
347
- add_closing_src( src )
348
-
349
- unless src_info[ :rbuff ].empty? then
350
- puts "p#{ Process.pid } #{ Time.new } lost rbuff #{ src_info[ :rbuff ].inspect }"
351
- end
352
- end
353
- end
354
- end
355
- end
356
- end
357
-
358
- ##
359
- # loop check resume
360
- #
361
- def loop_check_resume
362
- Thread.new do
363
- loop do
364
- sleep CHECK_RESUME_INTERVAL
365
-
366
- @paused_srcs.each do | src |
367
- src_info = @src_infos[ src ]
368
- dst = src_info[ :dst ]
369
-
370
- if dst && !dst.closed? then
371
- dst_info = @dst_infos[ dst ]
372
-
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 )
376
- end
377
- end
378
- end
379
-
380
- @paused_dsts.each do | dst |
381
- dst_info = @dst_infos[ dst ]
382
- src = dst_info[ :src ]
383
-
384
- if src && !src.closed? then
385
- src_info = @src_infos[ src ]
386
-
387
- if src_info[ :wbuff ].size < RESUME_BELOW then
388
- puts "p#{ Process.pid } #{ Time.new } resume dst #{ dst_info[ :domain ] }"
389
- add_resume_dst( dst )
390
- end
391
- end
392
- end
393
- end
394
- end
395
- end
396
-
397
- ##
398
- # new a dst
399
- #
400
- def new_a_dst( src, ip_info )
401
- return if src.closed?
402
- src_info = @src_infos[ src ]
403
- domain = src_info[ :destination_domain ]
404
- destination_addr = Socket.sockaddr_in( src_info[ :destination_port ], ip_info.ip_address )
405
- dst = Socket.new( ip_info.ipv4? ? Socket::AF_INET : Socket::AF_INET6, Socket::SOCK_STREAM, 0 )
406
-
407
- begin
408
- dst.connect_nonblock( destination_addr )
409
- rescue IO::WaitWritable
410
- # connect nonblock 必抛 wait writable
411
- rescue Exception => e
412
- puts "p#{ Process.pid } #{ Time.new } dst connect destination #{ domain } #{ src_info[ :destination_port ] } #{ ip_info.ip_address } #{ e.class }, close src"
413
- dst.close
414
- add_closing_src( src )
415
- return
416
- end
417
-
418
- # puts "debug a new dst #{ dst.local_address.inspect }"
419
- dst_info = {
420
- src: src, # 对应src
421
- domain: domain, # 目的地
422
- wbuff: '', # 写前
423
- closing_write: false # 准备关闭写
424
- }
425
-
426
- @dst_infos[ dst ] = dst_info
427
- add_read( dst, :dst )
428
- src_info[ :proxy_type ] = :direct
429
- src_info[ :dst ] = dst
430
- add_socks5_conn_reply( src )
431
- end
432
-
433
- ##
434
- # new a redir
435
- #
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')
456
- context = OpenSSL::SSL::SSLContext.new
457
- context.security_level = 1
458
- context.add_certificate( cert, key )
459
- redir = OpenSSL::SSL::SSLServer.new pre, context
460
- redir.listen( 127 )
461
- puts "p#{ Process.pid } #{ Time.new } redir listening"
462
- add_read( redir, :redir )
463
- end
464
-
465
- ##
466
- # next tick
467
- #
468
- def next_tick
469
- @dotw.write( '.' )
470
- end
471
-
472
- ##
473
- # resolve domain
474
- #
475
- def resolve_domain( src, domain )
476
- resolv_cache = @resolv_caches[ domain ]
477
-
478
- if resolv_cache then
479
- ip_info, created_at = resolv_cache
480
-
481
- if Time.new - created_at < RESOLV_CACHE_EXPIRE then
482
- # puts "debug #{ domain } hit resolv cache #{ ip_info.inspect }"
483
- new_a_dst( src, ip_info )
484
- return
485
- end
486
-
487
- # puts "debug expire #{ domain } resolv cache"
488
- @resolv_caches.delete( domain )
489
- end
490
-
491
- src_info = @src_infos[ src ]
492
- src_info[ :proxy_type ] = :checking
493
-
494
- Thread.new do
495
- begin
496
- ip_info = Addrinfo.ip( domain )
497
- rescue Exception => e
498
- puts "p#{ Process.pid } #{ Time.new } resolv #{ domain.inspect } #{ e.class }"
499
- end
500
-
501
- if ip_info then
502
- @resolv_caches[ domain ] = [ ip_info, Time.new ]
503
- puts "p#{ Process.pid } #{ Time.new } resolved #{ domain } #{ ip_info.ip_address }"
504
- new_a_dst( src, ip_info )
505
- else
506
- add_closing_src( src )
507
- end
508
- end
509
- end
510
-
511
- ##
512
- # set dst closing write
513
- #
514
- def set_dst_closing_write( dst )
515
- return if dst.closed?
516
- dst_info = @dst_infos[ dst ]
517
- return if dst_info[ :closing_write ]
518
- dst_info[ :closing_write ] = true
519
- add_write( dst )
520
- end
521
-
522
- ##
523
- # set src closing write
524
- #
525
- def set_src_closing_write( src )
526
- return if src.closed? || @closing_srcs.include?( src )
527
- src_info = @src_infos[ src ]
528
- return if src_info[ :closing_write ]
529
- src_info[ :closing_write ] = true
530
- add_write( src )
531
- end
532
-
533
- ##
534
- # read dotr
535
- #
536
- def read_dotr( dotr )
537
- dotr.read_nonblock( 65535 )
538
-
539
- if @closing_srcs.any? then
540
- @closing_srcs.each { | src | close_src( src ) }
541
- @closing_srcs.clear
542
- end
543
-
544
- if @resume_srcs.any? then
545
- @resume_srcs.each do | src |
546
- add_read( src )
547
- @paused_srcs.delete( src )
548
- end
549
-
550
- @resume_srcs.clear
551
- end
552
-
553
- if @resume_dsts.any? then
554
- @resume_dsts.each do | dst |
555
- add_read( dst )
556
- @paused_dsts.delete( dst )
557
- end
558
-
559
- @resume_dsts.clear
560
- end
561
- end
562
-
563
- ##
564
- # read redir
565
- #
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
-
579
- begin
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
585
- rescue Exception => e
586
- puts "p#{ Process.pid } #{ Time.new } redir accept #{ e.class }"
587
- puts e.full_message
588
- return
589
- end
590
-
591
- accepted = true
592
- # puts "debug accept a src"
593
-
594
- @src_infos[ src ] = {
595
- proxy_proto: :uncheck, # :uncheck / :socks5
596
- proxy_type: :uncheck, # :uncheck / :checking / :direct / :negotiation
597
- destination_domain: nil, # 目的地域名
598
- destination_port: nil, # 目的地端口
599
- is_connect: true, # 代理协议是http的场合,是否是CONNECT
600
- rbuff: '', # 读到的流量
601
- dst: nil, # 对应的dst
602
- wbuff: '', # 从dst读到的流量
603
- created_at: Time.new, # 创建时间
604
- last_recv_at: nil, # 上一次收到新流量(由dst收到)的时间
605
- last_sent_at: nil, # 上一次发出流量(由dst发出)的时间
606
- closing_write: false, # 准备关闭写
607
- close_read: false, # 已经关闭读
608
- close_write: false # 已经关闭写
609
- }
610
-
611
- add_read( src, :src )
612
- end
613
-
614
- ##
615
- # read src
616
- #
617
- def read_src( src )
618
- if src.closed? then
619
- puts "p#{ Process.pid } #{ Time.new } read src but src closed?"
620
- return
621
- end
622
-
623
- src_info = @src_infos[ src ]
624
-
625
- begin
626
- data = src.read_nonblock( 65535 )
627
- rescue IO::WaitReadable
628
- return
629
- rescue Errno::EINTR => e
630
- puts e.class
631
- return
632
- rescue Exception => e
633
- # puts "debug read src #{ e.class }"
634
- dst = src_info[ :dst ]
635
- close_read_src( src )
636
-
637
- if dst then
638
- set_dst_closing_write( dst )
639
- end
640
-
641
- return
642
- end
643
-
644
- src_info = @src_infos[ src ]
645
- proxy_type = src_info[ :proxy_type ]
646
-
647
- case proxy_type
648
- when :uncheck then
649
- if data[ 0 ].unpack( 'C' ).first != 5 then
650
- "p#{ Process.pid } #{ Time.new } unknown data #{ data.inspect }"
651
- end
652
-
653
- # puts "debug socks5 #{ data.inspect }"
654
-
655
- # https://tools.ietf.org/html/rfc1928
656
- #
657
- # +----+----------+----------+
658
- # |VER | NMETHODS | METHODS |
659
- # +----+----------+----------+
660
- # | 1 | 1 | 1 to 255 |
661
- # +----+----------+----------+
662
- nmethods = data[ 1 ].unpack( 'C' ).first
663
- methods = data[ 2, nmethods ].unpack( 'C*' )
664
-
665
- unless methods.include?( 0 ) then
666
- puts "p#{ Process.pid } #{ Time.new } miss method 0x00"
667
- add_closing_src( src )
668
- return
669
- end
670
-
671
- # +----+--------+
672
- # |VER | METHOD |
673
- # +----+--------+
674
- # | 1 | 1 |
675
- # +----+--------+
676
- data2 = [ 5, 0 ].pack( 'CC' )
677
- add_src_wbuff( src, data2 )
678
- src_info[ :proxy_proto ] = :socks5
679
- src_info[ :proxy_type ] = :negotiation
680
- when :checking then
681
- # puts "debug add src rbuff before resolved #{ data.inspect }"
682
- src_info[ :rbuff ] << data
683
- when :negotiation then
684
- # +----+-----+-------+------+----------+----------+
685
- # |VER | CMD | RSV | ATYP | DST.ADDR | DST.PORT |
686
- # +----+-----+-------+------+----------+----------+
687
- # | 1 | 1 | X'00' | 1 | Variable | 2 |
688
- # +----+-----+-------+------+----------+----------+
689
- # puts "debug negotiation #{ data.inspect }"
690
- ver, cmd, rsv, atyp = data[ 0, 4 ].unpack( 'C4' )
691
-
692
- if cmd == 1 then
693
- # puts "debug socks5 CONNECT"
694
-
695
- if atyp == 1 then
696
- destination_host, destination_port = data[ 4, 6 ].unpack( 'Nn' )
697
- destination_addr = Socket.sockaddr_in( destination_port, destination_host )
698
- destination_addrinfo = Addrinfo.new( destination_addr )
699
- destination_ip = destination_addrinfo.ip_address
700
- src_info[ :destination_domain ] = destination_ip
701
- src_info[ :destination_port ] = destination_port
702
- # puts "debug IP V4 address #{ destination_addrinfo.ip_unpack.inspect }"
703
- new_a_dst( src, destination_addrinfo )
704
- elsif atyp == 3 then
705
- domain_len = data[ 4 ].unpack( 'C' ).first
706
-
707
- if ( domain_len + 7 ) == data.bytesize then
708
- domain = data[ 5, domain_len ]
709
- port = data[ ( 5 + domain_len ), 2 ].unpack( 'n' ).first
710
- src_info[ :destination_domain ] = domain
711
- src_info[ :destination_port ] = port
712
- # puts "debug DOMAINNAME #{ domain } #{ port }"
713
- resolve_domain( src, domain )
714
- end
715
- end
716
- else
717
- puts "p#{ Process.pid } #{ Time.new } socks5 cmd #{ cmd } not implement"
718
- end
719
- when :direct then
720
- dst = src_info[ :dst ]
721
-
722
- if dst then
723
- add_dst_wbuff( dst, data )
724
- else
725
- # puts "debug add src.rbuff #{ data.bytesize }"
726
- add_src_rbuff( src, data )
727
- end
728
- end
729
- end
730
-
731
- ##
732
- # read dst
733
- #
734
- def read_dst( dst )
735
- if dst.closed? then
736
- puts "p#{ Process.pid } #{ Time.new } read dst but dst closed?"
737
- return
738
- end
739
-
740
- dst_info = @dst_infos[ dst ]
741
- src = dst_info[ :src ]
742
-
743
- begin
744
- data = dst.read_nonblock( 65535 )
745
- rescue IO::WaitReadable, Errno::EINTR
746
- print 'r'
747
- return
748
- rescue Exception => e
749
- # puts "debug read dst #{ e.class }"
750
- close_read_dst( dst )
751
- set_src_closing_write( src )
752
- return
753
- end
754
-
755
- # puts "debug read dst #{ data.bytesize }"
756
- add_src_wbuff( src, data )
757
- end
758
-
759
- ##
760
- # write src
761
- #
762
- def write_src( src )
763
- if src.closed? then
764
- puts "p#{ Process.pid } #{ Time.new } write src but src closed?"
765
- return
766
- end
767
-
768
- src_info = @src_infos[ src ]
769
- dst = src_info[ :dst ]
770
- data = src_info[ :wbuff ]
771
-
772
- # 写前为空,处理关闭写
773
- if data.empty? then
774
- if src_info[ :closing_write ] then
775
- close_write_src( src )
776
- else
777
- @writes.delete( src )
778
- end
779
-
780
- return
781
- end
782
-
783
- # 写入
784
- begin
785
- written = src.write_nonblock( data )
786
- rescue IO::WaitWritable, Errno::EINTR
787
- print 'w'
788
- return
789
- rescue Exception => e
790
- # puts "debug write src #{ e.class }"
791
- close_write_src( src )
792
-
793
- if dst then
794
- close_read_dst( dst )
795
- end
796
-
797
- return
798
- end
799
-
800
- data = data[ written..-1 ]
801
- src_info[ :wbuff ] = data
802
- end
803
-
804
- ##
805
- # write dst
806
- #
807
- def write_dst( dst )
808
- if dst.closed? then
809
- puts "p#{ Process.pid } #{ Time.new } write dst but dst closed?"
810
- return
811
- end
812
-
813
- dst_info = @dst_infos[ dst ]
814
- src = dst_info[ :src ]
815
- data = dst_info[ :wbuff ]
816
-
817
- # 写前为空,处理关闭写
818
- if data.empty? then
819
- if dst_info[ :closing_write ] then
820
- close_write_dst( dst )
821
- else
822
- @writes.delete( dst )
823
- end
824
-
825
- return
826
- end
827
-
828
- # 写入
829
- begin
830
- written = dst.write_nonblock( data )
831
- rescue IO::WaitWritable, Errno::EINTR
832
- print 'w'
833
- return
834
- rescue Exception => e
835
- # puts "debug write dst #{ e.class }"
836
- close_write_dst( dst )
837
- close_read_src( src )
838
- return
839
- end
840
-
841
- data = data[ written..-1 ]
842
- dst_info[ :wbuff ] = data
843
-
844
- unless src.closed? then
845
- src_info = @src_infos[ src ]
846
- src_info[ :last_sent_at ] = Time.new
847
- end
848
- end
849
-
850
- end
851
- end