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.

checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ba24b62a261882eae66a3aeacb3966b96a65019a290ee80414ddb1e59c451899
4
- data.tar.gz: 0b75d6df0abe02ac88a48debd383621e68f8679d41b856f09d88e08a81a37b82
3
+ metadata.gz: 826fa8949af020a9cf2e9158d0c95630f9ad0495370c22fd058542926e27dd72
4
+ data.tar.gz: b880ce49e5c125fb819626d0c124d7cae52b9da59627cfa7f87b6098fbd075c9
5
5
  SHA512:
6
- metadata.gz: 8e6bf4dedbf159c5bfe0a120c9bb16597432b70ae4796a1fa4a27c2f8564c0ddd0456eacf720a05aa14356369948f79d49f33ee4d2b23668ff4d3df1c053591c
7
- data.tar.gz: e3b579ab02a36d0807bc2f54a78f259a3a6510552ba16c2e44906baaf21c11433a8692818cd07bcd25bc684bc45ac0766f034babcb9987220830c2d9c6a897fe
6
+ metadata.gz: a06cb288a4f42d3ad1f73c9e6effe6e3c85ba5485f24940b9a6f36fec254be990b313922273ae28308ef9ef7f9e339797a2b79ed4a4ff8607717da4911edd47e
7
+ data.tar.gz: f8c6f735a2553134112885bbb2462d2d1eed44ac7cd1bc4873881644393e7a861cd7345a006b898692ea8036f0d87a81901343658e674b4be23ebe49369facd2
data/girl.gemspec CHANGED
@@ -19,6 +19,7 @@ girl.gemspec
19
19
  lib/girl.rb
20
20
  lib/girl/concurrent_hash.rb
21
21
  lib/girl/custom_dns_query.rb
22
+ lib/girl/custom.rb
22
23
  lib/girl/head.rb
23
24
  lib/girl/proxy_custom.rb
24
25
  lib/girl/proxy_worker.rb
@@ -19,4 +19,8 @@ class ConcurrentHash < Hash
19
19
  def each( *args )
20
20
  @mutex.synchronize { super }
21
21
  end
22
+
23
+ def clear( *args )
24
+ @mutex.synchronize { super }
25
+ end
22
26
  end
@@ -0,0 +1,11 @@
1
+ module Girl
2
+ module Custom
3
+ def encode( data )
4
+ data.reverse
5
+ end
6
+
7
+ def decode( data )
8
+ data.reverse
9
+ end
10
+ end
11
+ end
data/lib/girl/head.rb CHANGED
@@ -1,14 +1,17 @@
1
1
  module Girl
2
- READ_SIZE = 1024 * 1024 # 一次读多少
2
+ READ_SIZE = 1024 * 1024 # atun, btun一次读多少
3
3
  WBUFF_LIMIT = 50 * 1024 * 1024 # 写前上限,超过上限暂停读
4
4
  RESUME_BELOW = WBUFF_LIMIT / 2 # 降到多少以下恢复读
5
5
  EXPIRE_NEW = 5 # 多久没有建立通道,过期
6
6
  EXPIRE_AFTER = 300 # 多久没有新流量,过期
7
+ EXPIRE_CTL = 86400 # 多久没有ctlmsg来,过期
7
8
  RESET_TRAFF_DAY = 1 # 流量计数重置日,0为不重置
8
9
  CHECK_TRAFF_INTERVAL = 86400 # 检查今天是否是流量计数重置日间隔
9
10
  CHECK_EXPIRE_INTERVAL = 5 # 检查过期间隔
10
11
  CHECK_RESUME_INTERVAL = 1 # 检查恢复读间隔
11
12
  RESOLV_CACHE_EXPIRE = 300 # dns查询结果缓存多久过期
13
+ RESEND_LIMIT = 5 # ctlmsg重传次数
14
+ RESEND_INTERVAL = 1 # ctlmsg重传间隔
12
15
  HELLO = 1
13
16
  TUND_PORT = 2
14
17
  A_NEW_SOURCE = 3
@@ -31,6 +34,8 @@ module Girl
31
34
  RESOLV = 20
32
35
  RESOLVED = 21
33
36
  HEARTBEAT = 22
37
+ UNKNOWN_CTL_ADDR = 23
38
+ CTL_FIN = 24
34
39
  TRAFF_INFOS = 101
35
40
  SEPARATE = "\r\n\r\n"
36
41
  HTTP_OK = "HTTP/1.1 200 OK\r\n\r\n"
@@ -49,8 +54,13 @@ EOF
49
54
  RESUME_BELOW
50
55
  EXPIRE_NEW
51
56
  EXPIRE_AFTER
57
+ EXPIRE_CTL
58
+ RESET_TRAFF_DAY
59
+ CHECK_TRAFF_INTERVAL
52
60
  CHECK_EXPIRE_INTERVAL
53
61
  CHECK_RESUME_INTERVAL
54
62
  RESOLV_CACHE_EXPIRE
63
+ RESEND_LIMIT
64
+ RESEND_INTERVAL
55
65
  ]
56
66
  end
data/lib/girl/proxy.rb CHANGED
@@ -6,7 +6,6 @@ require 'girl/proxy_worker'
6
6
  require 'girl/version'
7
7
  require 'ipaddr'
8
8
  require 'json'
9
- require 'openssl'
10
9
  require 'socket'
11
10
 
12
11
  ##
@@ -14,29 +13,34 @@ require 'socket'
14
13
  #
15
14
  #
16
15
  =begin
17
- C: 1 hello -> hello
18
- 2 tund port -> n: tund port
19
- 3 a new source -> Q>: src id -> encoded destination address
20
- 4 paired -> Q>: src id -> n: dst id
21
- 5 dest status NOT USE
22
- 6 source status NOT USE
23
- 7 miss NOT USE
24
- 8 fin1 NOT USE
25
- 9 confirm fin1 NOT USE
26
- 10 fin2 NOT USE
27
- 11 confirm fin2 NOT USE
28
- 12 tund fin
29
- 13 tun fin
30
- 14 tun ip changed NOT USE
31
- 15 single miss NOT USE
32
- 16 range miss NOT USE
33
- 17 continue NOT USE
34
- 18 is resend ready NOT USE
35
- 19 resend ready NOT USE
36
- 20 resolv -> Q>: src id -> encoded domain
37
- 21 resolved -> Q>: src id -> encoded ip
16
+ C: 1 hello -> hello
17
+ 2 tund port -> n: tund port
18
+ 3 a new source -> Q>: src id -> encoded destination address
19
+ 4 paired -> Q>: src id -> n: dst id
20
+ 5 dest status NOT USE
21
+ 6 source status NOT USE
22
+ 7 miss NOT USE
23
+ 8 fin1 NOT USE
24
+ 9 confirm fin1 NOT USE
25
+ 10 fin2 NOT USE
26
+ 11 confirm fin2 NOT USE
27
+ 12 tund fin NOT USE
28
+ 13 tun fin NOT USE
29
+ 14 tun ip changed NOT USE
30
+ 15 single miss NOT USE
31
+ 16 range miss NOT USE
32
+ 17 continue NOT USE
33
+ 18 is resend ready NOT USE
34
+ 19 resend ready NOT USE
35
+ 20 resolv -> Q>: src id -> encoded domain
36
+ 21 resolved -> Q>: src id -> encoded ip
37
+ 22 heartbeat NOT USE
38
+ 23 unknown ctl addr
39
+ 24 ctl fin
40
+ 25 source eof -> Q>: dst id
41
+ 26 dest eof -> Q>: src id
38
42
  101 traff infos
39
- 101 traff infos -> [ C: im len -> im -> Q>: traff in -> Q>: traff out ]
43
+ 101 traff infos -> [ C: im len -> im -> Q>: traff in -> Q>: traff out ]
40
44
  =end
41
45
 
42
46
  module Girl
@@ -56,7 +60,6 @@ module Girl
56
60
  direct_path = conf[ :direct_path ]
57
61
  remote_path = conf[ :remote_path ]
58
62
  im = conf[ :im ]
59
- use_remote_resolv = conf[ :use_remote_resolv ]
60
63
  worker_count = conf[ :worker_count ]
61
64
 
62
65
  unless redir_port then
@@ -87,10 +90,6 @@ module Girl
87
90
  im = 'girl'
88
91
  end
89
92
 
90
- unless use_remote_resolv then
91
- use_remote_resolv = false
92
- end
93
-
94
93
  nprocessors = Etc.nprocessors
95
94
 
96
95
  if worker_count.nil? || worker_count <= 0 || worker_count > nprocessors then
@@ -105,7 +104,7 @@ module Girl
105
104
 
106
105
  title = "girl proxy #{ Girl::VERSION }"
107
106
  puts title
108
- puts "redir port #{ redir_port } proxyd host #{ proxyd_host } proxyd port #{ proxyd_port } im #{ im } use remote resolv #{ use_remote_resolv } worker count #{ worker_count }"
107
+ puts "redir port #{ redir_port } proxyd host #{ proxyd_host } proxyd port #{ proxyd_port } im #{ im } worker count #{ worker_count }"
109
108
  puts "#{ direct_path } #{ directs.size } directs"
110
109
  puts "#{ remote_path } #{ remotes.size } remotes"
111
110
 
@@ -116,7 +115,7 @@ module Girl
116
115
  worker_count.times do | i |
117
116
  workers << fork do
118
117
  $0 = 'girl proxy worker'
119
- worker = Girl::ProxyWorker.new( redir_port, proxyd_host, proxyd_port, directs, remotes, im, use_remote_resolv )
118
+ worker = Girl::ProxyWorker.new( redir_port, proxyd_host, proxyd_port, directs, remotes, im )
120
119
 
121
120
  Signal.trap( :TERM ) do
122
121
  puts "w#{ i } exit"
@@ -140,7 +139,7 @@ module Girl
140
139
 
141
140
  Process.waitall
142
141
  else
143
- Girl::ProxyWorker.new( redir_port, proxyd_host, proxyd_port, directs, remotes, im, use_remote_resolv ).looping
142
+ Girl::ProxyWorker.new( redir_port, proxyd_host, proxyd_port, directs, remotes, im ).looping
144
143
  end
145
144
  end
146
145
 
