IndySockets / Indy

Indy - Internet Direct
https://www.indyproject.org
460 stars 155 forks source link

TIdIPMCastServer is missing a required call to setSockOpt for IPv6 #203

Open DelphiWorlds opened 6 years ago

DelphiWorlds commented 6 years ago

Please refer to this SO post:

https://stackoverflow.com/questions/31574247/gcdasyncudpsocket-cannot-get-udp-multicast-over-ipv6-to-work

As per the post, in order for multicast sending to work with IPv6 (at least on iOS, and probably for macOS), a call must be made to setSockOpt() for the IPV6_MULTICAST_IF option, otherwise a send causes a "No route to host" error. This call requires passing the desired interface index, so the change would require discovery of the interface index associated with the address.

I've managed to work around the issue by "hacking" the TIdStackVCLPosix.GetLocalAddressList() method in the IdStackVCLPosix unit to associate the index (obtained by calling if_nametoindex(LAddrInfo^.ifa_name)) with the IP address into a dictionary of IP addresses/indexes, and calling SetSockOpt() on the binding by looking up the index for the address. Anyone who is interested can contact me for the workaround

rlebeau commented 6 years ago

Rather than making a separate dictionary of addresses/indexes, I would probably have instead added a new InterfaceIndex member to TIdStackLocalAddress, and then you could lookup the index by finding the IP using TIdStackLocalAddressList.IndexOfIP().

rlebeau commented 4 years ago

InterfaceName and InterfaceIndex properties were recently added to the TIdStackLocalAddress class.

InterfaceName has been implemented in all of the TIdStack-derived classes, except for TIdStackDotNet (which will be dropped anyway in Indy 11).

InterfaceIndex is currently implemented only in TIdStackWindows. Code has been added to TIdStackLibc, TIdStackLinux, TIdStackUnix, and TIdStackVCLPosix, but is currently wrapped with {$IFDEF HAS_if_nametoindex}, which is not defined yet as I don't know which platforms it applies to, if it is available on all platforms that getifaddrs() is available on, or even if FreePascal or Delphi RTL units define it or if it needs to be defined manually.