metasploit-framework/lib/rex/socket/comm.rb

127 lines
2.9 KiB
Ruby

require 'rex/socket'
require 'rex/sync/read_write_lock'
module Rex
module Socket
###
#
# This mixin provides the basic interface that a derived class must implement
# in order to be a compatible comm class. The base comm class also supports
# registering event handlers that can be notified when sockets are being
# created and have been created. This allows code to extend sockets on
# creation from the single point that they are created.
#
###
module Comm
###
#
# This mixin provides stubs for event notification handlers that can be
# registered with a Comm factory to be called when various events occur,
# such as socket instantiation.
#
###
module Events
#
# This callback is notified when a socket is being created and is passed
# the parameters that will be used to create it.
#
def on_before_socket_create(comm, param)
end
#
# This callback is notified when a new socket is created and the
# parameters that were used to create it. This provides the callback
# with a chance to extend or otherwise modify the socket before it's
# passed on to the actual requestor.
#
def on_socket_created(comm, sock, param)
end
end
#
# Creates a compatible socket based on the supplied uniform parameters.
#
def self.create(param)
raise NotImplementedError
end
#
# Indicates whether or not this comm can be chained with other chainable
# comms. This is particularly important for things like Proxy Comms that
# can be proxied through one another. The semantics of this are currently
# undefined and will probably need some more thought.
#
def chainable?
false
end
#
# Registers an event handler that implements the Rex::Socket::Comm::Event
# interface in at least some fashion. Event handlers are notified when
# sockets are created through the Comm instance that they register against.
#
def register_event_handler(handler)
if (handlers == nil)
self.handlers = []
self.handlers_rwlock = Rex::ReadWriteLock.new
end
self.handlers << handler
end
#
# Deregisters a previously registered event handler.
#
def deregister_event_handler(handler)
if (handlers)
handlers_rwlock.synchronize_write {
handlers.delete(handler)
}
end
end
#
# Enumerates each registered event handler so that they can be notified of
# an event.
#
def each_event_handler(&block)
if (handlers)
handlers_rwlock.synchronize_read {
handlers.each(&block)
}
end
end
#
# Notifies handlers of the before socket create event.
#
def notify_before_socket_create(comm, param)
each_event_handler() { |handler|
handler.on_before_socket_create(comm, param)
}
end
#
# Notifies handlers of the socket created event.
#
def notify_socket_created(comm, sock, param)
each_event_handler() { |handler|
handler.on_socket_created(comm, sock, param)
}
end
protected
attr_accessor :handlers # :nodoc:
attr_accessor :handlers_rwlock # :nodoc:
end
end
end