From fd95998b56d40c2acf753a3430d14de1b9ca1ede Mon Sep 17 00:00:00 2001 From: cmaj Date: Sat, 7 Jan 2023 22:04:57 -0700 Subject: [PATCH] res_phoneprov.c: Multihomed SERVER cache prevention Phones moving between subnets on multi-homed server have their initially connected interface IP cached in the SERVER variable, even when it is not specified in the configuration files. This prevents phones from obtaining the correct SERVER variable value when they move to another subnet. ASTERISK-30388 #close Reported-by: cmaj Change-Id: I1d18987a9d58e85556b4c4a6814ce7006524cc92 --- .../res_phoneprov_multihomed_server.txt | 5 +++++ res/res_phoneprov.c | 20 +++++++++++++++++-- 2 files changed, 23 insertions(+), 2 deletions(-) create mode 100644 doc/CHANGES-staging/res_phoneprov_multihomed_server.txt diff --git a/doc/CHANGES-staging/res_phoneprov_multihomed_server.txt b/doc/CHANGES-staging/res_phoneprov_multihomed_server.txt new file mode 100644 index 0000000000..ff68014570 --- /dev/null +++ b/doc/CHANGES-staging/res_phoneprov_multihomed_server.txt @@ -0,0 +1,5 @@ +Subject: res_phoneprov + +On multihomed Asterisk servers with dynamic SERVER template variables, +reloading this module is no longer required when re-provisioning your +phone to another interface address (e.g. when moving between VLANs.) diff --git a/res/res_phoneprov.c b/res/res_phoneprov.c index 5a4efa092b..ec3f387744 100644 --- a/res/res_phoneprov.c +++ b/res/res_phoneprov.c @@ -874,6 +874,8 @@ static int phoneprov_callback(struct ast_tcptls_session_instance *ser, const str char path[PATH_MAX]; char *file = NULL; char *server; + char *newserver = NULL; + struct extension *exten_iter; int len; int fd; struct ast_str *http_header; @@ -955,8 +957,7 @@ static int phoneprov_callback(struct ast_tcptls_session_instance *ser, const str if ((res = getsockname(ast_iostream_get_fd(ser->stream), &name.sa, &namelen))) { ast_log(LOG_WARNING, "Could not get server IP, breakage likely.\n"); } else { - struct extension *exten_iter; - const char *newserver = ast_inet_ntoa(name.sa_in.sin_addr); + newserver = ast_strdupa(ast_inet_ntoa(name.sa_in.sin_addr)); AST_LIST_TRAVERSE(&route->user->extensions, exten_iter, entry) { AST_VAR_LIST_INSERT_TAIL(exten_iter->headp, @@ -967,6 +968,21 @@ static int phoneprov_callback(struct ast_tcptls_session_instance *ser, const str ast_str_substitute_variables_varshead(&tmp, 0, AST_LIST_FIRST(&route->user->extensions)->headp, file); + /* Do not retain dynamic SERVER address because next request from the phone might arrive on + * different interface IP address eg. if this is a multi-homed server on multiple subnets */ + if (newserver) { + struct ast_var_t *varns; + AST_LIST_TRAVERSE(&route->user->extensions, exten_iter, entry) { + AST_LIST_TRAVERSE_SAFE_BEGIN(exten_iter->headp, varns, entries) { + if (!strcmp(variable_lookup[AST_PHONEPROV_STD_SERVER], ast_var_name(varns))) { + AST_LIST_REMOVE_CURRENT(entries); + ast_var_delete(varns); + } + } + AST_LIST_TRAVERSE_SAFE_END + } + } + ast_free(file); http_header = ast_str_create(80);