Welcome, guest | Sign In | My Account | Store | Cart
NOTE: Recipes have moved! Please visit GitHub.com/activestate/code for the current versions.

The title of this recipe contains the two words that gave the inspiration for the writing of what appears below. Port forwarding -- think about it.

Python, 45 lines
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
import socket
import sys
import thread

def main(setup, error):
    sys.stderr = file(error, 'a')
    for settings in parse(setup):
        thread.start_new_thread(server, settings)
    lock = thread.allocate_lock()
    lock.acquire()
    lock.acquire()

def parse(setup):
    settings = list()
    for line in file(setup):
        parts = line.split()
        settings.append((parts[0], int(parts[1]), int(parts[2])))
    return settings

def server(*settings):
    try:
        dock_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        dock_socket.bind(('', settings[2]))
        dock_socket.listen(5)
        while True:
            client_socket = dock_socket.accept()[0]
            server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            server_socket.connect((settings[0], settings[1]))
            thread.start_new_thread(forward, (client_socket, server_socket))
            thread.start_new_thread(forward, (server_socket, client_socket))
    finally:
        thread.start_new_thread(server, settings)

def forward(source, destination):
    string = ' '
    while string:
        string = source.recv(1024)
        if string:
            destination.sendall(string)
        else:
            source.shutdown(socket.SHUT_RD)
            destination.shutdown(socket.SHUT_WR)

if __name__ == '__main__':
    main('proxy.ini', 'error.log')

What follows is an example of a proxy.ini file. In this case, proxy sets up 11 servers designed to accept incoming connections and automatically create a connection with the server that the client is trying to connect to. An expansion of this concept would probably allow the client to specify what host and port should be connected to instead of having that automatically decided by the configuration file.

tucker.dorms.bju.edu 80 9000 Non-standard name for a dorm site.
pangl110.dorms.bju.edu 80 9001 The parser ignores this part.
rmelc208.dorms.bju.edu 80 9002 Here is Randy.
mangl442.dorms.bju.edu 80 9003 Brother ...
aangl403.dorms.bju.edu 80 9004 and sister.
ahamm894.dorms.bju.edu 80 9005 The format of this file is as follows:
swill190.dorms.bju.edu 80 9006 [server_name](space)[server_port](space)[proxy_port]
kstil371.dorms.bju.edu 80 9007 An optional space and more data may come after [proxy_port].
zcoch215.dorms.bju.edu 80 9008 Here is Zach.
eskog593.dorms.bju.edu 80 9009 The proxy code is slightly more complicated. :-)
pbeni427-web.dorms.bju.edu 80 9010 BTW, the proxy keeps errors in the error.log file.

1 comment

RaphaĆ«l Jolivet 6 years, 6 months ago  # | flag

Hi, nice work. However, your INI file is not formatted well in the discussion below your code.