TT#157801 shift handling of v4/v6 addresses

Handling of dual stack v4/v6 was previously done by the individual
listener objects for INADDR_ANY listening addresses. If listening on
INADDR_ANY was requested, then each listener would create two instances,
one for IPv4 and one for IPv6. This works fine for INADDR_ANY but fails
for listening on host names that resolve to multiple addresses, such as
`localhost`.

Solve this by relieving the listener objects from handling this and
instead handle it in the code setting up the listeners. If a host name
resolves to multiple addresses, then set up multiple listeners (up to
two supported currently). This allows us to listen on `localhost` by
default and have both 127.0.0.1 and ::1 active. INADDR_ANY is handled
specially by also setting up :: in that case.

Change-Id: I2a1e1d7090d7d23863c7a9bb1e89b85ad2ea44f4
pull/1430/head
Richard Fuchs 3 years ago
parent aad3fb3130
commit 12f23b311c

@ -315,11 +315,22 @@ static void cli_incoming_params_start(str *instr, struct cli_writer *cw) {
"recording-format = %s\niptables-chain = %s\n", initial_rtpe_config.b2b_url, initial_rtpe_config.redis_auth,
initial_rtpe_config.redis_write_auth, initial_rtpe_config.spooldir, initial_rtpe_config.rec_method,
initial_rtpe_config.rec_format, initial_rtpe_config.iptables_chain);
cw->cw_printf(cw,"listen-tcp = %s:%d\nlisten-udp = %s:%d\nlisten-ng = %s:%d\nlisten-cli = %s:%d\n",
sockaddr_print_buf(&initial_rtpe_config.tcp_listen_ep.address), initial_rtpe_config.tcp_listen_ep.port,
sockaddr_print_buf(&initial_rtpe_config.udp_listen_ep.address), initial_rtpe_config.udp_listen_ep.port,
sockaddr_print_buf(&initial_rtpe_config.ng_listen_ep.address), initial_rtpe_config.ng_listen_ep.port,
sockaddr_print_buf(&initial_rtpe_config.cli_listen_ep.address), initial_rtpe_config.cli_listen_ep.port);
cw->cw_printf(cw, "listen-tcp = %s\n",
endpoint_print_buf(&initial_rtpe_config.tcp_listen_ep[0]));
cw->cw_printf(cw, "listen-tcp = %s\n",
endpoint_print_buf(&initial_rtpe_config.tcp_listen_ep[1]));
cw->cw_printf(cw, "listen-udp = %s\n",
endpoint_print_buf(&initial_rtpe_config.udp_listen_ep[0]));
cw->cw_printf(cw, "listen-udp = %s\n",
endpoint_print_buf(&initial_rtpe_config.udp_listen_ep[1]));
cw->cw_printf(cw, "listen-ng = %s\n",
endpoint_print_buf(&initial_rtpe_config.ng_listen_ep[0]));
cw->cw_printf(cw, "listen-ng = %s\n",
endpoint_print_buf(&initial_rtpe_config.ng_listen_ep[1]));
cw->cw_printf(cw, "listen-cli = %s\n",
endpoint_print_buf(&initial_rtpe_config.cli_listen_ep[0]));
cw->cw_printf(cw, "listen-cli = %s\n",
endpoint_print_buf(&initial_rtpe_config.cli_listen_ep[1]));
}
static void cli_incoming_params_current(str *instr, struct cli_writer *cw) {
@ -367,11 +378,22 @@ static void cli_incoming_params_current(str *instr, struct cli_writer *cw) {
"recording-format = %s\niptables-chain = %s\n", rtpe_config.b2b_url, rtpe_config.redis_auth,
rtpe_config.redis_write_auth, rtpe_config.spooldir, rtpe_config.rec_method,
rtpe_config.rec_format, rtpe_config.iptables_chain);
cw->cw_printf(cw,"listen-tcp = %s:%d\nlisten-udp = %s:%d\nlisten-ng = %s:%d\nlisten-cli = %s:%d\n",
sockaddr_print_buf(&rtpe_config.tcp_listen_ep.address), rtpe_config.tcp_listen_ep.port,
sockaddr_print_buf(&rtpe_config.udp_listen_ep.address), rtpe_config.udp_listen_ep.port,
sockaddr_print_buf(&rtpe_config.ng_listen_ep.address), rtpe_config.ng_listen_ep.port,
sockaddr_print_buf(&rtpe_config.cli_listen_ep.address), rtpe_config.cli_listen_ep.port);
cw->cw_printf(cw, "listen-tcp = %s\n",
endpoint_print_buf(&rtpe_config.tcp_listen_ep[0]));
cw->cw_printf(cw, "listen-tcp = %s\n",
endpoint_print_buf(&rtpe_config.tcp_listen_ep[1]));
cw->cw_printf(cw, "listen-udp = %s\n",
endpoint_print_buf(&rtpe_config.udp_listen_ep[0]));
cw->cw_printf(cw, "listen-udp = %s\n",
endpoint_print_buf(&rtpe_config.udp_listen_ep[1]));
cw->cw_printf(cw, "listen-ng = %s\n",
endpoint_print_buf(&rtpe_config.ng_listen_ep[0]));
cw->cw_printf(cw, "listen-ng = %s\n",
endpoint_print_buf(&rtpe_config.ng_listen_ep[1]));
cw->cw_printf(cw, "listen-cli = %s\n",
endpoint_print_buf(&rtpe_config.cli_listen_ep[0]));
cw->cw_printf(cw, "listen-cli = %s\n",
endpoint_print_buf(&rtpe_config.cli_listen_ep[1]));
}
#define int_diff_print(struct_member, option_string) \
@ -1217,8 +1239,7 @@ void cli_handle(str *instr, struct cli_writer *cw) {
static void cli_free(void *p) {
struct cli *c = p;
streambuf_listener_shutdown(&c->listeners[0]);
streambuf_listener_shutdown(&c->listeners[1]);
streambuf_listener_shutdown(&c->listener);
}
struct cli *cli_new(struct poller *p, endpoint_t *ep) {
@ -1229,7 +1250,7 @@ struct cli *cli_new(struct poller *p, endpoint_t *ep) {
c = obj_alloc0("cli", sizeof(*c), cli_free);
if (streambuf_listener_init(&c->listeners[0], p, ep,
if (streambuf_listener_init(&c->listener, p, ep,
cli_incoming, cli_stream_readable,
NULL,
NULL,
@ -1238,17 +1259,6 @@ struct cli *cli_new(struct poller *p, endpoint_t *ep) {
ilogs(control, LOG_ERR, "Failed to open TCP control port: %s", strerror(errno));
goto fail;
}
if (ipv46_any_convert(ep)) {
if (streambuf_listener_init(&c->listeners[1], p, ep,
cli_incoming, cli_stream_readable,
NULL,
NULL,
&c->obj))
{
ilogs(control, LOG_ERR, "Failed to open TCP control port: %s", strerror(errno));
goto fail;
}
}
c->poller = p;
@ -1656,7 +1666,6 @@ static void cli_incoming_list_controltos(str *instr, struct cli_writer *cw) {
static void cli_incoming_set_controltos(str *instr, struct cli_writer *cw) {
long tos;
char *endptr;
int i;
if (str_shift(instr, 1)) {
cw->cw_printf(cw, "%s\n", "More parameters required.");
@ -1674,9 +1683,9 @@ static void cli_incoming_set_controltos(str *instr, struct cli_writer *cw) {
rtpe_config.control_tos = tos;
rwlock_unlock_w(&rtpe_config.config_lock);
for (i=0; i < G_N_ELEMENTS(rtpe_control_ng->udp_listeners); i++) {
if (rtpe_control_ng->udp_listeners[i].fd != -1) {
set_tos(&rtpe_control_ng->udp_listeners[i],tos);
for (int i = 0; i < G_N_ELEMENTS(rtpe_control_ng); i++) {
if (rtpe_control_ng[i]->udp_listener.fd != -1) {
set_tos(&rtpe_control_ng[i]->udp_listener, tos);
}
}

@ -26,7 +26,6 @@ mutex_t rtpe_cngs_lock;
mutex_t tcp_connections_lock;
GHashTable *rtpe_cngs_hash;
GHashTable *tcp_connections_hash;
struct control_ng *rtpe_control_ng;
static struct cookie_cache ng_cookie_cache;
const char magic_load_limit_strings[__LOAD_LIMIT_MAX][64] = {
@ -516,12 +515,9 @@ void control_ng_free(void *p) {
g_hash_table_destroy(rtpe_cngs_hash);
rtpe_cngs_hash = NULL;
}
poller_del_item(c->poller, c->udp_listeners[0].fd);
poller_del_item(c->poller, c->udp_listeners[1].fd);
close_socket(&c->udp_listeners[0]);
close_socket(&c->udp_listeners[1]);
streambuf_listener_shutdown(&c->tcp_listeners[0]);
streambuf_listener_shutdown(&c->tcp_listeners[1]);
poller_del_item(c->poller, c->udp_listener.fd);
close_socket(&c->udp_listener);
streambuf_listener_shutdown(&c->tcp_listener);
if (tcp_connections_hash)
g_hash_table_destroy(tcp_connections_hash);
}
@ -534,20 +530,13 @@ struct control_ng *control_ng_new(struct poller *p, endpoint_t *ep, unsigned cha
c = obj_alloc0("control_ng", sizeof(*c), control_ng_free);
c->udp_listeners[0].fd = -1;
c->udp_listeners[1].fd = -1;
c->udp_listener.fd = -1;
c->poller = p;
if (udp_listener_init(&c->udp_listeners[0], p, ep, control_ng_incoming, &c->obj))
if (udp_listener_init(&c->udp_listener, p, ep, control_ng_incoming, &c->obj))
goto fail2;
if (tos)
set_tos(&c->udp_listeners[0],tos);
if (ipv46_any_convert(ep)) {
if (udp_listener_init(&c->udp_listeners[1], p, ep, control_ng_incoming, &c->obj))
goto fail2;
if (tos)
set_tos(&c->udp_listeners[1],tos);
}
set_tos(&c->udp_listener, tos);
return c;
fail2:
@ -555,19 +544,16 @@ fail2:
return NULL;
}
struct control_ng *control_ng_tcp_new(struct poller *p, endpoint_t *ep, struct control_ng *ctrl_ng) {
struct control_ng *control_ng_tcp_new(struct poller *p, endpoint_t *ep) {
if (!p)
return NULL;
if (!ctrl_ng) {
ctrl_ng = obj_alloc0("control_ng", sizeof(*ctrl_ng), NULL);
ctrl_ng->udp_listeners[0].fd = -1;
ctrl_ng->udp_listeners[1].fd = -1;
}
struct control_ng * ctrl_ng = obj_alloc0("control_ng", sizeof(*ctrl_ng), NULL);
ctrl_ng->udp_listener.fd = -1;
ctrl_ng->poller = p;
if (streambuf_listener_init(&ctrl_ng->tcp_listeners[0], p, ep,
if (streambuf_listener_init(&ctrl_ng->tcp_listener, p, ep,
control_incoming, control_stream_readable,
control_closed,
NULL,
@ -575,16 +561,6 @@ struct control_ng *control_ng_tcp_new(struct poller *p, endpoint_t *ep, struct c
ilog(LOG_ERR, "Failed to open TCP control port: %s", strerror(errno));
goto fail;
}
if (ipv46_any_convert(ep)) {
if (streambuf_listener_init(&ctrl_ng->tcp_listeners[1], p, ep,
control_incoming, control_stream_readable,
control_closed,
NULL,
&ctrl_ng->obj)) {
ilog(LOG_ERR, "Failed to open TCP control port: %s", strerror(errno));
goto fail;
}
}
tcp_connections_hash = g_hash_table_new(g_str_hash, g_str_equal);
mutex_init(&tcp_connections_lock);

@ -26,7 +26,7 @@
struct control_tcp {
struct obj obj;
struct streambuf_listener listeners[2];
struct streambuf_listener listener;
pcre *parse_re;
pcre_extra *parse_ree;
@ -44,22 +44,20 @@ static void control_stream_closed(struct streambuf_stream *s) {
static void control_list(struct control_tcp *c, struct streambuf_stream *s) {
for (int i = 0; i < G_N_ELEMENTS(c->listeners); i++) {
if (!c->listeners[i].listener.family || !c->listeners[i].poller)
continue; // not used
if (!c->listener.listener.family || !c->listener.poller)
return;
mutex_lock(&c->listeners[i].lock);
mutex_lock(&c->listener.lock);
GList *streams = g_hash_table_get_values(c->listeners[i].streams);
for (GList *l = streams; l; l = l->next) {
struct streambuf_stream *cl = l->data;
streambuf_printf(s->outbuf, "%s\n", cl->addr);
}
GList *streams = g_hash_table_get_values(c->listener.streams);
for (GList *l = streams; l; l = l->next) {
struct streambuf_stream *cl = l->data;
streambuf_printf(s->outbuf, "%s\n", cl->addr);
}
mutex_unlock(&c->listeners[i].lock);
mutex_unlock(&c->listener.lock);
g_list_free(streams);
}
g_list_free(streams);
streambuf_printf(s->outbuf, "End.\n");
}
@ -156,8 +154,7 @@ static void control_incoming(struct streambuf_stream *s) {
static void control_tcp_free(void *p) {
struct control_tcp *c = p;
streambuf_listener_shutdown(&c->listeners[0]);
streambuf_listener_shutdown(&c->listeners[1]);
streambuf_listener_shutdown(&c->listener);
pcre_free(c->parse_re);
pcre_free_study(c->parse_ree);
}
@ -172,7 +169,7 @@ struct control_tcp *control_tcp_new(struct poller *p, endpoint_t *ep) {
c = obj_alloc0("control", sizeof(*c), control_tcp_free);
if (streambuf_listener_init(&c->listeners[0], p, ep,
if (streambuf_listener_init(&c->listener, p, ep,
control_incoming, control_stream_readable,
control_stream_closed,
control_stream_timer,
@ -181,17 +178,6 @@ struct control_tcp *control_tcp_new(struct poller *p, endpoint_t *ep) {
ilogs(control, LOG_ERR, "Failed to open TCP control port: %s", strerror(errno));
goto fail;
}
if (ipv46_any_convert(ep)) {
if (streambuf_listener_init(&c->listeners[1], p, ep,
control_incoming, control_stream_readable,
control_stream_closed,
control_stream_timer,
&c->obj))
{
ilogs(control, LOG_ERR, "Failed to open TCP control port: %s", strerror(errno));
goto fail;
}
}
c->parse_re = pcre_compile(
/* reqtype callid streams ip fromdom fromtype todom totype agent info |reqtype callid info | reqtype */

@ -138,8 +138,7 @@ void control_udp_free(void *p) {
pcre_free_study(u->parse_ree);
pcre_free(u->parse_re);
pcre_free(u->fallback_re);
close_socket(&u->udp_listeners[0]);
close_socket(&u->udp_listeners[1]);
close_socket(&u->udp_listener);
cookie_cache_cleanup(&u->cookie_cache);
}
@ -174,9 +173,7 @@ struct control_udp *control_udp_new(struct poller *p, endpoint_t *ep) {
cookie_cache_init(&c->cookie_cache);
if (udp_listener_init(&c->udp_listeners[0], p, ep, control_udp_incoming, &c->obj))
goto fail2;
if (ipv46_any_convert(ep) && udp_listener_init(&c->udp_listeners[1], p, ep, control_udp_incoming, &c->obj))
if (udp_listener_init(&c->udp_listener, p, ep, control_udp_incoming, &c->obj))
goto fail2;
return c;

@ -62,9 +62,12 @@ struct poller *rtpe_poller;
struct poller_map *rtpe_poller_map;
struct rtpengine_config initial_rtpe_config;
static struct control_tcp *rtpe_tcp;
static struct control_udp *rtpe_udp;
static struct cli *rtpe_cli;
static struct control_tcp *rtpe_tcp[2];
static struct control_udp *rtpe_udp[2];
static struct cli *rtpe_cli[2];
struct control_ng *rtpe_control_ng[2];
struct control_ng *rtpe_control_ng_tcp[2];
struct rtpengine_config rtpe_config = {
// non-zero defaults
@ -631,24 +634,27 @@ static void options(int *argc, char ***argv) {
}
if (listenps) {
if (endpoint_parse_any_getaddrinfo(&rtpe_config.tcp_listen_ep, listenps))
if (endpoint_parse_any_getaddrinfo_alt(&rtpe_config.tcp_listen_ep[0], &rtpe_config.tcp_listen_ep[1], listenps))
die("Invalid IP or port '%s' (--listen-tcp)", listenps);
}
if (listenudps) {
if (endpoint_parse_any_getaddrinfo(&rtpe_config.udp_listen_ep, listenudps))
if (endpoint_parse_any_getaddrinfo_alt(&rtpe_config.udp_listen_ep[0], &rtpe_config.udp_listen_ep[1], listenudps))
die("Invalid IP or port '%s' (--listen-udp)", listenudps);
}
if (listenngs) {
if (endpoint_parse_any_getaddrinfo(&rtpe_config.ng_listen_ep, listenngs))
if (endpoint_parse_any_getaddrinfo_alt(&rtpe_config.ng_listen_ep[0], &rtpe_config.ng_listen_ep[1], listenngs))
die("Invalid IP or port '%s' (--listen-ng)", listenngs);
}
if (listenngtcps) {
if (endpoint_parse_any_getaddrinfo(&rtpe_config.ng_tcp_listen_ep, listenngtcps))
if (endpoint_parse_any_getaddrinfo_alt(&rtpe_config.ng_tcp_listen_ep[0], &rtpe_config.ng_tcp_listen_ep[1],
listenngtcps))
die("Invalid IP or port '%s' (--listen-tcp-ng)", listenngtcps);
}
if (listencli) {if (endpoint_parse_any_getaddrinfo(&rtpe_config.cli_listen_ep, listencli))
die("Invalid IP or port '%s' (--listen-cli)", listencli);
if (listencli) {
if (endpoint_parse_any_getaddrinfo_alt(&rtpe_config.cli_listen_ep[0], &rtpe_config.cli_listen_ep[1],
listencli))
die("Invalid IP or port '%s' (--listen-cli)", listencli);
}
if (graphitep) {if (endpoint_parse_any_getaddrinfo_full(&rtpe_config.graphite_ep, graphitep))
@ -902,11 +908,11 @@ void fill_initial_rtpe_cfg(struct rtpengine_config* ini_rtpe_cfg) {
memcpy(&ini_rtpe_cfg->common.log_levels, &rtpe_config.common.log_levels, sizeof(ini_rtpe_cfg->common.log_levels));
ini_rtpe_cfg->graphite_ep = rtpe_config.graphite_ep;
ini_rtpe_cfg->tcp_listen_ep = rtpe_config.tcp_listen_ep;
ini_rtpe_cfg->udp_listen_ep = rtpe_config.udp_listen_ep;
ini_rtpe_cfg->ng_listen_ep = rtpe_config.ng_listen_ep;
ini_rtpe_cfg->ng_tcp_listen_ep = rtpe_config.ng_tcp_listen_ep;
ini_rtpe_cfg->cli_listen_ep = rtpe_config.cli_listen_ep;
memcpy(ini_rtpe_cfg->tcp_listen_ep, rtpe_config.tcp_listen_ep, sizeof(ini_rtpe_cfg->tcp_listen_ep));
memcpy(ini_rtpe_cfg->udp_listen_ep, rtpe_config.udp_listen_ep, sizeof(ini_rtpe_cfg->udp_listen_ep));
memcpy(ini_rtpe_cfg->ng_listen_ep, rtpe_config.ng_listen_ep, sizeof(ini_rtpe_cfg->ng_listen_ep));
memcpy(ini_rtpe_cfg->ng_tcp_listen_ep, rtpe_config.ng_tcp_listen_ep, sizeof(ini_rtpe_cfg->ng_tcp_listen_ep));
memcpy(ini_rtpe_cfg->cli_listen_ep, rtpe_config.cli_listen_ep, sizeof(ini_rtpe_cfg->cli_listen_ep));
ini_rtpe_cfg->redis_ep = rtpe_config.redis_ep;
ini_rtpe_cfg->redis_write_ep = rtpe_config.redis_write_ep;
ini_rtpe_cfg->homer_ep = rtpe_config.homer_ep;
@ -1073,41 +1079,84 @@ no_kernel:
if (rtpe_config.redis_num_threads < 1)
rtpe_config.redis_num_threads = num_cpu_cores(REDIS_RESTORE_NUM_THREADS);
rtpe_tcp = NULL;
if (rtpe_config.tcp_listen_ep.port) {
rtpe_tcp = control_tcp_new(rtpe_poller, &rtpe_config.tcp_listen_ep);
if (!rtpe_tcp)
die("Failed to open TCP control connection port");
if (rtpe_config.tcp_listen_ep[0].port) {
rtpe_tcp[0] = control_tcp_new(rtpe_poller, &rtpe_config.tcp_listen_ep[0]);
if (!rtpe_tcp[0])
die("Failed to open TCP control connection port (%s): %s",
endpoint_print_buf(&rtpe_config.tcp_listen_ep[0]),
strerror(errno));
if (rtpe_config.tcp_listen_ep[1].port) {
rtpe_tcp[1] = control_tcp_new(rtpe_poller, &rtpe_config.tcp_listen_ep[1]);
if (!rtpe_tcp[1])
die("Failed to open TCP control connection port (%s): %s",
endpoint_print_buf(&rtpe_config.tcp_listen_ep[1]),
strerror(errno));
}
}
rtpe_udp = NULL;
if (rtpe_config.udp_listen_ep.port) {
interfaces_exclude_port(rtpe_config.udp_listen_ep.port);
rtpe_udp = control_udp_new(rtpe_poller, &rtpe_config.udp_listen_ep);
if (!rtpe_udp)
die("Failed to open UDP control connection port");
if (rtpe_config.udp_listen_ep[0].port) {
interfaces_exclude_port(rtpe_config.udp_listen_ep[0].port);
rtpe_udp[0] = control_udp_new(rtpe_poller, &rtpe_config.udp_listen_ep[0]);
if (!rtpe_udp[0])
die("Failed to open UDP control connection port (%s): %s",
endpoint_print_buf(&rtpe_config.udp_listen_ep[0]),
strerror(errno));
if (rtpe_config.udp_listen_ep[1].port) {
rtpe_udp[1] = control_udp_new(rtpe_poller, &rtpe_config.udp_listen_ep[1]);
if (!rtpe_udp[1])
die("Failed to open UDP control connection port (%s): %s",
endpoint_print_buf(&rtpe_config.udp_listen_ep[1]),
strerror(errno));
}
}
rtpe_control_ng = NULL;
if (rtpe_config.ng_listen_ep.port) {
interfaces_exclude_port(rtpe_config.ng_listen_ep.port);
rtpe_control_ng = control_ng_new(rtpe_poller, &rtpe_config.ng_listen_ep, rtpe_config.control_tos);
if (!rtpe_control_ng)
die("Failed to open UDP control connection port");
if (rtpe_config.ng_listen_ep[0].port) {
interfaces_exclude_port(rtpe_config.ng_listen_ep[0].port);
rtpe_control_ng[0] = control_ng_new(rtpe_poller, &rtpe_config.ng_listen_ep[0],
rtpe_config.control_tos);
if (!rtpe_control_ng[0])
die("Failed to open UDP NG control connection port (%s): %s",
endpoint_print_buf(&rtpe_config.ng_listen_ep[0]),
strerror(errno));
if (rtpe_config.ng_listen_ep[1].port) {
rtpe_control_ng[1] = control_ng_new(rtpe_poller, &rtpe_config.ng_listen_ep[1],
rtpe_config.control_tos);
if (!rtpe_control_ng[1])
die("Failed to open UDP NG control connection port (%s): %s",
endpoint_print_buf(&rtpe_config.ng_listen_ep[1]),
strerror(errno));
}
}
if (rtpe_config.ng_tcp_listen_ep.port) {
rtpe_control_ng = control_ng_tcp_new(rtpe_poller, &rtpe_config.ng_tcp_listen_ep, rtpe_control_ng);
if (!rtpe_control_ng)
die("Failed to open TCP control connection port");
if (rtpe_config.ng_tcp_listen_ep[0].port) {
rtpe_control_ng_tcp[0] = control_ng_tcp_new(rtpe_poller, &rtpe_config.ng_tcp_listen_ep[0]);
if (!rtpe_control_ng_tcp[0])
die("Failed to open TCP NG control connection port (%s): %s",
endpoint_print_buf(&rtpe_config.ng_tcp_listen_ep[0]),
strerror(errno));
if (rtpe_config.ng_tcp_listen_ep[1].port) {
rtpe_control_ng_tcp[1] = control_ng_tcp_new(rtpe_poller, &rtpe_config.ng_tcp_listen_ep[1]);
if (!rtpe_control_ng_tcp[1])
die("Failed to open TCP NG control connection port (%s): %s",
endpoint_print_buf(&rtpe_config.ng_tcp_listen_ep[1]),
strerror(errno));
}
}
rtpe_cli = NULL;
if (rtpe_config.cli_listen_ep.port) {
interfaces_exclude_port(rtpe_config.cli_listen_ep.port);
rtpe_cli = cli_new(rtpe_poller, &rtpe_config.cli_listen_ep);
if (!rtpe_cli)
die("Failed to open UDP CLI connection port");
if (rtpe_config.cli_listen_ep[0].port) {
interfaces_exclude_port(rtpe_config.cli_listen_ep[0].port);
rtpe_cli[0] = cli_new(rtpe_poller, &rtpe_config.cli_listen_ep[0]);
if (!rtpe_cli[0])
die("Failed to open CLI connection port (%s): %s",
endpoint_print_buf(&rtpe_config.cli_listen_ep[0]),
strerror(errno));
if (rtpe_config.cli_listen_ep[1].port) {
rtpe_cli[1] = cli_new(rtpe_poller, &rtpe_config.cli_listen_ep[1]);
if (!rtpe_cli[1])
die("Failed to open CLI connection port (%s): %s",
endpoint_print_buf(&rtpe_config.cli_listen_ep[1]),
strerror(errno));
}
}
if (!is_addr_unspecified(&rtpe_config.redis_write_ep.address)) {
@ -1311,10 +1360,16 @@ int main(int argc, char **argv) {
log_free();
janus_free();
obj_release(rtpe_cli);
obj_release(rtpe_udp);
obj_release(rtpe_tcp);
obj_release(rtpe_control_ng);
obj_release(rtpe_cli[0]);
obj_release(rtpe_cli[1]);
obj_release(rtpe_udp[0]);
obj_release(rtpe_udp[1]);
obj_release(rtpe_tcp[0]);
obj_release(rtpe_tcp[1]);
obj_release(rtpe_control_ng[0]);
obj_release(rtpe_control_ng[1]);
obj_release(rtpe_control_ng_tcp[0]);
obj_release(rtpe_control_ng_tcp[1]);
poller_free(&rtpe_poller);
poller_map_free(&rtpe_poller_map);
interfaces_free();

@ -10,7 +10,7 @@ struct cli {
struct poller *poller;
struct streambuf_listener listeners[2];
struct streambuf_listener listener;
};
struct cli_writer;

@ -53,8 +53,8 @@ struct control_ng_stats {
struct control_ng {
struct obj obj;
socket_t udp_listeners[2];
struct streambuf_listener tcp_listeners[2];
socket_t udp_listener;
struct streambuf_listener tcp_listener;
struct poller *poller;
};
@ -69,7 +69,7 @@ extern const char *ng_command_strings[NGC_COUNT];
extern const char *ng_command_strings_short[NGC_COUNT];
struct control_ng *control_ng_new(struct poller *, endpoint_t *, unsigned char);
struct control_ng *control_ng_tcp_new(struct poller *, endpoint_t *, struct control_ng *);
struct control_ng *control_ng_tcp_new(struct poller *, endpoint_t *);
void notify_ng_tcp_clients(str *);
void control_ng_init(void);
void control_ng_cleanup(void);
@ -83,7 +83,6 @@ INLINE void ng_buffer_release(struct ng_buffer *ngbuf) {
extern mutex_t rtpe_cngs_lock;
extern GHashTable *rtpe_cngs_hash;
extern struct control_ng *rtpe_control_ng;
enum load_limit_reasons {
LOAD_LIMIT_NONE = -1,

@ -48,7 +48,7 @@ struct control_udp {
struct obj obj;
struct cookie_cache cookie_cache;
socket_t udp_listeners[2];
socket_t udp_listener;
pcre *parse_re;
pcre_extra *parse_ree;

@ -51,11 +51,11 @@ struct rtpengine_config {
int graphite_interval;
int redis_num_threads;
GQueue interfaces;
endpoint_t tcp_listen_ep;
endpoint_t udp_listen_ep;
endpoint_t ng_listen_ep;
endpoint_t ng_tcp_listen_ep;
endpoint_t cli_listen_ep;
endpoint_t tcp_listen_ep[2];
endpoint_t udp_listen_ep[2];
endpoint_t ng_listen_ep[2];
endpoint_t ng_tcp_listen_ep[2];
endpoint_t cli_listen_ep[2];
endpoint_t redis_ep;
endpoint_t redis_write_ep;
endpoint_t homer_ep;
@ -161,6 +161,9 @@ extern struct poller_map *rtpe_poller_map;
extern struct rtpengine_config rtpe_config;
extern struct rtpengine_config initial_rtpe_config;
extern struct control_ng *rtpe_control_ng[2];
extern struct control_ng *rtpe_control_ng_tcp[2];
#endif

@ -576,38 +576,52 @@ int endpoint_parse_any(endpoint_t *d, const char *s) {
return -1;
}
int sockaddr_getaddrinfo(sockaddr_t *a, const char *s) {
static int socket_addrinfo_convert(sockaddr_t *a, struct addrinfo *res) {
if (res->ai_family == AF_INET) { // IPv4
struct sockaddr_in *ipv4 = (struct sockaddr_in *) res->ai_addr;
a->u.ipv4 = ipv4->sin_addr;
a->family = &__socket_families[SF_IP4];
}
else if (res->ai_family == AF_INET6) {
struct sockaddr_in6 *ipv6 = (struct sockaddr_in6 *) res->ai_addr;
a->u.ipv6 = ipv6->sin6_addr;
a->family = &__socket_families[SF_IP6];
}
else
return -1;
return 0;
}
int sockaddr_getaddrinfo_alt(sockaddr_t *a, sockaddr_t *a2, const char *s) {
struct addrinfo hints, *res;
int status;
int ret;
memset(&hints, 0, sizeof hints);
hints.ai_family = AF_UNSPEC;
hints.ai_protocol = IPPROTO_UDP;
hints.ai_socktype = SOCK_DGRAM;
if ((status = getaddrinfo(s, NULL, &hints, &res)) != 0) {
__C_DBG("getaddrinfo failed for %s, status is \"%s\"\n", s, gai_strerror(status));
return -1;
}
ret = 0;
if (res->ai_family == AF_INET) { // IPv4
struct sockaddr_in *ipv4 = (struct sockaddr_in *) res->ai_addr;
a->u.ipv4 = ipv4->sin_addr;
a->family = &__socket_families[SF_IP4];
}
else if (res->ai_family == AF_INET6) {
struct sockaddr_in6 *ipv6 = (struct sockaddr_in6 *) res->ai_addr;
a->u.ipv6 = ipv6->sin6_addr;
a->family = &__socket_families[SF_IP6];
ret = socket_addrinfo_convert(a, res);
if (a2) {
if (ret == 0 && res->ai_next) {
struct addrinfo *next = res->ai_next;
ret = socket_addrinfo_convert(a2, next);
}
else
ZERO(*a2);
}
else
ret = -1;
freeaddrinfo(res);
return ret;
}
int endpoint_parse_any_getaddrinfo(endpoint_t *d, const char *s) {
int endpoint_parse_any_getaddrinfo_alt(endpoint_t *d, endpoint_t *d2, const char *s) {
unsigned int len;
const char *ep;
char buf[64];
@ -620,6 +634,11 @@ int endpoint_parse_any_getaddrinfo(endpoint_t *d, const char *s) {
d->port = atoi(s);
ZERO(d->address);
d->address.family = __get_socket_family_enum(SF_IP4);
if (d2) {
ZERO(*d2);
*d2 = *d;
ipv46_any_convert(d2);
}
return 0;
}
len = ep - s;
@ -636,9 +655,16 @@ int endpoint_parse_any_getaddrinfo(endpoint_t *d, const char *s) {
sprintf(buf, "%.*s", len, s);
}
if (sockaddr_getaddrinfo(&d->address, buf))
if (sockaddr_getaddrinfo_alt(&d->address, d2 ? &d2->address : NULL, buf))
return -1;
if (d2) {
if (d2->address.family)
d2->port = d->port;
else
ZERO(*d2);
}
return 0;
}

@ -218,8 +218,9 @@ int sockaddr_parse_any(sockaddr_t *dst, const char *src);
int sockaddr_parse_any_str(sockaddr_t *dst, const str *src);
int sockaddr_parse_str(sockaddr_t *dst, sockfamily_t *fam, const str *src);
int endpoint_parse_any(endpoint_t *, const char *); // address (ip) optional
int sockaddr_getaddrinfo(sockaddr_t *a, const char *s);
int endpoint_parse_any_getaddrinfo(endpoint_t *d, const char *s); // address (ip or hostname) optional
int sockaddr_getaddrinfo_alt(sockaddr_t *a, sockaddr_t *a2, const char *s);
int endpoint_parse_any_getaddrinfo_alt(endpoint_t *d, endpoint_t *d2, const char *s); // address (ip or hostname) optional
INLINE int endpoint_parse_any_getaddrinfo(endpoint_t *d, const char *s);
void endpoint_parse_sockaddr_storage(endpoint_t *, struct sockaddr_storage *);
void kernel2endpoint(endpoint_t *ep, const struct re_address *ra);
@ -264,6 +265,12 @@ INLINE int endpoint_parse_any_getaddrinfo_full(endpoint_t *d, const char *s) {
return -1;
return 0;
}
INLINE int sockaddr_getaddrinfo(sockaddr_t *a, const char *s) {
return sockaddr_getaddrinfo_alt(a, NULL, s);
}
INLINE int endpoint_parse_any_getaddrinfo(endpoint_t *d, const char *s) {
return endpoint_parse_any_getaddrinfo_alt(d, NULL, s);
}
INLINE int ipv46_any_convert(endpoint_t *ep) {
if (ep->address.family->af != AF_INET)
return 0;

@ -17,6 +17,7 @@ struct rtpengine_config initial_rtpe_config;
struct poller *rtpe_poller;
struct poller_map *rtpe_poller_map;
GString *dtmf_logs;
struct control_ng *rtpe_control_ng[2];
static void __assert_g_string_eq(GString *a, const char *b, unsigned int line) {
if (strcmp(a->str, b) == 0) {

@ -13,6 +13,7 @@ struct rtpengine_config initial_rtpe_config;
struct poller *rtpe_poller;
struct poller_map *rtpe_poller_map;
GString *dtmf_logs;
struct control_ng *rtpe_control_ng[2];
static str *sdup(char *s) {
str r;

Loading…
Cancel
Save