0

I'm writing a proxy with tcp connection that listens to multiple ports from a client and forward it to a server.

The problem is that the software hangs on the sock.accept.

Maybe I'm doing a messy logic here, but I need a client that connects to a PC, and that PC connects to another device. So I wrote that small proxy, and I get INVALID ARGUMENT ERROR in socket.accept()

import select
import socket
import threading

class Proxy(object):

    def __init__(self, ip, ports):
        self._ip = ip
        self._sockets = []
        self._proxy = {}

        for port in ports:
            self._proxy[port] = self.add_socket(port)

    def add_socket(self, port=None):
        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        if port:
            # sock.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
            sock.bind(('0.0.0.0',port))
        self._sockets.append(sock)
        return sock

    def get_client(self, src_sock, src_addr):
        src_ip, src_port = src_addr
        _, dst_port = src_sock.getsockname()

        if src_ip == self._ip:
            # got packet from device
            dst_addr = ("10.8.8.210", dst_port)
        else:
            # got packet from client
            dst_addr = self._ip, dst_port
            print(">", src_port, dst_addr)
        dst_sock = self._proxy[src_port]
        return dst_sock, dst_addr

    def run(self):
        while True:
            read_list, _, _ = select.select(self._sockets, [], [])

            if read_list:
                for sock in read_list:
                    try:

                        conn, addr = sock.accept()
                        data  = conn.recvfrom(16*2024)
                        # print("got data from {} {}".format(sock, addr))
                        dst_sock, dst_addr = self.get_client(sock, addr)
                       # print("forwarding data from {} to {}".format(addr, dst_addr, len(data)))
                        dst_sock.sendto(data, dst_addr)
                    except:
                        raise # pass # print("no recipient for data")
        for s in self._sockets:
             s.close()

ports = [30001,30002,30003, 30070, 30071,30072,30075]
p = Proxy("192.168.2.10", ports)                    
p.run()
5
  • 1
    You can only accept from a socket in listening state. And sendto and recvfrom are normally used for UDP (type=socket.SOCK_DGRAM) sockets. Before building a multi port proxy, just try to send one packet from one side to the other one... Commented Dec 21, 2018 at 15:10
  • Thanks so much I got it :), but I have another issues with ports that are not defined Commented Dec 21, 2018 at 15:11
  • I voted up for you, hope I find a solution for me Commented Dec 21, 2018 at 15:11
  • Your question is unclear. You do not say if you want UDP or TCP, and you do not explain the logic behind your code. I am sorry because I have tried to understand what you are trying to setup, but I could not. Commented Dec 21, 2018 at 15:17
  • I want TCP sorry for miss understanding Commented Dec 21, 2018 at 15:18

1 Answer 1

1

You have to call listen on the socket before accept:

adding sock.listen(1) to add_socket after bind

 sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
 sock.bind(('0.0.0.0', port))
 sock.listen(1)
 self._sockets.append(sock)

then allows you to call accept without the error. You may want to set the listen backlog to a greater number.

Sign up to request clarification or add additional context in comments.

4 Comments

With that code, I need to bind to EVERY port that my src client is using.. how can I fix that ?
Keyerror 51083 not found. line 49 dst_sock = self._proxy[src_port]
I hope you tell me the solution for this problem
Whenever I add the required port, I needed to add 10000 ports to make it running, and the ports are changing

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.