tor_extend 1.0.2 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -65,8 +65,12 @@
65
65
 
66
66
  <li><a href="../Tor/CachedDesc.html">Tor::CachedDesc</a>
67
67
 
68
+ <li><a href="../Tor/Circuit.html">Tor::Circuit</a>
69
+
68
70
  <li><a href="../Tor/Constants.html">Tor::Constants</a>
69
71
 
72
+ <li><a href="../Tor/LongCircuit.html">Tor::LongCircuit</a>
73
+
70
74
  <li><a href="../Tor/Router.html">Tor::Router</a>
71
75
 
72
76
  <li><a href="../Tor/StatsObj.html">Tor::StatsObj</a>
@@ -65,8 +65,12 @@
65
65
 
66
66
  <li><a href="../Tor/CachedDesc.html">Tor::CachedDesc</a>
67
67
 
68
+ <li><a href="../Tor/Circuit.html">Tor::Circuit</a>
69
+
68
70
  <li><a href="../Tor/Constants.html">Tor::Constants</a>
69
71
 
72
+ <li><a href="../Tor/LongCircuit.html">Tor::LongCircuit</a>
73
+
70
74
  <li><a href="../Tor/Router.html">Tor::Router</a>
71
75
 
72
76
  <li><a href="../Tor/StatsObj.html">Tor::StatsObj</a>
@@ -65,8 +65,12 @@
65
65
 
66
66
  <li><a href="../Tor/CachedDesc.html">Tor::CachedDesc</a>
67
67
 
68
+ <li><a href="../Tor/Circuit.html">Tor::Circuit</a>
69
+
68
70
  <li><a href="../Tor/Constants.html">Tor::Constants</a>
69
71
 
72
+ <li><a href="../Tor/LongCircuit.html">Tor::LongCircuit</a>
73
+
70
74
  <li><a href="../Tor/Router.html">Tor::Router</a>
71
75
 
72
76
  <li><a href="../Tor/StatsObj.html">Tor::StatsObj</a>
@@ -65,8 +65,12 @@
65
65
 
66
66
  <li><a href="../Tor/CachedDesc.html">Tor::CachedDesc</a>
67
67
 
68
+ <li><a href="../Tor/Circuit.html">Tor::Circuit</a>
69
+
68
70
  <li><a href="../Tor/Constants.html">Tor::Constants</a>
69
71
 
72
+ <li><a href="../Tor/LongCircuit.html">Tor::LongCircuit</a>
73
+
70
74
  <li><a href="../Tor/Router.html">Tor::Router</a>
71
75
 
72
76
  <li><a href="../Tor/StatsObj.html">Tor::StatsObj</a>
@@ -65,8 +65,12 @@
65
65
 
66
66
  <li><a href="../Tor/CachedDesc.html">Tor::CachedDesc</a>
67
67
 
68
+ <li><a href="../Tor/Circuit.html">Tor::Circuit</a>
69
+
68
70
  <li><a href="../Tor/Constants.html">Tor::Constants</a>
69
71
 
72
+ <li><a href="../Tor/LongCircuit.html">Tor::LongCircuit</a>
73
+
70
74
  <li><a href="../Tor/Router.html">Tor::Router</a>
71
75
 
72
76
  <li><a href="../Tor/StatsObj.html">Tor::StatsObj</a>
@@ -41,9 +41,15 @@
41
41
  </li>
42
42
  <li class="class">
43
43
  <a href="Tor/CachedDesc.html">Tor::CachedDesc</a>
44
+ </li>
45
+ <li class="class">
46
+ <a href="Tor/Circuit.html">Tor::Circuit</a>
44
47
  </li>
45
48
  <li class="module">
46
49
  <a href="Tor/Constants.html">Tor::Constants</a>
50
+ </li>
51
+ <li class="class">
52
+ <a href="Tor/LongCircuit.html">Tor::LongCircuit</a>
47
53
  </li>
48
54
  <li class="class">
49
55
  <a href="Tor/Router.html">Tor::Router</a>
@@ -62,16 +68,46 @@
62
68
 
63
69
  <li class="method"><a href="Tor/CachedDesc.html#method-c-new">::new &mdash; Tor::CachedDesc</a>
