Class: Arachni::Processes::Instances

Inherits:
Object
  • Object
show all
Includes:
Utilities, Singleton
Defined in:
lib/arachni/processes/instances.rb

Overview

Helper for managing RPC::Server::Instance processes.

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Utilities

#available_port, available_port_mutex, #bytes_to_kilobytes, #bytes_to_megabytes, #caller_name, #caller_path, #cookie_decode, #cookie_encode, #cookies_from_file, #cookies_from_parser, #cookies_from_response, #exception_jail, #exclude_path?, #follow_protocol?, #form_decode, #form_encode, #forms_from_parser, #forms_from_response, #full_and_absolute_url?, #generate_token, #get_path, #hms_to_seconds, #html_decode, #html_encode, #include_path?, #links_from_parser, #links_from_response, #normalize_url, #page_from_response, #page_from_url, #parse_set_cookie, #path_in_domain?, #path_too_deep?, #port_available?, #rand_port, #random_seed, #redundant_path?, #regexp_array_match, #remove_constants, #request_parse_body, #seconds_to_hms, #skip_page?, #skip_path?, #skip_resource?, #skip_response?, #to_absolute, #uri_decode, #uri_encode, #uri_parse, #uri_parse_query, #uri_parser, #uri_rewrite

Constructor Details

#initializeInstances



24
25
26
27
# File 'lib/arachni/processes/instances.rb', line 24

def initialize
    @list = {}
    @instance_connections = {}
end

Instance Attribute Details

#listArray<String> (readonly)



22
23
24
# File 'lib/arachni/processes/instances.rb', line 22

def list
  @list
end

Class Method Details

.method_missing(sym, *args, &block) ⇒ Object



219
220
221
222
223
224
225
# File 'lib/arachni/processes/instances.rb', line 219

def self.method_missing( sym, *args, &block )
    if instance.respond_to?( sym )
        instance.send( sym, *args, &block )
    else
        super( sym, *args, &block )
    end
end

.respond_to?(m) ⇒ Boolean



227
228
229
# File 'lib/arachni/processes/instances.rb', line 227

def self.respond_to?( m )
    super( m ) || instance.respond_to?( m )
end

Instance Method Details

#connect(url, token = nil) ⇒ RPC::Client::Instance

Connects to a Instance by URL.



38
39
40
41
42
43
44
45
46
# File 'lib/arachni/processes/instances.rb', line 38

def connect( url, token = nil )
    Reactor.global.run_in_thread if !Reactor.global.running?

    token ||= @list[url]
    @list[url] ||= token

    @instance_connections[url] ||=
        RPC::Client::Instance.new( Options, url, token )
end

#dispatcher_spawnRPC::Client::Instance

Starts RPC::Server::Dispatcher and returns an Instance.



172
173
174
175
# File 'lib/arachni/processes/instances.rb', line 172

def dispatcher_spawn
    info = Dispatchers.light_spawn.dispatch
    connect( info['url'], info['token'] )
end

#each(&block) ⇒ Object



49
50
51
52
53
# File 'lib/arachni/processes/instances.rb', line 49

def each( &block )
    @list.keys.each do |url|
        block.call connect( url )
    end
end

#grid_spawn(options = {}) ⇒ RPC::Client::Instance

Starts RPC::Server::Dispatcher grid and returns a high-performance Instance.

Options Hash (options):

  • :grid_size (Integer) — default: 3

    Amount of Dispatchers to spawn.



122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
# File 'lib/arachni/processes/instances.rb', line 122

def grid_spawn( options = {} )
    options[:grid_size] ||= 3

    last_member = nil
    options[:grid_size].times do |i|
        last_member = Dispatchers.spawn(
            neighbour: last_member ? last_member.url : last_member,
            pipe_id:   Utilities.available_port.to_s + Utilities.available_port.to_s
        )
    end

    info = last_member.dispatch

    instance = connect( info['url'], info['token'] )
    instance.framework.set_as_master
    instance.options.set( dispatcher: { grid_mode: :aggregate } )
    instance
end

#kill(url) ⇒ Object



177
178
179
180
181
182
183
184
185
186
187
# File 'lib/arachni/processes/instances.rb', line 177

def kill( url )
    service = connect( url ).service
    service.consumed_pids do |pids|
        service.shutdown do
            # Make sure....
            Manager.kill_many pids
        end
    end

    @list.delete url
end

#killallObject

Kills all #list.



190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
# File 'lib/arachni/processes/instances.rb', line 190

def killall
    pids = []
    each do |instance|
        begin
            Timeout.timeout 5 do
                pids |= instance.service.consumed_pids
            end
        rescue => e
            #ap e
            #ap e.backtrace
        end
    end

    each do |instance|
        begin
            Timeout.timeout 5 do
                instance.service.shutdown
            end
        rescue => e
            #ap e
            #ap e.backtrace
        end
    end

    @list.clear
    @instance_connections.clear
    Manager.kill_many pids
end

#light_grid_spawn(options = {}) ⇒ RPC::Client::Instance

Starts RPC::Server::Dispatcher grid and returns a high-performance Instance.

Options Hash (options):

  • :grid_size (Integer) — default: 3

    Amount of Dispatchers to spawn.



147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
# File 'lib/arachni/processes/instances.rb', line 147

def light_grid_spawn( options = {} )
    options[:grid_size] ||= 3

    last_member = nil
    options[:grid_size].times do |i|
        last_member = Dispatchers.light_spawn(
            neighbour: last_member ? last_member.url : last_member,
            pipe_id:   Utilities.available_port.to_s + Utilities.available_port.to_s
        )
    end

    info = nil
    info = last_member.dispatch while !info && sleep( 0.1 )

    instance = connect( info['url'], info['token'] )
    instance.framework.set_as_master
    instance.options.set( dispatcher: { grid_mode: :aggregate } )
    instance
end

#spawn(options = {}, &block) ⇒ RPC::Client::Instance

Spawns an RPC::Server::Instance process.



71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
# File 'lib/arachni/processes/instances.rb', line 71

def spawn( options = {}, &block )
    token = options.delete(:token) || Utilities.generate_token
    fork  = options.delete(:fork)

    options = {
        spawns: options[:spawns],
        rpc:    {
            server_socket:  options[:socket],
            server_port:    options[:port]    || Utilities.available_port,
            server_address: options[:address] || '127.0.0.1'
        }
    }

    url = nil
    if options[:rpc][:server_socket]
        url = options[:rpc][:server_socket]

        options[:rpc].delete :server_address
        options[:rpc].delete :server_port
    else
        url = "#{options[:rpc][:server_address]}:#{options[:rpc][:server_port]}"
    end

    Manager.spawn( :instance, options: options, token: token, fork: fork )

    client = connect( url, token )

    if block_given?
        client.when_ready do
            block.call client
        end
    else
        while sleep( 0.1 )
            begin
                client.service.alive?
                break
            rescue => e
                # ap "#{e.class}: #{e}"
                # ap e.backtrace
            end
        end
        client
    end
end

#token_for(client_or_url) ⇒ String



60
61
62
# File 'lib/arachni/processes/instances.rb', line 60

def token_for( client_or_url )
    @list[client_or_url.is_a?( String ) ? client_or_url : client_or_url.url ]
end