From e8b40191fe6bc22ef47561dcaa8124011b922a0d Mon Sep 17 00:00:00 2001 From: Claudiu Boriga Date: Wed, 14 Feb 2018 14:07:27 +0100 Subject: [PATCH] Enable round robin for default interface --- README.md | 4 ++++ daemon/media_socket.c | 21 ++++++++++++++++++--- daemon/media_socket.h | 1 + 3 files changed, 23 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index e36eec43b..0d1e209e1 100644 --- a/README.md +++ b/README.md @@ -674,6 +674,10 @@ no alternatives would be used. When IPv6 is needed as a primary address, either `pub:3` might be selected. If at any given time not enough ports are available on any interface, it will not be selected by the round-robin algorithm. +It is possible to use the round-robin algorithm even if the `direction` is not given. If the first +given interface has the `BASE:SUFFIX` format then the round-robin algorithm is used and will select +interfaces with the same `BASE` name. + If you're not using the NG protocol but rather the legacy UDP protocol used by the *rtpproxy* module, the interfaces must be named `internal` and `external` corresponding to the `i` and `e` flags if you wish to use network bridging in this mode. diff --git a/daemon/media_socket.c b/daemon/media_socket.c index 60b5042bf..db2feee3a 100644 --- a/daemon/media_socket.c +++ b/daemon/media_socket.c @@ -378,6 +378,7 @@ done: // 'fam' may only be NULL if 'name' is also NULL struct logical_intf *get_logical_interface(const str *name, sockfamily_t *fam, int num_ports) { struct logical_intf *log = NULL; + int rr_use_default_intf = 0; __C_DBG("Get logical interface for %d ports", num_ports); @@ -397,14 +398,26 @@ struct logical_intf *get_logical_interface(const str *name, sockfamily_t *fam, i got_some: ; } - - return q->head ? q->head->data : NULL; + if (!q->head) + return NULL; + + log = q->head->data; + // if interface is in the form foo:bar then use round-robin + if (!fam || log->name.len == log->name_base.len) + return log; + else + rr_use_default_intf = 1; } // check if round-robin is desired struct logical_intf key; - key.name = *name; + + if (rr_use_default_intf) + key.name = log->name_base; + else + key.name = *name; key.preferred_family = fam; + struct intf_rr *rr = g_hash_table_lookup(__logical_intf_name_family_rr_hash, &key); if (!rr) return __get_logical_interface(name, fam); @@ -522,7 +535,9 @@ static void __interface_append(struct intf_config *ifa, sockfamily_t *fam) { if (!lif) { lif = g_slice_alloc0(sizeof(*lif)); + g_queue_init(&lif->list); lif->name = ifa->name; + lif->name_base = ifa->name_base; lif->preferred_family = fam; lif->addr_hash = g_hash_table_new(__addr_type_hash, __addr_type_eq); lif->rr_specs = g_hash_table_new(str_hash, str_equal); diff --git a/daemon/media_socket.h b/daemon/media_socket.h index 173f8e9f6..521ec117b 100644 --- a/daemon/media_socket.h +++ b/daemon/media_socket.h @@ -23,6 +23,7 @@ struct logical_intf { GQueue list; /* struct local_intf */ GHashTable *addr_hash; // addr + type -> struct local_intf XXX obsolete? GHashTable *rr_specs; + str name_base; // if name is "foo:bar", this is "foo" }; struct port_pool { BIT_ARRAY_DECLARE(ports_used, 0x10000);