@@ -1,13 +1,16 @@
1
- module Girl
2
- class ProxyCustom
3
-
4
- def initialize( im )
5
- @im = im
6
- end
7
-
8
- def hello
9
- @im
10
- end
11
-
12
- end
13
- end
1
+ require 'girl/custom'
2
+
3
+ module Girl
4
+ class ProxyCustom
5
+ include Custom
6
+
7
+ def initialize( im )
8
+ @im = im
9
+ end
10
+
11
+ def hello
12
+ @im
13
+ end
14
+
15
+ end
16
+ end
@@ -4,28 +4,27 @@ module Girl
4
4
  ##
5
5
  # initialize
6
6
  #
7
- def initialize( redir_port, proxyd_host, proxyd_port, directs, remotes, im, use_remote_resolv )
7
+ def initialize( redir_port, proxyd_host, proxyd_port, directs, remotes, im )
8
8
  @proxyd_host = proxyd_host
9
9
  @proxyd_addr = Socket.sockaddr_in( proxyd_port, proxyd_host )
10
10
  @directs = directs
11
11
  @remotes = remotes
12
12
  @custom = Girl::ProxyCustom.new( im )
13
- @use_remote_resolv = use_remote_resolv
14
13
  @reads = []
15
14
  @writes = []
16
15
  @closing_srcs = []
17
16
  @paused_srcs = []
18
17
  @paused_dsts = []
19
- @paused_tuns = []
18
+ @paused_btuns = []
20
19
  @resume_srcs = []
21
20
  @resume_dsts = []
22
- @resume_tuns = []
21
+ @resume_btuns = []
23
22
  @pending_srcs = [] # 还没配到tund,暂存的src
24
- @roles = ConcurrentHash.new # sock => :dotr / :redir / :proxy / :src / :dst / :tun / :pre_proxy / :pre_tun
23
+ @roles = ConcurrentHash.new # sock => :dotr / :redir / :ctl / :src / :dst / :atun / :btun
25
24
  @src_infos = ConcurrentHash.new # src => {}
26
25
  @dst_infos = ConcurrentHash.new # dst => {}
27
- @tun_infos = ConcurrentHash.new # tun => {}
28
- @pre_tun_infos = ConcurrentHash.new # pre_tun => {}
26
+ @atun_infos = ConcurrentHash.new # atun => {}
27
+ @btun_infos = ConcurrentHash.new # btun => {}
29
28
  @resolv_caches = ConcurrentHash.new # domain => [ ip, created_at ]
30
29
  @is_direct_caches = ConcurrentHash.new # ip => true / false
31
30
  @srcs = ConcurrentHash.new # src_id => src
@@ -46,6 +45,7 @@ module Girl
46
45
  loop_check_resume
47
46
 
48
47
  loop do
48
+ # puts "debug select"
49
49
  rs, ws = IO.select( @reads, @writes )
50
50
 
51
51
  rs.each do | sock |
@@ -54,31 +54,27 @@ module Girl
54
54
  read_dotr( sock )
55
55
  when :redir then
56
56
  read_redir( sock )
57
- when :proxy then
58
- read_proxy( sock )
57
+ when :ctl then
58
+ read_ctl( sock )
59
59
  when :src then
60
60
  read_src( sock )
61
61
  when :dst then
62
62
  read_dst( sock )
63
- when :tun then
64
- read_tun( sock )
63
+ when :btun then
64
+ read_btun( sock )
65
65
  end
66
66
  end
67
67
 
68
68
  ws.each do | sock |
69
69
  case @roles[ sock ]
70
- when :proxy then
71
- write_proxy( sock )
72
70
  when :src then
73
71
  write_src( sock )
74
72
  when :dst then
75
73
  write_dst( sock )
76
- when :tun then
77
- write_tun( sock )
78
- when :pre_proxy then
79
- write_pre_proxy( sock )
80
- when :pre_tun then
81
- write_pre_tun( sock )
74
+ when :atun then
75
+ write_atun( sock )
76
+ when :btun then
77
+ write_btun( sock )
82
78
  end
83
79
  end
84
80
  end
@@ -91,13 +87,8 @@ module Girl
91
87
  # quit!
92
88
  #
93
89
  def quit!
94
- if @proxy && !@proxy.closed? then
95
- # puts "debug1 send tun fin"
96
- data = [ TUN_FIN ].pack( 'C' )
97
- @proxy.write( data )
98
- end
99
-
100
- # puts "debug1 exit"
90
+ # puts "debug exit"
91
+ send_ctlmsg( [ CTL_FIN ].pack( 'C' ) )
101
92
  exit
102
93
  end
103
94
 
@@ -111,8 +102,24 @@ module Girl
111
102
  destination_domain = src_info[ :destination_domain ]
112
103
  destination_port = src_info[ :destination_port ]
113
104
  domain_port = [ destination_domain, destination_port ].join( ':' )
114
- data = "#{ [ A_NEW_SOURCE, src_info[ :id ] ].pack( 'CQ>' ) }#{ domain_port }"
115
- add_ctlmsg( data )
105
+ # puts "debug add a new source #{ src_info[ :id ] } #{ domain_port }"
106
+ key = [ A_NEW_SOURCE, src_info[ :id ] ].pack( 'CQ>' )
107
+ add_ctlmsg( key, domain_port )
108
+ end
109
+
110
+ ##
111
+ # add atun wbuff
112
+ #
113
+ def add_atun_wbuff( atun, data )
114
+ return if atun.closed?
115
+ atun_info = @atun_infos[ atun ]
116
+ atun_info[ :wbuff ] << data
117
+ add_write( atun )
118
+
119
+ if atun_info[ :wbuff ].bytesize >= WBUFF_LIMIT then
120
+ puts "p#{ Process.pid } #{ Time.new } pause tunnel src #{ atun_info[ :domain ] }"
121
+ add_paused_src( atun_info[ :src ] )
122
+ end
116
123
  end
117
124
 
118
125
  ##
@@ -127,16 +134,18 @@ module Girl
127
134
  ##
128
135
  # add ctlmsg
129
136
  #
130
- def add_ctlmsg( data )
131
- return if @proxy.nil? || @proxy.closed?
132
- @proxy_info[ :ctlmsgs ] << data
133
- add_write( @proxy )
137
+ def add_ctlmsg( key, data )
138
+ ctlmsg = "#{ key }#{ data }"
139
+ send_ctlmsg( ctlmsg )
140
+ @ctl_info[ :resends ][ key ] = 0
141
+ loop_resend_ctlmsg( key, ctlmsg )
134
142
  end
135
143
 
136
144
  ##
137
145
  # add dst wbuff
138
146
  #
139
147
  def add_dst_wbuff( dst, data )
148
+ return if dst.closed?
140
149
  dst_info = @dst_infos[ dst ]
141
150
  dst_info[ :wbuff ] << data
142
151
  add_write( dst )
@@ -147,6 +156,15 @@ module Girl
147
156
  end
148
157
  end
149
158
 
159
+ ##
160
+ # add paused btun
161
+ #
162
+ def add_paused_btun( btun )
163
+ return if btun.closed? || @paused_btuns.include?( btun )
164
+ @reads.delete( btun )
165
+ @paused_btuns << btun
166
+ end
167
+
150
168
  ##
151
169
  # add paused dst
152
170
  #
@@ -165,15 +183,6 @@ module Girl
165
183
  @paused_srcs << src
166
184
  end
167
185
 
168
- ##
169
- # add paused tun
170
- #
171
- def add_paused_tun( tun )
172
- return if tun.closed? || @paused_tuns.include?( tun )
173
- @reads.delete( tun )
174
- @paused_tuns << tun
175
- end
176
-
177
186
  ##
178
187
  # add read
179
188
  #
@@ -188,6 +197,15 @@ module Girl
188
197
  next_tick
189
198
  end
190
199
 
200
+ ##
201
+ # add resume btun
202
+ #
203
+ def add_resume_btun( btun )
204
+ return if @resume_btuns.include?( btun )
205
+ @resume_btuns << btun
206
+ next_tick
207
+ end
208
+
191
209
  ##
192
210
  # add resume dst
193
211
  #
@@ -206,15 +224,6 @@ module Girl
206
224
  next_tick
207
225
  end
208
226
 
209
- ##
210
- # add resume tun
211
- #
212
- def add_resume_tun( tun )
213
- return if @resume_tuns.include?( tun )
214
- @resume_tuns << tun
215
- next_tick
216
- end
217
-
218
227
  ##
219
228
  # add socks5 conn reply
220
229
  #
@@ -226,7 +235,7 @@ module Girl
226
235
  # +----+-----+-------+------+----------+----------+
227
236
  redir_ip, redir_port = @redir_local_address.ip_unpack
228
237
  data = [ [ 5, 0, 0, 1 ].pack( 'C4' ), IPAddr.new( redir_ip ).hton, [ redir_port ].pack( 'n' ) ].join
229
- # puts "debug1 add src.wbuff socks5 conn reply #{ data.inspect }"
238
+ # puts "debug add src.wbuff socks5 conn reply #{ data.inspect }"
230
239
  add_src_wbuff( src, data )
231
240
  end
232
241
 
@@ -238,7 +247,7 @@ module Girl
238
247
  src_info[ :rbuff ] << data
239
248
 
240
249
  if src_info[ :rbuff ].bytesize >= WBUFF_LIMIT then
241
- # puts "debug1 src.rbuff full"
250
+ # puts "debug src.rbuff full"
242
251
  add_closing_src( src )
243
252
  end
244
253
  end
@@ -260,30 +269,16 @@ module Girl
260
269
  puts "p#{ Process.pid } #{ Time.new } pause dst #{ src_info[ :destination_domain ] }"
261
270
  add_paused_dst( dst )
262
271
  else
263
- tun = src_info[ :tun ]
272
+ btun = src_info[ :btun ]
264
273
 
265
- if tun then
266
- puts "p#{ Process.pid } #{ Time.new } pause tun #{ src_info[ :destination_domain ] }"
267
- add_paused_tun( tun )
274
+ if btun then
275
+ puts "p#{ Process.pid } #{ Time.new } pause btun #{ src_info[ :destination_domain ] }"
276
+ add_paused_btun( btun )
268
277
  end
269
278
  end
270
279
  end
271
280
  end
