class PacketThief::Handlers::TransparentProxy

Provides a transparent proxy for any TCP connection.

Attributes

buffer[RW]

An internal buffer of packet data received from the client. It will grow until the destination connection connects.

client[RW]

This holds a reference to the connection to the client. It is actually self.

client_host[R]
client_port[R]
closing[RW]

Boolean that represents whether this handler has started to close/unbind. Used to ensure there is no unbind-loop between the two connections that make up the proxy.

dest[RW]

This holds a reference to the connection to the destination. If it is null, it hasn’t been created yet.

dest_host[RW]

Override these before connecting to dest to change the dest connection.

dest_port[RW]

Override these before connecting to dest to change the dest connection.

when_to_connect_to_dest[RW]

When the proxy should connect to a destination.

Public Class Methods

new(log=nil) click to toggle source
# File lib/packetthief/handlers/transparent_proxy.rb, line 71
def initialize(log=nil)
  @logger = log
end

Public Instance Methods

_send_buffer() click to toggle source
# File lib/packetthief/handlers/transparent_proxy.rb, line 121
def _send_buffer
  @buffer.each do |pkt|
    @dest.send_data pkt
  end
  @buffer = []
end
client_closed() click to toggle source

Called when the client connection closes. At present, it only provides informational utility.

# File lib/packetthief/handlers/transparent_proxy.rb, line 170
def client_closed
  logdebug("client closed connection")
end
client_connected() click to toggle source

This method is called when a client connects. The default behavior is to begin initating the connection to the original destination. Override this method to change its behavior.

# File lib/packetthief/handlers/transparent_proxy.rb, line 146
def client_connected
  connect_to_dest
end
client_recv(data) click to toggle source

This method is called when the proxy receives data from the client connection. The default behavior is to call #send_to_dest(data) in order to foward the data on to the original destination. Override this method to analyze the data, or modify it before sending it on.

# File lib/packetthief/handlers/transparent_proxy.rb, line 154
def client_recv(data)
  logdebug("received from client", :data => data)
  send_to_dest data
end
connect_to_dest() click to toggle source

Initiate the connection to @#dest_host:@dest_port.

# File lib/packetthief/handlers/transparent_proxy.rb, line 113
def connect_to_dest
  logdebug "Connecting to #{@dest_host}:#{@dest_port}"
  @dest = ::EM.connect(@dest_host, @dest_port, ProxyConnection, self)
  newport, newhost = Socket::unpack_sockaddr_in(@dest.get_sockname)
  # Add the new connection to the list to prevent loops.
  @@activeconns["#{newhost}:#{newport}"] = "#{dest_host}:#{dest_port}"
end
dest_closed() click to toggle source

Called when the original destination connection closes. At present, it only provides informational utility.

# File lib/packetthief/handlers/transparent_proxy.rb, line 176
def dest_closed
  logdebug("dest closed connection")
end
dest_recv(data) click to toggle source

Called when the proxy receives data from the destination connection. The default behavior calls dest_recv() to send the data to the client.

Override it to analyze or modify the data.

# File lib/packetthief/handlers/transparent_proxy.rb, line 163
def dest_recv(data)
  logdebug("received from dest", :data => data)
  send_to_client data
end
post_init() click to toggle source
# File lib/packetthief/handlers/transparent_proxy.rb, line 75
def post_init
  @closing = false

  @client = self
  @dest = nil

  @buffer = []
  @@activeconns ||= {}

  @client_port, @client_host = Socket.unpack_sockaddr_in(get_peername)
  @dest_port, @dest_host = PacketThief.original_dest(self)

  logdebug "Client connected", :client_host => client_host, :client => "#{@client_host}:#{@client_port}", :orig_dest => "#{@dest_host}:#{@dest_port}"

  if @@activeconns.has_key? "#{client_host}:#{client_port}"
    puts "Warning: loop detected! Stopping the loop."
    close_connection
    return
  end

  client_connected
end
receive_data(data) click to toggle source
# File lib/packetthief/handlers/transparent_proxy.rb, line 98
def receive_data(data)
  client_recv data
end
send_to_client(data) click to toggle source

Sends data back to the client

# File lib/packetthief/handlers/transparent_proxy.rb, line 138
def send_to_client(data)
  send_data data
end
send_to_dest(data) click to toggle source

Queues up data to send to the remote host, only sending it if the connection to the remote host exists.

# File lib/packetthief/handlers/transparent_proxy.rb, line 131
def send_to_dest(data)
  logdebug "sending to dest", :data => data
  @buffer << data
  _send_buffer if @dest
end
unbind() click to toggle source

Start the closing process and close the other connection if it is not already closing.

# File lib/packetthief/handlers/transparent_proxy.rb, line 104
def unbind
  client_closed
  @@activeconns.delete "#{client_host}:#{client_port}"
  self.closing = true
  @dest.close_connection_after_writing if @dest and not @dest.closing
end