Steven Siloti
2016-02-15 19:55:25 UTC
Arvid,
I did some research and found the handy socket option IPV6_PKTINFO which
allows recvmsg()/sendmsg() to get/set the interface index and
destination/source address of the datagram. This is just what we need to
support multi-homed clients while only using a single UDP socket
listening on IN6ADDR_ANY. Of course it's not supported by asio so we'll
have to call the native send/recv functions directly, but this shouldn't
be too much work.
For the DHT my plan is to iterator over the list of local addresses at
startup and construct dht::node instances with the following rules:
A single IPv4 node is created for each interface that has at least one
non-loopback IPv4 address associated with it.
A node is created for each IPv6 address with global scope. We may want
to add some logic to avoid creating nodes for temporary addresses if we can.
Multi-home with IPv4 on a single interface will not not be supported
because NAT would make it a nightmare. Each IPv4 interface will get its
own external_ip instance while IPv6 will use the local address directly.
While NAT with IPv6 technically exists (NAT66), I don't think it's
widely used enough to warrant supporting it.
Incoming DHT messages would be routed to the appropriate node based on
the receiving interface/address. All outgoing messages will pass the
node's interface/address to sendmsg(). This is important both to ensure
that responses use the same interface/address the request was
sent/received on and to detect when an interface/address becomes
invalid. If a sendmsg() call returns one of the errors defined in RFC
3542 Section 6.6 then the corresponding DHT node(s) are destroyed.
Detecting when new local addresses become available is more challenging.
I don't know of any standard way to get notifications about network
changes so we'll have to write separate implementations for each
platform. The monitoring will likely have to be done in a separate thread.
UTP sockets would be bound to the interface/address the SYN or STATE
packet is received on. Outgoing SYN packets would not specify an
interface/address to use (i.e. let the OS decide) while all others would
specify the bound interface/address.
Similarly, UDP tracker connect requests would not specify an
interface/address to use while announce/scrape requests would specify
the interface/address the connect response was received on.
Does this sound reasonable?
I did some research and found the handy socket option IPV6_PKTINFO which
allows recvmsg()/sendmsg() to get/set the interface index and
destination/source address of the datagram. This is just what we need to
support multi-homed clients while only using a single UDP socket
listening on IN6ADDR_ANY. Of course it's not supported by asio so we'll
have to call the native send/recv functions directly, but this shouldn't
be too much work.
For the DHT my plan is to iterator over the list of local addresses at
startup and construct dht::node instances with the following rules:
A single IPv4 node is created for each interface that has at least one
non-loopback IPv4 address associated with it.
A node is created for each IPv6 address with global scope. We may want
to add some logic to avoid creating nodes for temporary addresses if we can.
Multi-home with IPv4 on a single interface will not not be supported
because NAT would make it a nightmare. Each IPv4 interface will get its
own external_ip instance while IPv6 will use the local address directly.
While NAT with IPv6 technically exists (NAT66), I don't think it's
widely used enough to warrant supporting it.
Incoming DHT messages would be routed to the appropriate node based on
the receiving interface/address. All outgoing messages will pass the
node's interface/address to sendmsg(). This is important both to ensure
that responses use the same interface/address the request was
sent/received on and to detect when an interface/address becomes
invalid. If a sendmsg() call returns one of the errors defined in RFC
3542 Section 6.6 then the corresponding DHT node(s) are destroyed.
Detecting when new local addresses become available is more challenging.
I don't know of any standard way to get notifications about network
changes so we'll have to write separate implementations for each
platform. The monitoring will likely have to be done in a separate thread.
UTP sockets would be bound to the interface/address the SYN or STATE
packet is received on. Outgoing SYN packets would not specify an
interface/address to use (i.e. let the OS decide) while all others would
specify the bound interface/address.
Similarly, UDP tracker connect requests would not specify an
interface/address to use while announce/scrape requests would specify
the interface/address the connect response was received on.
Does this sound reasonable?