class RaptorIO::Socket::SwitchBoard
A routing table that associates subnets with {Comm} objects. Comm classes are used to instantiate objects that are tied to remote network entities. For example, {Comm::Local} is used to build network connections directly from the local machine whereas, for instance, a SOCKS Comm would build a local socket pair that is associated with a connection established by a remote SOCKS server. This can be seen as a uniform way of communicating with hosts through arbitrary channels.
Constants
- DEFAULT_ROUTE
If no route matches the host/netmask when searching for {#best_comm}, this will be the fallback - always route through the local machine creating Ruby ::Sockets.
Attributes
The list of routes this swithboard knows about
@return [Array<Route>]
Public Class Methods
# File lib/raptor-io/socket/switch_board.rb, line 33 def initialize @routes = Array.new @mutex = Mutex.new end
Public Instance Methods
Adds a route for a given subnet and netmask destined through a given comm instance.
@param (see RaptorIO::Socket::SwitchBoard::Route#new) @return [Boolean] Whether the route was added. This may fail if a
route already {#route_exists? existed} or if the given `comm` does not support the address family of the `subnet` (e.g., an IPv6 address for a comm that does not support IPv6)
# File lib/raptor-io/socket/switch_board.rb, line 46 def add_route(subnet, netmask, comm) rv = true subnet = IPAddr.parse(subnet) if subnet.ipv6? and comm.respond_to?(:support_ipv6?) return false unless comm.support_ipv6? end synchronize do # If the route already exists, return false to the caller. if route_exists?(subnet, netmask) rv = false else @routes << Route.new(subnet, netmask, comm) end end rv end
Finds the best possible comm for the supplied target address.
@param addr [String,IPAddr] The address to which we want to talk @return [Comm]
# File lib/raptor-io/socket/switch_board.rb, line 69 def best_comm(addr) addr = IPAddr.parse(addr) # Find the most specific route that this address fits in. If none, # use the default, i.e., local. best_route = reduce(DEFAULT_ROUTE) do |best, route| if route.subnet.include?(addr) && route.netmask >= best.netmask route else best end end best_route.comm end
Create a TCP client socket on the {#best_comm best comm} available for ‘:peer_host`.
@param (see Comm#create_tcp) @option opts (see Comm#create_tcp)
# File lib/raptor-io/socket/switch_board.rb, line 162 def create_tcp(opts) best_comm(opts[:peer_host]).create_tcp(opts) end
Create a TCP server socket on the {#best_comm best comm} available for ‘:local_host`.
@param (see Comm#create_tcp_server) @option opts (see Comm#create_tcp_server)
# File lib/raptor-io/socket/switch_board.rb, line 171 def create_tcp_server(opts) best_comm(opts[:local_host]).create_tcp_server(opts) end
Enumerates each entry in the routing table.
# File lib/raptor-io/socket/switch_board.rb, line 87 def each(&block) @routes.each(&block) end
Clears all established routes.
@return [void]
# File lib/raptor-io/socket/switch_board.rb, line 96 def flush_routes # Remove each of the individual routes so the comms don't think they're # still routing after a flush. @routes.each do |r| if r.comm.respond_to? :routes r.comm.routes.delete("#{r.subnet}/#{r.netmask}") end end # Re-initialize to an empty array @routes.clear end
Remove all routes that go through the supplied ‘comm`.
@param comm [Comm] @return [void]
# File lib/raptor-io/socket/switch_board.rb, line 114 def remove_by_comm(comm) synchronize do @routes.delete_if { |route| route.comm == comm } end nil end
Removes a route for a given subnet and netmask destined through a given comm instance.
@param (see Route.new
) @return [Boolean] Whether we found one to delete
# File lib/raptor-io/socket/switch_board.rb, line 128 def remove_route(subnet, netmask, comm) rv = false other = Route.new(subnet, netmask, comm) synchronize do @routes.delete_if do |route| if route == other rv = true else false end end end rv end
Checks to see if a route already exists for the supplied subnet and netmask.
# File lib/raptor-io/socket/switch_board.rb, line 149 def route_exists?(subnet, netmask) each do |route| return true if route.subnet == subnet and route.netmask == netmask end false end
Private Instance Methods
# File lib/raptor-io/socket/switch_board.rb, line 177 def synchronize( &block ) @mutex.synchronize( &block ) end