Class/Module Index [+]

Quicksearch

Rex::IO::StreamServer

This mixin provides the framework and interface for implementing a streaming server that can listen for and accept stream client connections. Stream servers extend this class and are required to implement the following methods:

accept
fd

Attributes

client_waiter[RW]
on_client_close_proc[RW]

This callback procedure can be set and will be called when a client disconnects from the server.

on_client_connect_proc[RW]

This callback procedure can be set and will be called when new clients connect.

on_client_data_proc[RW]

This callback procedure can be set and will be called when clients have data to be processed.

Public Instance Methods

close_client(client) click to toggle source

This method closes a client connection and cleans up the resources associated with it.

# File lib/rex/io/stream_server.rb, line 92
def close_client(client)
        if (client)
                clients.delete(client)

                begin
                        client.close
                rescue IOError
                end
        end
end
on_client_close(client) click to toggle source

This callback is notified when a client connection has closed.

# File lib/rex/io/stream_server.rb, line 54
def on_client_close(client)
        if (on_client_close_proc)
                on_client_close_proc.call(client)
        end
end
on_client_connect(client) click to toggle source

This callback is notified when a client connects.

# File lib/rex/io/stream_server.rb, line 35
def on_client_connect(client)
        if (on_client_connect_proc)
                on_client_connect_proc.call(client)
        end
end
on_client_data(client) click to toggle source

This callback is notified when a client connection has data that needs to be processed.

# File lib/rex/io/stream_server.rb, line 45
def on_client_data(client)
        if (on_client_data_proc)
                on_client_data_proc.call(client)
        end
end
start() click to toggle source

Start monitoring the listener socket for connections and keep track of all client connections.

# File lib/rex/io/stream_server.rb, line 64
def start
        self.clients = []
        self.client_waiter = ::Queue.new

        self.listener_thread = Rex::ThreadFactory.spawn("StreamServerListener", false) {
                monitor_listener
        }
        self.clients_thread = Rex::ThreadFactory.spawn("StreamServerClientMonitor", false) {
                monitor_clients
        }
end
stop() click to toggle source

Terminates the listener monitoring threads and closes all active clients.

# File lib/rex/io/stream_server.rb, line 79
def stop
        self.listener_thread.kill
        self.clients_thread.kill

        self.clients.each { |cli|
                close_client(cli)
        }
end
wait() click to toggle source

This method waits on the server listener thread

# File lib/rex/io/stream_server.rb, line 106
def wait
        self.listener_thread.join if self.listener_thread
end

Protected Instance Methods

monitor_clients() click to toggle source

This method monitors client connections for data and calls the on_client_data routine when new data arrives.

# File lib/rex/io/stream_server.rb, line 178
def monitor_clients
        begin
        
                # Wait for a notify if our client list is empty
                if (clients.length == 0)
                        self.client_waiter.pop
                        next
                end

                sd = Rex::ThreadSafe.select(clients, nil, nil, nil)

                sd[0].each { |cfd|
                        begin
                                on_client_data(cfd)
                        rescue ::EOFError, ::Errno::ECONNRESET, ::Errno::ENOTCONN, ::Errno::ECONNABORTED
                                on_client_close(cfd)
                                close_client(cfd)
                        rescue ::Interrupt
                                raise $!
                        rescue ::Exception
                                close_client(cfd)
                                elog("Error in stream server client monitor: #{$!}")
                                rlog(ExceptionCallStack)

                        end
                }

        rescue ::Rex::StreamClosedError => e
                # Remove the closed stream from the list
                clients.delete(e.stream)
        rescue ::Interrupt
                raise $!
        rescue ::Exception
                elog("Error in stream server client monitor: #{$!}")
                rlog(ExceptionCallStack)
        end while true
end
monitor_listener() click to toggle source

This method monitors the listener socket for new connections and calls the on_client_connect callback routine.

# File lib/rex/io/stream_server.rb, line 142
def monitor_listener

        while true
                begin
                        cli = accept
                        if not cli
                                elog("The accept() returned nil in stream server listener monitor:  #{fd.inspect}")
                                ::IO.select(nil, nil, nil, 0.10)
                                next
                        end

                        # Append to the list of clients
                        self.clients << cli

                        # Initialize the connection processing
                        on_client_connect(cli)
                        
                        # Notify the client monitor
                        self.client_waiter.push(cli)

                # Skip exceptions caused by accept() [ SSL ]
                rescue ::EOFError, ::Errno::ECONNRESET, ::Errno::ENOTCONN, ::Errno::ECONNABORTED
                rescue ::Interrupt
                        raise $!
                rescue ::Exception
                        elog("Error in stream server server monitor: #{$!}")
                        rlog(ExceptionCallStack)
                        break
                end
        end
end

[Validate]

Generated with the Darkfish Rdoc Generator 2.