girl 0.95.0 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


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

checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 995e842429be7063ce5e29248927b336029f2e4dc864e4855979770d18ff7766
4
- data.tar.gz: 83b4619a2b8cf5f99058282345478eee57a2b7638cefafa5a15d1d0170abfb96
3
+ metadata.gz: 0c0254d6f9509721f13f14148087071820ae5ad13a3a7a87884d5372e7d93035
4
+ data.tar.gz: 2e718e248d7b3967e350a0dd4b6266c2a396a7eb5193a2fcd419222606b9ac19
5
5
  SHA512:
6
- metadata.gz: 349a7012c29fd90bae97816b1af481d25623f580969f3ec354c0b747c43aea805bba0b02f8ebb8e653427b12fa5af07584fc3566ddb67bd48fd04947b4386fcf
7
- data.tar.gz: c078531bb08ed0568e28170336c2a10b8b22896b2138bfdc149d9f61758cae938816ea623f7b4e7bab89e48620c855c731c4c3fdb2485573f2706125e9602b7c
6
+ metadata.gz: f9546abfd9b420cf80fa128670ba0db60e95bf54ed88466e1309820bb247ced3e7aa552d6afb93db12388a35b3d432d6994dfe2ea9a5f80580c82dce8655ff66
7
+ data.tar.gz: 7e3b2c573cd03bb284cc5d51a44b0c4aa882f7c069759f63075216759cf5abdab44f80babe5f3dbe81c126a05d9e1449c9e65bab0d34e3a9f184a417e922d326
@@ -25,8 +25,6 @@ lib/girl/proxy.rb
25
25
  lib/girl/proxyd_custom.rb
26
26
  lib/girl/proxyd_worker.rb
27
27
  lib/girl/proxyd.rb
28
- lib/girl/udp.rb
29
- lib/girl/udpd.rb
30
28
  lib/girl/version.rb
31
29
  ]
32
30
 
@@ -13,6 +13,13 @@ module Girl
13
13
  @mutex = Mutex.new
14
14
  @reads = []
15
15
  @writes = []
16
+ @closing_srcs = []
17
+ @paused_srcs = []
18
+ @paused_dsts = []
19
+ @paused_streams = []
20
+ @resume_srcs = []
21
+ @resume_dsts = []
22
+ @resume_streams = []
16
23
  @roles = {} # sock => :dotr / :proxy / :src / :dst / :tun / :stream
17
24
  @src_infos = {} # src => {}
18
25
  @dst_infos = {} # dst => {}
@@ -37,7 +44,6 @@ module Girl
37
44
  rs, ws = IO.select( @reads, @writes )
38
45
 
39
46
  @mutex.synchronize do
40
- # 先读,再写,避免打上关闭标记后读到
41
47
  rs.each do | sock |
42
48
  case @roles[ sock ]
43
49
  when :dotr then
@@ -90,6 +96,15 @@ module Girl
90
96
 
91
97
  private
92
98
 
99
+ ##
100
+ # add closing src
101
+ #
102
+ def add_closing_src( src )
103
+ return if src.closed? || @closing_srcs.include?( src )
104
+ @closing_srcs << src
105
+ next_tick
106
+ end
107
+
93
108
  ##
94
109
  # add ctlmsg
95
110
  #
@@ -101,14 +116,56 @@ module Girl
101
116
  if to_addr then
102
117
  @tun_info[ :ctlmsgs ] << [ data, to_addr ]
103
118
  add_write( @tun )
119
+ next_tick
104
120
  end
105
121
  end
106
122
 
123
+ ##
124
+ # add dst wbuff
125
+ #
126
+ def add_dst_wbuff( dst, data )
127
+ dst_info = @dst_infos[ dst ]
128
+ dst_info[ :wbuff ] << data
129
+ add_write( dst )
130
+
131
+ if dst_info[ :wbuff ].bytesize >= WBUFF_LIMIT then
132
+ puts "p#{ Process.pid } #{ Time.new } pause direct src #{ dst_info[ :domain ] }"
133
+ add_paused_src( dst_info[ :src ] )
134
+ end
135
+ end
136
+
137
+ ##
138
+ # add paused dst
139
+ #
140
+ def add_paused_dst( dst )
141
+ return if dst.closed? || @paused_dsts.include?( dst )
142
+ @reads.delete( dst )
143
+ @paused_dsts << dst
144
+ end
145
+
146
+ ##
147
+ # add paused src
148
+ #
149
+ def add_paused_src( src )
150
+ return if src.closed? || @paused_srcs.include?( src )
151
+ @reads.delete( src )
152
+ @paused_srcs << src
153
+ end
154
+
155
+ ##
156
+ # add paused stream
157
+ #
158
+ def add_paused_stream( stream )
159
+ return if stream.closed? || @paused_streams.include?( stream )
160
+ @reads.delete( stream )
161
+ @paused_streams << stream
162
+ end
163
+
107
164
  ##
108
165
  # add read
109
166
  #
110
167
  def add_read( sock, role = nil )
111
- unless @reads.include?( sock ) then
168
+ if !sock.closed? && !@reads.include?( sock ) then
112
169
  @reads << sock
113
170
 
114
171
  if role then
