0

I'm trying to bind a client socket connection explicitly to my wlan but I just get a timeout. curl is working just fine so there should not be any firewall or routing issue.

import socket

def isOpen(ip, port, proto=socket.SOCK_STREAM):
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.bind(('192.168.2.15', 0))
    print(s.getsockname())
    s.settimeout(30)

    try:
        s.connect((ip, int(port)))
        return True

    except Exception as e:
        print(e)
        return False

    finally:
        s.close()

def test_wlan(): assert isOpen('1.1.1.1', 443)
poetry run pytest --no-header -s
=============== test session starts ===============
collected 1 item

tests/test_network.py ('192.168.2.15', 36031)
timed out
F
curl -v -4 --interface wlan https://1.1.1.1
...
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
* old SSL session ID is stale, removing
< HTTP/2 200
...

Any idea what I need to do to make it work?

mr.moe
  • 75
  • 4
  • https://stackoverflow.com/questions/8437726/can-python-select-what-network-adapter-when-opening-a-socket – Mat Apr 16 '23 at 16:08
  • `s.bind(('192.168.2.15', 0))` isn't 'binding to the WLAN'. It is binding, probably redundantly, to a local address. – user207421 Apr 17 '23 at 00:42
  • You are right, '192.168.2.15' is a local device address so it is not bound to a device but to a local interface. But as noted in my answer Linux and Windows are working differently and thus this does not work under Linux. At least in my case. – mr.moe Apr 24 '23 at 20:06

1 Answers1

0

Thanks to @mat who pointed me in the right direction.

On Linux it seems client connection socket.bind works only on a local network basis since I could connect to my gateway without problem but not to the outside world. Routing seems to be ignored despite the correct interface was used (validated with wireshark).

Using s.setsockopt(socket.SOL_SOCKET, socket.SO_BINDTODEVICE, str("wlan" + '\0').encode('utf-8')) seems to set source and routing the correct way.

Here the working code.

import socket

def isOpen(ip, port, proto=socket.SOCK_STREAM):
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.setsockopt(socket.SOL_SOCKET, socket.SO_BINDTODEVICE, str("wlan" + '\0').encode('utf-8'))
    s.settimeout(30)

    try:
        s.connect((ip, int(port)))
        return True

    except Exception as e:
        print(e)
        return False

    finally:
        s.close()

def test_wlan(): assert isOpen('1.1.1.1', 443)

best regards.

mr.moe
  • 75
  • 4