About Me

My name is Ricardo Pascal, I'm a developer and sysadmin who lives in Florianopolis/Brazil. I enjoy work with projects related to Linux, Python, Science, Web, Django and Network.

g+ "I've seen countless science fiction movies and documentaries about the future of humanity. Nothing ... | it's a fun hobby | Matéria bacana que aponta floripa como a melhor capital para se empreender no brasil. | Axado está com vaga aberta para desenvolvedor Python & Django. | | A common use of web applications has been serving files, django is capable of that, but is usually not... | A common use of web applications has been serving files, django is capable of that, but is usually not... | For the first time since I became a Ubuntu user, I'm considering not update my system to a new release... | Now try arguing with these people.... #climatechange   #climatechangeisreal   #climatechangedenial ... | | VAGA PARA DESENVOLVEDOR BACK-END PYTHON Requisitos: • Mínimo de 1 ano de experiência profissional com... | A lot of great services free of charges if you are a student! | Oportunidade para programador python  na Gymglish de Florianopolis. "We document our code, unit test... | | https://micropython.org/store/ is open and accepting pre-orders!  | Venha trabalhar na Neoprospecta como pesquisador RHAE/CNPq. A Neoprospecta ainda possui uma vaga aberta... | Faking like a pro | "Since the virtual size of the cp process was now more than 17 GB and the server only had 10 GB of RAM... | now you can edit your requirements and remove south :)  | |

A python proxy in less than 100 lines of code

What is a tcp proxy?

It's a intermediary server intended to act in name of a client, and sometimes to do something useful with the data before it reaches the original target. Let's see a picture:


My idea was to produce a proxy using only the default python library, and to guide me during development I set the following:

  • Each new client connection to our proxy must generate a new connection to the original target.
  • Each data packet that reaches our proxy must be forwarded to the original target.
  • Each data packet received from the target must be sent back to the correct client
  • The proxy must accept multiple clients
  • Must be fast
  • Must have a low resource usage

The result:

The explanation

class Forward()

The Forward class is the one responsible for establishing a connection between the proxy and the remote server(original target).

class TheServer().main_loop()

The input_list stores all the avaiable sockets that will be managed by select.select, the first one to be appended is the server socket itself, each new connection to this socket will trigger the on_accept() method.

If the current socket inputready (returned by select) is not a new connection, it will be considered as incoming data(maybe from server, maybe from client), if the data lenght is 0 it's a close request, otherwise the packet should be forwarded to the correct endpoint.

class TheServer().on_accept()

This method creates a new connection with the original target (proxy -> remote server), and accepts the current client connection (client->proxy). Both sockets are stored in input_list, to be then handled by main_loop. A "channel" dictionary is used to associate the endpoints(client<=>server).

class TheServer().recv()

This method is used to process and forward the data to the original destination ( client <- proxy -> server ).

class TheServer().on_close()

Disables and removes the socket connection between the proxy and the original server and the one between the client and the proxy itself.

That's it.

by Ricardo Pascal on Aug 29, 2012

comments powered by Disqus