@@ -117,11 +174,51 @@ module Girl
117
174
  end
118
175
  end
119
176
 
177
+ ##
178
+ # add resume dst
179
+ #
180
+ def add_resume_dst( dst )
181
+ return if @resume_dsts.include?( dst )
182
+ @resume_dsts << dst
183
+ next_tick
184
+ end
185
+
186
+ ##
187
+ # add resume src
188
+ #
189
+ def add_resume_src( src )
190
+ return if @resume_srcs.include?( src )
191
+ @resume_srcs << src
192
+ next_tick
193
+ end
194
+
195
+ ##
196
+ # add resume stream
197
+ #
198
+ def add_resume_stream( stream )
199
+ return if @resume_streams.include?( stream )
200
+ @resume_streams << stream
201
+ next_tick
202
+ end
203
+
204
+ ##
205
+ # add src rbuff
206
+ #
207
+ def add_src_rbuff( src, data )
208
+ src_info = @src_infos[ src ]
209
+ src_info[ :rbuff ] << data
210
+
211
+ if src_info[ :rbuff ].bytesize >= WBUFF_LIMIT then
212
+ # puts "debug1 src.rbuff full"
213
+ add_closing_src( src )
214
+ end
215
+ end
216
+
120
217
  ##
121
218
  # add src wbuff
122
219
  #
123
220
  def add_src_wbuff( src, data )
124
- return if src.closed?
221
+ return if src.closed? || @closing_srcs.include?( src )
125
222
  src_info = @src_infos[ src ]
126
223
  src_info[ :wbuff ] << data
127
224
  src_info[ :last_recv_at ] = Time.new
@@ -131,18 +228,14 @@ module Girl
131
228
  dst = src_info[ :dst ]
132
229
 
133
230
  if dst then
134
- dst_info = @dst_infos[ dst ]
135
- puts "p#{ Process.pid } #{ Time.new } pause dst #{ dst_info[ :domain ] }"
136
- dst_info[ :paused ] = true
137
- @reads.delete( dst )
231
+ puts "p#{ Process.pid } #{ Time.new } pause dst #{ src_info[ :destination_domain ] }"
232
+ add_paused_dst( dst )
138
233
  else
139
234
  stream = src_info[ :stream ]
140
235
 
141
236
  if stream then
142
- stream_info = @stream_infos[ stream ]
143
- puts "p#{ Process.pid } #{ Time.new } pause stream #{ stream_info[ :domain ] }"
144
- stream_info[ :paused ] = true
145
- @reads.delete( stream )
237
+ puts "p#{ Process.pid } #{ Time.new } pause stream #{ src_info[ :destination_domain ] }"
238
+ add_paused_stream( stream )
146
239
  end
147
240
  end
148
241
  end
@@ -164,34 +257,46 @@ module Girl
164
257
  end
165
258
 
166
259
  ##
167
- # add write
260
+ # add stream wbuff
168
261
  #
169
- def add_write( sock )
170
- unless @writes.include?( sock ) then
171
- @writes << sock
262
+ def add_stream_wbuff( stream, data )
263
+ stream_info = @stream_infos[ stream ]
264
+ stream_info[ :wbuff ] << data
265
+ add_write( stream )
266
+
267
+ if stream_info[ :wbuff ].bytesize >= WBUFF_LIMIT then
268
+ puts "p#{ Process.pid } #{ Time.new } pause tunnel src #{ stream_info[ :domain ] }"
269
+ add_paused_src( stream_info[ :src ] )
172
270
  end
173
271
  end
174
272
 
175
273
  ##
176
- # close sock
274
+ # add write
177
275
  #
178
- def close_sock( sock )
179
- sock.close
180
- @reads.delete( sock )
181
- @writes.delete( sock )
182
- @roles.delete( sock )
276
+ def add_write( sock )
277
+ if !sock.closed? && !@writes.include?( sock ) then
278
+ @writes << sock
279
+ end
183
280
  end
184
281
 
185
282
  ##
186
- # close dst
283
+ # close read dst
187
284
  #
188
- def close_dst( dst )
189
- # puts "debug1 close dst"
190
- close_sock( dst )
191
- dst_info = @dst_infos.delete( dst )
192
- src = dst_info[ :src ]
193
- close_read_src( src )
194
- set_src_closing_write( src )
285
+ def close_read_dst( dst )
286
+ return if dst.closed?
287
+ # puts "debug1 close read dst"
288
+ dst.close_read
289
+ @reads.delete( dst )
290
+
291
+ if dst.closed? then
292
+ # puts "debug1 delete dst info"
293
+ @roles.delete( dst )
294
+ dst_info = @dst_infos.delete( dst )
295
+ else
296
+ dst_info = @dst_infos[ dst ]
297
+ end
298
+
299
+ dst_info
195
300
  end
196
301
 
197
302
  ##
@@ -211,30 +316,9 @@ module Girl
211
316
  src_info = @src_infos[ src ]
212
317
  end
213
318
 
214
- src_info[ :paused ] = false
215
319
  src_info
216
320
  end
217
321
 
