ffnord / mesh-announce

Discussion at #mesh-announce:irc.hackint.org and (separately) at
https://matrix.to/#/!MjLIHcALOcENXZWQlH:irc.hackint.org/$1547640760901FmKaD:matrix.eclabs.de
13 stars 45 forks source link

Spawn one ThreadingUDPServer per Interface #23

Closed mweinelt closed 5 years ago

mweinelt commented 7 years ago

Spawn one ThreadingUDPServer per Interface and bind them to their device scope.

Looks like this:

root     18782  0.4  1.2 553888 12788 ?        Ssl  00:06   0:13 python3 /opt/mesh-announce/respondd.py -i ffda-br -i ffda-tp -i ffda-vpn-1280 -i ffda-vpn-1312 -b ffda-bat
root     20172  0.0  1.0 256244 11044 ?        Ssl  00:44   0:00 python3 /opt/mesh-announce/respondd.py -i ffdef-br -i ffdef-tp -i ffdef-vpn-1312 -b ffdef-bat
udp    UNCONN     0      0      ff02::2:1001%ffdef-vpn-1312:1001                 :::*      users:(("python3",pid=20172,fd=5))
udp    UNCONN     0      0      ff02::2:1001%ffdef-tp:1001                 :::*      users:(("python3",pid=20172,fd=4))
udp    UNCONN     0      0      ff02::2:1001%ffdef-br:1001                 :::*      users:(("python3",pid=20172,fd=3))
udp    UNCONN     0      0      ff02::2:1001%ffda-vpn-1312:1001                 :::*      users:(("python3",pid=18782,fd=6))
udp    UNCONN     0      0      ff02::2:1001%ffda-vpn-1280:1001                 :::*      users:(("python3",pid=18782,fd=5))
udp    UNCONN     0      0      ff02::2:1001%ffda-tp:1001                 :::*      users:(("python3",pid=18782,fd=4))
udp    UNCONN     0      0      ff02::2:1001%ffda-br:1001                 :::*      users:(("python3",pid=18782,fd=3))
jplitza commented 7 years ago

Why do you only listen to the multicast address? That breaks unicast requests, doesn't it? Or is it impossible to bind to a device if you don't specify an address?

mweinelt commented 7 years ago

When I bound the sockets to "" I was running into the "Address already in use" error.

It's certainly possible to detect the link local address on the interface and spawn yet another socketserver for that. Would link-local be sufficient, or is ULA/Global required?

mweinelt commented 7 years ago
# ss -lpn | grep 1001 | column -t
udp  UNCONN  0  0  fe80::d8ff:61ff:fe01:103%ffda-vpn-1312:1001   :::*  users:(("python3",pid=29446,fd=10))
udp  UNCONN  0  0  ff02::2:1001%ffda-vpn-1312:1001               :::*  users:(("python3",pid=29446,fd=9))
udp  UNCONN  0  0  fe80::d8ff:61ff:fe00:103%ffda-vpn-1280:1001   :::*  users:(("python3",pid=29446,fd=8))
udp  UNCONN  0  0  ff02::2:1001%ffda-vpn-1280:1001               :::*  users:(("python3",pid=29446,fd=7))
udp  UNCONN  0  0  fe80::d8ff:61ff:fe00:105%ffda-tp:1001         :::*  users:(("python3",pid=29446,fd=6))
udp  UNCONN  0  0  ff02::2:1001%ffda-tp:1001                     :::*  users:(("python3",pid=29446,fd=5))
udp  UNCONN  0  0  fe80::d8ff:61ff:fe00:104%ffda-br:1001         :::*  users:(("python3",pid=29446,fd=4))
udp  UNCONN  0  0  ff02::2:1001%ffda-br:1001                     :::*  users:(("python3",pid=29446,fd=3))
udp  UNCONN  0  0  fe80::d8ff:60ff:fe00:103%ffdef-vpn-1312:1001  :::*  users:(("python3",pid=29420,fd=8))
udp  UNCONN  0  0  ff02::2:1001%ffdef-vpn-1312:1001              :::*  users:(("python3",pid=29420,fd=7))
udp  UNCONN  0  0  fe80::d8ff:60ff:fe00:105%ffdef-tp:1001        :::*  users:(("python3",pid=29420,fd=6))
udp  UNCONN  0  0  ff02::2:1001%ffdef-tp:1001                    :::*  users:(("python3",pid=29420,fd=5))
udp  UNCONN  0  0  fe80::d8ff:60ff:fe00:104%ffdef-br:1001        :::*  users:(("python3",pid=29420,fd=4))
udp  UNCONN  0  0  ff02::2:1001%ffdef-br:1001                    :::*  users:(("python3",pid=29420,fd=3))
mweinelt commented 7 years ago

The changes should be sufficient to address the issue. Do you have more feedback?

jplitza commented 7 years ago

I'm not entirely happy with having to bind to every single address, and don't know if there are use cases of querying a non-link-local address, but I'd be fine with merging.

mweinelt commented 7 years ago

Listening on link-local only is supposed to be a protection against attacks from outside the mesh. via https://github.com/freifunk-gluon/packages/issues/142

With the BSD Socket API there is little choice between binding anything or just a single address, so I'm not sure where else this would go.

neocturne commented 7 years ago

Shouldn't a single socket bound to any be sufficient? Just join all the interfaces' multicast groups after binding. Filtering for link-local addresses can be done after receiving a packet just fine if desired (it's what Gluon's respondd does).

jplitza commented 7 years ago

@NeoRaider That's what we do now, but that way, you cannot serve different data on different interfaces.

mweinelt commented 7 years ago

@jplitza We talked about this on IRC and it might be possible to bind to device with any, join the multicast group and filter in the process for link-local sources.

Honestly, I don't like that approach much, binding should be preferred to filtering, even if it uses twice the amount of sockets. What's the cost here?

Another issue is, that the bind to e.g. the vpn interface breaks as soon as fastd is restarted. uradvd solves this by monitoring the netlink events and (I guess) rebinding.

rubo77 commented 6 years ago

Is this doing any harm, if you only use one interface in your domain?

It seems like the version on https://github.com/freifunk-darmstadt/mesh-announce works fine so far.

Can this be merged?

mweinelt commented 6 years ago

Known Issue: If an interface which mesh-announce was bound to vanishes and reappears mesh-announce would need to rebind the socket or else it wouldn't listen on that interface anymore.

mweinelt commented 6 years ago

With the latest patch mesh-announce will check every 15 seconds all configured interfaces for changed interface ids, which would indicate that the interface vanished and reappeared.

In such a case mesh-announce will now stop the threads listening on the vanished interface and create new threads when the interface reappears.

mweinelt commented 6 years ago

Before we continue with this we should discuss, whether one instance should serve multiple domains (https://github.com/ffnord/mesh-announce/pull/28) or if one instance should be started per domain.

rubo77 commented 6 years ago

Is this the solution you realized in https://github.com/freifunk-darmstadt/mesh-announce ?

could this be rebased then?

mweinelt commented 5 years ago

This is that solution, but it breaks with site-local scoped multicast groups, which are required since https://github.com/freifunk-gluon/gluon/commit/59a44274cb00e88e3420b4c9c4303ca70f16b211.