272
281
 
273
- ##
274
- # add tun wbuff
275
- #
276
- def add_tun_wbuff( tun, data )
277
- tun_info = @tun_infos[ tun ]
278
- tun_info[ :wbuff ] << data
279
- add_write( tun )
280
-
281
- if tun_info[ :wbuff ].bytesize >= WBUFF_LIMIT then
282
- puts "p#{ Process.pid } #{ Time.new } pause tunnel src #{ tun_info[ :domain ] }"
283
- add_paused_src( tun_info[ :src ] )
284
- end
285
- end
286
-
287
282
  ##
288
283
  # add write
289
284
  #
@@ -294,32 +289,33 @@ module Girl
294
289
  end
295
290
 
296
291
  ##
297
- # close pre proxy
292
+ # close atun
298
293
  #
299
- def close_pre_proxy( pre_proxy )
300
- return if pre_proxy.closed?
301
- # puts "debug1 close pre proxy"
302
- close_sock( pre_proxy )
294
+ def close_atun( atun )
295
+ return if atun.closed?
296
+ # puts "debug close atun"
297
+ close_sock( atun )
298
+ @atun_infos.delete( atun )
303
299
  end
304
300
 
305
301
  ##
306
- # close pre tun
302
+ # close btun
307
303
  #
308
- def close_pre_tun( pre_tun )
309
- return if pre_tun.closed?
310
- # puts "debug1 close pre tun"
311
- close_sock( pre_tun )
312
- @pre_tun_infos.delete( pre_tun )
304
+ def close_btun( btun )
305
+ return if btun.closed?
306
+ # puts "debug close btun"
307
+ close_sock( btun )
308
+ @btun_infos.delete( btun )
309
+ @paused_btuns.delete( btun )
310
+ @resume_btuns.delete( btun )
313
311
  end
314
312
 
315
313
  ##
316
- # close proxy
314
+ # close ctl
317
315
  #
318
- def close_proxy( proxy )
319
- return if proxy.closed?
320
- # puts "debug1 close proxy"
321
- close_sock( proxy )
322
- close_pre_proxy( @pre_proxy )
316
+ def close_ctl( ctl )
317
+ close_sock( ctl )
318
+ @ctl_info[ :resends ].clear
323
319
  end
324
320
 
325
321
  ##
@@ -327,20 +323,15 @@ module Girl
327
323
  #
328
324
  def close_read_dst( dst )
329
325
  return if dst.closed?
330
- # puts "debug1 close read dst"
326
+ # puts "debug close read dst"
331
327
  dst.close_read
332
328
  @reads.delete( dst )
333
329
 
334
330
  if dst.closed? then
335
- # puts "debug1 delete dst info"
336
331
  @writes.delete( dst )
337
332
  @roles.delete( dst )
338
- dst_info = @dst_infos.delete( dst )
339
- else
340
- dst_info = @dst_infos[ dst ]
333
+ del_dst_info( dst )
341
334
  end
342
-
343
- dst_info
344
335
  end
345
336
 
346
337
  ##
@@ -348,39 +339,15 @@ module Girl
348
339
  #
349
340
  def close_read_src( src )
350
341
  return if src.closed?
351
- # puts "debug1 close read src"
342
+ # puts "debug close read src"
352
343
  src.close_read
353
344
  @reads.delete( src )
354
345
 
355
346
  if src.closed? then
356
- # puts "debug1 delete src info"
357
347
  @writes.delete( src )
358
348
  @roles.delete( src )
359
- src_info = del_src_info( src )
360
- else
361
- src_info = @src_infos[ src ]
349
+ del_src_info( src )
362
350
  end
363
-
364
- src_info
365
- end
366
-
367
- ##
368
- # close read tun
369
- #
370
- def close_read_tun( tun )
371
- return if tun.closed?
372
- # puts "debug1 close read tun"
373
- tun_info = @tun_infos[ tun ]
374
- tun_info[ :close_read ] = true
375
-
376
- if tun_info[ :close_write ] then
377
- # puts "debug1 close tun"
378
- close_tun( tun )
379
- else
380
- @reads.delete( tun )
381
- end
382
-
383
- tun_info
384
351
  end
385
352
 
386
353
  ##
@@ -398,59 +365,42 @@ module Girl
398
365
  #
399
366
  def close_src( src )
400
367
  return if src.closed?
401
- # puts "debug1 close src"
368
+ # puts "debug close src"
402
369
  close_sock( src )
403
370
  src_info = del_src_info( src )
404
371
  dst = src_info[ :dst ]
405
372
 
406
373
  if dst then
407
374
  close_sock( dst )
408
- @dst_infos.delete( dst )
375
+ del_dst_info( dst )
409
376
  else
410
- tun = src_info[ :tun ]
377
+ atun = src_info[ :atun ]
378
+ btun = src_info[ :btun ]
411
379
 
412
- if tun then
413
- close_tun( tun )
414
- else
415
- pre_tun = src_info[ :pre_tun ]
380
+ if atun then
381
+ close_atun( atun )
382
+ end
416
383
 
417
- if pre_tun then
418
- close_pre_tun( pre_tun )
419
- end
384
+ if btun then
385
+ close_btun( btun )
420
386
  end
421
387
  end
422
388
  end
423
389
 
424
- ##
425
- # close tun
426
- #
427
- def close_tun( tun )
428
- return if tun.closed?
429
- # puts "debug1 close tun"
430
- close_sock( tun )
431
- tun_info = @tun_infos.delete( tun )
432
- close_pre_tun( tun_info[ :pre_tun ] )
433
- end
434
-
435
390
  ##
436
391
  # close write dst
437
392
  #
438
393
  def close_write_dst( dst )
439
394
  return if dst.closed?
440
- # puts "debug1 close write dst"
395
+ # puts "debug close write dst"
441
396
  dst.close_write
442
397
  @writes.delete( dst )
443
398
 
444
399
  if dst.closed? then
445
- # puts "debug1 delete dst info"
446
400
  @reads.delete( dst )
447
401
  @roles.delete( dst )
448
- dst_info = @dst_infos.delete( dst )
449
- else
450
- dst_info = @dst_infos[ dst ]
402
+ del_dst_info( dst )
451
403
  end
452
-
453
- dst_info
454
404
  end
455
405
 
456
406
  ##
@@ -458,39 +408,15 @@ module Girl
458
408
  #
459
409
  def close_write_src( src )
460
410
  return if src.closed?
461
- # puts "debug1 close write src"
411
+ # puts "debug close write src"
462
412
  src.close_write
463
413
  @writes.delete( src )
464
414
 
465
415
  if src.closed? then
466
- # puts "debug1 delete src info"
467
416
  @reads.delete( src )
468
417
  @roles.delete( src )
469
- src_info = del_src_info( src )
470
- else
471
- src_info = @src_infos[ src ]
472
- end
473
-
474
- src_info
475
- end
476
-
477
- ##
478
- # close write tun
479
- #
480
- def close_write_tun( tun )
481
- return if tun.closed?
482
- # puts "debug1 close write tun"
483
- tun_info = @tun_infos[ tun ]
484
- tun_info[ :close_write ] = true
485
-
486
- if tun_info[ :close_read ] then
487
- # puts "debug1 close tun"
488
- close_tun( tun )
489
- else
490
- @writes.delete( tun )
418
+ del_src_info( src )
491
419
  end
492
-
493
- tun_info
494
420
  end
495
421
 
496
422
  ##
@@ -525,23 +451,36 @@ module Girl
525
451
  end
526
452
 
527
453
  if is_direct then
528
- # puts "debug1 #{ ip_info.inspect } hit directs"
454
+ # puts "debug #{ ip_info.inspect } hit directs"
529
455
  new_a_dst( src, ip_info )
530
456
  else
531
457
  # 走远端
532
- # puts "debug1 #{ ip_info.inspect } go tunnel"
458
+ # puts "debug #{ ip_info.inspect } go tunnel"
533
459
  set_proxy_type_tunnel( src )
534
460
  end
535
461
  end
536
462
 
463
+ ##
464
+ # del dst info
465
+ #
466
+ def del_dst_info( dst )
467
+ # puts "debug delete dst info"
468
+ dst_info = @dst_infos.delete( dst )
469
+ @paused_dsts.delete( dst )
470
+ @resume_dsts.delete( dst )
471
+ dst_info
472
+ end
473
+
537
474
  ##
538
475
  # del src info
539
476
  #
540
477
  def del_src_info( src )
478
+ # puts "debug delete src info"
541
479
  src_info = @src_infos.delete( src )
542
480
  @srcs.delete( src_info[ :id ] )
543
481
  @pending_srcs.delete( src )
544
-
482
+ @paused_srcs.delete( src )
483
+ @resume_srcs.delete( src )
545
484
  src_info
546
485
  end
547
486
 
@@ -554,37 +493,23 @@ module Girl
554
493
  sleep CHECK_EXPIRE_INTERVAL
555
494
  now = Time.new
556
495
 
557
- if @proxy && !@proxy.closed? then
558
- if @proxy_info[ :last_recv_at ] then
559
- last_recv_at = @proxy_info[ :last_recv_at ]
560
- expire_after = EXPIRE_AFTER
561
- else
562
- last_recv_at = @proxy_info[ :created_at ]
563
- expire_after = EXPIRE_NEW
564
- end
496
+ if @ctl && !@ctl.closed? then
497
+ last_recv_at = @ctl_info[ :last_recv_at ] || @ctl_info[ :created_at ]
565
498
 
566
- if now - last_recv_at >= expire_after then
567
- puts "p#{ Process.pid } #{ Time.new } expire proxy"
568
- @proxy_info[ :closing ] = true
569
- next_tick
570
- else
571
- # puts "debug1 #{ Time.new } send heartbeat"
572
- data = [ HEARTBEAT ].pack( 'C' )
573
- add_ctlmsg( data )
499
+ if now - last_recv_at >= EXPIRE_AFTER then
500
+ puts "p#{ Process.pid } #{ Time.new } expire ctl"
501
+ @ctl_info[ :closing ] = true
502
+ next_tick
574
503
  end