218
- ##
219
- # close read dst
220
- #
221
- def close_read_dst( dst )
222
- return if dst.closed?
223
- # puts "debug1 close read dst"
224
- dst.close_read
225
- @reads.delete( dst )
226
-
227
- if dst.closed? then
228
- # puts "debug1 delete dst info"
229
- @roles.delete( dst )
230
- dst_info = @dst_infos.delete( dst )
231
- else
232
- dst_info = @dst_infos[ dst ]
233
- end
234
-
235
- dst_info
236
- end
237
-
238
322
  ##
239
323
  # close read stream
240
324
  #
@@ -255,68 +339,47 @@ module Girl
255
339
  stream_info
256
340
  end
257
341
 
342
+ ##
343
+ # close sock
344
+ #
345
+ def close_sock( sock )
346
+ sock.close
347
+ @reads.delete( sock )
348
+ @writes.delete( sock )
349
+ @roles.delete( sock )
350
+ end
351
+
258
352
  ##
259
353
  # close src
260
354
  #
261
355
  def close_src( src )
356
+ return if src.closed?
262
357
  # puts "debug1 close src"
263
358
  close_sock( src )
264
359
  src_info = del_src_info( src )
265
360
  dst = src_info[ :dst ]
266
361
 
267
362
  if dst then
268
- close_read_dst( dst )
269
- set_dst_closing_write( dst )
363
+ close_sock( dst )
364
+ @dst_infos.delete( dst )
270
365
  else
271
366
  stream = src_info[ :stream ]
272
367
 
273
368
  if stream then
274
- close_read_stream( stream )
275
- set_stream_closing_write( stream )
369
+ close_sock( stream )
370
+ @stream_infos.delete( stream )
276
371
  end
277
372
  end
278
373
  end
279
374
 
280
- ##
281
- # close stream
282
- #
283
- def close_stream( stream )
284
- # puts "debug1 close stream"
285
- close_sock( stream )
286
- stream_info = @stream_infos.delete( stream )
287
- src = stream_info[ :src ]
288
- close_read_src( src )
289
- set_src_closing_write( src )
290
- end
291
-
292
375
  ##
293
376
  # close tun
294
377
  #
295
378
  def close_tun( tun )
296
379
  # puts "debug1 close tun"
297
380
  close_sock( tun )
298
- @tun_info[ :srcs ].each{ | _, src | set_src_closing( src ) }
299
- end
300
-
301
- ##
302
- # close write src
303
- #
304
- def close_write_src( src )
305
- return if src.closed?
306
- # puts "debug1 close write src"
307
- src.close_write
308
- @writes.delete( src )
309
-
310
- if src.closed? then
311
- # puts "debug1 delete src info"
312
- @roles.delete( src )
313
- src_info = del_src_info( src )
314
- else
315
- src_info = @src_infos[ src ]
316
- end
317
-
318
- src_info[ :closed_write ] = true
319
- src_info
381
+ @tun_info[ :ctlmsgs ].clear
382
+ @tun_info[ :srcs ].each{ | _, src | close_src( src ) }
320
383
  end
321
384
 
322
385
  ##
@@ -336,10 +399,29 @@ module Girl
336
399
  dst_info = @dst_infos[ dst ]
337
400
  end
338
401
 
339
- dst_info[ :closed_write ] = true
340
402
  dst_info
341
403
  end
342
404
 
405
+ ##
406
+ # close write src
407
+ #
408
+ def close_write_src( src )
409
+ return if src.closed?
410
+ # puts "debug1 close write src"
411
+ src.close_write
412
+ @writes.delete( src )
413
+
414
+ if src.closed? then
415
+ # puts "debug1 delete src info"
416
+ @roles.delete( src )
417
+ src_info = del_src_info( src )
418
+ else
419
+ src_info = @src_infos[ src ]
420
+ end
421
+
422
+ src_info
423
+ end
424
+
343
425
  ##
344
426
  # close write stream
345
427
  #
@@ -357,7 +439,6 @@ module Girl
357
439
  stream_info = @stream_infos[ stream ]
358
440
  end
359
441
 
360
- stream_info[ :closed_write ] = true
361
442
  stream_info
362
443
  end
363
444
 
@@ -384,7 +465,7 @@ module Girl
384
465
  def del_src_info( src )
385
466
  src_info = @src_infos.delete( src )
386
467
 
387
- if ( src_info[ :proxy_type ] == :tunnel ) && @tun && !@tun.closed? then
468
+ if ( src_info[ :proxy_type ] == :tunnel ) && @tun then
388
469
  @tun_info[ :srcs ].delete( src_info[ :id ] )
389
470
  end
390
471
 
@@ -400,7 +481,6 @@ module Girl
400
481
  sleep CHECK_EXPIRE_INTERVAL
401
482
 
402
483
  @mutex.synchronize do
403
- trigger = false
404
484
  now = Time.new
405
485
 
406
486
  if @tun && !@tun.closed? then
@@ -414,8 +494,6 @@ module Girl
414
494
  data = [ 0, HEARTBEAT ].pack( 'Q>C' )
415
495
  add_ctlmsg( data )
416
496
  end
417
-
418
- trigger = true
419
497
  end
420
498
 
421
499
  @src_infos.each do | src, src_info |
@@ -424,12 +502,9 @@ module Girl
424
502
 