64
70
 
71
+ <li class="method"><a href="Tor/Circuit.html#method-c-new">::new &mdash; Tor::Circuit</a>
72
+
73
+ <li class="method"><a href="Tor/LongCircuit.html#method-c-new">::new &mdash; Tor::LongCircuit</a>
74
+
75
+ <li class="method"><a href="Tor/TController.html#method-c-new">::new &mdash; Tor::TController</a>
76
+
65
77
  <li class="method"><a href="Tor/TController.html#method-i-attach_stream">#attach_stream &mdash; Tor::TController</a>
66
78
 
79
+ <li class="method"><a href="Tor/Circuit.html#method-i-attach_streams">#attach_streams &mdash; Tor::Circuit</a>
80
+
81
+ <li class="method"><a href="Tor/LongCircuit.html#method-i-attach_streams">#attach_streams &mdash; Tor::LongCircuit</a>
82
+
67
83
  <li class="method"><a href="Tor/TController.html#method-i-bridges">#bridges &mdash; Tor::TController</a>
68
84
 
85
+ <li class="method"><a href="Tor/LongCircuit.html#method-i-built-3F">#built? &mdash; Tor::LongCircuit</a>
86
+
87
+ <li class="method"><a href="Tor/Circuit.html#method-i-built-3F">#built? &mdash; Tor::Circuit</a>
88
+
69
89
  <li class="method"><a href="Tor/TController.html#method-i-cir_status">#cir_status &mdash; Tor::TController</a>
70
90
 
91
+ <li class="method"><a href="Tor/LongCircuit.html#method-i-circuit">#circuit &mdash; Tor::LongCircuit</a>
92
+
93
+ <li class="method"><a href="Tor/Circuit.html#method-i-circuit">#circuit &mdash; Tor::Circuit</a>
94
+
95
+ <li class="method"><a href="Tor/LongCircuit.html#method-i-cirnum">#cirnum &mdash; Tor::LongCircuit</a>
96
+
97
+ <li class="method"><a href="Tor/Circuit.html#method-i-cirnum">#cirnum &mdash; Tor::Circuit</a>
98
+
99
+ <li class="method"><a href="Tor/LongCircuit.html#method-i-close_apps">#close_apps &mdash; Tor::LongCircuit</a>
100
+
101
+ <li class="method"><a href="Tor/Circuit.html#method-i-close_apps">#close_apps &mdash; Tor::Circuit</a>
102
+
71
103
  <li class="method"><a href="Tor/TController.html#method-i-closeallcircuits">#closeallcircuits &mdash; Tor::TController</a>
72
104
 
105
+ <li class="method"><a href="Tor/Circuit.html#method-i-closecir">#closecir &mdash; Tor::Circuit</a>
106
+
73
107
  <li class="method"><a href="Tor/TController.html#method-i-closecircuit">#closecircuit &mdash; Tor::TController</a>
74
108
 
109
+ <li class="method"><a href="Tor/Circuit.html#method-i-closed-3F">#closed? &mdash; Tor::Circuit</a>
110
+
75
111
  <li class="method"><a href="Tor/StatsObj.html#method-i-continent_count">#continent_count &mdash; Tor::StatsObj</a>
76
112
 
77
113
  <li class="method"><a href="Tor/StatsObj.html#method-i-continent_count_uniq">#continent_count_uniq &mdash; Tor::StatsObj</a>
@@ -84,6 +120,8 @@
84
120
 
85
121
  <li class="method"><a href="Tor/StatsObj.html#method-i-continent_stat_uniq">#continent_stat_uniq &mdash; Tor::StatsObj</a>
86
122
 
123
+ <li class="method"><a href="Tor/Circuit.html#method-i-controller">#controller &mdash; Tor::Circuit</a>
124
+
87
125
  <li class="method"><a href="Tor/StatsObj.html#method-i-country_count">#country_count &mdash; Tor::StatsObj</a>
88
126
 
89
127
  <li class="method"><a href="Tor/StatsObj.html#method-i-country_count_uniq">#country_count_uniq &mdash; Tor::StatsObj</a>
