Browse Source

MT#62053 add interfaces-config= option

Change-Id: I32c67bd6834f51c835c08af67a7d84f3216486db
pull/1910/head
Richard Fuchs 10 months ago
parent
commit
672bf5305c
5 changed files with 190 additions and 12 deletions
  1. +67
    -9
      daemon/main.c
  2. +91
    -0
      docs/rtpengine.md
  3. +9
    -2
      etc/rtpengine.conf
  4. +1
    -0
      lib/auxlib.h
  5. +22
    -1
      t/test3.conf

+ 67
- 9
daemon/main.c View File

@ -123,6 +123,11 @@ struct rtpengine_config rtpe_config = {
.kernel_player_media = 128,
};
struct interface_config_callback_arg {
struct ifaddrs *ifas;
intf_config_q *icq;
};
static void sighandler(gpointer x) {
sigset_t ss;
int ret;
@ -346,6 +351,33 @@ static bool if_add(intf_config_q *q, struct ifaddrs *ifas, const str *name,
return true;
}
static void add_if_from_config(const char *name, charp_ht ht, struct interface_config_callback_arg *icca) {
char *alias = t_hash_table_lookup(ht, "alias");
if (alias) {
if_add_alias(&rtpe_config.interfaces, STR_PTR(name), alias);
return;
}
char *address = t_hash_table_lookup(ht, "address");
if (!address)
die("No 'address' given in interface config section '%s'", name);
char *adv_addr = t_hash_table_lookup(ht, "advertised");
if (!adv_addr)
adv_addr = t_hash_table_lookup(ht, "advertised address");
if (!adv_addr)
adv_addr = t_hash_table_lookup(ht, "advertised-address");
if (!adv_addr)
adv_addr = t_hash_table_lookup(ht, "advertised_address");
const char *orig_name = name;
char *n2 = t_hash_table_lookup(ht, "name");
if (n2)
name = n2;
if (!if_add(icca->icq, icca->ifas, STR_PTR(name), address, adv_addr, 0, 0))
die("Failed to parse interface information '%s' from config file", orig_name);
}
static bool if_addr_parse(intf_config_q *q, char *s, struct ifaddrs *ifas) {
str name;
char *c;
@ -552,6 +584,7 @@ static void options(int *argc, char ***argv, charp_ht templates) {
#endif
g_autoptr(char) redis_format = NULL;
g_autoptr(char) templates_section = NULL;
g_autoptr(char) interfaces_config = NULL;
GOptionEntry e[] = {
{ "table", 't', 0, G_OPTION_ARG_INT, &rtpe_config.kernel_table, "Kernel table to use", "INT" },
@ -566,6 +599,7 @@ static void options(int *argc, char ***argv, charp_ht templates) {
{ "nftables-status",0, 0, G_OPTION_ARG_NONE, &nftables_status, "Check nftables rules, print result and exit", NULL },
#endif
{ "interface", 'i', 0, G_OPTION_ARG_STRING_ARRAY,&if_a, "Local interface for RTP", "[NAME/]IP[!IP]"},
{ "interfaces-config",0,0, G_OPTION_ARG_STRING, &interfaces_config, "Config section prefix for interfaces", "STR"},
{ "templates", 0, 0, G_OPTION_ARG_STRING, &templates_section, "Config section to read signalling templates from ", "STR"},
{ "save-interface-ports",'S', 0, G_OPTION_ARG_NONE, &rtpe_config.save_interface_ports, "Bind ports only on first available interface of desired family", NULL },
{ "subscribe-keyspace", 'k', 0, G_OPTION_ARG_STRING_ARRAY,&ks_a, "Subscription keyspace list", "INT INT ..."},
@ -738,6 +772,17 @@ static void options(int *argc, char ***argv, charp_ht templates) {
{ NULL, }
};
struct ifaddrs *ifas;
if (getifaddrs(&ifas)) {
ifas = NULL;
ilog(LOG_WARN, "Failed to retrieve list of network interfaces: %s", strerror(errno));
}
// Store interfaces in separate queue first, instead of directly populating
// rtpe_config.interface. This is to ensure predictable ordering, and also because
// global port-min/max may not be set yet.
intf_config_q icq = TYPED_GQUEUE_INIT;
config_load_ext(argc, argv, e, " - next-generation media proxy",
"/etc/rtpengine/rtpengine.conf", "rtpengine", &rtpe_config.common,
(struct rtpenging_config_callback []) {
@ -749,6 +794,17 @@ static void options(int *argc, char ***argv, charp_ht templates) {
.callback = add_c_str_to_ht,
},
},
{
.type = RCC_FILE_GROUPS,
.arg.icca = &(struct interface_config_callback_arg) {
.ifas = ifas,
.icq = &icq,
},
.file_groups = {
.prefix = &interfaces_config,
.callback = add_if_from_config,
},
},
{ 0 },
});
@ -816,18 +872,20 @@ static void options(int *argc, char ***argv, charp_ht templates) {
}
#endif
if (!if_a)
die("Missing option --interface");
struct ifaddrs *ifas;
if (getifaddrs(&ifas)) {
ifas = NULL;
ilog(LOG_WARN, "Failed to retrieve list of network interfaces: %s", strerror(errno));
}
for (iter = if_a; *iter; iter++) {
for (iter = if_a; iter && *iter; iter++) {
if (!if_addr_parse(&rtpe_config.interfaces, *iter, ifas))
die("Invalid interface specification: '%s'", *iter);
}
while (icq.length) {
__auto_type ic = t_queue_pop_head(&icq);
// fill in port ranges from global if needed
if (!ic->port_min)
ic->port_min = rtpe_config.port_min;
if (!ic->port_max)
ic->port_max = rtpe_config.port_max;
t_queue_push_tail(&rtpe_config.interfaces, ic);
}
if (ifas)
freeifaddrs(ifas);


+ 91
- 0
docs/rtpengine.md View File

@ -1485,6 +1485,13 @@ call to inject-DTMF won't be sent to __\-\-dtmf-log-dest=__ or __\-\-listen-tcp-
## INTERFACES
This section describes the legacy syntax for configuring interfaces, which can
equally be used from the configuration file as from the command line. The new
syntax to configure interfaces, which can only be used from the config file, is
described at the end of this section, which now is the preferred method.
### Legacy Syntax
The command-line options __-i__ or __\-\-interface__, or equivalently the
__interface__ config file option, specify local network interfaces for RTP.
At least one must be given, but multiple can be specified.
@ -1653,6 +1660,90 @@ 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.
### New Configuration-File Based Syntax
When a configuration file is in use, instead of having to list multiple
interfaces in one long line in the config file, it's now possible to use config
file sections (or "groups") for a more convenient way to configure and manage
multiple interfaces. To use it, instead of setting the __interface__ option to
any value, the option __interfaces-config__ must be set to a non-empty string.
This string is a prefix, which *rtpengine* uses to look in the config file for
config sections (groups) that contain interface configurations.
For example, if the setting `interfaces-config = interface` is present in the
config file, *rtpengine* would consider config file sections starting with the
string `interface` and followed by a dash to be interface configurations. The
remainder of the name of the config section (the part after the dash) becomes
the default name of the interface. The name for the interface can then be
overridden within the config section (see below).
_NOTE: The names of config sections must be unique within the config file, and
each interface config can list only a single address. To add multiple addresses
to the same logical interface, the name of the logical interfaces must
necessarily be explicitly set in each config section, instead of relying on the
name extracted from the name of the config section._
Each config section must at least define an interface address by setting the
__address__ option, or define an alias interface (as described above) by
setting the __alias__ option. The option __name__ can be set to override the
default name extracted from the name of the config section.
Non-alias interfaces support the additional option __advertised__ to set the
advertised address. Round-robin interface usage is supported in the same way as
described above, i.e. by using a colon and a suffix as part of the interface
name.
Interface sections are processed in order, and as such the first one listed
becomes the default interface. If both legacy syntax and new configuration-file
based syntax are in use, then interfaces from the legacy syntax are processed
first.
A complete example:
[rtpengine]
interfaces-config = interface
# Create an interface "default" and pick up any non-local addresses
# that are bound to the system at startup.
[interface-default]
address = any
# Create an interface "external" and pick up any addresses bound
# to the physical interface "enp63s0".
[interface-external]
address = enp63s0
# Create an interface "internal" with an explicitly set address,
# and also set the advertised address.
[interface-internal]
address = 192.168.67.43
advertised = 203.0.113.7
# Create an interface "ICE" and add all addresses bound to the
# physical interface "enp63s0". Use a mismatched but unique name for
# the interface section so more addresses can be added to this
# interface.
[interface-ICE-1]
name = ICE
address = enp63s0
# Add addresses from interface "enp35s0" to the interface "ICE".
[interface-ICE-2]
name = ICE
address = enp35s0
# Create an alias interface "virt" pointing to "external".
[interface-virt]
alias = external
# Create two interfaces that will be used in a round-robin way
# by referring to the interface "rr".
[interface-rr:0]
address = enp5p0
[interface-rr:1]
address = enp15p0
## SIGNALLING TEMPLATES
Since much of the behaviour of *rtpengine* is controlled by flags and


+ 9
- 2
etc/rtpengine.conf View File

@ -5,6 +5,10 @@ table = 0
### for userspace forwarding only:
# table = -1
interfaces-config = interface
### legacy interface config syntax:
# interface = any
### a single interface:
# interface = 123.234.345.456
### separate multiple interfaces with semicolons:
@ -12,8 +16,6 @@ table = 0
### for different advertised address:
# interface = 12.23.34.45!23.34.45.56
interface = any
# name of config section in this file to contain signalling templates
templates = templates
@ -177,6 +179,11 @@ recording-method = proc
[templates]
WebRTC = transport-protocol=UDP/TLS/RTP/SAVPF ICE=force trickle-ICE rtcp-mux=[offer require] no-rtcp-attribute SDES=off generate-mid
# one single default interface
[interface-default]
address = any
# name = default
[rtpengine-testing]
table = -1
interface = 10.15.20.121


+ 1
- 0
lib/auxlib.h View File

@ -56,6 +56,7 @@ TYPED_GHASHTABLE(charp_ht, char, char, c_str_hash, c_str_equal, g_free, g_free)
union rtpenging_config_callback_arg {
charp_ht ht;
struct interface_config_callback_arg *icca;
} __attribute__((__transparent_union__));
struct rtpenging_config_callback {


+ 22
- 1
t/test3.conf View File

@ -1,6 +1,6 @@
[rtpengine]
table = -1
interface = 203.0.113.1 ; 2001:db8:4321::1 ; 203.0.113.2 ; 2001:db8:4321::2 ; foobar/203.0.113.3 ; quux/203.0.113.4
interfaces-config = interface
listen-ng = 2223
foreground = true
log-level = 7
@ -9,3 +9,24 @@ templates = templates
[templates]
offer = transport-protocol=UDP/TLS/RTP/SAVPF ICE=force trickle-ICE rtcp-mux=[offer require] no-rtcp-attribute SDES=off generate-mid
[interface-default]
address = 203.0.113.1
[interface-default-2]
name = default
address = 2001:db8:4321::1
[interface-default-3]
name = default
address = 203.0.113.2
[interface-default-4]
name = default
address = 2001:db8:4321::2
[interface-foobar]
address = 203.0.113.3
[interface-quux]
address = 203.0.113.4

Loading…
Cancel
Save