575
- elsif @pre_proxy && !@pre_proxy.closed? && ( now - @pre_proxy_info[ :created_at ] > EXPIRE_NEW ) then
576
- puts "p#{ Process.pid } #{ Time.new } expire pre proxy"
577
- @pre_proxy_info[ :closing ] = true
578
- next_tick
579
504
  end
580
505
 
581
506
  @src_infos.each do | src, src_info |
582
507
  last_recv_at = src_info[ :last_recv_at ] || src_info[ :created_at ]
583
508
  last_sent_at = src_info[ :last_sent_at ] || src_info[ :created_at ]
584
- expire_after = ( src_info[ :dst ] || src_info[ :tun ] ) ? EXPIRE_AFTER : EXPIRE_NEW
509
+ expire_after = ( src_info[ :dst ] || src_info[ :atun ] ) ? EXPIRE_AFTER : EXPIRE_NEW
585
510
 
586
511
  if ( now - last_recv_at >= expire_after ) && ( now - last_sent_at >= expire_after ) then
587
- puts "p#{ Process.pid } #{ Time.new } expire src #{ expire_after } #{ src_info[ :destination_domain ] }"
512
+ puts "p#{ Process.pid } #{ Time.new } expire src #{ expire_after } #{ src_info[ :id ] } #{ src_info[ :destination_domain ] }"
588
513
  add_closing_src( src )
589
514
 
590
515
  unless src_info[ :rbuff ].empty? then
@@ -605,64 +530,77 @@ module Girl
605
530
  sleep CHECK_RESUME_INTERVAL
606
531
 
607
532
  @paused_srcs.each do | src |
608
- if src.closed? then
609
- add_resume_src( src )
533
+ src_info = @src_infos[ src ]
534
+ dst = src_info[ :dst ]
535
+
536
+ if dst then
537
+ dst_info = @dst_infos[ dst ]
538
+
539
+ if dst_info[ :wbuff ].size < RESUME_BELOW then
540
+ puts "p#{ Process.pid } #{ Time.new } resume direct src #{ src_info[ :destination_domain ] }"
541
+ add_resume_src( src )
542
+ end
610
543
  else
611
- src_info = @src_infos[ src ]
612
- dst = src_info[ :dst ]
613
-
614
- if dst then
615
- dst_info = @dst_infos[ dst ]
616
-
617
- if dst_info[ :wbuff ].size < RESUME_BELOW then
618
- puts "p#{ Process.pid } #{ Time.new } resume direct src #{ src_info[ :destination_domain ] }"
619
- add_resume_src( src )
620
- end
621
- else
622
- tun = src_info[ :tun ]
623
- tun_info = @tun_infos[ tun ]
624
-
625
- if tun_info[ :wbuff ].size < RESUME_BELOW then
626
- puts "p#{ Process.pid } #{ Time.new } resume tunnel src #{ src_info[ :destination_domain ] }"
627
- add_resume_src( src )
628
- end
544
+ btun = src_info[ :btun ]
545
+ btun_info = @btun_infos[ btun ]
546
+
547
+ if btun_info[ :wbuff ].size < RESUME_BELOW then
548
+ puts "p#{ Process.pid } #{ Time.new } resume tunnel src #{ src_info[ :destination_domain ] }"
549
+ add_resume_src( src )
629
550
  end
630
551
  end
631
552
  end
632
553
 
633
554
  @paused_dsts.each do | dst |
634
- if dst.closed? then
635
- add_resume_dst( dst )
636
- else
637
- dst_info = @dst_infos[ dst ]
638
- src = dst_info[ :src ]
639
- src_info = @src_infos[ src ]
555
+ dst_info = @dst_infos[ dst ]
556
+ src = dst_info[ :src ]
557
+ src_info = @src_infos[ src ]
640
558
 
641
- if src_info[ :wbuff ].size < RESUME_BELOW then
642
- puts "p#{ Process.pid } #{ Time.new } resume dst #{ dst_info[ :domain ] }"
643
- add_resume_dst( dst )
644
- end
559
+ if src_info[ :wbuff ].size < RESUME_BELOW then
560
+ puts "p#{ Process.pid } #{ Time.new } resume dst #{ dst_info[ :domain ] }"
561
+ add_resume_dst( dst )
645
562
  end
646
563
  end
647
564
 
648
- @paused_tuns.each do | tun |
649
- if tun.closed? then
650
- add_resume_tun( tun )
651
- else
652
- tun_info = @tun_infos[ tun ]
653
- src = tun_info[ :src ]
654
- src_info = @src_infos[ src ]
565
+ @paused_btuns.each do | btun |
566
+ btun_info = @btun_infos[ btun ]
567
+ src = btun_info[ :src ]
568
+ src_info = @src_infos[ src ]
655
569
 
656
- if src_info[ :wbuff ].size < RESUME_BELOW then
657
- puts "p#{ Process.pid } #{ Time.new } resume tun #{ tun_info[ :domain ] }"
658
- add_resume_tun( tun )
659
- end
570
+ if src_info[ :wbuff ].size < RESUME_BELOW then
571
+ puts "p#{ Process.pid } #{ Time.new } resume btun #{ btun_info[ :domain ] }"
572
+ add_resume_btun( btun )
660
573
  end
661
574
  end
662
575
  end
663
576
  end
664
577
  end
665
578
 
579
+ ##
580
+ # loop resend ctlmsg
581
+ #
582
+ def loop_resend_ctlmsg( key, ctlmsg )
583
+ Thread.new do
584
+ loop do
585
+ sleep RESEND_INTERVAL
586
+
587
+ resend = @ctl_info[ :resends ][ key ]
588
+ break unless resend
589
+
590
+ puts "p#{ Process.pid } #{ Time.new } resend #{ ctlmsg.inspect }"
591
+ send_ctlmsg( ctlmsg )
592
+ resend += 1
593
+
594
+ if resend >= RESEND_LIMIT then
595
+ @ctl_info[ :resends ].delete( key )
596
+ break
597
+ end
598
+
599
+ @ctl_info[ :resends ][ key ] = resend
600
+ end
601
+ end
602
+ end
603
+
666
604
  ##
667
605
  # new a dst
668
606
  #
@@ -672,7 +610,6 @@ module Girl
672
610
  domain = src_info[ :destination_domain ]
673
611
  destination_addr = Socket.sockaddr_in( src_info[ :destination_port ], ip_info.ip_address )
674
612
  dst = Socket.new( ip_info.ipv4? ? Socket::AF_INET : Socket::AF_INET6, Socket::SOCK_STREAM, 0 )
675
- dst.setsockopt( Socket::SOL_TCP, Socket::TCP_NODELAY, 1 ) if RUBY_PLATFORM.include?( 'linux' )
676
613
 
677
614
  begin
678
615
  dst.connect_nonblock( destination_addr )
@@ -685,7 +622,7 @@ module Girl
685
622
  return
686
623
  end
687
624
 