@@ -102,6 +140,10 @@
102
140
 
103
141
  <li class="method"><a href="Tor/TController.html#method-i-ds">#ds &mdash; Tor::TController</a>
104
142
 
143
+ <li class="method"><a href="Tor/Circuit.html#method-i-extend">#extend &mdash; Tor::Circuit</a>
144
+
145
+ <li class="method"><a href="Tor/LongCircuit.html#method-i-extend">#extend &mdash; Tor::LongCircuit</a>
146
+
105
147
  <li class="method"><a href="Tor/TController.html#method-i-extendcir">#extendcir &mdash; Tor::TController</a>
106
148
 
107
149
  <li class="method"><a href="Tor/TController.html#method-i-extendcir_slowly">#extendcir_slowly &mdash; Tor::TController</a>
@@ -110,6 +152,8 @@
110
152
 
111
153
  <li class="method"><a href="Tor/TController.html#method-i-get_bridges">#get_bridges &mdash; Tor::TController</a>
112
154
 
155
+ <li class="method"><a href="Tor/Circuit.html#method-i-get_bridges">#get_bridges &mdash; Tor::Circuit</a>
156
+
113
157
  <li class="method"><a href="Tor/StatsObj.html#method-i-get_countryname">#get_countryname &mdash; Tor::StatsObj</a>
114
158
 
115
159
  <li class="method"><a href="Tor/TController.html#method-i-get_entryguards">#get_entryguards &mdash; Tor::TController</a>
@@ -128,6 +172,10 @@
128
172
 
129
173
  <li class="method"><a href="Tor/TController.html#method-i-getinfo">#getinfo &mdash; Tor::TController</a>
130
174
 
175
+ <li class="method"><a href="Tor/Circuit.html#method-i-launch">#launch &mdash; Tor::Circuit</a>
176
+
177
+ <li class="method"><a href="Tor/Circuit.html#method-i-launched-3F">#launched? &mdash; Tor::Circuit</a>
178
+
131
179
  <li class="method"><a href="Tor/TController.html#method-i-net_status">#net_status &mdash; Tor::TController</a>
132
180
 
133
181
  <li class="method"><a href="Tor/TController.html#method-i-newstreams">#newstreams &mdash; Tor::TController</a>
@@ -142,6 +190,8 @@
142
190
 
143
191
  <li class="method"><a href="Tor/TController.html#method-i-sr">#sr &mdash; Tor::TController</a>
144
192
 
193
+ <li class="method"><a href="Tor/Circuit.html#method-i-start">#start &mdash; Tor::Circuit</a>
194
+
145
195
  <li class="method"><a href="Tor/CachedDesc.html#method-i-stat">#stat &mdash; Tor::CachedDesc</a>
146
196
 
147
197
  <li class="method"><a href="Tor/StatsObj.html#method-i-topcountries">#topcountries &mdash; Tor::StatsObj</a>
