Hi all,
how can i write a tcp proxy which is capable to connect dynamically to
different systems depending on information coming from a client
connecting to the proxy??
I already have a standard proxy script, which can forward an incoming
client request to a predefined server target.
Target scenario is a client with a repository of targets. This client
sends requests to some targets via this proxy. Therefore it sends the
request, together with the target ip/port, to the proxy. The proxy now
takes the information, opens a connection to target and forwards the
request.
I got stuck because when i read the incoming request from socket once,
for setting up the connection, it is not available anymore in the later
listening loop to send it via the new connection to the server.
Any idea how to achieve this??
Current code ist this:
require “socket”
require ‘json’
max_threads = 5
threads = []
Read proxy bindadress and port from configfile
conf = JSON.parse(File.read(‘hvp.conf’))
puts "starting proxy on " + conf[‘proxyip’] + ‘(’ + conf[‘proxyport’] +
‘)’
#Start proxy with data from configfile
server = TCPServer.new(conf[‘proxyip’],conf[‘proxyport’])
while true
Start a new thread for every client connection.
puts “waiting for connections”
threads << Thread.new(server.accept) do |client_socket|
begin
puts “#{Thread.current}: got a client connection”
begin
params = JSON.parse(client_socket.gets.chomp.to_s)
remote_host = params[‘agentip’]
remote_port = params[‘agentport’]
server_socket = TCPSocket.new(remote_host, remote_port)
rescue Errno::ECONNREFUSED
client_socket.close
raise
end
puts “#{Thread.current}: connected to server at
#{remote_host}:#{remote_port}”
while true
# Wait for data to be available on either socket.
(ready_sockets, dummy, dummy) = IO.select([client_socket,
server_socket])
begin
ready_sockets.each do |socket|
data = socket.readpartial(4096)
if socket == client_socket
# Read from client, write to server.
puts “#{Thread.current}: client->server #{data.inspect}”
server_socket.write data
server_socket.flush
else
# Read from server, write to client.
puts “#{Thread.current}: server->client #{data.inspect}”
client_socket.write data
client_socket.flush
end
end
rescue EOFError
break
end
end
rescue StandardError => e
puts “Thread #{Thread.current} got exception #{e.inspect}”
end
puts “#{Thread.current}: closing the connections”
client_socket.close rescue StandardError
server_socket.close rescue StandardError
end
Clean up the dead threads, and wait until we have available threads.
puts “#{threads.size} threads running”
threads = threads.select { |t| t.alive? ? true : (t.join; false) }
while threads.size >= max_threads
sleep 1
threads = threads.select { |t| t.alive? ? true : (t.join; false) }
end
end