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