425
503
  if ( now - last_recv_at >= EXPIRE_AFTER ) && ( now - last_sent_at >= EXPIRE_AFTER ) then
426
504
  puts "p#{ Process.pid } #{ Time.new } expire src #{ src_info[ :destination_domain ] }"
427
- set_src_closing( src )
428
- trigger = true
505
+ add_closing_src( src )
429
506
  end
430
507
  end
431
-
432
- next_tick if trigger
433
508
  end
434
509
  end
435
510
  end
@@ -444,56 +519,61 @@ module Girl
444
519
  sleep CHECK_RESUME_INTERVAL
445
520
 
446
521
  @mutex.synchronize do
447
- trigger = false
448
-
449
- @src_infos.select{ | _, src_info | src_info[ :paused ] }.each do | src, src_info |
450
- dst = src_info[ :dst ]
451
-
452
- if dst then
453
- dst_info = @dst_infos[ dst ]
454
-
455
- if dst_info[ :wbuff ].size < RESUME_BELOW then
456
- puts "p#{ Process.pid } #{ Time.new } dst.wbuff below #{ RESUME_BELOW }, resume src #{ src_info[ :destination_domain ] }"
457
- resume_src( src )
458
- trigger = true
459
- end
522
+ @paused_srcs.each do | src |
523
+ if src.closed? then
524
+ add_resume_src( src )
460
525
  else
461
- stream = src_info[ :stream ]
462
- stream_info = @stream_infos[ stream ]
463
-
464
- if stream_info[ :wbuff ].size < RESUME_BELOW then
465
- puts "p#{ Process.pid } #{ Time.new } stream.wbuff below #{ RESUME_BELOW }, resume src #{ src_info[ :destination_domain ] }"
466
- resume_src( src )
467
- trigger = true
526
+ src_info = @src_infos[ src ]
527
+ dst = src_info[ :dst ]
528
+
529
+ if dst then
530
+ dst_info = @dst_infos[ dst ]
531
+
532
+ if dst_info[ :wbuff ].size < RESUME_BELOW then
533
+ puts "p#{ Process.pid } #{ Time.new } resume direct src #{ src_info[ :destination_domain ] }"
534
+ add_resume_src( src )
535
+ end
536
+ else
537
+ stream = src_info[ :stream ]
538
+ stream_info = @stream_infos[ stream ]
539
+
540
+ if stream_info[ :wbuff ].size < RESUME_BELOW then
541
+ puts "p#{ Process.pid } #{ Time.new } resume tunnel src #{ src_info[ :destination_domain ] }"
542
+ add_resume_src( src )
543
+ end
468
544
  end
469
545
  end
470
546
  end
471
547
 
472
- @dst_infos.select{ | _, dst_info | dst_info[ :paused ] }.each do | dst, dst_info |
473
- src = dst_info[ :src ]
474
- src_info = @src_infos[ src ]
548
+ @paused_dsts.each do | dst |
549
+ if dst.closed? then
550
+ add_resume_dst( dst )
551
+ else
552
+ dst_info = @dst_infos[ dst ]
553
+ src = dst_info[ :src ]
554
+ src_info = @src_infos[ src ]
475
555
 
476
- if src_info[ :wbuff ].size < RESUME_BELOW then
477
- puts "p#{ Process.pid } #{ Time.new } src.wbuff below #{ RESUME_BELOW }, resume dst #{ dst_info[ :domain ] }"
478
- dst_info[ :paused ] = false
479
- add_read( dst )
480
- trigger = true
556
+ if src_info[ :wbuff ].size < RESUME_BELOW then
557
+ puts "p#{ Process.pid } #{ Time.new } resume dst #{ dst_info[ :domain ] }"
558
+ add_resume_dst( dst )
559
+ end
481
560
  end
482
561
  end
483
562
 
484
- @stream_infos.select{ | _, stream_info | stream_info[ :paused ] }.each do | stream, stream_info |
485
- src = stream_info[ :src ]
486
- src_info = @src_infos[ src ]
563
+ @paused_streams.each do | stream |
564
+ if stream.closed? then
565
+ add_resume_stream( stream )
566
+ else
567
+ stream_info = @stream_infos[ stream ]
568
+ src = stream_info[ :src ]
569
+ src_info = @src_infos[ src ]
487
570
 
488
- if src_info[ :wbuff ].size < RESUME_BELOW then
489
- puts "p#{ Process.pid } #{ Time.new } src.wbuff below #{ RESUME_BELOW }, resume stream #{ stream_info[ :domain ] }"
490
- stream_info[ :paused ] = false
491
- add_read( stream )
492
- trigger = true
571
+ if src_info[ :wbuff ].size < RESUME_BELOW then
572
+ puts "p#{ Process.pid } #{ Time.new } resume stream #{ stream_info[ :domain ] }"
573
+ add_resume_stream( stream )
574
+ end
493
575
  end
494
576
  end
495
-
496
- next_tick if trigger
497
577
  end
498
578
  end
499
579
  end
@@ -513,7 +593,7 @@ module Girl
513
593
 
514
594
  Thread.new do
515
595
  SEND_HELLO_COUNT.times do | i |