688
- # puts "debug1 a new dst #{ dst.local_address.inspect }"
625
+ # puts "debug a new dst #{ dst.local_address.inspect }"
689
626
  dst_info = {
690
627
  src: src, # 对应src
691
628
  domain: domain, # 目的地
@@ -700,10 +637,10 @@ module Girl
700
637
 
701
638
  if src_info[ :proxy_proto ] == :http then
702
639
  if src_info[ :is_connect ] then
703
- # puts "debug1 add src.wbuff http ok"
640
+ # puts "debug add src.wbuff http ok"
704
641
  add_src_wbuff( src, HTTP_OK )
705
642
  elsif src_info[ :rbuff ] then
706
- # puts "debug1 move src.rbuff to dst.wbuff"
643
+ # puts "debug move src.rbuff to dst.wbuff"
707
644
  dst_info[ :wbuff ] << src_info[ :rbuff ]
708
645
  add_write( dst )
709
646
  end
@@ -713,65 +650,31 @@ module Girl
713
650
  end
714
651
 
715
652
  ##
716
- # new a pre proxy
653
+ # new a ctl
717
654
  #
718
- def new_a_pre_proxy
719
- pre_proxy = Socket.new( Socket::AF_INET, Socket::SOCK_STREAM, 0 )
720
- pre_proxy.setsockopt( Socket::SOL_SOCKET, Socket::SO_REUSEADDR, 1 )
655
+ def new_a_ctl
656
+ ctl = Socket.new( Socket::AF_INET, Socket::SOCK_DGRAM, 0 )
721
657
 
722
658
  if RUBY_PLATFORM.include?( 'linux' ) then
723
- pre_proxy.setsockopt( Socket::SOL_SOCKET, Socket::SO_REUSEPORT, 1 )
724
- pre_proxy.setsockopt( Socket::SOL_TCP, Socket::TCP_NODELAY, 1 )
659
+ ctl.setsockopt( Socket::SOL_SOCKET, Socket::SO_REUSEPORT, 1 )
725
660
  end
726
661
 
727
- begin
728
- pre_proxy.connect_nonblock( @proxyd_addr )
729
- rescue IO::WaitWritable
730
- rescue Exception => e
731
- puts "p#{ Process.pid } #{ Time.new } connect proxyd #{ e.class }, close pre proxy"
732
- pre_proxy.close
733
- return
734
- end
662
+ @ctl = ctl
663
+ add_read( ctl, :ctl )
735
664
 
736
- @pre_proxy = pre_proxy
737
- @roles[ pre_proxy ] = :pre_proxy
738
- @pre_proxy_info = {
739
- closing: false,
740
- created_at: Time.new
665
+ @ctl_info = {
666
+ resends: ConcurrentHash.new, # key => count
667
+ atund_addr: nil, # atund地址,src->dst
668
+ btund_addr: nil, # btund地址,dst->src
669
+ closing: false, # 准备关闭
670
+ created_at: Time.new, # 创建时间
671
+ last_recv_at: nil # 最近一次收到数据时间
741
672
  }
742
- add_write( pre_proxy )
743
- end
744
-
745
- ##
746
- # new a pre tun
747
- #
748
- def new_a_pre_tun( src_id, dst_id )
749
- src = @srcs[ src_id ]
750
- return if src.nil? || src.closed?
751
- src_info = @src_infos[ src ]
752
- return if src_info[ :dst_id ]
753
-
754
- pre_tun = Socket.new( Socket::AF_INET, Socket::SOCK_STREAM, 0 )
755
- pre_tun.setsockopt( Socket::SOL_TCP, Socket::TCP_NODELAY, 1 ) if RUBY_PLATFORM.include?( 'linux' )
756
-
757
- begin
758
- pre_tun.connect_nonblock( @proxy_info[ :tund_addr ] )
759
- rescue IO::WaitWritable
760
- rescue Exception => e
761
- puts "p#{ Process.pid } #{ Time.new } connect tund #{ e.class }, close pre tun"
762
- pre_tun.close
763
- return
764
- end
765
673
 
766
- src_info[ :pre_tun ] = pre_tun
767
- src_info[ :dst_id ] = dst_id
768
- @pre_tun_infos[ pre_tun ] = {
769
- src: src,
770
- destination_domain: src_info[ :destination_domain ],
771
- created_at: Time.new
772
- }
773
- @roles[ pre_tun ] = :pre_tun
774
- add_write( pre_tun )
674
+ hello = @custom.hello
675
+ puts "p#{ Process.pid } #{ Time.new } hello i'm #{ hello.inspect }"
676
+ key = [ HELLO ].pack( 'C' )
677
+ add_ctlmsg( key, hello )
775
678
  end
776
679
 
777
680
  ##
@@ -783,7 +686,6 @@ module Girl
783
686
 
784
687
  if RUBY_PLATFORM.include?( 'linux' ) then
785
688
  redir.setsockopt( Socket::SOL_SOCKET, Socket::SO_REUSEPORT, 1 )
786
- redir.setsockopt( Socket::SOL_TCP, Socket::TCP_NODELAY, 1 )
787
689
  end
788
690
 
789
691
  redir.bind( Socket.sockaddr_in( redir_port, '0.0.0.0' ) )
@@ -794,6 +696,84 @@ module Girl
794
696
  @redir_local_address = redir.local_address
795
697
  end
796
698
 
699
+ ##
700
+ # new tuns
701
+ #
702
+ def new_tuns( src_id, dst_id )
703
+ src = @srcs[ src_id ]
704
+ return if src.nil? || src.closed?
705
+ src_info = @src_infos[ src ]
706
+ return if src_info[ :dst_id ]
707
+
708
+ # puts "debug new atun and btun"
709
+ atun = Socket.new( Socket::AF_INET, Socket::SOCK_STREAM, 0 )
710
+
711
+ begin
712
+ atun.connect_nonblock( @ctl_info[ :atund_addr ] )
713
+ rescue IO::WaitWritable
714
+ rescue Exception => e
715
+ puts "p#{ Process.pid } #{ Time.new } connect atund #{ e.class }, close atun"
716
+ atun.close
717
+ return
718
+ end
719
+
720
+ btun = Socket.new( Socket::AF_INET, Socket::SOCK_STREAM, 0 )
721
+
722
+ begin
723
+ btun.connect_nonblock( @ctl_info[ :btund_addr ] )
724
+ rescue IO::WaitWritable
725
+ rescue Exception => e
726
+ puts "p#{ Process.pid } #{ Time.new } connect btund #{ e.class }, close btun"
727
+ btun.close
728
+ return
729
+ end
730
+
731
+ domain = src_info[ :destination_domain ]
732
+ atun_wbuff = [ dst_id ].pack( 'n' )
733
+
734
+ until src_info[ :rbuff ].empty? do
735
+ data = src_info[ :rbuff ][ 0, 65535 ]
736
+ data_size = data.bytesize
737
+ # puts "debug move src.rbuff #{ data_size } to atun.wbuff"
738
+ atun_wbuff << pack_a_chunk( data )
739
+ src_info[ :rbuff ] = src_info[ :rbuff ][ data_size..-1 ]
740
+ end
741
+
742
+ @atun_infos[ atun ] = {
743
+ src: src, # 对应src
744
+ domain: domain, # 目的地
745
+ wbuff: atun_wbuff, # 写前
746
+ closing: false # 准备关闭
747
+ }
748
+
749
+ btun_wbuff = [ dst_id ].pack( 'n' )
750
+
751
+ @btun_infos[ btun ] = {
752
+ src: src, # 对应src
753
+ domain: domain, # 目的地
754
+ wbuff: btun_wbuff, # 写前
755
+ rbuff: '', # 暂存当前块没收全的流量
756
+ wait_bytes: 0 # 还差多少字节收全当前块
757
+ }
758
+
759
+ src_info[ :dst_id ] = dst_id
760
+ src_info[ :atun ] = atun
761
+ src_info[ :btun ] = btun
762
+ add_read( atun, :atun )
763
+ add_read( btun, :btun )
764
+ add_write( atun )
765
+ add_write( btun )
766
+
767
+ if src_info[ :proxy_proto ] == :http then
768
+ if src_info[ :is_connect ] then
769
+ # puts "debug add src.wbuff http ok"
770
+ add_src_wbuff( src, HTTP_OK )
771
+ end
772
+ elsif src_info[ :proxy_proto ] == :socks5 then
773
+ add_socks5_conn_reply( src )
774
+ end
775
+ end
776
+
797
777
  ##
798
778
  # next tick
799
779
  #
@@ -801,6 +781,15 @@ module Girl
801
781
  @dotw.write( '.' )
802
782
  end
803
783
 
784
+ ##
785
+ # pack a chunk
786
+ #
787
+ def pack_a_chunk( data )
788
+ # puts "debug pack a chunk"
789
+ data = @custom.encode( data )
790
+ "#{ [ data.bytesize ].pack( 'n' ) }#{ data }"
791
+ end
792
+
804
793
  ##
805
794
  # resolve domain
806
795
  #
@@ -817,24 +806,18 @@ module Girl
817
806
  ip_info, created_at = resolv_cache
818
807
 
819
808
  if Time.new - created_at < RESOLV_CACHE_EXPIRE then
820
- # puts "debug1 #{ domain } hit resolv cache #{ ip_info.inspect }"
809
+ # puts "debug #{ domain } hit resolv cache #{ ip_info.inspect }"
821
810
  deal_with_destination_ip( src, ip_info )
822
811
  return
823
812
  end
824
813
 
825
- # puts "debug1 expire #{ domain } resolv cache"
814
+ # puts "debug expire #{ domain } resolv cache"
826
815
  @resolv_caches.delete( domain )
827
816
  end
828
817
 
829
818
  src_info = @src_infos[ src ]
830
819
  src_info[ :proxy_type ] = :checking
831
820
 
832
- if @use_remote_resolv then
833
- data = "#{ [ RESOLV, src_info[ :id ] ].pack( 'CQ>' ) }#{ domain }"
834
- add_ctlmsg( data )
835
- return
836
- end
837
-
838
821
  Thread.new do
839
822
  begin
840
823
  ip_info = Addrinfo.ip( domain )
@@ -852,6 +835,33 @@ module Girl
852
835
  end
853
836
  end
854
837
 
838
+ ##
839
+ # send ctlmsg
840
+ #
841
+ def send_ctlmsg( data )
842
+ return if @ctl.nil? || @ctl.closed?
843
+
844
+ begin
845
+ @ctl.sendmsg( data, 0, @proxyd_addr )
846
+ @ctl_info[ :last_sent_at ] = Time.new
847
+ rescue Exception => e
848
+ puts "p#{ Process.pid } #{ Time.new } sendmsg #{ e.class }"
849
+ close_ctl( @ctl )
850
+ end
851
+ end
852
+
853
+ ##
854
+ # set atun closing
855
+ #
856
+ def set_atun_closing( atun )
857
+ return if atun.closed?
858
+ atun_info = @atun_infos[ atun ]
859
+ return if atun_info[ :closing ]
860
+ # puts "debug set atun closing"
861
+ atun_info[ :closing ] = true
862
+ add_write( atun )
863
+ end
864
+
855
865
  ##
856
866
  # set dst closing write
857
867
  #
@@ -859,6 +869,7 @@ module Girl
859
869
  return if dst.closed?
860
870
  dst_info = @dst_infos[ dst ]
861
871
  return if dst_info[ :closing_write ]
872
+ # puts "debug set dst closing write"
862
873
  dst_info[ :closing_write ] = true
863
874
  add_write( dst )
864
875
  end
@@ -872,7 +883,7 @@ module Girl
872
883
  src_info[ :proxy_type ] = :tunnel
873
884
  src_id = src_info[ :id ]
874
885
 
875
- if @proxy && !@proxy.closed? && @proxy_info[ :tund_addr ] then
886
+ if @ctl && !@ctl.closed? && @ctl_info[ :atund_addr ] then
876
887
  add_a_new_source( src )
877
888
  else
878
889
  @pending_srcs << src
@@ -890,17 +901,6 @@ module Girl
890
901
  add_write( src )
891
902
  end
892
903
 
893
- ##
894
- # set tun closing write
895
- #
896
- def set_tun_closing_write( tun )
897
- return if tun.closed?
898
- tun_info = @tun_infos[ tun ]
899
- return if tun_info[ :closing_write ]
900
- tun_info[ :closing_write ] = true
901
- add_write( tun )
902
- end
903
-
904
904
  ##
905
905
  # sub http request
906
906
  #
@@ -914,7 +914,7 @@ module Girl
914
914
  if proto && url && proto[ 0, 4 ] == 'HTTP' && url[ 0, 7 ] == 'http://' then
915
915
  domain_port = url.split( '/' )[ 2 ]
916
916
  data = data.sub( "http://#{ domain_port }", '' )
917
- # puts "debug1 subed #{ data.inspect } #{ domain_port }"
917
+ # puts "debug subed #{ data.inspect } #{ domain_port }"
918
918
  end
919
919
 
920
920
  [ data, domain_port ]
@@ -924,14 +924,11 @@ module Girl
924
924
  # read dotr
925
925
  #
926
926
  def read_dotr( dotr )
927
- dotr.read_nonblock( READ_SIZE )
927
+ dotr.read_nonblock( 65535 )
928
928
 
929
- if @proxy && !@proxy.closed? then
930
- if @proxy_info[ :closing ] then
931
- close_proxy( @proxy )
932
- end
933
- elsif @pre_proxy && !@pre_proxy.closed? && @pre_proxy_info[ :closing ] then
934
- close_pre_proxy( @pre_proxy )
929
+ if @ctl_info && @ctl_info[ :closing ] then
930
+ send_ctlmsg( [ CTL_FIN ].pack( 'C' ) )
931
+ close_ctl( @ctl )
935
932
  end
936
933
 
937
934
  if @closing_srcs.any? then
@@ -957,13 +954,13 @@ module Girl
957
954
  @resume_dsts.clear
958
955
  end
959
956
 
960
- if @resume_tuns.any? then
961
- @resume_tuns.each do | tun |
962
- add_read( tun )
963
- @paused_tuns.delete( tun )
957
+ if @resume_btuns.any? then
958
+ @resume_btuns.each do | btun |
959
+ add_read( btun )
960
+ @paused_btuns.delete( btun )
964
961
  end
965
962
 
966
- @resume_tuns.clear
963
+ @resume_btuns.clear
967
964
  end
968
965
  end
969
966
 
@@ -979,7 +976,7 @@ module Girl
979
976
  end
980
977
 
981
978
  src_id = rand( ( 2 ** 64 ) - 2 ) + 1
982
- # puts "debug1 accept a src #{ addrinfo.ip_unpack.inspect } #{ src_id }"
979
+ # puts "debug accept a src #{ src_id } #{ addrinfo.ip_unpack.inspect }"
983
980
 
984
981
  @srcs[ src_id ] = src
985
982
  @src_infos[ src ] = {
@@ -991,10 +988,11 @@ module Girl
991
988
  is_connect: true, # 代理协议是http的场合,是否是CONNECT
992
989
  rbuff: '', # 读到的流量
993
990
  dst: nil, # :direct的场合,对应的dst
994
- pre_tun: nil, # :tunnel的场合,对应的pre tun
995
- tun: nil, # :tunnel的场合,对应的tun
991
+ ctl: nil, # :tunnel的场合,对应的ctl
992
+ atun: nil, # :tunnel的场合,对应的atun
993
+ btun: nil, # :tunnel的场合,对应的btun
996
994
  dst_id: nil, # 远端dst id
997
- wbuff: '', # 从dst/tun读到的流量
995
+ wbuff: '', # 从dst/btun读到的流量
998
996
  created_at: Time.new, # 创建时间
999
997
  last_recv_at: nil, # 上一次收到新流量(由dst收到,或者由tun收到)的时间
1000
998
  last_sent_at: nil, # 上一次发出流量(由dst发出,或者由tun发出)的时间
@@ -1003,75 +1001,50 @@ module Girl
1003
1001
 
1004
1002
  add_read( src, :src )
1005
1003
 
1006
- # 避免多线程重复建proxy,在accept到src时就建。
1007
- if @pre_proxy.nil? || @pre_proxy.closed? then
1008
- new_a_pre_proxy
1004
+ if @ctl.nil? || @ctl.closed? then
1005
+ new_a_ctl
1009
1006
  end
1010
1007
  end
1011
1008
 
1012
1009
  ##
1013
- # read proxy
1010
+ # read ctl
1014
1011
  #
1015
- def read_proxy( proxy )
1016
- if proxy.closed? then
1017
- puts "p#{ Process.pid } #{ Time.new } read proxy but proxy closed?"
1018
- return
1019
- end
1020
-
1012
+ def read_ctl( ctl )
1021
1013
  begin
1022
- data = proxy.read_nonblock( READ_SIZE )
1023
- rescue IO::WaitReadable
1024
- return
1025
- rescue Errno::EINTR
1026
- puts e.class
1027
- return
1014
+ data, addrinfo, rflags, *controls = ctl.recvmsg
1028
1015
  rescue Exception => e
1029
- # puts "debug1 read proxy #{ e.class }"
1030
- close_proxy( proxy )
1016
+ puts "p#{ Process.pid } #{ Time.new } recvmsg #{ e.class }"
1017
+ close_ctl( ctl )
1031
1018
  return
1032
1019
  end
1033
1020
 
1034
- @proxy_info[ :last_recv_at ] = Time.new
1021
+ ctl_num = data[ 0 ].unpack( 'C' ).first
1035
1022
 
1036
- data.split( SEPARATE ).each do | ctlmsg |
1037
- next unless ctlmsg[ 0 ]
1023
+ case ctl_num
1024
+ when TUND_PORT then
1025
+ return if @ctl_info[ :atund_addr ] || data.size != 5
1026
+ atund_port, btund_port = data[ 1, 4 ].unpack( 'nn' )
1027
+ puts "p#{ Process.pid } #{ Time.new } got tund port #{ atund_port } #{ btund_port }"
1028
+ @ctl_info[ :resends ].delete( [ HELLO ].pack( 'C' ) )
1029
+ @ctl_info[ :atund_addr ] = Socket.sockaddr_in( atund_port, @proxyd_host )
1030
+ @ctl_info[ :btund_addr ] = Socket.sockaddr_in( btund_port, @proxyd_host )
1031
+ @ctl_info[ :last_recv_at ] = Time.new
1038
1032
 
1039
- ctl_num = ctlmsg[ 0 ].unpack( 'C' ).first
1040
-
1041
- case ctl_num
1042
- when TUND_PORT then
1043
- next if @proxy_info[ :tund_addr ] || ( ctlmsg.size != 3 )
1044
- tund_port = ctlmsg[ 1, 2 ].unpack( 'n' ).first
1045
- puts "p#{ Process.pid } #{ Time.new } got tund port #{ tund_port }"
1046
- @proxy_info[ :tund_addr ] = Socket.sockaddr_in( tund_port, @proxyd_host )
1047
-
1048
- if @pending_srcs.any? then
1049
- puts "p#{ Process.pid } #{ Time.new } send pending sources"
1050
- @pending_srcs.each { | src | add_a_new_source( src ) }
1051
- @pending_srcs.clear
1052
- end
1053
- when PAIRED then
1054
- next if ctlmsg.size != 11
1055
- src_id, dst_id = ctlmsg[ 1, 10 ].unpack( 'Q>n' )
1056
- # puts "debug1 got paired #{ src_id } #{ dst_id }"
1057
- new_a_pre_tun( src_id, dst_id )
1058
- when RESOLVED then
1059
- next if ctlmsg.size <= 9
1060
- src_id = ctlmsg[ 1, 8 ].unpack( 'Q>' ).first
1061
- src = @srcs[ src_id ]
1062
- next if src.nil? || src.closed?
1063
- src_info = @src_infos[ src ]
1064
- ip = ctlmsg[ 9..-1 ]
1065
- puts "p#{ Process.pid } #{ Time.new } remote resolved #{ src_info[ :destination_domain ] } #{ ip }"
1066
- ip_info = Addrinfo.ip( ip )
1067
- deal_with_destination_ip( src, ip_info )
1068
- when TUND_FIN then
1069
- puts "p#{ Process.pid } #{ Time.new } got tund fin"
1070
- close_proxy( proxy )
1071
- return
1072
- when HEARTBEAT
1073
- # puts "debug1 #{ Time.new } got heartbeat"
1033
+ if @pending_srcs.any? then
1034
+ puts "p#{ Process.pid } #{ Time.new } send pending sources"
1035
+ @pending_srcs.each { | src | add_a_new_source( src ) }
1036
+ @pending_srcs.clear
1074
1037
  end
1038
+ when PAIRED then
1039
+ return if @ctl_info[ :atund_addr ].nil? || @ctl_info[ :btund_addr ].nil? || data.size != 11
1040
+ src_id, dst_id = data[ 1, 10 ].unpack( 'Q>n' )
1041
+ # puts "debug got paired #{ src_id } #{ dst_id }"
1042
+ @ctl_info[ :resends ].delete( [ A_NEW_SOURCE, src_id ].pack( 'CQ>' ) )
1043
+ @ctl_info[ :last_recv_at ] = Time.new
1044
+ new_tuns( src_id, dst_id )
1045
+ when UNKNOWN_CTL_ADDR then
1046
+ puts "p#{ Process.pid } #{ Time.new } got unknown ctl addr, close ctl"
1047
+ close_ctl( ctl )
1075
1048
  end
1076
1049
  end
1077
1050
 
@@ -1084,33 +1057,38 @@ module Girl
1084
1057
  return
1085
1058
  end
1086
1059
 
1060
+ src_info = @src_infos[ src ]
1061
+
1087
1062
  begin
1088
- data = src.read_nonblock( READ_SIZE )
1089
- rescue IO::WaitReadable, Errno::EINTR
1063
+ data = src.read_nonblock( 65535 )
1064
+ rescue IO::WaitReadable
1090
1065
  print 'r'
1091
1066
  return
1092
1067
  rescue Exception => e
1093
- # puts "debug1 read src #{ e.class }"
1094
- src_info = close_read_src( src )
1068
+ # puts "debug read src #{ e.class }"
1069
+ close_read_src( src )
1095
1070
  dst = src_info[ :dst ]
1096
1071
 
1097
1072
  if dst then
1098
1073
  set_dst_closing_write( dst )
1099
1074
  else
1100
- tun = src_info[ :tun ]
1101
- set_tun_closing_write( tun ) if tun
1075
+ atun = src_info[ :atun ]
1076
+
1077
+ if atun then
1078
+ set_atun_closing( atun )
1079
+ end
1102
1080
  end
1103
1081
 
1104
1082
  return
1105
1083
  end
1106
1084
 
1107
- src_info = @src_infos[ src ]
1085
+ # puts "debug read src #{ data.bytesize }"
1108
1086
  proxy_type = src_info[ :proxy_type ]
1109
1087
 
1110
1088
  case proxy_type
1111
1089
  when :uncheck then
1112
1090
  if data[ 0, 7 ] == 'CONNECT' then
1113
- # puts "debug1 CONNECT"
1091
+ # puts "debug CONNECT"
1114
1092
  domain_port = data.split( "\r\n" )[ 0 ].split( ' ' )[ 1 ]
1115
1093
 
1116
1094
  unless domain_port then
@@ -1119,7 +1097,7 @@ module Girl
1119
1097
  return
1120
1098
  end
1121
1099
  elsif data[ 0 ].unpack( 'C' ).first == 5 then
1122
- # puts "debug1 socks5 #{ data.inspect }"
1100
+ # puts "debug socks5 #{ data.inspect }"
1123
1101
 
1124
1102
  # https://tools.ietf.org/html/rfc1928
1125
1103
  #
@@ -1148,11 +1126,11 @@ module Girl
1148
1126
  src_info[ :proxy_type ] = :negotiation
1149
1127
  return
1150
1128
  else
1151
- # puts "debug1 not CONNECT #{ data.inspect }"
1129
+ # puts "debug not CONNECT #{ data.inspect }"
1152
1130
  host_line = data.split( "\r\n" ).find { | _line | _line[ 0, 6 ] == 'Host: ' }
1153
1131
 
1154
1132
  unless host_line then
1155
- # puts "debug1 not found host line"
1133
+ # puts "debug not found host line"
1156
1134
  add_closing_src( src )
1157
1135
  return
1158
1136
  end
@@ -1160,7 +1138,7 @@ module Girl
1160
1138
  data, domain_port = sub_http_request( data )
1161
1139
 
1162
1140
  unless domain_port then
1163
- # puts "debug1 not HTTP"
1141
+ # puts "debug not HTTP"
1164
1142
  domain_port = host_line.split( ' ' )[ 1 ]
1165
1143
 
1166
1144
  unless domain_port then
@@ -1183,7 +1161,7 @@ module Girl
1183
1161
 
1184
1162
  resolve_domain( src, domain )
1185
1163
  when :checking then
1186
- # puts "debug1 add src rbuff before resolved #{ data.inspect }"
1164
+ # puts "debug add src rbuff before resolved #{ data.inspect }"
1187
1165
  src_info[ :rbuff ] << data
1188
1166
  when :negotiation then
1189
1167
  # +----+-----+-------+------+----------+----------+
@@ -1191,11 +1169,11 @@ module Girl
1191
1169
  # +----+-----+-------+------+----------+----------+
1192
1170
  # | 1 | 1 | X'00' | 1 | Variable | 2 |
1193
1171
  # +----+-----+-------+------+----------+----------+
1194
- # puts "debug1 negotiation #{ data.inspect }"
1172
+ # puts "debug negotiation #{ data.inspect }"
1195
1173
  ver, cmd, rsv, atyp = data[ 0, 4 ].unpack( 'C4' )
1196
1174
 
1197
1175
  if cmd == 1 then
1198
- # puts "debug1 socks5 CONNECT"
1176
+ # puts "debug socks5 CONNECT"
1199
1177
 
1200
1178
  if atyp == 1 then
1201
1179
  destination_host, destination_port = data[ 4, 6 ].unpack( 'Nn' )
@@ -1204,7 +1182,7 @@ module Girl
1204
1182
  destination_ip = destination_addrinfo.ip_address
1205
1183
  src_info[ :destination_domain ] = destination_ip
1206
1184
  src_info[ :destination_port ] = destination_port
1207
- # puts "debug1 IP V4 address #{ destination_addrinfo.ip_unpack.inspect }"
1185
+ # puts "debug IP V4 address #{ destination_addrinfo.ip_unpack.inspect }"
1208
1186
  deal_with_destination_ip( src, destination_addrinfo )
1209
1187
  elsif atyp == 3 then
1210
1188
  domain_len = data[ 4 ].unpack( 'C' ).first
@@ -1214,7 +1192,7 @@ module Girl
1214
1192
  port = data[ ( 5 + domain_len ), 2 ].unpack( 'n' ).first
1215
1193
  src_info[ :destination_domain ] = domain
1216
1194
  src_info[ :destination_port ] = port
1217
- # puts "debug1 DOMAINNAME #{ domain } #{ port }"
1195
+ # puts "debug DOMAINNAME #{ domain } #{ port }"
1218
1196
  resolve_domain( src, domain )
1219
1197
  end
1220
1198
  end
@@ -1222,35 +1200,29 @@ module Girl
1222
1200
  puts "p#{ Process.pid } #{ Time.new } socks5 cmd #{ cmd } not implement"
1223
1201
  end
1224
1202
  when :tunnel then
1225
- tun = src_info[ :tun ]
1203
+ atun = src_info[ :atun ]
1226
1204
 
1227
- if tun then
1228
- unless tun.closed? then
1229
- unless src_info[ :is_connect ] then
1230
- data, _ = sub_http_request( data )
1231
- end
1205
+ if atun && !src_info[ :is_connect ] then
1206
+ data, _ = sub_http_request( data )
1207
+ end
1232
1208
 
1233
- # puts "debug2 add tun.wbuff #{ data.bytesize }"
1234
- add_tun_wbuff( tun, data )
1235
- end
1209
+ if atun then
1210
+ add_atun_wbuff( atun, pack_a_chunk( data ) )
1236
1211
  else
1237
- # puts "debug1 tun not ready, save data to src.rbuff"
1212
+ # puts "debug add src.rbuff #{ data.bytesize }"
1238
1213
  add_src_rbuff( src, data )
1239
1214
  end
1240
1215
  when :direct then
1241
1216
  dst = src_info[ :dst ]
1242
1217
 
1243
1218
  if dst then
1244
- unless dst.closed? then
1245
- unless src_info[ :is_connect ] then
1246
- data, _ = sub_http_request( data )
1247
- end
1248
-
1249
- # puts "debug2 add dst.wbuff #{ data.bytesize }"
1250
- add_dst_wbuff( dst, data )
1219
+ unless src_info[ :is_connect ] then
1220
+ data, _ = sub_http_request( data )
1251
1221
  end
1222
+
1223
+ add_dst_wbuff( dst, data )
1252
1224
  else
1253
- # puts "debug1 dst not ready, save data to src.rbuff"
1225
+ # puts "debug add src.rbuff #{ data.bytesize }"
1254
1226
  add_src_rbuff( src, data )
1255
1227
  end
1256
1228
  end
@@ -1265,82 +1237,88 @@ module Girl
1265
1237
  return
1266
1238
  end
1267
1239
 
1240
+ dst_info = @dst_infos[ dst ]
1241
+ src = dst_info[ :src ]
1242
+
1268
1243
  begin
1269
- data = dst.read_nonblock( READ_SIZE )
1270
- rescue IO::WaitReadable, Errno::EINTR
1244
+ data = dst.read_nonblock( 65535 )
1245
+ rescue IO::WaitReadable
1271
1246
  print 'r'
1272
1247
  return
1273
1248
  rescue Exception => e
1274
- # puts "debug1 read dst #{ e.class }"
1275
- dst_info = close_read_dst( dst )
1276
- src = dst_info[ :src ]
1249
+ # puts "debug read dst #{ e.class }"
1250
+ close_read_dst( dst )
1277
1251
  set_src_closing_write( src )
1278
1252
  return
1279
1253
  end
1280
1254
 
1281
- dst_info = @dst_infos[ dst ]
1282
- src = dst_info[ :src ]
1255
+ # puts "debug read dst #{ data.bytesize }"
1283
1256
  add_src_wbuff( src, data )
1284
1257
  end
1285
1258
 
1286
1259
  ##
1287
- # read tun
1260
+ # read btun
1288
1261
  #
1289
- def read_tun( tun )
1290
- if tun.closed? then
1291
- puts "p#{ Process.pid } #{ Time.new } read tun but tun closed?"
1262
+ def read_btun( btun )
1263
+ if btun.closed? then
1264
+ puts "p#{ Process.pid } #{ Time.new } read btun but btun closed?"
1292
1265
  return
1293
1266
  end
1294
1267
 
1268
+ btun_info = @btun_infos[ btun ]
1269
+ src = btun_info[ :src ]
1270
+
1295
1271
  begin
1296
- data = tun.read_nonblock( READ_SIZE )
1297
- rescue IO::WaitReadable
1298
- return
1299
- rescue Errno::EINTR
1300
- puts e.class
1301
- return
1272
+ data = btun.read_nonblock( READ_SIZE )
1302
1273
  rescue Exception => e
1303
- # puts "debug1 read tun #{ e.class }"
1304
- tun_info = close_read_tun( tun )
1305
- src = tun_info[ :src ]
1306
- set_src_closing_write( src )
1307
- return
1308
- end
1274
+ # puts "debug read btun #{ btun_info[ :im ] } #{ e.class }"
1275
+ close_btun( btun )
1309
1276
 
1310
- tun_info = @tun_infos[ tun ]
1311
- src = tun_info[ :src ]
1312
- # puts "debug2 add src.wbuff #{ data.bytesize }"
1313
- add_src_wbuff( src, data )
1314
- end
1277
+ if src then
1278
+ set_src_closing_write( src )
1279
+ end
1315
1280
 
1316
- ##
1317
- # write proxy
1318
- #
1319
- def write_proxy( proxy )
1320
- if proxy.closed? then
1321
- puts "p#{ Process.pid } #{ Time.new } write proxy but proxy closed?"
1322
1281
  return
1323
1282
  end
1324
1283
 
1325
- if @proxy_info[ :ctlmsgs ].any? then
1326
- data = @proxy_info[ :ctlmsgs ].map{ | ctlmsg | "#{ ctlmsg }#{ SEPARATE }" }.join
1284
+ until data.empty? do
1285
+ rbuff = btun_info[ :rbuff ]
1286
+ wait_bytes = btun_info[ :wait_bytes ]
1327
1287
 
1328
- # 写入
1329
- begin
1330
- written = proxy.write( data )
1331
- rescue IO::WaitWritable, Errno::EINTR
1332
- print 'w'
1333
- return
1334
- rescue Exception => e
1335
- # puts "debug1 write proxy #{ e.class }"
1336
- close_proxy( proxy )
1337
- return
1288
+ if wait_bytes > 0 then
1289
+ len = wait_bytes
1290
+ # puts "debug wait bytes #{ len }"
1291
+ else
1292
+ if data.bytesize <= 2 then
1293
+ # puts "debug unexpect data length #{ data.bytesize }"
1294
+ close_btun( btun )
1295
+ return
1296
+ end
1297
+
1298
+ len = data[ 0, 2 ].unpack( 'n' ).first
1299
+ # puts "debug read len #{ len }"
1300
+ data = data[ 2..-1 ]
1338
1301
  end
1339
1302
 
1340
- @proxy_info[ :ctlmsgs ].clear
1341
- end
1303
+ chunk = data[ 0, len ]
1304
+ chunk_size = chunk.bytesize
1342
1305
 
1343
- @writes.delete( proxy )
1306
+ if chunk_size == len then
1307
+ # 取完整了
1308
+ chunk = @custom.decode( "#{ rbuff }#{ chunk }" )
1309
+ # puts "debug decode and add src.wbuff #{ chunk.bytesize }"
1310
+ add_src_wbuff( src, chunk )
1311
+ btun_info[ :rbuff ].clear
1312
+ btun_info[ :wait_bytes ] = 0
1313
+ else
1314
+ # 暂存
1315
+ # puts "debug add btun.rbuff #{ chunk_size } wait bytes #{ len - chunk_size }"
1316
+ btun_info[ :rbuff ] << chunk
1317
+ btun_info[ :wait_bytes ] = len - chunk_size
1318
+ end
1319
+
1320
+ data = data[ chunk_size..-1 ]
1321
+ end
1344
1322
  end
1345
1323
 
1346
1324
  ##
@@ -1370,24 +1348,27 @@ module Girl
1370
1348
  # 写入
1371
1349
  begin
1372
1350
  written = src.write_nonblock( data )
1373
- rescue IO::WaitWritable, Errno::EINTR
1351
+ rescue IO::WaitWritable
1374
1352
  print 'w'
1375
1353
  return
1376
1354
  rescue Exception => e
1377
- # puts "debug1 write src #{ e.class }"
1355
+ # puts "debug write src #{ e.class }"
1378
1356
  close_write_src( src )
1379
1357
 
1380
1358
  if dst then
1381
1359
  close_read_dst( dst )
1382
1360
  else
1383
- tun = src_info[ :tun ]
1384
- close_read_tun( tun ) if tun
1361
+ btun = src_info[ :btun ]
1362
+
1363
+ if btun then
1364
+ close_btun( btun )
1365
+ end
1385
1366
  end
1386
1367
 
1387
1368
  return
1388
1369
  end
1389
1370
 
1390
- # puts "debug2 written src #{ written }"
1371
+ # puts "debug write src #{ written }"
1391
1372
  data = data[ written..-1 ]
1392
1373
  src_info[ :wbuff ] = data
1393
1374
  end
@@ -1419,11 +1400,11 @@ module Girl
1419
1400
  # 写入
1420
1401
  begin
1421
1402
  written = dst.write_nonblock( data )
1422
- rescue IO::WaitWritable, Errno::EINTR
1403
+ rescue IO::WaitWritable
1423
1404
  print 'w'
1424
1405
  return
1425
1406
  rescue Exception => e
1426
- # puts "debug1 write dst #{ e.class }"
1407
+ # puts "debug write dst #{ e.class }"
1427
1408
  close_write_dst( dst )
1428
1409
  close_read_src( src )
1429
1410
  return
@@ -1439,24 +1420,24 @@ module Girl
1439
1420
  end
1440
1421
 
1441
1422
  ##
1442
- # write tun
1423
+ # write atun
1443
1424
  #
1444
- def write_tun( tun )
1445
- if tun.closed? then
1446
- puts "p#{ Process.pid } #{ Time.new } write tun but tun closed?"
1425
+ def write_atun( atun )
1426
+ if atun.closed? then
1427
+ puts "p#{ Process.pid } #{ Time.new } write atun but atun closed?"
1447
1428
  return
1448
1429
  end
1449
1430
 
1450
- tun_info = @tun_infos[ tun ]
1451
- src = tun_info[ :src ]
1452
- data = tun_info[ :wbuff ]
1431
+ atun_info = @atun_infos[ atun ]
1432
+ src = atun_info[ :src ]
1433
+ data = atun_info[ :wbuff ]
1453
1434
 
1454
1435
  # 写前为空,处理关闭写
1455
1436
  if data.empty? then
1456
- if tun_info[ :closing_write ] then
1457
- close_write_tun( tun )
1437
+ if atun_info[ :closing ] then
1438
+ close_atun( atun )
1458
1439
  else
1459
- @writes.delete( tun )
1440
+ @writes.delete( atun )
1460
1441
  end
1461
1442
 
1462
1443
  return
@@ -1464,23 +1445,20 @@ module Girl
1464
1445
 
1465
1446
  # 写入
1466
1447
  begin
1467
- written = tun.write_nonblock( data )
1468
- rescue IO::WaitReadable
1469
- # OpenSSL::SSL::SSLErrorWaitReadable
1470
- return
1471
- rescue IO::WaitWritable, Errno::EINTR
1448
+ written = atun.write_nonblock( data )
1449
+ rescue IO::WaitWritable
1472
1450
  print 'w'
1473
1451
  return
1474
1452
  rescue Exception => e
1475
- # puts "debug1 write tun #{ e.class }"
1476
- close_write_tun( tun )
1453
+ # puts "debug write atun #{ e.class }"
1454
+ close_atun( atun )
1477
1455
  close_read_src( src )
1478
1456
  return
1479
1457
  end
1480
1458
 
1481
- # puts "debug2 written tun #{ written }"
1459
+ # puts "debug write atun #{ written }"
1482
1460
  data = data[ written..-1 ]
1483
- tun_info[ :wbuff ] = data
1461
+ atun_info[ :wbuff ] = data
1484
1462
 
1485
1463
  unless src.closed? then
1486
1464
  src_info = @src_infos[ src ]
@@ -1489,112 +1467,30 @@ module Girl
1489
1467
  end
1490
1468
 
1491
1469
  ##
1492
- # write pre proxy
1470
+ # write btun
1493
1471
  #
1494
- def write_pre_proxy( pre_proxy )
1495
- if pre_proxy.closed? then
1496
- puts "p#{ Process.pid } #{ Time.new } write pre proxy but pre proxy closed?"
1472
+ def write_btun( btun )
1473
+ if btun.closed? then
1474
+ puts "p#{ Process.pid } #{ Time.new } write btun but btun closed?"
1497
1475
  return
1498
1476
  end
1499
1477
 
1500
- proxy = OpenSSL::SSL::SSLSocket.new pre_proxy
1478
+ btun_info = @btun_infos[ btun ]
1479
+ data = btun_info[ :wbuff ]
1501
1480
 
1481
+ # 写入dst id
1502
1482
  begin
1503
- proxy.connect_nonblock
1504
- rescue IO::WaitReadable
1505
- rescue IO::WaitWritable
1483
+ written = btun.write( data )
1506
1484
  rescue Exception => e
1507
- puts "p#{ Process.pid } #{ Time.new } proxy connect #{ e.class }, close proxy"
1508
- proxy.close
1509
- close_pre_proxy( pre_proxy )
1510
- return
1511
- end
1512
-
1513
- @proxy = proxy
1514
- @proxy_info = {
1515
- ctlmsgs: [], # ctlmsg
1516
- tund_addr: nil, # tund地址
1517
- created_at: Time.new, # 创建时间
1518
- last_recv_at: nil, # 上一次收到流量的时间
1519
- closing: false # 是否准备关闭
1520
- }
1521
- add_read( proxy, :proxy )
1522
- hello = @custom.hello
1523
- puts "p#{ Process.pid } #{ Time.new } tunnel #{ hello.inspect }"
1524
- data = "#{ [ HELLO ].pack( 'C' ) }#{ hello }"
1525
- add_ctlmsg( data )
1526
-
1527
- @roles.delete( pre_proxy )
1528
- @writes.delete( pre_proxy )
1529
- end
1530
-
1531
- ##
1532
- # write pre tun
1533
- #
1534
- def write_pre_tun( pre_tun )
1535
- if pre_tun.closed? then
1536
- puts "p#{ Process.pid } #{ Time.new } write pre tun but pre tun closed?"
1537
- return
1538
- end
1539
-
1540
- pre_tun_info = @pre_tun_infos[ pre_tun ]
1541
- src = pre_tun_info[ :src ]
1542
-
1543
- if src.closed? then
1544
- puts "p#{ Process.pid } #{ Time.new } new a tun but src closed?"
1545
- return
1546
- end
1547
-
1548
- tun = OpenSSL::SSL::SSLSocket.new pre_tun
1549
-
1550
- begin
1551
- tun.connect_nonblock
1552
- rescue IO::WaitReadable
1553
- rescue IO::WaitWritable
1554
- rescue Exception => e
1555
- puts "p#{ Process.pid } #{ Time.new } tun connect #{ e.class }, close tun"
1556
- tun.close
1557
- close_pre_tun( pre_tun )
1485
+ # puts "debug write btun #{ e.class }"
1486
+ src = btun_info[ :src ]
1487
+ close_btun( btun )
1488
+ add_closing_src( src )
1558
1489
  return
1559
1490
  end
1560
1491
 
1561
- src_info = @src_infos[ src ]
1562
- dst_id = src_info[ :dst_id ]
1563
- # puts "debug1 set tun.wbuff #{ dst_id }"
1564
- data = [ dst_id ].pack( 'n' )
1565
-
1566
- unless src_info[ :rbuff ].empty? then
1567
- # puts "debug1 move src.rbuff to tun.wbuff"
1568
- data << src_info[ :rbuff ]
1569
- end
1570
-
1571
- domain = src_info[ :destination_domain ]
1572
- @tun_infos[ tun ] = {
1573
- pre_tun: pre_tun, # 对应pre tun
1574
- src: src, # 对应src
1575
- domain: domain, # 目的地
1576
- wbuff: data, # 写前
1577
- closing_write: false, # 准备关闭写
1578
- close_read: false, # 已经关闭读
1579
- close_write: false # 已经关闭写
1580
- }
1581
-
1582
- src_info[ :tun ] = tun
1583
- add_read( tun, :tun )
1584
- add_write( tun )
1585
-
1586
- if src_info[ :proxy_proto ] == :http then
1587
- if src_info[ :is_connect ] then
1588
- # puts "debug1 add src.wbuff http ok"
1589
- add_src_wbuff( src, HTTP_OK )
1590
- end
1591
- elsif src_info[ :proxy_proto ] == :socks5 then
1592
- add_socks5_conn_reply( src )
1593
- end
1594
-
1595
- @pre_tun_infos.delete( pre_tun )
1596
- @roles.delete( pre_tun )
1597
- @writes.delete( pre_tun )
1492
+ # puts "debug write btun #{ written }"
1493
+ @writes.delete( btun )
1598
1494
  end
1599
1495
 
1600
1496
  end