ansible-collection-tp-link-easy-smart-switch icon indicating copy to clipboard operation
ansible-collection-tp-link-easy-smart-switch copied to clipboard

Bind receiving socket to specific interface

Open cmair opened this issue 3 years ago • 10 comments

This makes sure the receiving socket only gets one answer from the switch, even if multiple interfaces are connected to the same network.

cmair avatar Jun 18 '21 17:06 cmair

My laptop has two network interfaces, both are connected to the same switch. This might be unusual, but I use it to play with different vlans without loosing internet connectivity when I screw up things on one port. I'm now trying to manage this switch (and later others as well) without the web interface.

When I first tried your Ansible collection (and also the original smrt code it is based on) I figured that neither worked at all. The switch answered as expected but the software somehow didn't get the correct answers. After hours of debugging I found that the the debug logs showed the exact same response beeing parsed twice, but for different requests. I also found that wireshark captured two answer packets per request, when listening on the 'any' interface. This seems plausible as the switch answers to the broadcast address, which should obviously go to all ports. Having one machine connected to multiple ports at the same time triggers the issue.

My first quick fix was to call rs.recvfrom() twice, discarding the first result. As this would break with just one or more than two connections to the switch, I tried to find a way to get around this issue.

Another possibility could be to just read all remaining data from the socket before sending a new request or keep track of expected and received/processed answers to detect duplicates, but this seemed to be a simple and elegant solution.

cmair avatar Jun 18 '21 18:06 cmair

I now understand! And I like the solution :-)

Can you also bind the sending socket to that interface? I think that would make it more consistent with the intent of "use the same interface to send/receive data despite the host network configuration".

rgl avatar Jun 18 '21 18:06 rgl

I think the sending interface is already bound to the correct interface, as bind is called with the corresponding IP.

I'm not sure if I already understood the overall picture, but maybe it would make even more sense to specify the interface in the inventory.yml and defer the IP from there, as the specified IP is just used to bind to the correct interface? That would make sure the correct interface is used, as someone could also assign the same IP to different interfaces.

cmair avatar Jun 18 '21 18:06 cmair

Ah indeed it is. Scrap what I've said :-)

Since I assign multiple IPs to the same interface, I'd rather not use the interface to infer its IP address.

How about if we binded the receiving socket to the IP instead of the broadcast address? I'm not really sure whether that socket would receive broadcast packets from other interfaces thou... but, if that works, the code would be even simpler.

rgl avatar Jun 18 '21 19:06 rgl

I tried binding to the IP, but could not make it work.

Multiple IPs on the interface should'nt be a problem. The IP just shows up as the sender address but as far as I know, the switch does not care. So, just picking the first IPv4 should be fine, as long as the interface is correct. Others are doing so as well.

I'd be more worried about breaking existing configurations. Thats why I didn't look into that yet. Also, because I just started with Ansible today and I still have no clue how things work :see_no_evil:

cmair avatar Jun 18 '21 19:06 cmair

What does seem to work:

binding the sending socket to 255.255.255.255:28809 and to the interface. Then, a single socket can be used to send/receive stuff. No IP needed at all.

cmair avatar Jun 18 '21 19:06 cmair

New proposal: I tried to change the configuration to use the interface instead of MAC and IP. My tests where successful so far. I didn't touch the take_ownership files yet as I can't test them right now (will need to find some switch downtime).

cmair avatar Jun 18 '21 23:06 cmair

Its looking good :-)

What switch model are you testing this on?

rgl avatar Jun 19 '21 07:06 rgl

I own two TL-SG108.

cmair avatar Jun 20 '21 09:06 cmair

I also changed switch_take_ownership_client.py to the changed constructor of Network. I think this should work now, but I still didn't test yet.

I'll now change the PR to ready for review, as I think all necessary changes are in now.

cmair avatar Jun 20 '21 10:06 cmair