516
- if @tun.nil? || @tun.closed? || src.closed? || src_info[ :stream ] then
596
+ if @tun.nil? || @tun.closed? || @tun_info[ :closing ] || src.closed? || src_info[ :stream ] then
517
597
  # puts "debug1 break loop send a new source #{ src_info[ :dst_port ] }"
518
598
  break
519
599
  end
@@ -524,7 +604,6 @@ module Girl
524
604
  end
525
605
 
526
606
  add_ctlmsg( data )
527
- next_tick
528
607
  end
529
608
 
530
609
  sleep SEND_HELLO_INTERVAL
@@ -549,21 +628,17 @@ module Girl
549
628
  # connect nonblock 必抛 wait writable
550
629
  rescue Exception => e
551
630
  puts "p#{ Process.pid } #{ Time.new } dst connect destination #{ domain } #{ src_info[ :destination_port ] } #{ ip_info.ip_address } #{ e.class }, close src"
552
- set_src_closing( src )
631
+ dst.close
632
+ add_closing_src( src )
553
633
  return
554
634
  end
555
635
 
556
636
  # puts "debug1 a new dst #{ dst.local_address.inspect }"
557
- local_port = dst.local_address.ip_port
558
637
  dst_info = {
559
- local_port: local_port, # 本地端口
560
- src: src, # 对应src
561
- domain: domain, # 目的地
562
- wbuff: '', # 写前,从src读到的流量
563
- paused: false, # 是否已暂停读
564
- closing: false, # 准备关闭
565
- closing_write: false, # 准备关闭写
566
- closed_write: false # 已关闭写
638
+ src: src, # 对应src
639
+ domain: domain, # 目的地
640
+ wbuff: '', # 写前,从src读到的流量
641
+ closing_write: false # 准备关闭写
567
642
  }
568
643
 
569
644
  @dst_infos[ dst ] = dst_info
@@ -585,6 +660,25 @@ module Girl
585
660
  end
586
661
  end
587
662
 
663
+ ##
664
+ # new a proxy
665
+ #
666
+ def new_a_proxy( proxy_port )
667
+ proxy = Socket.new( Socket::AF_INET, Socket::SOCK_STREAM, 0 )
668
+ proxy.setsockopt( Socket::SOL_SOCKET, Socket::SO_REUSEADDR, 1 )
669
+
670
+ if RUBY_PLATFORM.include?( 'linux' ) then
671
+ proxy.setsockopt( Socket::SOL_SOCKET, Socket::SO_REUSEPORT, 1 )
672
+ proxy.setsockopt( Socket::SOL_TCP, Socket::TCP_NODELAY, 1 )
673
+ end
674
+
675
+ proxy.bind( Socket.sockaddr_in( proxy_port, '0.0.0.0' ) )
676
+ proxy.listen( 127 )
677
+ puts "p#{ Process.pid } #{ Time.new } proxy listen on #{ proxy_port }"
678
+ add_read( proxy, :proxy )
679
+ @proxy_local_address = proxy.local_address
680
+ end
681
+
588
682
  ##
589
683
  # new a stream
590
684
  #
@@ -597,7 +691,7 @@ module Girl
597
691
 
598
692
  if dst_id == 0 then
599
693
  puts "p#{ Process.pid } #{ Time.new } remote dst already closed"
600
- set_src_closing( src )
694
+ add_closing_src( src )
601
695
  return
602
696
  end
603
697
 
@@ -609,6 +703,7 @@ module Girl
609
703
  rescue IO::WaitWritable
610
704
  rescue Exception => e
611
705
  puts "p#{ Process.pid } #{ Time.new } connect tcpd #{ e.class }"
706
+ stream.close
612
707
  return
613
708
  end
614
709
 
@@ -625,10 +720,7 @@ module Girl
625
720
  src: src, # 对应src
626
721
  domain: domain, # 目的地
627
722
  wbuff: data, # 写前,写往远端streamd
628
- paused: false, # 是否已暂停读
629
- closing: false, # 准备关闭
630
- closing_write: false, # 准备关闭写
631
- closed_write: false # 已关闭写
723
+ closing_write: false # 准备关闭写
632
724
  }
633
725
 
634
726
  src_info[ :dst_id ] = dst_id
@@ -646,25 +738,6 @@ module Girl
646
738
  end
647
739
  end
648
740
 
649
- ##
650
- # new a proxy
651
- #
652
- def new_a_proxy( proxy_port )
653
- proxy = Socket.new( Socket::AF_INET, Socket::SOCK_STREAM, 0 )
654
- proxy.setsockopt( Socket::SOL_SOCKET, Socket::SO_REUSEADDR, 1 )
655
-
656
- if RUBY_PLATFORM.include?( 'linux' ) then
657
- proxy.setsockopt( Socket::SOL_SOCKET, Socket::SO_REUSEPORT, 1 )
658
- proxy.setsockopt( Socket::SOL_TCP, Socket::TCP_NODELAY, 1 )
659
- end
660
-
661
- proxy.bind( Socket.sockaddr_in( proxy_port, '0.0.0.0' ) )
662
- proxy.listen( 127 )
663
- puts "p#{ Process.pid } #{ Time.new } proxy listen on #{ proxy_port }"
664
- add_read( proxy, :proxy )
665
- @proxy_local_address = proxy.local_address
666
- end
667
-
668
741
  ##
