Improve multicast related defaults

* use multicast only for participant discovery if using a WiFi network
* default to using unicast for retransmits

Signed-off-by: Erik Boasson <eb@ilities.com>
This commit is contained in:
Erik Boasson 2019-07-16 16:50:02 +02:00 committed by eboasson
parent fda285e2f5
commit 4e80559763
9 changed files with 190 additions and 10 deletions

View file

@ -18,11 +18,18 @@
extern "C" {
#endif
enum ddsrt_iftype {
DDSRT_IFTYPE_UNKNOWN,
DDSRT_IFTYPE_WIRED,
DDSRT_IFTYPE_WIFI
};
struct ddsrt_ifaddrs {
struct ddsrt_ifaddrs *next;
char *name;
uint32_t index;
uint32_t flags;
enum ddsrt_iftype type;
struct sockaddr *addr;
struct sockaddr *netmask;
struct sockaddr *broadaddr;

View file

@ -95,6 +95,7 @@ copyaddr(
} else {
ifa->flags = getflags(netif, addr);
ifa->index = netif->num;
ifa->type = DDSRT_IFTYPE_UNKNOWN;
if (IP_IS_V4(addr)) {
static const size_t sz = sizeof(struct sockaddr_in);

View file

@ -21,8 +21,113 @@
extern const int *const os_supp_afs;
#if defined __linux
#include <stdio.h>
static enum ddsrt_iftype guess_iftype (const struct ifaddrs *sys_ifa)
{
FILE *fp;
char ifnam[IFNAMSIZ + 1]; /* not sure whether IFNAMSIZ includes a terminating 0, can't be bothered */
int c;
size_t np;
enum ddsrt_iftype type = DDSRT_IFTYPE_UNKNOWN;
if ((fp = fopen ("/proc/net/wireless", "r")) == NULL)
return type;
/* expected format:
:Inter-| sta-| Quality | Discarded packets | Missed | WE
: face | tus | link level noise | nwid crypt frag retry misc | beacon | 22
: wlan0: 0000 67. -43. -256 0 0 0 0 0 0
(where : denotes the start of the line)
SKIP_HEADER_1 skips up to and including the first newline; then SKIP_TO_EOL skips
up to and including the second newline, so the first line that gets interpreted is
the third.
*/
enum { SKIP_HEADER_1, SKIP_WHITE, READ_NAME, SKIP_TO_EOL } state = SKIP_HEADER_1;
np = 0;
while (type != DDSRT_IFTYPE_WIFI && (c = fgetc (fp)) != EOF) {
switch (state) {
case SKIP_HEADER_1:
if (c == '\n') {
state = SKIP_TO_EOL;
}
break;
case SKIP_WHITE:
if (c != ' ' && c != '\t') {
ifnam[np++] = (char) c;
state = READ_NAME;
}
break;
case READ_NAME:
if (c == ':') {
ifnam[np] = 0;
if (strcmp (ifnam, sys_ifa->ifa_name) == 0)
type = DDSRT_IFTYPE_WIFI;
state = SKIP_TO_EOL;
np = 0;
} else if (np < sizeof (ifnam) - 1) {
ifnam[np++] = (char) c;
}
break;
case SKIP_TO_EOL:
if (c == '\n') {
state = SKIP_WHITE;
}
break;
}
}
fclose (fp);
return type;
}
#elif defined __APPLE__ /* probably works for all BSDs */
#include <sys/ioctl.h>
#include <sys/sockio.h>
#include <net/if.h>
#include <net/if_media.h>
static enum ddsrt_iftype guess_iftype (const struct ifaddrs *sys_ifa)
{
int sock;
if ((sock = socket (sys_ifa->ifa_addr->sa_family, SOCK_DGRAM, 0)) == -1)
return DDSRT_IFTYPE_UNKNOWN;
struct ifmediareq ifmr;
enum ddsrt_iftype type;
memset (&ifmr, 0, sizeof (ifmr));
ddsrt_strlcpy (ifmr.ifm_name, sys_ifa->ifa_name, sizeof (ifmr.ifm_name));
if (ioctl (sock, SIOCGIFMEDIA, (caddr_t) &ifmr) < 0)
{
type = DDSRT_IFTYPE_UNKNOWN;
}
else
{
switch (IFM_TYPE (ifmr.ifm_active))
{
case IFM_ETHER:
case IFM_TOKEN:
case IFM_FDDI:
type = DDSRT_IFTYPE_WIRED;
break;
case IFM_IEEE80211:
type = DDSRT_IFTYPE_WIFI;
break;
default:
type = DDSRT_IFTYPE_UNKNOWN;
break;
}
}
close (sock);
return type;
}
#else
static enum ddsrt_iftype guess_iftype (const struct ifaddrs *sys_ifa)
{
return DDSRT_IFTYPE_UNKNOWN;
}
#endif
static dds_return_t
copyaddr(ddsrt_ifaddrs_t **ifap, const struct ifaddrs *sys_ifa)
copyaddr(ddsrt_ifaddrs_t **ifap, const struct ifaddrs *sys_ifa, enum ddsrt_iftype type)
{
dds_return_t err = DDS_RETCODE_OK;
ddsrt_ifaddrs_t *ifa;
@ -37,6 +142,7 @@ copyaddr(ddsrt_ifaddrs_t **ifap, const struct ifaddrs *sys_ifa)
err = DDS_RETCODE_OUT_OF_RESOURCES;
} else {
ifa->index = if_nametoindex(sys_ifa->ifa_name);
ifa->type = type;
ifa->flags = sys_ifa->ifa_flags;
if ((ifa->name = ddsrt_strdup(sys_ifa->ifa_name)) == NULL ||
(ifa->addr = ddsrt_memdup(sys_ifa->ifa_addr, sz)) == NULL ||
@ -109,7 +215,8 @@ ddsrt_getifaddrs(
}
if (use) {
err = copyaddr(&ifa_next, sys_ifa);
enum ddsrt_iftype type = guess_iftype (sys_ifa);
err = copyaddr(&ifa_next, sys_ifa, type);
if (err == DDS_RETCODE_OK) {
if (ifa == NULL) {
ifa = ifa_root = ifa_next;

View file

@ -152,6 +152,21 @@ getflags(const PIP_ADAPTER_ADDRESSES iface)
return flags;
}
static enum ddsrt_iftype
guess_iftype (const PIP_ADAPTER_ADDRESSES iface)
{
switch (iface->IfType) {
case IF_TYPE_IEEE80211:
return DDSRT_IFTYPE_WIFI;
case IF_TYPE_ETHERNET_CSMACD:
case IF_TYPE_IEEE1394:
case IF_TYPE_ISO88025_TOKENRING:
return DDSRT_IFTYPE_WIRED;
default:
return DDSRT_IFTYPE_UNKNOWN;
}
}
static int
copyaddr(
ddsrt_ifaddrs_t **ifap,
@ -175,6 +190,7 @@ copyaddr(
err = DDS_RETCODE_OUT_OF_RESOURCES;
} else {
ifa->flags = getflags(iface);
ifa->type = guess_iftype(iface);
ifa->addr = ddsrt_memdup(sa, sz);
(void)ddsrt_asprintf(&ifa->name, "%wS", iface->FriendlyName);
if (ifa->addr == NULL || ifa->name == NULL) {