@@ -0,0 +1,370 @@
1
+ module Tor
2
+
3
+ # This is a single (sub-)circuit object over exactly 3 nodes.Suitable nodes must be chosesn to allow the creation of a successful circuit.
4
+ class Circuit
5
+
6
+ # Initialises a Tor::Circuit instance variable with attibutes including the @built, @cirnum and @torcontroller
7
+ # Use nil for proxyport if Tor is running already.
8
+ def initialize(ctrller_config, circuitarray, proxyconfig)
9
+ @built = true
10
+ @closed = true
11
+ @circuitarray = circuitarray
12
+ @cirnum = nil
13
+ @ctrller_config = ctrller_config
14
+ @proxyconfig = proxyconfig
15
+ if @proxyconfig.nil? # When proxyconfig.nil?, then it's an existing
16
+ @launched = true
17
+ @torcontroller = Tor::TController.new(@ctrller_config)
18
+ else
19
+ @launched = false
20
+ end
21
+ end
22
+
23
+ # Returns the nodes that make up the circuit.
24
+ def circuit
25
+ @circuitarray
26
+ end
27
+
28
+ # Returns the Tor:Controller used for the circuit.
29
+ def controller
30
+ if defined?(@torcontroller)
31
+ @torcontroller
32
+ end
33
+ end
34
+
35
+ # Returns the circuit number. Returns 0 if it has not been attached
36
+ def cirnum
37
+ @cirnum
38
+ end
39
+
40
+ # Checks if the application instances for Tor and polipo have been closed
41
+ def closed?
42
+ @closed
43
+ end
44
+
45
+ # This creates / builds the actual circuit using @circuitarray.
46
+ def extend
47
+ if defined?(@torcontroller)
48
+ @cirnum = @torcontroller.extendcir(0,@circuitarray)
49
+ else
50
+ puts "launch before extending\n"
51
+ return nil
52
+ end
53
+ end
54
+
55
+ # This attaches all streams on this controller to a prebuilt circuit that has been
56
+ def start
57
+ if ! launched?
58
+ launch
59
+ end
60
+ if ! built?
61
+ extend
62
+ end
63
+ # sleep(3.5) ###################### wait 3 seconds before checking if built. # May not be needed
64
+ # use events here instead to (build) no matter what. or (launch and build). If built, attach existing streams from preceeding subcircuit
65
+ if built?
66
+ streams_array = @torcontroller.newstreams
67
+ if ! streams_array.empty? and ! @cirnum.nil?
68
+ streams_array.each{|each_stream|
69
+ @torcontroller.attach_stream(each_stream, @cirnum)
70
+ }
71
+ end
72
+ end
73
+ end
74
+
75
+ # This methods checks if the circuit has been built. It only reflects a single segment of the circuit
76
+ def built?
77
+ if defined?(@torcontroller) # cant check built? before launching.
78
+ @built = ! @torcontroller.cir_status.detect{|z| z =~ /#{@cirnum} BUILT/ }.nil? if not @cirnum.nil?
79
+ else
80
+ false
81
+ end
82
+ end
83
+
84
+ # Checks if the launched method has been called
85
+ def launched?
86
+ @launched
87
+ end
88
+
89
+ # Run this after initializing a Tor::Circuit instaance. This writes the following Tor configuration options to a temp file if proxyport not nil: Write HttpProxy, HttpsProxy , DataDirectory /tmp/dir, __LeaveStreamUnattached 1.
90
+ # This also writes polipoo configuration to a temporary file and executes polipo
91
+ # It executes Tor and polipo if proxyport is not nil
92
+ # Note: The applicaitons will continue running even if the ruby shell is exited. The Circuit.close_apps method can be used to terminate the application and remove the temp dir
93
+ def launch
94
+ # should I use popen3? dont need stdin and stderror from tor or polipo
95
+ if ! @proxyconfig.nil?
96
+ @path = Dir.mktmpdir if not defined?(@path)
97
+ @pid= {}
98
+ torrc_filename = File.join(@path,"torrc")
99
+ torrc = File.new( torrc_filename, "w")
100
+ # populate torrc
101
+ socks_port = @ctrller_config[:port] - 1
102
+ torrc.puts "ControlPort #{@ctrller_config[:port]}\n"
103
+ torrc.puts "DataDirectory #{@path}\n"
104
+ torrc.puts "HttpProxy 127.0.0.1:#{@proxyconfig - 1}\n" # Use the preceeding polipo port
105
+ torrc.puts "HttpsProxy 127.0.0.1:#{@proxyconfig - 1}\n"
106
+ torrc.puts "RunAsDaemon 1\n"
107
+ torrc.puts "SocksPort #{socks_port}\n"
108
+ torrc.puts "SocksListenAddress 127.0.0.1\n"
109
+ # can add a random password and call tor --hashcontrolpassword read stdout..but feels like long thing. Or ruby implementation of hash
110
+ torrc.close
111
+ puts "Torrc config written \n"
112
+ #puts @tor_io=Process.spawn("tor","-f",torrc_filename) # stdin, stdout, stderr, thread
113
+ #puts @tor_io=Open3.popen3("tor","-f",torrc_filename) # stdin, stdout, stderr, thread
114
+ @pid[:tor] = Process.spawn("tor","-f",torrc_filename)
115
+ sleep(7) # wait 7 seconds to download cached consensus and descriptors. -Consider copuing the existing one from the previous directory
116
+ # check here # **************** why sleep? can I use the cached desc from the first tor process
117
+ @torcontroller = Tor::TController.new(@ctrller_config)
118
+ # write proxyconfig to polipo
119
+ polipo_filename = File.join(@path,"polipo_config")
120
+ polipo_config = File.new( polipo_filename , "w")
121
+ polipo_config.puts "proxyPort = #{@proxyconfig}\n"
122
+ polipo_config.puts "socksParentProxy = localhost:#{socks_port}\n"
123
+ polipo_config.puts "socksProxyType = socks5\n"
124
+ polipo_config.puts "daemonise = true\n"
125
+ polipo_log = File.join(@path,"polipo_log")
126
+ polipo_pid = File.join(@path,"polipo.pid")
127
+ polipo_forbid = File.join(@path,"forbidden")
128
+ polipo_config.puts "logFile = #{polipo_log}\n"
129
+ polipo_config.puts "pidFile = #{polipo_pid}\n"
130
+ polipo_config.puts "forbiddenFile = #{polipo_forbid}\n"
131
+ polipo_config.close
132
+ @pid[:polipo]= Process.spawn( "polipo", "-c", polipo_filename)
133
+ end
134
+ @torcontroller = Tor::TController.new(@ctrller_config)
135
+ # @path = @torcontroller.getconf("DataDirectory") when proxyconfig==nil # dont need path for the first Tor
136
+ @torcontroller.setconf("__DisablePredictedCircuits",1)
137
+ @torcontroller.setconf("newcircuitperiod",999999999)
138
+ @torcontroller.setconf("maxcircuitdirtiness",999999999)
139
+ @torcontroller.setconf("MaxOnionsPending",0)
140
+ @torcontroller.setconf("__LeaveStreamsUnattached",1)
141
+ @launched = true
142
+ @closed = false
143
+ end
144
+
145
+ # Closes the circuit
146
+ def closecir
147
+ @torcontroller.closecircuit(@cirnum) if ! @cirnum.nil?
148
+ @built=false
149
+ end
150
+
151
+ # Closes the Tor and Polipo launched by the instance of this class, and removes the tmp directory
152
+ def close_apps
153
+ if defined?(@pid)
154
+ @torcontroller.signal("SHUTDOWN")
155
+ Process.kill("KILL",@pid[:polipo])
156
+ FileUtils.remove_entry_secure @path # srm path ( delete tmp directory recursively )
157
+ @launched=false
158
+ @built=false
159
+ end
160
+ @closed = true
161
+ end
162
+
163
+ # This tries to attach all streams to the circuit.
164
+ def attach_streams
165
+ controller.newstreams.each{|z|
166
+ controller.attach_stream(z,@cirnum)
167
+ }
168
+ end
169
+
170
+ # This gets 3 bridge IP addresses from the Tor bridge website. proxyconfig is optional.
171
+ # default proxyconfig = {:type=>'polipo' ,:port=>8118,:addr=>'127.0.0.1'}
172
+ # The return format is fo the form:
173
+ # [HTTPcode, [{:bridgeip, :bridgeport},{:bridgeip, :bridgeport},{:bridgeip, :bridgeport}].
174
+ # The types can be one of 'tor', 'polipo', 'socks', 'http', 'https',nil, 'none'.
175
+ #
176
+ # <b>Get 3 bridges</b>
177
+ #
178
+ # Tor::Circuit.get_bridges( Tor::Cacheddesc, {:proxytype=>'polipo',:proxyport=>8118,:proxyaddr=>'127.0.0.1'} )
179
+ #
180
+ # cachedDesc can be nil if the Google Earth file is not needed.
181
+ def get_bridges(cacheddesc, *config)
182
+ url = URI.parse "https://bridges.torproject.org/"
183
+ if config.empty?
184
+ proxyconfig={:type=>'polipo' ,:port=>8118,:addr=>'127.0.0.1'}
185
+ else
186
+ proxyconfig = config[0]
187
+ end
188
+
189
+ if ! defined?(@myhttperrors)
190
+ @myhttperrors=0
191
+ end
192
+ case proxyconfig[:type]
193
+ when /none/i,nil
194
+ http_session=Net::HTTP.new(url.host,url.port)
195
+ when /socks/i,/tor/i
196
+ http_session=Net::HTTP.SOCKSProxy(proxyconfig[:addr], proxyconfig[:port]).new(url.host,url.port)
197
+ when /http/i,/https/i,/polipo/i
198
+ http_session=Net::HTTP::Proxy(proxyconfig[:addr], proxyconfig[:port]).new(url.host,url.port)
199
+ end
200
+
201
+ if url.scheme=="https"
202
+ http_session.use_ssl = true
203
+ http_session.verify_mode = OpenSSL::SSL::VERIFY_NONE
204
+ else
205
+ http_session.use_ssl=false
206
+ end
207
+ bridges=[]
208
+ # Rescue from http error
209
+ begin
210
+ resp = http_session.get2 url.path # Let Tor choose circuit itself
211
+ # Additional code will be added shortly to attach the stream to the circuit directly
212
+ puts "#{resp.code} HTTP response"
213
+ # puts resp.body
214
+ respcode= resp.code=="200" ? 200:nil
215
+ if resp.code == "200"
216
+ torbridgeip=resp.body.scan(/\d+\.\d+\.\d+\.\d+\:\d+/)
217
+ torbridgeip.each{|eachbridge|
218
+ bridgeip,bridgeport= eachbridge.split(':')
219
+ x = Tor::Bridge.where(:ipaddr=>bridgeip, :port =>bridgeport)
220
+ if x.empty?
221
+ if cacheddesc.nil? or (bridge_geoip = cacheddesc.get_geoiprecord(bridgeip)).nil?
222
+ Tor::Bridge.create(:ipaddr=>bridgeip, :port =>bridgeport,
223
+ :lat=>0, :lng=>0)
224
+ else
225
+ Tor::Bridge.create(:ipaddr=>bridgeip, :port =>bridgeport,
226
+ :lat=>bridge_geoip.latitude.to_f,
227
+ :lng=>bridge_geoip.longitude.to_f )
228
+ end
229
+ end
230
+ }
231
+ end
232
+ bridges = torbridgeip
233
+ rescue
234
+ @myhttperrors +=1
235
+ respcode=nil
236
+ bridges=[]
237
+ end
238
+ bridges.nil? ? [] : bridges #Return array of all bridges
239
+ end
240
+
241
+ end
242
+
243
+ # tcontrolarray = [ {:host=>'127.0.0.1',:port => 9051, :password=> "test1234"}, {:host=>'127.0.0.1',:port => 9053},
244
+ # {:host=>'127.0.0.1',:port => 9055}, {:host=>'127.0.0.1',:port => 9057} ]
245
+ # proxyconfig = 8100 # I can "getconf SocksPort" from circuitarray[0] to determine the first array member here
246
+ # orarray = ["A","B","C", "E","F","G", "A","B","C", "E","F","G"]
247
+ # test = Tor::LongCircuit.new(tcontrolarray, orarray,proxyconfig)
248
+
249
+ # This creates a Long circuit comprising of multiple sub-circuits. Methods include LongCircuit.built?, LongCircuit.extend,LongCircuit..attach_streams,
250
+ class LongCircuit
251
+
252
+ # Creates an instance of Tor::LongCircuit and initialises the attributes of the instance including the cirnum, @built and @circuitarray containing an sub-circuits that are instances of Tor::Circuit
253
+ def initialize( tcontrolarray=[], circuitarray=[], proxyconfig )
254
+ # Would it be better to get proxyconfig from mytor.getconf("SocksPort")
255
+ @built = false
256
+ @cirnum = 0
257
+ @circuitarray = []
258
+ i = 0; j = 2; k=0
259
+ while i < circuitarray.count
260
+ if tcontrolarray[k]
261
+ if k == 0
262
+ @circuitarray << Circuit.new( tcontrolarray[k], circuitarray[ i..j ] , nil )
263
+ else
264
+ @circuitarray << Circuit.new( tcontrolarray[k], circuitarray[ i..j ] , proxyconfig + k )
265
+ end
266
+ i +=3
267
+ j +=3
268
+ k +=1
269
+ end
270
+ end
271
+ end
272
+
273
+ # This tries to attach all streams to to a single pre-established circuit.
274
+ def attach_streams
275
+ # fork_reactor runs the reactor in a new thread thus allowing other methods to e run. Should I store the pid? When do I close the pid?
276
+ # EM.fork_reactor{
277
+ EM.run {
278
+ # @counter = 0 if not defined?(@seun) # To count how many times an event has been triggered
279
+ @timer=Array.new(@circuitarray.count)
280
+ 0.upto(@circuitarray.count - 1){|z|
281
+ if ! @circuitarray[z].launched?
282
+ @circuitarray[z].launch
283
+ end
284
+
285
+ # Periodic timer to fire an event, in this case launch/attach sub circuits. If a custom value (Tor::PERIODIC_TIMER) is defined, use it instead
286
+ timer = (defined? Tor::PERIODIC_TIMER) ? Tor::PERIODIC_TIMER : Tor::Constants::PERIODIC_TIMER
287
+
288
+ # Keep checking if any of the subcircuits has been closed using the timer duration
289
+ @timer[z] = EventMachine::PeriodicTimer.new(timer) do
290
+ @timer[z].cancel if @circuitarray[z].closed?
291
+ # puts "Counter = #{@counter+=1}\n"
292
+ @circuitarray[z].start
293
+ end
294
+ }
295
+ }
296
+
297
+ y = ( built? ).index(false)
298
+ puts "#{y} - #{built?}\n"
299
+ extend y
300
+ return nil
301
+ end
302
+
303
+ #
304
+ def cirnum
305
+ @circuitarray[0].cirnum
306
+ end
307
+
308
+ # Checks if the subcircuits have been built.
309
+ def built?
310
+ @built = true
311
+ truth_table = @circuitarray.collect{|each_circuit| each_circuit.built? } # To know where the circuit is failing
312
+ truth_table.each{|truth_value| @built = @built & truth_value }
313
+ truth_table
314
+ end
315
+
316
+ # This closes all the sub-circuits.
317
+ def close_apps
318
+ @circuitarray.each{|z|
319
+ z.close_apps
320
+ }
321
+ end
322
+
323
+ # Returns the array of Tor::Circuit instances that make up the LongCircuit instance.
324
+ def circuit
325
+ @circuitarray
326
+ end
327
+
328
+ # Returns the circuit number of the entry circuit.
329
+ def cirnum
330
+ @circuitarray[0].cirnum # built? ? @circuitarray[0].cirnum : nil
331
+ end
332
+
333
+ # Extend circuits from startcir position in the circuit array. This is used internally by Tor.attach_streams There is no need to call this directly, instead use attach_streams method.
334
+ def extend(*startcir)
335
+ if startcir.empty?
336
+ tmp=0
337
+ elsif startcir[0].nil?
338
+ tmp=0
339
+ else
340
+ tmp = startcir[0]
341
+ end
342
+
343
+ # Extend all sub-circuits or extend only circuits from startcir index.
344
+ tmp.upto(@circuitarray.count - 1 ){ |y|
345
+ each_circuit = @circuitarray[y]
346
+ counter_z=0
347
+ while ! each_circuit.built? and counter_z < 15 # Try up to 15 times to build the same circuit before giving up
348
+ # each_circuit.launch if y != 0 # here I need to launch tor and polipo in this method with the right config file after adding tmpdir path and configs
349
+ cirnum = each_circuit.extend
350
+ if each_circuit.built?
351
+ next
352
+ else
353
+ sleep( 2 * @circuitarray.index(each_circuit) + 2 ) # arithmetic progression time possible delay between each circuits [2,4,6,8,10,12]...
354
+ next if each_circuit.built?
355
+ end
356
+ z += 1
357
+ end
358
+
359
+ if z == 15
360
+ puts "Circuit failed \n"
361
+ return nil
362
+ else
363
+ cirnum
364
+ end
365
+ }
366
+ end # end extend()
367
+
368
+
369
+ end # end of class
370
+ end #end of module