669
742
  # new a tun
670
743
  #
@@ -692,7 +765,7 @@ module Girl
692
765
 
693
766
  Thread.new do
694
767
  SEND_HELLO_COUNT.times do | i |
695
- if @tun.nil? || @tun.closed? || @tun_info[ :tund_addr ] then
768
+ if @tun.nil? || @tun.closed? || @tun_info[ :closing ] || @tun_info[ :tund_addr ] then
696
769
  # puts "debug1 break loop send hello"
697
770
  break
698
771
  end
@@ -703,7 +776,6 @@ module Girl
703
776
  # puts "debug1 #{ data.inspect }"
704
777
 
705
778
  add_ctlmsg( data, @proxyd_addr )
706
- next_tick
707
779
  end
708
780
 
709
781
  sleep SEND_HELLO_INTERVAL
@@ -723,7 +795,7 @@ module Girl
723
795
  #
724
796
  def resolve_domain( src, domain )
725
797
  if @remotes.any? { | remote | ( domain.size >= remote.size ) && ( domain[ ( remote.size * -1 )..-1 ] == remote ) } then
726
- # puts "debug1 #{ domain } hit remotes"
798
+ puts "p#{ Process.pid } #{ Time.new } #{ domain } hit remotes"
727
799
  set_src_proxy_type_tunnel( src )
728
800
  return
729
801
  end
@@ -760,41 +832,15 @@ module Girl
760
832
  unless src.closed? then
761
833
  puts "p#{ Process.pid } #{ Time.new } resolved #{ domain } #{ ip_info.ip_address }"
762
834
  deal_with_destination_ip( src, ip_info )
835
+ next_tick
763
836
  end
764
837
  else
765
- set_src_closing( src )
838
+ add_closing_src( src )
766
839
  end
767
-
768
- next_tick
769
840
  end
770
841
  end
771
842
  end
772
843
 
773
- ##
774
- # resume src
775
- #
776
- def resume_src( src )
777
- src_info = @src_infos[ src ]
778
- src_info[ :paused ] = false
779
- add_read( src )
780
- end
781
-
782
- ##
783
- # set dst closing
784
- #
785
- def set_dst_closing( dst )
786
- return if dst.closed?
787
- dst_info = @dst_infos[ dst ]
788
- dst_info[ :closing ] = true
789
-
790
- if dst_info[ :closed_write ] then
791
- add_read( dst )
792
- else
793
- @reads.delete( dst )
794
- add_write( dst )
795
- end
796
- end
797
-
798
844
  ##
799
845
  # set dst closing write
800
846
  #
@@ -802,36 +848,20 @@ module Girl
802
848
  return if dst.closed?
803
849
 
804
850
  dst_info = @dst_infos[ dst ]
805
- return if dst_info[ :closed_write ]
851
+ return if dst_info[ :closing_write ]
806
852
 
807
853
  dst_info[ :closing_write ] = true
808
854
  add_write( dst )
809
855
  end
810
856
 
811
- ##
812
- # set src is closing
813
- #
814
- def set_src_closing( src )
815
- return if src.closed?
816
- src_info = @src_infos[ src ]
817
- src_info[ :closing ] = true
818
-
819
- if src_info[ :closed_write ] then
820
- add_read( src )
821
- else
822
- @reads.delete( src )
823
- add_write( src )
824
- end
825
- end
826
-
827
857
  ##
828
858
  # set src closing write
829
859
  #
830
860
  def set_src_closing_write( src )
831
- return if src.closed?
861
+ return if src.closed? || @closing_srcs.include?( src )
832
862
 
833
863
  src_info = @src_infos[ src ]
834
- return if src_info[ :closed_write ]
864
+ return if src_info[ :closing_write ]
835
865
 
836
866
  src_info[ :closing_write ] = true
837
867
  add_write( src )
@@ -841,10 +871,6 @@ module Girl
841
871
  # set src proxy type tunnel
842
872
  #
843
873
  def set_src_proxy_type_tunnel( src )
844
- if @tun.nil? || @tun.closed? then
845
- new_a_tun
846
- end
847
-
848
874
  src_info = @src_infos[ src ]
849
875
  src_info[ :proxy_type ] = :tunnel
850
876
  src_id = src_info[ :id ]
@@ -864,7 +890,7 @@ module Girl
864
890
  return if stream.closed?
865
891
 
866
892
  stream_info = @stream_infos[ stream ]
867
- return if stream_info[ :closed_write ]
893
+ return if stream_info[ :closing_write ]
868
894
 
869
895
  stream_info[ :closing_write ] = true
870
896
  add_write( stream )
@@ -874,10 +900,11 @@ module Girl
874
900
  # set tun is closing
875
901
  #
876
902
  def set_tun_closing
877
- return if @tun.closed?
903
+ return if @tun.closed? || @tun_info[ :closing ]
878
904
  @tun_info[ :closing ] = true
879
905
  @reads.delete( @tun )
880
- add_write( @tun )
906
+ @writes.delete( @tun )
907
+ next_tick
881
908
  end
