0

I have a Tcp socket server class that is to run in CPython and MicroPython. It does, no problem there. Only I would like to extend its functionality with an IP filter. From an earlier version that still was a http server, I have a regular expression pattern to match the requesting IP-address. But where can I step in and inspect the remote address to accept or refuse the connection?

Note: the reader object in newConnection has no attribute '_transport' in microPython.

def log(*args, prio = 0):
    if prio >= 0:
        print(*args)



class TcpServer(SocketBase):
    
    def __init__(self, port=8888, requestHandler = None, ipMask = r"192.168.(\d+).(\d+)|localhost|127.0.0.1"):
        '''
        :param requestHandler: callable with parameters request, response
        '''
        super().__init__(host="0.0.0.0", port = port)
        self.requestHandler = requestHandler
        self.ipRange        = re.compile(ipMask)
        self.timeout        = TimeOut()

    
    async def start(self):
        self.server = await asyncio.start_server(self.newConnection, host=self.host, port=self.port)
        log("server started at ", (self.host, self.port), prio=1)
        
        while True:
            await asyncio.sleep(10)

    
    
    async def newConnection(self, reader, writer):
        log("Connected")

        self.connection = (reader, writer)
        self.timeout.extend(30)
        while not self.timeout.expired():
            if not await self.pollOpenConnection(reader, writer):
                # not data, then doze a while:
                await asyncio.sleep(1./25.)
                
        writer.close()
        log("Disconnected")
        
        
2
  • AFAIK it is not possible in a TCP server program to refuse a connection from banned IP addresses. The server could accept the connection, check the remote address and immediately reset the connection. It is not the same thing as refusing an incoming connection, but might be good enough. Commented Apr 24 at 19:29
  • The client will not know that the connection has been closed immediately, so it gets a 'connection reset'-error (localhost) or a timeout (network). It is good enough indeed for a private service. Commented Apr 25 at 15:12

1 Answer 1

2

In your connection handler you can find it from the stream writer:

remote_addr = writer.get_extra_info('peername')[0]
Sign up to request clarification or add additional context in comments.

2 Comments

Spot on, thank you. I wonder how you figured that one out, all resources I found said to interrogate the reader, so I didn't even try the writer...
I took the example from my own MicroPython web framework: github.com/DavesCodeMusings/thimble Where I first learned it, I don't remember. Possibly some helpful person on the MicroPython Github Discussion board: github.com/orgs/micropython/discussions

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.