882
909
 
883
910
  ##
@@ -903,7 +930,43 @@ module Girl
903
930
  # read dotr
904
931
  #
905
932
  def read_dotr( dotr )
906
- dotr.read( 1 )
933
+ dotr.read_nonblock( READ_SIZE )
934
+
935
+ if @tun && !@tun.closed? && @tun_info[ :closing ] then
936
+ close_tun( @tun )
937
+ end
938
+
939
+ if @closing_srcs.any? then
940
+ @closing_srcs.each{ | src | close_src( src ) }
941
+ @closing_srcs.clear
942
+ end
943
+
944
+ if @resume_srcs.any? then
945
+ @resume_srcs.each do | src |
946
+ add_read( src )
947
+ @paused_srcs.delete( src )
948
+ end
949
+
950
+ @resume_srcs.clear
951
+ end
952
+
953
+ if @resume_dsts.any? then
954
+ @resume_dsts.each do | dst |
955
+ add_read( dst )
956
+ @paused_dsts.delete( dst )
957
+ end
958
+
959
+ @resume_dsts.clear
960
+ end
961
+
962
+ if @resume_streams.any? then
963
+ @resume_streams.each do | stream |
964
+ add_read( stream )
965
+ @paused_streams.delete( stream )
966
+ end
967
+
968
+ @resume_streams.clear
969
+ end
907
970
  end
908
971
 
909
972
  ##
@@ -935,19 +998,23 @@ module Girl
935
998
  created_at: Time.new, # 创建时间
936
999
  last_recv_at: nil, # 上一次收到新流量(由dst收到,或者由stream收到)的时间
937
1000
  last_sent_at: nil, # 上一次发出流量(由dst发出,或者由stream发出)的时间
938
- paused: false, # 是否已暂停读
939
- closing: false, # 准备关闭
940
- closing_write: false, # 准备关闭写
941
- closed_write: false # 已关闭写
1001
+ closing_write: false # 准备关闭写
942
1002
  }
943
1003
 
944
1004
  add_read( src, :src )
1005
+
1006
+ # 用到tun,是在解析目的地域名得出是国外ip之后。但解析域名是额外的线程,为避免多线程重复建tun,在accept到src时就建。
1007
+ if @tun.nil? || @tun.closed? then
1008
+ new_a_tun
1009
+ end
945
1010
  end
946
1011
 
947
1012
  ##
948
1013
  # read tun
949
1014
  #
950
1015
  def read_tun( tun )
1016
+ return if tun.closed?
1017
+
951
1018
  begin
952
1019
  data, addrinfo, rflags, *controls = tun.recvmsg_nonblock
953
1020
  rescue IO::WaitReadable, Errno::EINTR
@@ -1028,13 +1095,6 @@ module Girl
1028
1095
  end
1029
1096
 
1030
1097
  src_info = @src_infos[ src ]
1031
-
1032
- # 处理关闭
1033
- if src_info[ :closing ] then
1034
- close_src( src )
1035
- return
1036
- end
1037
-
1038
1098
  proxy_type = src_info[ :proxy_type ]
1039
1099
 
1040
1100
  case proxy_type
@@ -1045,7 +1105,7 @@ module Girl
1045
1105
 
1046
1106
  unless domain_port then
1047
1107
  puts "p#{ Process.pid } #{ Time.new } CONNECT miss domain"
1048
- set_src_closing( src )
1108
+ add_closing_src( src )
1049
1109
  return
1050
1110
  end
1051
1111
  elsif data[ 0 ].unpack( 'C' ).first == 5 then
@@ -1063,7 +1123,7 @@ module Girl
1063
1123
 
1064
1124
  unless methods.include?( 0 ) then
1065
1125
  puts "p#{ Process.pid } #{ Time.new } miss method 00"
1066
- set_src_closing( src )
1126
+ add_closing_src( src )
1067
1127
  return
1068
1128
  end
1069
1129
 
@@ -1083,7 +1143,7 @@ module Girl
1083
1143
 
1084
1144
  unless host_line then
1085
1145
  # puts "debug1 not found host line"
1086
- set_src_closing( src )
1146
+ add_closing_src( src )
1087
1147
  return
1088
1148
  end
1089
1149
 
@@ -1095,7 +1155,7 @@ module Girl
1095
1155
 
1096
1156
  unless domain_port then
1097
1157
  puts "p#{ Process.pid } #{ Time.new } Host line miss domain"
1098
- set_src_closing( src )
1158
+ add_closing_src( src )
1099
1159
  return
1100
1160
  end
1101
1161
  end
@@ -1160,26 +1220,13 @@ module Girl
1160
1220
  data, _ = sub_http_request( data )
1161
1221
  end
1162
1222
 
1163
- stream_info = @stream_infos[ stream ]
1164
1223
  data = @custom.encode( data )
1165
1224
  # puts "debug2 add stream.wbuff encoded #{ data.bytesize }"
1166
- stream_info[ :wbuff ] << data
1167
- add_write( stream )
1168
-
1169
- if stream_info[ :wbuff ].bytesize >= WBUFF_LIMIT then
1170
- puts "p#{ Process.pid } #{ Time.new } pause tunnel src #{ src_info[ :destination_domain ] }"
1171
- src_info[ :paused ] = true
1172
- @reads.delete( src )
1173
- end
1225
+ add_stream_wbuff( stream, data )
1174
1226
  end
1175
1227
  else
1176
1228
  # puts "debug1 stream not ready, save data to src.rbuff"
1177
- src_info[ :rbuff ] << data
1178
-
1179
- if src_info[ :rbuff ].bytesize >= WBUFF_LIMIT then
1180
- # puts "debug1 tunnel src.rbuff full"
1181
- set_src_closing( src )
1182
- end
1229
+ add_src_rbuff( src, data )
1183
1230
  end
1184
1231
  when :direct then
1185
1232
  dst = src_info[ :dst ]
@@ -1190,25 +1237,12 @@ module Girl
1190
1237
  data, _ = sub_http_request( data )
1191
1238
  end
1192
1239
 
1193
- dst_info = @dst_infos[ dst ]
1194
1240
  # puts "debug2 add dst.wbuff #{ data.bytesize }"
1195
- dst_info[ :wbuff ] << data
1196
- add_write( dst )
1197
-
1198
- if dst_info[ :wbuff ].bytesize >= WBUFF_LIMIT then
1199
- puts "p#{ Process.pid } #{ Time.new } pause direct src #{ src_info[ :destination_domain ] }"
1200
- src_info[ :paused ] = true
1201
- @reads.delete( src )
1202
- end
1241
+ add_dst_wbuff( dst, data )
1203
1242
  end
1204
1243
  else
1205
1244
  # puts "debug1 dst not ready, save data to src.rbuff"
1206
- src_info[ :rbuff ] << data
1207
-
1208
- if src_info[ :rbuff ].bytesize >= WBUFF_LIMIT then
1209
- # puts "debug1 direct src.rbuff full"
1210
- set_src_closing( src )
1211
- end
1245
+ add_src_rbuff( src, data )
1212
1246
  end
1213
1247
  end
1214
1248
  end
@@ -1233,13 +1267,6 @@ module Girl
1233
1267
  end
1234
1268
 
1235
1269
  dst_info = @dst_infos[ dst ]
1236
-
1237
- # 处理关闭
1238
- if dst_info[ :closing ] then
1239
- close_dst( dst )
1240
- return
1241
- end
1242
-
1243
1270
  src = dst_info[ :src ]
1244
1271
  add_src_wbuff( src, data )
1245
1272
  end
@@ -1274,13 +1301,7 @@ module Girl
1274
1301
  # write tun
1275
1302
  #
1276
1303
  def write_tun( tun )
1277
- # 处理关闭
1278
- if @tun_info[ :closing ] then
1279
- close_tun( tun )
1280
- return
1281
- end
1282
-
1283
- now = Time.new
1304
+ return if tun.closed?
1284
1305
 
1285
1306
  # 发ctlmsg
1286
1307
  while @tun_info[ :ctlmsgs ].any? do
@@ -1292,8 +1313,8 @@ module Girl
1292
1313
  puts "p#{ Process.pid } #{ Time.new } wait send ctlmsg, left #{ @tun_info[ :ctlmsgs ].size }"
1293
1314
  return
1294
1315
  rescue Errno::EHOSTUNREACH, Errno::ENETUNREACH, Errno::ENETDOWN => e
1295
- puts "p#{ Process.pid } #{ Time.new } sendmsg #{ e.class }, close tun"
1296
- close_tun( tun )
1316
+ puts "p#{ Process.pid } #{ Time.new } sendmsg #{ e.class }, set tun closing"
1317
+ set_tun_closing
1297
1318
  return
1298
1319
  end
1299
1320
 
@@ -1310,14 +1331,6 @@ module Girl
1310
1331
  return if src.closed?
1311
1332
  src_info = @src_infos[ src ]
1312
1333
  dst = src_info[ :dst ]
1313
-
1314
- # 处理关闭
1315
- if src_info[ :closing ] then
1316
- close_src( src )
1317
- return
1318
- end
1319
-
1320
- # 处理wbuff
1321
1334
  data = src_info[ :wbuff ]
1322
1335
 
1323
1336
  # 写前为空,处理关闭写
@@ -1363,13 +1376,6 @@ module Girl
1363
1376
  return if dst.closed?
1364
1377
  dst_info = @dst_infos[ dst ]
1365
1378
  src = dst_info[ :src ]
1366
-
1367
- # 处理关闭
1368
- if dst_info[ :closing ] then
1369
- close_dst( dst )
1370
- return
1371
- end
1372
-
1373
1379
  data = dst_info[ :wbuff ]
1374
1380
 
1375
1381
  # 写前为空,处理关闭写
@@ -1412,13 +1418,6 @@ module Girl
1412
1418
  return if stream.closed?
1413
1419
  stream_info = @stream_infos[ stream ]
1414
1420
  src = stream_info[ :src ]
1415
-
1416
- # 处理关闭
1417
- if stream_info[ :closing ] then
1418
- close_stream( stream )
1419
- return
1420
- end
1421
-
1422
1421
  data = stream_info[ :wbuff ]
1423
1422
 
1424
1423
  # 写前为空,处理关闭写