summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README-SERIOUSLY.bestpractices.md4
-rw-r--r--README.md7
-rw-r--r--apps/app_ices.c4
-rw-r--r--channels/chan_phone.c4
-rw-r--r--channels/chan_pjsip.c5
-rw-r--r--channels/chan_sip.c17
-rw-r--r--channels/pjsip/dialplan_functions.c50
-rw-r--r--channels/vgrabbers.c8
-rw-r--r--codecs/codec_dahdi.c7
-rw-r--r--codecs/codecs.xml1
-rw-r--r--configs/samples/iax.conf.sample12
-rw-r--r--funcs/func_cdr.c127
-rw-r--r--funcs/func_channel.c19
-rw-r--r--include/asterisk/astdb.h10
-rw-r--r--include/asterisk/res_pjsip_session.h2
-rw-r--r--include/asterisk/utils.h40
-rw-r--r--main/alertpipe.c13
-rw-r--r--main/asterisk.c62
-rw-r--r--main/bridge_basic.c61
-rw-r--r--main/db.c121
-rw-r--r--main/iostream.c2
-rw-r--r--main/loader.c43
-rw-r--r--main/media_index.c121
-rw-r--r--main/sounds_index.c9
-rw-r--r--main/stasis_channels.c8
-rw-r--r--main/tcptls.c13
-rw-r--r--main/translate.c2
-rw-r--r--main/udptl.c4
-rw-r--r--main/utils.c34
-rw-r--r--menuselect/Makefile5
-rw-r--r--res/res_agi.c16
-rw-r--r--res/res_http_websocket.c10
-rw-r--r--res/res_musiconhold.c7
-rw-r--r--res/res_pjsip/config_transport.c10
-rw-r--r--res/res_pjsip/pjsip_cli.c24
-rw-r--r--res/res_pjsip/pjsip_configuration.c17
-rw-r--r--res/res_pjsip/pjsip_options.c53
-rw-r--r--res/res_pjsip_dlg_options.c1
-rw-r--r--res/res_pjsip_outbound_publish.c1
-rw-r--r--res/res_pjsip_phoneprov_provider.c1
-rw-r--r--res/res_pjsip_publish_asterisk.c1
-rw-r--r--res/res_pjsip_sdp_rtp.c3
-rw-r--r--res/res_pjsip_session.c15
-rw-r--r--res/res_pktccops.c5
-rw-r--r--res/res_rtp_asterisk.c11
-rw-r--r--res/res_sorcery_astdb.c6
-rw-r--r--res/res_speech.c2
-rw-r--r--res/res_stasis.c4
-rw-r--r--res/res_timing_pthread.c4
49 files changed, 634 insertions, 372 deletions
diff --git a/README-SERIOUSLY.bestpractices.md b/README-SERIOUSLY.bestpractices.md
index 7e18c4aa8..ec36fac98 100644
--- a/README-SERIOUSLY.bestpractices.md
+++ b/README-SERIOUSLY.bestpractices.md
@@ -17,7 +17,8 @@ change over time as best practices are defined.
Recognizing potential issues with certain classes of authorization
* [Avoid Privilege Escalations]:
Disable the ability to execute functions that may escalate privileges
-
+* [Important Security Considerations]:
+ More information on the Asterisk Wiki
## Additional Links
@@ -386,3 +387,4 @@ In Asterisk 12 and later, live_dangerously defaults to no.
[Reducing Pattern Match Typos]: #reducing-pattern-match-typos
[Manager Class Authorizations]: #manager-class-authorizations
[Avoid Privilege Escalations]: #avoid-privilege-escalations
+[Important Security Considerations]: https://wiki.asterisk.org/wiki/display/AST/Important+Security+Considerations
diff --git a/README.md b/README.md
index 4ed9b3eec..153c4f3e4 100644
--- a/README.md
+++ b/README.md
@@ -9,10 +9,7 @@
the security information document before you attempt to configure and run
an Asterisk server.
- If you downloaded Asterisk as a tarball, see the security section in the PDF
-version of the documentation in doc/tex/asterisk.pdf. Alternatively, pull up
-the HTML version of the documentation in doc/tex/asterisk/index.html. The
-source for the security document is available in doc/tex/security.tex.
+See [Important Security Considerations] for more information.
## WHAT IS ASTERISK ?
@@ -269,4 +266,4 @@ Asterisk is a trademark of Digium, Inc.
[CHANGES]: CHANGES
[configs]: configs
[doc]: doc
-
+[Important Security Considerations]: https://wiki.asterisk.org/wiki/display/AST/Important+Security+Considerations
diff --git a/apps/app_ices.c b/apps/app_ices.c
index 4ca4b67c5..1194384d4 100644
--- a/apps/app_ices.c
+++ b/apps/app_ices.c
@@ -113,7 +113,6 @@ static int ices_exec(struct ast_channel *chan, const char *data)
int fds[2];
int ms = -1;
int pid = -1;
- int flags;
struct ast_format *oreadformat;
struct ast_frame *f;
char filename[256]="";
@@ -128,8 +127,7 @@ static int ices_exec(struct ast_channel *chan, const char *data)
ast_log(LOG_WARNING, "Unable to create pipe\n");
return -1;
}
- flags = fcntl(fds[1], F_GETFL);
- fcntl(fds[1], F_SETFL, flags | O_NONBLOCK);
+ ast_fd_set_flags(fds[1], O_NONBLOCK);
ast_stopstream(chan);
diff --git a/channels/chan_phone.c b/channels/chan_phone.c
index 76891ac98..832f28b49 100644
--- a/channels/chan_phone.c
+++ b/channels/chan_phone.c
@@ -1191,7 +1191,6 @@ static struct phone_pvt *mkif(const char *iface, int mode, int txgain, int rxgai
{
/* Make a phone_pvt structure for this interface */
struct phone_pvt *tmp;
- int flags;
tmp = ast_calloc(1, sizeof(*tmp));
if (tmp) {
@@ -1224,8 +1223,7 @@ static struct phone_pvt *mkif(const char *iface, int mode, int txgain, int rxgai
ioctl(tmp->fd, PHONE_VAD, tmp->silencesupression);
#endif
tmp->mode = mode;
- flags = fcntl(tmp->fd, F_GETFL);
- fcntl(tmp->fd, F_SETFL, flags | O_NONBLOCK);
+ ast_fd_set_flags(tmp->fd, O_NONBLOCK);
tmp->owner = NULL;
ao2_cleanup(tmp->lastformat);
tmp->lastformat = NULL;
diff --git a/channels/chan_pjsip.c b/channels/chan_pjsip.c
index e4e8fa586..69bcc187f 100644
--- a/channels/chan_pjsip.c
+++ b/channels/chan_pjsip.c
@@ -605,6 +605,11 @@ static struct ast_channel *chan_pjsip_new(struct ast_sip_session *session, int s
ast_party_id_copy(&ast_channel_caller(chan)->id, &session->id);
ast_party_id_copy(&ast_channel_caller(chan)->ani, &session->id);
+ if (!ast_strlen_zero(exten)) {
+ /* Set provided DNID on the new channel. */
+ ast_channel_dialed(chan)->number.str = ast_strdup(exten);
+ }
+
ast_channel_priority_set(chan, 1);
ast_channel_callgroup_set(chan, session->endpoint->pickup.callgroup);
diff --git a/channels/chan_sip.c b/channels/chan_sip.c
index a6e5493c2..4bae39da0 100644
--- a/channels/chan_sip.c
+++ b/channels/chan_sip.c
@@ -30125,6 +30125,7 @@ static int sip_send_keepalive(const void *data)
struct sip_peer *peer = (struct sip_peer*) data;
int res = 0;
const char keepalive[] = "\r\n";
+ size_t count = sizeof(keepalive) - 1;
peer->keepalivesend = -1;
@@ -30135,12 +30136,12 @@ static int sip_send_keepalive(const void *data)
/* Send the packet out using the proper method for this peer */
if ((peer->socket.fd != -1) && (peer->socket.type == AST_TRANSPORT_UDP)) {
- res = ast_sendto(peer->socket.fd, keepalive, sizeof(keepalive), 0, &peer->addr);
+ res = ast_sendto(peer->socket.fd, keepalive, count, 0, &peer->addr);
} else if ((peer->socket.type & (AST_TRANSPORT_TCP | AST_TRANSPORT_TLS)) &&
peer->socket.tcptls_session) {
- res = sip_tcptls_write(peer->socket.tcptls_session, keepalive, sizeof(keepalive));
+ res = sip_tcptls_write(peer->socket.tcptls_session, keepalive, count);
} else if (peer->socket.type == AST_TRANSPORT_UDP) {
- res = ast_sendto(sipsock, keepalive, sizeof(keepalive), 0, &peer->addr);
+ res = ast_sendto(sipsock, keepalive, count, 0, &peer->addr);
}
if (res == -1) {
@@ -30154,7 +30155,7 @@ static int sip_send_keepalive(const void *data)
}
}
- if (res != sizeof(keepalive)) {
+ if (res != count) {
ast_log(LOG_WARNING, "sip_send_keepalive to %s returned %d: %s\n", ast_sockaddr_stringify(&peer->addr), res, strerror(errno));
}
@@ -30554,6 +30555,14 @@ static struct ast_channel *sip_request_call(const char *type, struct ast_format_
}
}
+ /* If stripping the DNID left us with nothing, bail out */
+ if (ast_strlen_zero(tmp)) {
+ dialog_unlink_all(p);
+ dialog_unref(p, "unref dialog p from bad destination");
+ *cause = AST_CAUSE_DESTINATION_OUT_OF_ORDER;
+ return NULL;
+ }
+
/* Divvy up the items separated by slashes */
AST_NONSTANDARD_APP_ARGS(args, tmp, '/');
diff --git a/channels/pjsip/dialplan_functions.c b/channels/pjsip/dialplan_functions.c
index 861edf72d..aa376f892 100644
--- a/channels/pjsip/dialplan_functions.c
+++ b/channels/pjsip/dialplan_functions.c
@@ -388,7 +388,7 @@
</enumlist>
</enum>
<enum name="target_uri">
- <para>The request URI of the <literal>INVITE</literal> request associated with the creation of this channel.</para>
+ <para>The contact URI where requests are sent.</para>
</enum>
<enum name="local_uri">
<para>The local URI.</para>
@@ -402,6 +402,10 @@
<enum name="remote_tag">
<para>Tag in To header</para>
</enum>
+ <enum name="request_uri">
+ <para>The request URI of the incoming <literal>INVITE</literal>
+ associated with the creation of this channel.</para>
+ </enum>
<enum name="t38state">
<para>The current state of any T.38 fax on this channel.</para>
<enumlist>
@@ -656,6 +660,27 @@ static int channel_read_rtcp(struct ast_channel *chan, const char *type, const c
return 0;
}
+static int print_escaped_uri(struct ast_channel *chan, const char *type,
+ pjsip_uri_context_e context, const void *uri, char *buf, size_t size)
+{
+ int res;
+ char *buf_copy;
+
+ res = pjsip_uri_print(context, uri, buf, size);
+ if (res < 0) {
+ ast_log(LOG_ERROR, "Channel %s: Unescaped %s too long for %d byte buffer\n",
+ ast_channel_name(chan), type, (int) size);
+
+ /* Empty buffer that likely is not terminated. */
+ buf[0] = '\0';
+ return -1;
+ }
+
+ buf_copy = ast_strdupa(buf);
+ ast_escape_quoted(buf_copy, buf, size);
+ return 0;
+}
+
/*!
* \internal \brief Handle reading signalling information
*/
@@ -664,6 +689,7 @@ static int channel_read_pjsip(struct ast_channel *chan, const char *type, const
struct ast_sip_channel_pvt *channel = ast_channel_tech_pvt(chan);
char *buf_copy;
pjsip_dialog *dlg;
+ int res = 0;
if (!channel) {
ast_log(AST_LOG_WARNING, "Channel %s has no pvt!\n", ast_channel_name(chan));
@@ -689,25 +715,27 @@ static int channel_read_pjsip(struct ast_channel *chan, const char *type, const
return -1;
#endif
} else if (!strcmp(type, "target_uri")) {
- pjsip_uri_print(PJSIP_URI_IN_REQ_URI, dlg->target, buf, buflen);
- buf_copy = ast_strdupa(buf);
- ast_escape_quoted(buf_copy, buf, buflen);
+ res = print_escaped_uri(chan, type, PJSIP_URI_IN_REQ_URI, dlg->target, buf,
+ buflen);
} else if (!strcmp(type, "local_uri")) {
- pjsip_uri_print(PJSIP_URI_IN_FROMTO_HDR, dlg->local.info->uri, buf, buflen);
- buf_copy = ast_strdupa(buf);
- ast_escape_quoted(buf_copy, buf, buflen);
+ res = print_escaped_uri(chan, type, PJSIP_URI_IN_FROMTO_HDR, dlg->local.info->uri,
+ buf, buflen);
} else if (!strcmp(type, "local_tag")) {
ast_copy_pj_str(buf, &dlg->local.info->tag, buflen);
buf_copy = ast_strdupa(buf);
ast_escape_quoted(buf_copy, buf, buflen);
} else if (!strcmp(type, "remote_uri")) {
- pjsip_uri_print(PJSIP_URI_IN_FROMTO_HDR, dlg->remote.info->uri, buf, buflen);
- buf_copy = ast_strdupa(buf);
- ast_escape_quoted(buf_copy, buf, buflen);
+ res = print_escaped_uri(chan, type, PJSIP_URI_IN_FROMTO_HDR,
+ dlg->remote.info->uri, buf, buflen);
} else if (!strcmp(type, "remote_tag")) {
ast_copy_pj_str(buf, &dlg->remote.info->tag, buflen);
buf_copy = ast_strdupa(buf);
ast_escape_quoted(buf_copy, buf, buflen);
+ } else if (!strcmp(type, "request_uri")) {
+ if (channel->session->request_uri) {
+ res = print_escaped_uri(chan, type, PJSIP_URI_IN_REQ_URI,
+ channel->session->request_uri, buf, buflen);
+ }
} else if (!strcmp(type, "t38state")) {
ast_copy_string(buf, t38state_to_string[channel->session->t38state], buflen);
} else if (!strcmp(type, "local_addr")) {
@@ -743,7 +771,7 @@ static int channel_read_pjsip(struct ast_channel *chan, const char *type, const
return -1;
}
- return 0;
+ return res;
}
/*! \brief Struct used to push function arguments to task processor */
diff --git a/channels/vgrabbers.c b/channels/vgrabbers.c
index 25817407e..169e59c5d 100644
--- a/channels/vgrabbers.c
+++ b/channels/vgrabbers.c
@@ -226,12 +226,8 @@ static void *grab_v4l1_open(const char *dev, struct fbuf_t *geom, int fps)
v->b = *geom;
b = &v->b; /* shorthand */
- i = fcntl(fd, F_GETFL);
- if (-1 == fcntl(fd, F_SETFL, i | O_NONBLOCK)) {
- /* non fatal, just emit a warning */
- ast_log(LOG_WARNING, "error F_SETFL for %s [%s]\n",
- dev, strerror(errno));
- }
+ ast_fd_set_flags(fd, O_NONBLOCK);
+
/* set format for the camera.
* In principle we could retry with a different format if the
* one we are asking for is not supported.
diff --git a/codecs/codec_dahdi.c b/codecs/codec_dahdi.c
index efb016853..941bb1fb2 100644
--- a/codecs/codec_dahdi.c
+++ b/codecs/codec_dahdi.c
@@ -613,7 +613,6 @@ static int dahdi_translate(struct ast_trans_pvt *pvt, uint32_t dst_dahdi_fmt, ui
/* Request translation through zap if possible */
int fd;
struct codec_dahdi_pvt *dahdip = pvt->pvt;
- int flags;
int tried_once = 0;
const char *dev_filename = "/dev/dahdi/transcode";
@@ -659,11 +658,7 @@ retry:
return -1;
}
- flags = fcntl(fd, F_GETFL);
- if (flags > - 1) {
- if (fcntl(fd, F_SETFL, flags | O_NONBLOCK))
- ast_log(LOG_WARNING, "Could not set non-block mode!\n");
- }
+ ast_fd_set_flags(fd, O_NONBLOCK);
dahdip->fd = fd;
diff --git a/codecs/codecs.xml b/codecs/codecs.xml
index 0b4e2a474..c3ccf00f1 100644
--- a/codecs/codecs.xml
+++ b/codecs/codecs.xml
@@ -3,6 +3,7 @@
<depend>xmlstarlet</depend>
<depend>bash</depend>
<depend>res_format_attr_opus</depend>
+ <depend>curl</depend>
<defaultenabled>no</defaultenabled>
</member>
<member name="codec_silk" displayname="Download the SILK codec from Digium. See http://downloads.digium.com/pub/telephony/codec_silk/README.">
diff --git a/configs/samples/iax.conf.sample b/configs/samples/iax.conf.sample
index ebe4d7fdc..c6da46179 100644
--- a/configs/samples/iax.conf.sample
+++ b/configs/samples/iax.conf.sample
@@ -576,12 +576,12 @@ inkeys=freeworlddialup
;
; Peers may also be specified, with a secret and a remote hostname.
;
-[demo]
-type=peer
-username=asterisk
-secret=supersecret
-host=216.207.245.47
-description=Demo System At Digium ; Description of this peer, as listed by
+;[demo]
+;type=peer
+;username=asterisk
+;secret=supersecret
+;host=192.168.10.10
+;description=My IAX2 Peer ; Description of this peer, as listed by
; 'iax2 show peers'
;sendani=no
;host=asterisk.linux-support.net
diff --git a/funcs/func_cdr.c b/funcs/func_cdr.c
index 573431237..2dd9f1578 100644
--- a/funcs/func_cdr.c
+++ b/funcs/func_cdr.c
@@ -356,7 +356,7 @@ static void cdr_read_callback(void *data, struct stasis_subscription *sub, struc
static void cdr_write_callback(void *data, struct stasis_subscription *sub, struct stasis_message *message)
{
- struct cdr_func_payload *payload = stasis_message_data(message);
+ struct cdr_func_payload *payload;
struct ast_flags flags = { 0 };
AST_DECLARE_APP_ARGS(args,
AST_APP_ARG(variable);
@@ -367,21 +367,17 @@ static void cdr_write_callback(void *data, struct stasis_subscription *sub, stru
if (cdr_write_message_type() != stasis_message_type(message)) {
return;
}
-
+ payload = stasis_message_data(message);
if (!payload) {
return;
}
-
- if (ast_strlen_zero(payload->arguments)) {
- ast_log(AST_LOG_WARNING, "%s requires a variable (%s(variable)=value)\n)",
- payload->cmd, payload->cmd);
- return;
- }
- if (!payload->value) {
- ast_log(AST_LOG_WARNING, "%s requires a value (%s(variable)=value)\n)",
- payload->cmd, payload->cmd);
+ if (ast_strlen_zero(payload->arguments)
+ || !payload->value) {
+ /* Sanity check. cdr_write() could never send these bad messages */
+ ast_assert(0);
return;
}
+
parse = ast_strdupa(payload->arguments);
AST_STANDARD_APP_ARGS(args, parse);
@@ -389,32 +385,16 @@ static void cdr_write_callback(void *data, struct stasis_subscription *sub, stru
ast_app_parse_options(cdr_func_options, &flags, NULL, args.options);
}
- if (!strcasecmp(args.variable, "accountcode")) {
- ast_log(AST_LOG_WARNING, "Using the CDR function to set 'accountcode' is deprecated. Please use the CHANNEL function instead.\n");
- ast_channel_lock(payload->chan);
- ast_channel_accountcode_set(payload->chan, payload->value);
- ast_channel_unlock(payload->chan);
- } else if (!strcasecmp(args.variable, "peeraccount")) {
- ast_log(AST_LOG_WARNING, "The 'peeraccount' setting is not supported. Please set the 'accountcode' on the appropriate channel using the CHANNEL function.\n");
- } else if (!strcasecmp(args.variable, "userfield")) {
+ /* These are already handled by cdr_write() */
+ ast_assert(strcasecmp(args.variable, "accountcode")
+ && strcasecmp(args.variable, "peeraccount")
+ && strcasecmp(args.variable, "amaflags"));
+
+ if (!strcasecmp(args.variable, "userfield")) {
ast_cdr_setuserfield(ast_channel_name(payload->chan), payload->value);
- } else if (!strcasecmp(args.variable, "amaflags")) {
- ast_log(AST_LOG_WARNING, "Using the CDR function to set 'amaflags' is deprecated. Please use the CHANNEL function instead.\n");
- if (isdigit(*payload->value)) {
- int amaflags;
- sscanf(payload->value, "%30d", &amaflags);
- ast_channel_lock(payload->chan);
- ast_channel_amaflags_set(payload->chan, amaflags);
- ast_channel_unlock(payload->chan);
- } else {
- ast_channel_lock(payload->chan);
- ast_channel_amaflags_set(payload->chan, ast_channel_string2amaflag(payload->value));
- ast_channel_unlock(payload->chan);
- }
} else {
ast_cdr_setvar(ast_channel_name(payload->chan), args.variable, payload->value);
}
- return;
}
static void cdr_prop_write_callback(void *data, struct stasis_subscription *sub, struct stasis_message *message)
@@ -523,27 +503,70 @@ static int cdr_read(struct ast_channel *chan, const char *cmd, char *parse,
return 0;
}
-static int cdr_write(struct ast_channel *chan, const char *cmd, char *parse,
- const char *value)
+static int cdr_write(struct ast_channel *chan, const char *cmd, char *arguments,
+ const char *value)
{
- RAII_VAR(struct stasis_message *, message, NULL, ao2_cleanup);
- RAII_VAR(struct cdr_func_payload *, payload, NULL, ao2_cleanup);
- RAII_VAR(struct stasis_message_router *, router,
- ast_cdr_message_router(), ao2_cleanup);
+ struct stasis_message *message;
+ struct cdr_func_payload *payload;
+ struct stasis_message_router *router;
+ AST_DECLARE_APP_ARGS(args,
+ AST_APP_ARG(variable);
+ AST_APP_ARG(options);
+ );
+ char *parse;
if (!chan) {
ast_log(LOG_WARNING, "No channel was provided to %s function.\n", cmd);
return -1;
}
-
- if (!router) {
- ast_log(AST_LOG_WARNING, "Failed to manipulate CDR for channel %s: no message router\n",
- ast_channel_name(chan));
+ if (ast_strlen_zero(arguments)) {
+ ast_log(LOG_WARNING, "%s requires a variable (%s(variable)=value)\n)",
+ cmd, cmd);
+ return -1;
+ }
+ if (!value) {
+ ast_log(LOG_WARNING, "%s requires a value (%s(variable)=value)\n)",
+ cmd, cmd);
return -1;
}
+ parse = ast_strdupa(arguments);
+ AST_STANDARD_APP_ARGS(args, parse);
+
+ /* These CDR variables are no longer supported or set directly on the channel */
+ if (!strcasecmp(args.variable, "accountcode")) {
+ ast_log(LOG_WARNING, "Using the %s function to set 'accountcode' is deprecated. Please use the CHANNEL function instead.\n",
+ cmd);
+ ast_channel_lock(chan);
+ ast_channel_accountcode_set(chan, value);
+ ast_channel_unlock(chan);
+ return 0;
+ }
+ if (!strcasecmp(args.variable, "amaflags")) {
+ int amaflags;
+
+ ast_log(LOG_WARNING, "Using the %s function to set 'amaflags' is deprecated. Please use the CHANNEL function instead.\n",
+ cmd);
+ if (isdigit(*value)) {
+ if (sscanf(value, "%30d", &amaflags) != 1) {
+ amaflags = AST_AMA_NONE;
+ }
+ } else {
+ amaflags = ast_channel_string2amaflag(value);
+ }
+ ast_channel_lock(chan);
+ ast_channel_amaflags_set(chan, amaflags);
+ ast_channel_unlock(chan);
+ return 0;
+ }
+ if (!strcasecmp(args.variable, "peeraccount")) {
+ ast_log(LOG_WARNING, "The 'peeraccount' setting is not supported. Please set the 'accountcode' on the appropriate channel using the CHANNEL function.\n");
+ return 0;
+ }
+
+ /* The remaining CDR variables are handled by CDR processing code */
if (!cdr_write_message_type()) {
- ast_log(AST_LOG_WARNING, "Failed to manipulate CDR for channel %s: message type not available\n",
+ ast_log(LOG_WARNING, "Failed to manipulate CDR for channel %s: message type not available\n",
ast_channel_name(chan));
return -1;
}
@@ -554,16 +577,26 @@ static int cdr_write(struct ast_channel *chan, const char *cmd, char *parse,
}
payload->chan = chan;
payload->cmd = cmd;
- payload->arguments = parse;
+ payload->arguments = arguments;
payload->value = value;
message = stasis_message_create(cdr_write_message_type(), payload);
+ ao2_ref(payload, -1);
if (!message) {
- ast_log(AST_LOG_WARNING, "Failed to manipulate CDR for channel %s: unable to create message\n",
+ ast_log(LOG_WARNING, "Failed to manipulate CDR for channel %s: unable to create message\n",
ast_channel_name(chan));
return -1;
}
+ router = ast_cdr_message_router();
+ if (!router) {
+ ast_log(LOG_WARNING, "Failed to manipulate CDR for channel %s: no message router\n",
+ ast_channel_name(chan));
+ ao2_ref(message, -1);
+ return -1;
+ }
stasis_message_router_publish_sync(router, message);
+ ao2_ref(router, -1);
+ ao2_ref(message, -1);
return 0;
}
@@ -586,7 +619,7 @@ static int cdr_prop_write(struct ast_channel *chan, const char *cmd, char *parse
return -1;
}
- if (!cdr_write_message_type()) {
+ if (!cdr_prop_write_message_type()) {
ast_log(AST_LOG_WARNING, "Failed to manipulate CDR for channel %s: message type not available\n",
ast_channel_name(chan));
return -1;
diff --git a/funcs/func_channel.c b/funcs/func_channel.c
index eb3ceddb4..b72cb141e 100644
--- a/funcs/func_channel.c
+++ b/funcs/func_channel.c
@@ -495,18 +495,17 @@ static int func_channel_write_real(struct ast_channel *chan, const char *functio
ast_bridge_set_after_go_on(chan, ast_channel_context(chan), ast_channel_exten(chan), ast_channel_priority(chan), value);
}
} else if (!strcasecmp(data, "amaflags")) {
- ast_channel_lock(chan);
+ int amaflags;
+
if (isdigit(*value)) {
- int amaflags;
- sscanf(value, "%30d", &amaflags);
- ast_channel_amaflags_set(chan, amaflags);
- } else if (!strcasecmp(value,"OMIT")){
- ast_channel_amaflags_set(chan, 1);
- } else if (!strcasecmp(value,"BILLING")){
- ast_channel_amaflags_set(chan, 2);
- } else if (!strcasecmp(value,"DOCUMENTATION")){
- ast_channel_amaflags_set(chan, 3);
+ if (sscanf(value, "%30d", &amaflags) != 1) {
+ amaflags = AST_AMA_NONE;
+ }
+ } else {
+ amaflags = ast_channel_string2amaflag(value);
}
+ ast_channel_lock(chan);
+ ast_channel_amaflags_set(chan, amaflags);
ast_channel_unlock(chan);
} else if (!strcasecmp(data, "peeraccount"))
locked_string_field_set(chan, peeraccount, value);
diff --git a/include/asterisk/astdb.h b/include/asterisk/astdb.h
index 8a870ae83..383864baf 100644
--- a/include/asterisk/astdb.h
+++ b/include/asterisk/astdb.h
@@ -83,6 +83,16 @@ int ast_db_deltree(const char *family, const char *keytree);
*/
struct ast_db_entry *ast_db_gettree(const char *family, const char *keytree);
+/*!
+ * \brief Get a list of values with the given key prefix
+ *
+ * \param family The family to search under
+ * \param key_prefix The key prefix to search under
+ *
+ * \retval NULL An error occurred
+ */
+struct ast_db_entry *ast_db_gettree_by_prefix(const char *family, const char *key_prefix);
+
/*! \brief Free structure created by ast_db_gettree() */
void ast_db_freetree(struct ast_db_entry *entry);
diff --git a/include/asterisk/res_pjsip_session.h b/include/asterisk/res_pjsip_session.h
index de6589abd..6d506a35b 100644
--- a/include/asterisk/res_pjsip_session.h
+++ b/include/asterisk/res_pjsip_session.h
@@ -211,6 +211,8 @@ struct ast_sip_session {
unsigned int ended_while_deferred:1;
/*! DTMF mode to use with this session, from endpoint but can change */
enum ast_sip_dtmf_mode dtmf;
+ /*! Initial incoming INVITE Request-URI. NULL otherwise. */
+ pjsip_uri *request_uri;
};
typedef int (*ast_sip_session_request_creation_cb)(struct ast_sip_session *session, pjsip_tx_data *tdata);
diff --git a/include/asterisk/utils.h b/include/asterisk/utils.h
index 0a12b1d8a..c6c34074e 100644
--- a/include/asterisk/utils.h
+++ b/include/asterisk/utils.h
@@ -1141,4 +1141,44 @@ int ast_compare_versions(const char *version1, const char *version2);
*/
int ast_check_ipv6(void);
+enum ast_fd_flag_operation {
+ AST_FD_FLAG_SET,
+ AST_FD_FLAG_CLEAR,
+};
+
+/*
+ * \brief Set flags on the given file descriptor
+ * \since 13.19
+ *
+ * If getting or setting flags of the given file descriptor fails, logs an
+ * error message.
+ *
+ * \param fd File descriptor to set flags on
+ * \param flags The flag(s) to set
+ *
+ * \return -1 on error
+ * \return 0 if successful
+ */
+#define ast_fd_set_flags(fd, flags) \
+ __ast_fd_set_flags((fd), (flags), AST_FD_FLAG_SET, __FILE__, __LINE__, __PRETTY_FUNCTION__)
+
+/*
+ * \brief Clear flags on the given file descriptor
+ * \since 13.19
+ *
+ * If getting or setting flags of the given file descriptor fails, logs an
+ * error message.
+ *
+ * \param fd File descriptor to clear flags on
+ * \param flags The flag(s) to clear
+ *
+ * \return -1 on error
+ * \return 0 if successful
+ */
+#define ast_fd_clear_flags(fd, flags) \
+ __ast_fd_set_flags((fd), (flags), AST_FD_FLAG_CLEAR, __FILE__, __LINE__, __PRETTY_FUNCTION__)
+
+int __ast_fd_set_flags(int fd, int flags, enum ast_fd_flag_operation op,
+ const char *file, int lineno, const char *function);
+
#endif /* _ASTERISK_UTILS_H */
diff --git a/main/alertpipe.c b/main/alertpipe.c
index fa6ec7bcc..7932a7346 100644
--- a/main/alertpipe.c
+++ b/main/alertpipe.c
@@ -55,17 +55,8 @@ int ast_alertpipe_init(int alert_pipe[2])
ast_log(LOG_WARNING, "Failed to create alert pipe: %s\n", strerror(errno));
return -1;
} else {
- int flags = fcntl(alert_pipe[0], F_GETFL);
- if (fcntl(alert_pipe[0], F_SETFL, flags | O_NONBLOCK) < 0) {
- ast_log(LOG_WARNING, "Failed to set non-blocking mode on alert pipe: %s\n",
- strerror(errno));
- ast_alertpipe_close(alert_pipe);
- return -1;
- }
- flags = fcntl(alert_pipe[1], F_GETFL);
- if (fcntl(alert_pipe[1], F_SETFL, flags | O_NONBLOCK) < 0) {
- ast_log(LOG_WARNING, "Failed to set non-blocking mode on alert pipe: %s\n",
- strerror(errno));
+ if (ast_fd_set_flags(alert_pipe[0], O_NONBLOCK)
+ || ast_fd_set_flags(alert_pipe[1], O_NONBLOCK)) {
ast_alertpipe_close(alert_pipe);
return -1;
}
diff --git a/main/asterisk.c b/main/asterisk.c
index 2c86d1ebc..006a1b03a 100644
--- a/main/asterisk.c
+++ b/main/asterisk.c
@@ -733,6 +733,27 @@ static char *handle_show_sysinfo(struct ast_cli_entry *e, int cmd, struct ast_cl
int totalswap = 0;
#if defined(HAVE_SYSINFO)
struct sysinfo sys_info;
+#elif defined(HAVE_SYSCTL)
+ static int pageshift;
+ struct vmtotal vmtotal;
+ struct timeval boottime;
+ time_t now;
+ int mib[2], pagesize, usedswap = 0;
+ size_t len;
+#endif
+
+ switch (cmd) {
+ case CLI_INIT:
+ e->command = "core show sysinfo";
+ e->usage =
+ "Usage: core show sysinfo\n"
+ " List current system information.\n";
+ return NULL;
+ case CLI_GENERATE:
+ return NULL;
+ }
+
+#if defined(HAVE_SYSINFO)
sysinfo(&sys_info);
uptime = sys_info.uptime / 3600;
physmem = sys_info.totalram * sys_info.mem_unit;
@@ -741,12 +762,6 @@ static char *handle_show_sysinfo(struct ast_cli_entry *e, int cmd, struct ast_cl
freeswap = (sys_info.freeswap * sys_info.mem_unit) / 1024;
nprocs = sys_info.procs;
#elif defined(HAVE_SYSCTL)
- static int pageshift;
- struct vmtotal vmtotal;
- struct timeval boottime;
- time_t now;
- int mib[2], pagesize, usedswap = 0;
- size_t len;
/* calculate the uptime by looking at boottime */
time(&now);
mib[0] = CTL_KERN;
@@ -794,17 +809,6 @@ static char *handle_show_sysinfo(struct ast_cli_entry *e, int cmd, struct ast_cl
#endif
#endif
- switch (cmd) {
- case CLI_INIT:
- e->command = "core show sysinfo";
- e->usage =
- "Usage: core show sysinfo\n"
- " List current system information.\n";
- return NULL;
- case CLI_GENERATE:
- return NULL;
- }
-
ast_cli(a->fd, "\nSystem Statistics\n");
ast_cli(a->fd, "-----------------\n");
ast_cli(a->fd, " System Uptime: %ld hours\n", uptime);
@@ -1569,7 +1573,6 @@ static void *listener(void *unused)
int s;
socklen_t len;
int x;
- int flags;
struct pollfd fds[1];
for (;;) {
if (ast_socket < 0)
@@ -1607,8 +1610,7 @@ static void *listener(void *unused)
close(s);
break;
}
- flags = fcntl(consoles[x].p[1], F_GETFL);
- fcntl(consoles[x].p[1], F_SETFL, flags | O_NONBLOCK);
+ ast_fd_set_flags(consoles[x].p[1], O_NONBLOCK);
consoles[x].mute = 1; /* Default is muted, we will un-mute if necessary */
/* Default uid and gid to -2, so then in cli.c/cli_has_permissions() we will be able
to know if the user didn't send the credentials. */
@@ -3012,19 +3014,26 @@ static char *cli_prompt(EditLine *editline)
static struct ast_vector_string *ast_el_strtoarr(char *buf)
{
char *retstr;
+ char *bestmatch;
struct ast_vector_string *vec = ast_calloc(1, sizeof(*vec));
if (!vec) {
return NULL;
}
+ /* bestmatch must not be deduplicated */
+ bestmatch = strsep(&buf, " ");
+ if (!bestmatch || !strcmp(bestmatch, AST_CLI_COMPLETE_EOF)) {
+ goto vector_cleanup;
+ }
+
while ((retstr = strsep(&buf, " "))) {
if (!strcmp(retstr, AST_CLI_COMPLETE_EOF)) {
break;
}
/* Older daemons sent duplicates. */
- if (AST_VECTOR_GET_CMP(vec, retstr, strcasecmp)) {
+ if (AST_VECTOR_GET_CMP(vec, retstr, !strcasecmp)) {
continue;
}
@@ -3036,7 +3045,9 @@ static struct ast_vector_string *ast_el_strtoarr(char *buf)
}
}
- if (!AST_VECTOR_SIZE(vec)) {
+ bestmatch = ast_strdup(bestmatch);
+ if (!bestmatch || AST_VECTOR_INSERT_AT(vec, 0, bestmatch)) {
+ ast_free(bestmatch);
goto vector_cleanup;
}
@@ -4632,10 +4643,15 @@ static void asterisk_daemon(int isroot, const char *runuser, const char *rungrou
check_init(init_manager(), "Asterisk Manager Interface");
check_init(ast_enum_init(), "ENUM Support");
check_init(ast_cc_init(), "Call Completion Supplementary Services");
- check_init(ast_sounds_index_init(), "Sounds Indexer");
check_init(load_modules(0), "Module");
/*
+ * This is initialized after the dynamic modules load to avoid repeatedly
+ * reindexing sounds for every format module load.
+ */
+ check_init(ast_sounds_index_init(), "Sounds Indexer");
+
+ /*
* This has to load after the dynamic modules load, as items in the media
* cache can't be constructed from items in the AstDB without their
* bucket backends.
diff --git a/main/bridge_basic.c b/main/bridge_basic.c
index fd6bac0c9..68138bdcc 100644
--- a/main/bridge_basic.c
+++ b/main/bridge_basic.c
@@ -3170,7 +3170,8 @@ static int grab_transfer(struct ast_channel *chan, char *exten, size_t exten_len
ast_channel_lock(chan);
xfer_cfg = ast_get_chan_features_xfer_config(chan);
if (!xfer_cfg) {
- ast_log(LOG_ERROR, "Unable to get transfer configuration\n");
+ ast_log(LOG_ERROR, "Channel %s: Unable to get transfer configuration\n",
+ ast_channel_name(chan));
ast_channel_unlock(chan);
return -1;
}
@@ -3214,9 +3215,9 @@ static int grab_transfer(struct ast_channel *chan, char *exten, size_t exten_len
} else if (!res) {
/* 0 for invalid extension dialed. */
if (ast_strlen_zero(exten)) {
- ast_debug(1, "%s dialed no digits.\n", ast_channel_name(chan));
+ ast_verb(3, "Channel %s: Dialed no digits.\n", ast_channel_name(chan));
} else {
- ast_debug(1, "%s dialed '%s@%s' does not exist.\n",
+ ast_verb(3, "Channel %s: Dialed '%s@%s' does not exist.\n",
ast_channel_name(chan), exten, context);
}
if (attempts < max_attempts) {
@@ -3303,9 +3304,12 @@ static int feature_attended_transfer(struct ast_bridge_channel *bridge_channel,
/* Inhibit the bridge before we do anything else. */
bridge = ast_bridge_channel_merge_inhibit(bridge_channel, +1);
+ ast_verb(3, "Channel %s: Started DTMF attended transfer.\n",
+ ast_channel_name(bridge_channel->chan));
+
if (strcmp(bridge->v_table->name, "basic")) {
- ast_log(LOG_ERROR, "Attended transfer attempted on unsupported bridge type '%s'.\n",
- bridge->v_table->name);
+ ast_log(LOG_ERROR, "Channel %s: Attended transfer attempted on unsupported bridge type '%s'.\n",
+ ast_channel_name(bridge_channel->chan), bridge->v_table->name);
ast_bridge_merge_inhibit(bridge, -1);
ao2_ref(bridge, -1);
return 0;
@@ -3327,7 +3331,8 @@ static int feature_attended_transfer(struct ast_bridge_channel *bridge_channel,
props = attended_transfer_properties_alloc(bridge_channel->chan,
attended_transfer ? attended_transfer->context : NULL);
if (!props) {
- ast_log(LOG_ERROR, "Unable to allocate control structure for performing attended transfer.\n");
+ ast_log(LOG_ERROR, "Channel %s: Unable to allocate control structure for performing attended transfer.\n",
+ ast_channel_name(bridge_channel->chan));
ast_bridge_merge_inhibit(bridge, -1);
ao2_ref(bridge, -1);
return 0;
@@ -3336,7 +3341,8 @@ static int feature_attended_transfer(struct ast_bridge_channel *bridge_channel,
props->transferee_bridge = bridge;
if (add_transferer_role(props->transferer, attended_transfer)) {
- ast_log(LOG_ERROR, "Unable to set transferrer bridge role.\n");
+ ast_log(LOG_ERROR, "Channel %s: Unable to set transferrer bridge role.\n",
+ ast_channel_name(bridge_channel->chan));
attended_transfer_properties_shutdown(props);
return 0;
}
@@ -3345,7 +3351,15 @@ static int feature_attended_transfer(struct ast_bridge_channel *bridge_channel,
/* Grab the extension to transfer to */
if (grab_transfer(bridge_channel->chan, exten, sizeof(exten), props->context)) {
- ast_log(LOG_WARNING, "Unable to acquire target extension for attended transfer.\n");
+ /*
+ * XXX The warning here really should be removed. While the
+ * message is accurate, this is a normal exit for when the user
+ * fails to specify a valid transfer target. e.g., The user
+ * hungup, didn't dial any digits, or dialed an invalid
+ * extension.
+ */
+ ast_log(LOG_WARNING, "Channel %s: Unable to acquire target extension for attended transfer.\n",
+ ast_channel_name(bridge_channel->chan));
ast_bridge_channel_write_unhold(bridge_channel);
attended_transfer_properties_shutdown(props);
return 0;
@@ -3356,12 +3370,14 @@ static int feature_attended_transfer(struct ast_bridge_channel *bridge_channel,
/* Fill the variable with the extension and context we want to call */
snprintf(destination, sizeof(destination), "%s@%s", props->exten, props->context);
- ast_debug(1, "Attended transfer to '%s'\n", destination);
+ ast_debug(1, "Channel %s: Attended transfer target '%s'\n",
+ ast_channel_name(bridge_channel->chan), destination);
/* Get a channel that is the destination we wish to call */
props->transfer_target = dial_transfer(bridge_channel->chan, destination);
if (!props->transfer_target) {
- ast_log(LOG_ERROR, "Unable to request outbound channel for attended transfer target.\n");
+ ast_log(LOG_ERROR, "Channel %s: Unable to request outbound channel for attended transfer target.\n",
+ ast_channel_name(bridge_channel->chan));
stream_failsound(props->transferer);
ast_bridge_channel_write_unhold(bridge_channel);
attended_transfer_properties_shutdown(props);
@@ -3372,7 +3388,8 @@ static int feature_attended_transfer(struct ast_bridge_channel *bridge_channel,
/* Create a bridge to use to talk to the person we are calling */
props->target_bridge = ast_bridge_basic_new();
if (!props->target_bridge) {
- ast_log(LOG_ERROR, "Unable to create bridge for attended transfer target.\n");
+ ast_log(LOG_ERROR, "Channel %s: Unable to create bridge for attended transfer target.\n",
+ ast_channel_name(bridge_channel->chan));
stream_failsound(props->transferer);
ast_bridge_channel_write_unhold(bridge_channel);
ast_hangup(props->transfer_target);
@@ -3383,7 +3400,8 @@ static int feature_attended_transfer(struct ast_bridge_channel *bridge_channel,
ast_bridge_merge_inhibit(props->target_bridge, +1);
if (attach_framehook(props, props->transfer_target)) {
- ast_log(LOG_ERROR, "Unable to attach framehook to transfer target.\n");
+ ast_log(LOG_ERROR, "Channel %s: Unable to attach framehook to transfer target.\n",
+ ast_channel_name(bridge_channel->chan));
stream_failsound(props->transferer);
ast_bridge_channel_write_unhold(bridge_channel);
ast_hangup(props->transfer_target);
@@ -3398,7 +3416,8 @@ static int feature_attended_transfer(struct ast_bridge_channel *bridge_channel,
BRIDGE_BASIC_PERSONALITY_ATXFER, props);
if (ast_call(props->transfer_target, destination, 0)) {
- ast_log(LOG_ERROR, "Unable to place outbound call to transfer target.\n");
+ ast_log(LOG_ERROR, "Channel %s: Unable to place outbound call to transfer target.\n",
+ ast_channel_name(bridge_channel->chan));
stream_failsound(props->transferer);
ast_bridge_channel_write_unhold(bridge_channel);
ast_hangup(props->transfer_target);
@@ -3414,7 +3433,8 @@ static int feature_attended_transfer(struct ast_bridge_channel *bridge_channel,
ast_channel_ref(props->transfer_target);
if (ast_bridge_impart(props->target_bridge, props->transfer_target, NULL, NULL,
AST_BRIDGE_IMPART_CHAN_INDEPENDENT)) {
- ast_log(LOG_ERROR, "Unable to place transfer target into bridge.\n");
+ ast_log(LOG_ERROR, "Channel %s: Unable to place transfer target into bridge.\n",
+ ast_channel_name(bridge_channel->chan));
stream_failsound(props->transferer);
ast_bridge_channel_write_unhold(bridge_channel);
ast_hangup(props->transfer_target);
@@ -3424,7 +3444,8 @@ static int feature_attended_transfer(struct ast_bridge_channel *bridge_channel,
}
if (ast_pthread_create_detached(&thread, NULL, attended_transfer_monitor_thread, props)) {
- ast_log(LOG_ERROR, "Unable to create monitoring thread for attended transfer.\n");
+ ast_log(LOG_ERROR, "Channel %s: Unable to create monitoring thread for attended transfer.\n",
+ ast_channel_name(bridge_channel->chan));
stream_failsound(props->transferer);
ast_bridge_channel_write_unhold(bridge_channel);
attended_transfer_properties_shutdown(props);
@@ -3455,6 +3476,9 @@ static int feature_blind_transfer(struct ast_bridge_channel *bridge_channel, voi
const char *xfer_context;
char *goto_on_blindxfr;
+ ast_verb(3, "Channel %s: Started DTMF blind transfer.\n",
+ ast_channel_name(bridge_channel->chan));
+
ast_bridge_channel_write_hold(bridge_channel, NULL);
ast_channel_lock(bridge_channel->chan);
@@ -3470,13 +3494,16 @@ static int feature_blind_transfer(struct ast_bridge_channel *bridge_channel, voi
return 0;
}
+ ast_debug(1, "Channel %s: Blind transfer target '%s@%s'\n",
+ ast_channel_name(bridge_channel->chan), xfer_exten, xfer_context);
+
if (!ast_strlen_zero(goto_on_blindxfr)) {
const char *chan_context;
const char *chan_exten;
int chan_priority;
- ast_debug(1, "After transfer, transferer %s goes to %s\n",
- ast_channel_name(bridge_channel->chan), goto_on_blindxfr);
+ ast_debug(1, "Channel %s: After transfer, transferrer goes to %s\n",
+ ast_channel_name(bridge_channel->chan), goto_on_blindxfr);
ast_channel_lock(bridge_channel->chan);
chan_context = ast_strdupa(ast_channel_context(bridge_channel->chan));
diff --git a/main/db.c b/main/db.c
index fa125d749..afaf04341 100644
--- a/main/db.c
+++ b/main/db.c
@@ -127,6 +127,20 @@ DEFINE_SQL_STATEMENT(gettree_all_stmt, "SELECT key, value FROM astdb ORDER BY ke
DEFINE_SQL_STATEMENT(showkey_stmt, "SELECT key, value FROM astdb WHERE key LIKE '%' || '/' || ? ORDER BY key")
DEFINE_SQL_STATEMENT(create_astdb_stmt, "CREATE TABLE IF NOT EXISTS astdb(key VARCHAR(256), value VARCHAR(256), PRIMARY KEY(key))")
+/* This query begs an explanation:
+ *
+ * First, the parameter binding syntax used here is slightly different then the other
+ * queries in that we use a numbered parameter so that we can bind once and get the same
+ * value substituted multiple times within the executed query.
+ *
+ * Second, the key comparison is being used to find all keys that are lexicographically
+ * greater than the provided key, but less than the provided key with a high (but
+ * invalid) Unicode codepoint appended to it. This will give us all keys in the database
+ * that have 'key' as a prefix and performs much better than the equivalent "LIKE key ||
+ * '%'" operation.
+ */
+DEFINE_SQL_STATEMENT(gettree_prefix_stmt, "SELECT key, value FROM astdb WHERE key > ?1 AND key <= ?1 || X'ffff'")
+
static int init_stmt(sqlite3_stmt **stmt, const char *sql, size_t len)
{
ast_mutex_lock(&dblock);
@@ -167,6 +181,7 @@ static void clean_statements(void)
clean_stmt(&deltree_all_stmt, deltree_all_stmt_sql);
clean_stmt(&gettree_stmt, gettree_stmt_sql);
clean_stmt(&gettree_all_stmt, gettree_all_stmt_sql);
+ clean_stmt(&gettree_prefix_stmt, gettree_prefix_stmt_sql);
clean_stmt(&showkey_stmt, showkey_stmt_sql);
clean_stmt(&put_stmt, put_stmt_sql);
clean_stmt(&create_astdb_stmt, create_astdb_stmt_sql);
@@ -182,6 +197,7 @@ static int init_statements(void)
|| init_stmt(&deltree_all_stmt, deltree_all_stmt_sql, sizeof(deltree_all_stmt_sql))
|| init_stmt(&gettree_stmt, gettree_stmt_sql, sizeof(gettree_stmt_sql))
|| init_stmt(&gettree_all_stmt, gettree_all_stmt_sql, sizeof(gettree_all_stmt_sql))
+ || init_stmt(&gettree_prefix_stmt, gettree_prefix_stmt_sql, sizeof(gettree_prefix_stmt_sql))
|| init_stmt(&showkey_stmt, showkey_stmt_sql, sizeof(showkey_stmt_sql))
|| init_stmt(&put_stmt, put_stmt_sql, sizeof(put_stmt_sql));
}
@@ -473,19 +489,64 @@ int ast_db_deltree(const char *family, const char *keytree)
return res;
}
+static struct ast_db_entry *db_gettree_common(sqlite3_stmt *stmt)
+{
+ struct ast_db_entry *head = NULL, *prev = NULL, *cur;
+
+ while (sqlite3_step(stmt) == SQLITE_ROW) {
+ const char *key, *value;
+ size_t key_len, value_len;
+
+ key = (const char *) sqlite3_column_text(stmt, 0);
+ value = (const char *) sqlite3_column_text(stmt, 1);
+
+ if (!key || !value) {
+ break;
+ }
+
+ key_len = strlen(key);
+ value_len = strlen(value);
+
+ cur = ast_malloc(sizeof(*cur) + key_len + value_len + 2);
+ if (!cur) {
+ break;
+ }
+
+ cur->next = NULL;
+ cur->key = cur->data + value_len + 1;
+ memcpy(cur->data, value, value_len + 1);
+ memcpy(cur->key, key, key_len + 1);
+
+ if (prev) {
+ prev->next = cur;
+ } else {
+ head = cur;
+ }
+ prev = cur;
+ }
+
+ return head;
+}
+
struct ast_db_entry *ast_db_gettree(const char *family, const char *keytree)
{
char prefix[MAX_DB_FIELD];
sqlite3_stmt *stmt = gettree_stmt;
- struct ast_db_entry *cur, *last = NULL, *ret = NULL;
+ size_t res = 0;
+ struct ast_db_entry *ret;
if (!ast_strlen_zero(family)) {
if (!ast_strlen_zero(keytree)) {
/* Family and key tree */
- snprintf(prefix, sizeof(prefix), "/%s/%s", family, keytree);
+ res = snprintf(prefix, sizeof(prefix), "/%s/%s", family, keytree);
} else {
/* Family only */
- snprintf(prefix, sizeof(prefix), "/%s", family);
+ res = snprintf(prefix, sizeof(prefix), "/%s", family);
+ }
+
+ if (res >= sizeof(prefix)) {
+ ast_log(LOG_WARNING, "Requested prefix is too long: %s\n", keytree);
+ return NULL;
}
} else {
prefix[0] = '\0';
@@ -493,41 +554,47 @@ struct ast_db_entry *ast_db_gettree(const char *family, const char *keytree)
}
ast_mutex_lock(&dblock);
- if (!ast_strlen_zero(prefix) && (sqlite3_bind_text(stmt, 1, prefix, -1, SQLITE_STATIC) != SQLITE_OK)) {
- ast_log(LOG_WARNING, "Could bind %s to stmt: %s\n", prefix, sqlite3_errmsg(astdb));
+ if (res && (sqlite3_bind_text(stmt, 1, prefix, res, SQLITE_STATIC) != SQLITE_OK)) {
+ ast_log(LOG_WARNING, "Could not bind %s to stmt: %s\n", prefix, sqlite3_errmsg(astdb));
sqlite3_reset(stmt);
ast_mutex_unlock(&dblock);
return NULL;
}
- while (sqlite3_step(stmt) == SQLITE_ROW) {
- const char *key_s, *value_s;
- if (!(key_s = (const char *) sqlite3_column_text(stmt, 0))) {
- break;
- }
- if (!(value_s = (const char *) sqlite3_column_text(stmt, 1))) {
- break;
- }
- if (!(cur = ast_malloc(sizeof(*cur) + strlen(key_s) + strlen(value_s) + 2))) {
- break;
- }
- cur->next = NULL;
- cur->key = cur->data + strlen(value_s) + 1;
- strcpy(cur->data, value_s);
- strcpy(cur->key, key_s);
- if (last) {
- last->next = cur;
- } else {
- ret = cur;
- }
- last = cur;
- }
+ ret = db_gettree_common(stmt);
sqlite3_reset(stmt);
ast_mutex_unlock(&dblock);
return ret;
}
+struct ast_db_entry *ast_db_gettree_by_prefix(const char *family, const char *key_prefix)
+{
+ char prefix[MAX_DB_FIELD];
+ size_t res;
+ struct ast_db_entry *ret;
+
+ res = snprintf(prefix, sizeof(prefix), "/%s/%s", family, key_prefix);
+ if (res >= sizeof(prefix)) {
+ ast_log(LOG_WARNING, "Requested key prefix is too long: %s\n", key_prefix);
+ return NULL;
+ }
+
+ ast_mutex_lock(&dblock);
+ if (sqlite3_bind_text(gettree_prefix_stmt, 1, prefix, res, SQLITE_STATIC) != SQLITE_OK) {
+ ast_log(LOG_WARNING, "Could not bind %s to stmt: %s\n", prefix, sqlite3_errmsg(astdb));
+ sqlite3_reset(gettree_prefix_stmt);
+ ast_mutex_unlock(&dblock);
+ return NULL;
+ }
+
+ ret = db_gettree_common(gettree_prefix_stmt);
+ sqlite3_reset(gettree_prefix_stmt);
+ ast_mutex_unlock(&dblock);
+
+ return ret;
+}
+
void ast_db_freetree(struct ast_db_entry *dbe)
{
struct ast_db_entry *last;
diff --git a/main/iostream.c b/main/iostream.c
index d91863319..aaa74fae1 100644
--- a/main/iostream.c
+++ b/main/iostream.c
@@ -77,7 +77,7 @@ int ast_iostream_get_fd(struct ast_iostream *stream)
void ast_iostream_nonblock(struct ast_iostream *stream)
{
- fcntl(stream->fd, F_SETFL, fcntl(stream->fd, F_GETFL) | O_NONBLOCK);
+ ast_fd_set_flags(stream->fd, O_NONBLOCK);
}
SSL *ast_iostream_get_ssl(struct ast_iostream *stream)
diff --git a/main/loader.c b/main/loader.c
index 19e30f835..23a29d994 100644
--- a/main/loader.c
+++ b/main/loader.c
@@ -376,35 +376,39 @@ static int verify_key(const unsigned char *key)
return -1;
}
-static int resource_name_match(const char *name1_in, const char *name2_in)
+static size_t resource_name_baselen(const char *name)
{
- char *name1 = (char *) name1_in;
- char *name2 = (char *) name2_in;
+ size_t len = strlen(name);
- /* trim off any .so extensions */
- if (!strcasecmp(name1 + strlen(name1) - 3, ".so")) {
- name1 = ast_strdupa(name1);
- name1[strlen(name1) - 3] = '\0';
+ if (len > 3 && !strcasecmp(name + len - 3, ".so")) {
+ return len - 3;
}
- if (!strcasecmp(name2 + strlen(name2) - 3, ".so")) {
- name2 = ast_strdupa(name2);
- name2[strlen(name2) - 3] = '\0';
+
+ return len;
+}
+
+static int resource_name_match(const char *name1, size_t baselen1, const char *name2)
+{
+ if (baselen1 != resource_name_baselen(name2)) {
+ return -1;
}
- return strcasecmp(name1, name2);
+ return strncasecmp(name1, name2, baselen1);
}
static struct ast_module *find_resource(const char *resource, int do_lock)
{
struct ast_module *cur;
+ size_t resource_baselen = resource_name_baselen(resource);
if (do_lock) {
AST_DLLIST_LOCK(&module_list);
}
AST_DLLIST_TRAVERSE(&module_list, cur, entry) {
- if (!resource_name_match(resource, cur->resource))
+ if (!resource_name_match(resource, resource_baselen, cur->resource)) {
break;
+ }
}
if (do_lock) {
@@ -939,6 +943,7 @@ enum ast_module_reload_result ast_module_reload(const char *name)
struct ast_module *cur;
enum ast_module_reload_result res = AST_MODULE_RELOAD_NOT_FOUND;
int i;
+ size_t name_baselen = name ? resource_name_baselen(name) : 0;
/* If we aren't fully booted, we just pretend we reloaded but we queue this
up to run once we are booted up. */
@@ -992,8 +997,9 @@ enum ast_module_reload_result ast_module_reload(const char *name)
AST_DLLIST_TRAVERSE(&module_list, cur, entry) {
const struct ast_module_info *info = cur->info;
- if (name && resource_name_match(name, cur->resource))
+ if (name && resource_name_match(name, name_baselen, cur->resource)) {
continue;
+ }
if (!cur->flags.running || cur->flags.declined) {
if (res == AST_MODULE_RELOAD_NOT_FOUND) {
@@ -1187,9 +1193,10 @@ AST_LIST_HEAD_NOLOCK(load_order, load_order_entry);
static struct load_order_entry *add_to_load_order(const char *resource, struct load_order *load_order, int required)
{
struct load_order_entry *order;
+ size_t resource_baselen = resource_name_baselen(resource);
AST_LIST_TRAVERSE(load_order, order, entry) {
- if (!resource_name_match(order->resource, resource)) {
+ if (!resource_name_match(resource, resource_baselen, order->resource)) {
/* Make sure we have the proper setting for the required field
(we might have both load= and required= lines in modules.conf) */
order->required |= required;
@@ -1436,11 +1443,15 @@ int load_modules(unsigned int preload_only)
/* now scan the config for any modules we are prohibited from loading and
remove them from the load order */
for (v = ast_variable_browse(cfg, "modules"); v; v = v->next) {
- if (strcasecmp(v->name, "noload"))
+ size_t baselen;
+
+ if (strcasecmp(v->name, "noload")) {
continue;
+ }
+ baselen = resource_name_baselen(v->value);
AST_LIST_TRAVERSE_SAFE_BEGIN(&load_order, order, entry) {
- if (!resource_name_match(order->resource, v->value)) {
+ if (!resource_name_match(v->value, baselen, order->resource)) {
AST_LIST_REMOVE_CURRENT(entry);
ast_free(order->resource);
ast_free(order);
diff --git a/main/media_index.c b/main/media_index.c
index 3e3824580..60bdfe3fd 100644
--- a/main/media_index.c
+++ b/main/media_index.c
@@ -45,10 +45,10 @@
/*! \brief Structure to hold a list of the format variations for a media file for a specific variant */
struct media_variant {
AST_DECLARE_STRING_FIELDS(
- AST_STRING_FIELD(variant); /*!< The variant this media is available in */
AST_STRING_FIELD(description); /*!< The description of the media */
);
struct ast_format_cap *formats; /*!< The formats this media is available in for this variant */
+ char variant[0]; /*!< The variant this media is available in */
};
static void media_variant_destroy(void *obj)
@@ -61,20 +61,23 @@ static void media_variant_destroy(void *obj)
static struct media_variant *media_variant_alloc(const char *variant_str)
{
- RAII_VAR(struct media_variant *, variant, ao2_alloc(sizeof(*variant), media_variant_destroy), ao2_cleanup);
+ size_t str_sz = strlen(variant_str) + 1;
+ struct media_variant *variant;
- if (!variant || ast_string_field_init(variant, 8)) {
+ variant = ao2_alloc(sizeof(*variant) + str_sz, media_variant_destroy);
+ if (!variant) {
return NULL;
}
+ memcpy(variant->variant, variant_str, str_sz);
+
variant->formats = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT);
- if (!variant->formats) {
+ if (!variant->formats || ast_string_field_init(variant, 8)) {
+ ao2_ref(variant, -1);
+
return NULL;
}
- ast_string_field_set(variant, variant, variant_str);
-
- ao2_ref(variant, 1);
return variant;
}
@@ -93,37 +96,35 @@ static int media_variant_cmp(void *obj, void *arg, int flags)
/*! \brief Structure to hold information about a media file */
struct media_info {
- AST_DECLARE_STRING_FIELDS(
- AST_STRING_FIELD(name); /*!< The file name of the media */
- );
- struct ao2_container *variants; /*!< The variants for which this media is available */
+ struct ao2_container *variants; /*!< The variants for which this media is available */
+ char name[0]; /*!< The file name of the media */
};
static void media_info_destroy(void *obj)
{
struct media_info *info = obj;
- ast_string_field_free_memory(info);
ao2_cleanup(info->variants);
- info->variants = NULL;
}
static struct media_info *media_info_alloc(const char *name)
{
- RAII_VAR(struct media_info *, info, ao2_alloc(sizeof(*info), media_info_destroy), ao2_cleanup);
+ size_t name_sz = strlen(name) + 1;
+ struct media_info *info = ao2_alloc(sizeof(*info) + name_sz, media_info_destroy);
- if (!info || ast_string_field_init(info, 128)) {
+ if (!info) {
return NULL;
}
+ memcpy(info->name, name, name_sz);
+
info->variants = ao2_container_alloc(VARIANT_BUCKETS, media_variant_hash, media_variant_cmp);
if (!info->variants) {
+ ao2_ref(info, -1);
+
return NULL;
}
- ast_string_field_set(info, name, name);
-
- ao2_ref(info, 1);
return info;
}
@@ -141,38 +142,37 @@ static int media_info_cmp(void *obj, void *arg, int flags)
}
struct ast_media_index {
- AST_DECLARE_STRING_FIELDS(
- AST_STRING_FIELD(base_dir); /*!< Base directory for indexing */
- );
struct ao2_container *index; /*!< The index of media that has requested */
struct ao2_container *media_list_cache; /*!< Cache of filenames to prevent them from being regenerated so often */
+ char base_dir[0]; /*!< Base directory for indexing */
};
static void media_index_dtor(void *obj)
{
struct ast_media_index *index = obj;
+
ao2_cleanup(index->index);
- index->index = NULL;
ao2_cleanup(index->media_list_cache);
- index->media_list_cache = NULL;
- ast_string_field_free_memory(index);
}
struct ast_media_index *ast_media_index_create(const char *base_dir)
{
- RAII_VAR(struct ast_media_index *, index, ao2_alloc(sizeof(*index), media_index_dtor), ao2_cleanup);
- if (!index || ast_string_field_init(index, 64)) {
+ size_t base_dir_sz = strlen(base_dir) + 1;
+ struct ast_media_index *index = ao2_alloc(sizeof(*index) + base_dir_sz, media_index_dtor);
+
+ if (!index) {
return NULL;
}
- ast_string_field_set(index, base_dir, base_dir);
+ memcpy(index->base_dir, base_dir, base_dir_sz);
index->index = ao2_container_alloc(INDEX_BUCKETS, media_info_hash, media_info_cmp);
if (!index->index) {
+ ao2_ref(index, -1);
+
return NULL;
}
- ao2_ref(index, +1);
return index;
}
@@ -191,8 +191,8 @@ static struct media_variant *find_variant(struct ast_media_index *index, const c
/*! \brief create the appropriate media_variant and any necessary structures */
static struct media_variant *alloc_variant(struct ast_media_index *index, const char *filename, const char *variant_str)
{
- RAII_VAR(struct media_info *, info, NULL, ao2_cleanup);
- RAII_VAR(struct media_variant *, variant, NULL, ao2_cleanup);
+ struct media_info *info;
+ struct media_variant *variant = NULL;
info = ao2_find(index->index, filename, OBJ_KEY);
if (!info) {
@@ -204,21 +204,21 @@ static struct media_variant *alloc_variant(struct ast_media_index *index, const
}
ao2_link(index->index, info);
+ } else {
+ variant = ao2_find(info->variants, variant_str, OBJ_KEY);
}
- variant = ao2_find(info->variants, variant_str, OBJ_KEY);
if (!variant) {
/* This is the first time the index has seen this variant for
* this filename, allocate and link */
variant = media_variant_alloc(variant_str);
- if (!variant) {
- return NULL;
+ if (variant) {
+ ao2_link(info->variants, variant);
}
-
- ao2_link(info->variants, variant);
}
- ao2_ref(variant, +1);
+ ao2_ref(info, -1);
+
return variant;
}
@@ -324,15 +324,16 @@ struct ao2_container *ast_media_get_media(struct ast_media_index *index)
/*! \brief Update an index with new format/variant information */
static int update_file_format_info(struct ast_media_index *index, const char *filename, const char *variant_str, struct ast_format *file_format)
{
- RAII_VAR(struct media_variant *, variant, find_variant(index, filename, variant_str), ao2_cleanup);
+ struct media_variant *variant;
+
+ variant = alloc_variant(index, filename, variant_str);
if (!variant) {
- variant = alloc_variant(index, filename, variant_str);
- if (!variant) {
- return -1;
- }
+ return -1;
}
ast_format_cap_append(variant->formats, file_format, 0);
+ ao2_ref(variant, -1);
+
return 0;
}
@@ -341,7 +342,8 @@ static int process_media_file(struct ast_media_index *index, const char *variant
{
struct ast_format *file_format;
const char *file_identifier = filename_stripped;
- RAII_VAR(struct ast_str *, file_id_str, NULL, ast_free);
+ char *file_id_str = NULL;
+ int res;
file_format = ast_get_format_for_file_ext(ext);
if (!file_format) {
@@ -351,19 +353,17 @@ static int process_media_file(struct ast_media_index *index, const char *variant
/* handle updating the file information */
if (subdir) {
- file_id_str = ast_str_create(64);
- if (!file_id_str) {
+ if (ast_asprintf(&file_id_str, "%s/%s", subdir, filename_stripped) == -1) {
return -1;
}
- ast_str_set(&file_id_str, 0, "%s/%s", subdir, filename_stripped);
- file_identifier = ast_str_buffer(file_id_str);
+ file_identifier = file_id_str;
}
- if (update_file_format_info(index, file_identifier, variant, file_format)) {
- return -1;
- }
- return 0;
+ res = update_file_format_info(index, file_identifier, variant, file_format);
+ ast_free(file_id_str);
+
+ return res;
}
/*!
@@ -443,20 +443,18 @@ static int process_description_file(struct ast_media_index *index,
} else {
/* if there's text in cumulative_description, archive it and start anew */
if (file_id_persist && !ast_strlen_zero(ast_str_buffer(cumulative_description))) {
- RAII_VAR(struct media_variant *, variant, NULL, ao2_cleanup);
+ struct media_variant *variant;
- variant = find_variant(index, file_id_persist, variant_str);
+ variant = alloc_variant(index, file_id_persist, variant_str);
if (!variant) {
- variant = alloc_variant(index, file_id_persist, variant_str);
- if (!variant) {
- res = -1;
- break;
- }
+ res = -1;
+ break;
}
ast_string_field_set(variant, description, ast_str_buffer(cumulative_description));
ast_str_reset(cumulative_description);
+ ao2_ref(variant, -1);
}
ast_free(file_id_persist);
@@ -468,15 +466,12 @@ static int process_description_file(struct ast_media_index *index,
/* handle the last one */
if (file_id_persist && !ast_strlen_zero(ast_str_buffer(cumulative_description))) {
- RAII_VAR(struct media_variant *, variant, NULL, ao2_cleanup);
-
- variant = find_variant(index, file_id_persist, variant_str);
- if (!variant) {
- variant = alloc_variant(index, file_id_persist, variant_str);
- }
+ struct media_variant *variant;
+ variant = alloc_variant(index, file_id_persist, variant_str);
if (variant) {
ast_string_field_set(variant, description, ast_str_buffer(cumulative_description));
+ ao2_ref(variant, -1);
} else {
res = -1;
}
diff --git a/main/sounds_index.c b/main/sounds_index.c
index c7f9f4dd9..c792c1bbd 100644
--- a/main/sounds_index.c
+++ b/main/sounds_index.c
@@ -285,13 +285,15 @@ static void sounds_cleanup(void)
static void format_update_cb(void *data, struct stasis_subscription *sub,
struct stasis_message *message)
{
- ast_sounds_reindex();
+ /* Reindexing during shutdown is pointless. */
+ if (!ast_shutting_down()) {
+ ast_sounds_reindex();
+ }
}
int ast_sounds_index_init(void)
{
int res = 0;
- sounds_index = NULL;
if (ast_sounds_reindex()) {
return -1;
}
@@ -328,6 +330,5 @@ int ast_sounds_index_init(void)
struct ast_media_index *ast_sounds_get_index(void)
{
- ao2_ref(sounds_index, +1);
- return sounds_index;
+ return ao2_bump(sounds_index);
}
diff --git a/main/stasis_channels.c b/main/stasis_channels.c
index b81dbe599..293db06d3 100644
--- a/main/stasis_channels.c
+++ b/main/stasis_channels.c
@@ -236,22 +236,24 @@ struct ast_channel_snapshot *ast_channel_snapshot_create(struct ast_channel *cha
S_COR(ast_channel_caller(chan)->id.name.valid, ast_channel_caller(chan)->id.name.str, ""));
ast_string_field_set(snapshot, caller_number,
S_COR(ast_channel_caller(chan)->id.number.valid, ast_channel_caller(chan)->id.number.str, ""));
- ast_string_field_set(snapshot, caller_dnid, S_OR(ast_channel_dialed(chan)->number.str, ""));
ast_string_field_set(snapshot, caller_subaddr,
S_COR(ast_channel_caller(chan)->id.subaddress.valid, ast_channel_caller(chan)->id.subaddress.str, ""));
- ast_string_field_set(snapshot, dialed_subaddr,
- S_COR(ast_channel_dialed(chan)->subaddress.valid, ast_channel_dialed(chan)->subaddress.str, ""));
ast_string_field_set(snapshot, caller_ani,
S_COR(ast_channel_caller(chan)->ani.number.valid, ast_channel_caller(chan)->ani.number.str, ""));
+
ast_string_field_set(snapshot, caller_rdnis,
S_COR(ast_channel_redirecting(chan)->from.number.valid, ast_channel_redirecting(chan)->from.number.str, ""));
+
ast_string_field_set(snapshot, caller_dnid,
S_OR(ast_channel_dialed(chan)->number.str, ""));
+ ast_string_field_set(snapshot, dialed_subaddr,
+ S_COR(ast_channel_dialed(chan)->subaddress.valid, ast_channel_dialed(chan)->subaddress.str, ""));
ast_string_field_set(snapshot, connected_name,
S_COR(ast_channel_connected(chan)->id.name.valid, ast_channel_connected(chan)->id.name.str, ""));
ast_string_field_set(snapshot, connected_number,
S_COR(ast_channel_connected(chan)->id.number.valid, ast_channel_connected(chan)->id.number.str, ""));
+
ast_string_field_set(snapshot, language, ast_channel_language(chan));
if ((bridge = ast_channel_get_bridge(chan))) {
diff --git a/main/tcptls.c b/main/tcptls.c
index a6d0538af..02a2af5c6 100644
--- a/main/tcptls.c
+++ b/main/tcptls.c
@@ -223,7 +223,7 @@ void *ast_tcptls_server_root(void *data)
pthread_t launched;
for (;;) {
- int i, flags;
+ int i;
if (desc->periodic_fn) {
desc->periodic_fn(desc);
@@ -261,8 +261,7 @@ void *ast_tcptls_server_root(void *data)
close(fd);
continue;
}
- flags = fcntl(fd, F_GETFL);
- fcntl(fd, F_SETFL, flags & ~O_NONBLOCK);
+ ast_fd_clear_flags(fd, O_NONBLOCK);
tcptls_session->stream = ast_iostream_from_fd(&fd);
if (!tcptls_session->stream) {
@@ -514,7 +513,6 @@ void ast_ssl_teardown(struct ast_tls_config *cfg)
struct ast_tcptls_session_instance *ast_tcptls_client_start(struct ast_tcptls_session_instance *tcptls_session)
{
struct ast_tcptls_session_args *desc;
- int flags;
if (!(desc = tcptls_session->parent)) {
goto client_start_error;
@@ -528,8 +526,7 @@ struct ast_tcptls_session_instance *ast_tcptls_client_start(struct ast_tcptls_se
goto client_start_error;
}
- flags = fcntl(desc->accept_fd, F_GETFL);
- fcntl(desc->accept_fd, F_SETFL, flags & ~O_NONBLOCK);
+ ast_fd_clear_flags(desc->accept_fd, O_NONBLOCK);
if (desc->tls_cfg) {
desc->tls_cfg->enabled = 1;
@@ -621,7 +618,6 @@ error:
void ast_tcptls_server_start(struct ast_tcptls_session_args *desc)
{
- int flags;
int x = 1;
int tls_changed = 0;
int sd_socket;
@@ -740,8 +736,7 @@ void ast_tcptls_server_start(struct ast_tcptls_session_args *desc)
}
systemd_socket_activation:
- flags = fcntl(desc->accept_fd, F_GETFL);
- fcntl(desc->accept_fd, F_SETFL, flags | O_NONBLOCK);
+ ast_fd_set_flags(desc->accept_fd, O_NONBLOCK);
if (ast_pthread_create_background(&desc->master, NULL, desc->accept_fn, desc)) {
ast_log(LOG_ERROR, "Unable to launch thread for %s on %s: %s\n",
desc->name,
diff --git a/main/translate.c b/main/translate.c
index 70e97f955..ce4745ce0 100644
--- a/main/translate.c
+++ b/main/translate.c
@@ -1307,7 +1307,7 @@ int ast_unregister_translator(struct ast_translator *t)
}
AST_RWLIST_TRAVERSE_SAFE_END;
- if (found) {
+ if (found && !ast_shutting_down()) {
matrix_rebuild(0);
}
diff --git a/main/udptl.c b/main/udptl.c
index 853e43c44..d982f6bcb 100644
--- a/main/udptl.c
+++ b/main/udptl.c
@@ -1012,7 +1012,6 @@ struct ast_udptl *ast_udptl_new_with_bindaddr(struct ast_sched_context *sched, s
int x;
int startplace;
int i;
- long int flags;
RAII_VAR(struct udptl_config *, cfg, ao2_global_obj_ref(globals), ao2_cleanup);
if (!cfg || !cfg->general) {
@@ -1043,8 +1042,7 @@ struct ast_udptl *ast_udptl_new_with_bindaddr(struct ast_sched_context *sched, s
ast_log(LOG_WARNING, "Unable to allocate socket: %s\n", strerror(errno));
return NULL;
}
- flags = fcntl(udptl->fd, F_GETFL);
- fcntl(udptl->fd, F_SETFL, flags | O_NONBLOCK);
+ ast_fd_set_flags(udptl->fd, O_NONBLOCK);
#ifdef SO_NO_CHECK
if (cfg->general->nochecksums)
diff --git a/main/utils.c b/main/utils.c
index dd7176295..a070da49f 100644
--- a/main/utils.c
+++ b/main/utils.c
@@ -2758,3 +2758,37 @@ int ast_compare_versions(const char *version1, const char *version2)
}
return extra[0] - extra[1];
}
+
+int __ast_fd_set_flags(int fd, int flags, enum ast_fd_flag_operation op,
+ const char *file, int lineno, const char *function)
+{
+ int f;
+
+ f = fcntl(fd, F_GETFL);
+ if (f == -1) {
+ ast_log(__LOG_ERROR, file, lineno, function,
+ "Failed to get fcntl() flags for file descriptor: %s\n", strerror(errno));
+ return -1;
+ }
+
+ switch (op) {
+ case AST_FD_FLAG_SET:
+ f |= flags;
+ break;
+ case AST_FD_FLAG_CLEAR:
+ f &= ~flags;
+ break;
+ default:
+ ast_assert(0);
+ break;
+ }
+
+ f = fcntl(fd, F_SETFL, f);
+ if (f == -1) {
+ ast_log(__LOG_ERROR, file, lineno, function,
+ "Failed to set fcntl() flags for file descriptor: %s\n", strerror(errno));
+ return -1;
+ }
+
+ return 0;
+}
diff --git a/menuselect/Makefile b/menuselect/Makefile
index 96c574eb8..c6a6facb6 100644
--- a/menuselect/Makefile
+++ b/menuselect/Makefile
@@ -64,7 +64,10 @@ all: $(ALL_TGTS)
$(OBJS) $(C_OBJS) $(N_OBJS) $(G_OBJS) $(M_OBJS): autoconfig.h menuselect.h
-makeopts autoconfig.h: autoconfig.h.in makeopts.in
+makeopts: makeopts.in
+autoconfig.h: autoconfig.h.in
+
+makeopts autoconfig.h:
@./configure $(CONFIGURE_SILENT)
@echo "****"
@echo "**** The configure script was just executed, so 'make' needs to be"
diff --git a/res/res_agi.c b/res/res_agi.c
index 13af48f49..85914c018 100644
--- a/res/res_agi.c
+++ b/res/res_agi.c
@@ -2046,7 +2046,7 @@ static int handle_connection(const char *agiurl, const struct ast_sockaddr addr,
FastAGI defaults to port 4573 */
static enum agi_result launch_netscript(char *agiurl, char *argv[], int *fds)
{
- int s = 0, flags;
+ int s = 0;
char *host, *script;
int num_addrs = 0, i = 0;
struct ast_sockaddr *addrs;
@@ -2076,14 +2076,7 @@ static enum agi_result launch_netscript(char *agiurl, char *argv[], int *fds)
continue;
}
- if ((flags = fcntl(s, F_GETFL)) < 0) {
- ast_log(LOG_WARNING, "fcntl(F_GETFL) failed: %s\n", strerror(errno));
- close(s);
- continue;
- }
-
- if (fcntl(s, F_SETFL, flags | O_NONBLOCK) < 0) {
- ast_log(LOG_WARNING, "fnctl(F_SETFL) failed: %s\n", strerror(errno));
+ if (ast_fd_set_flags(s, O_NONBLOCK)) {
close(s);
continue;
}
@@ -2249,9 +2242,8 @@ static enum agi_result launch_script(struct ast_channel *chan, char *script, int
close(toast[1]);
return AGI_RESULT_FAILURE;
}
- res = fcntl(audio[1], F_GETFL);
- if (res > -1)
- res = fcntl(audio[1], F_SETFL, res | O_NONBLOCK);
+
+ res = ast_fd_set_flags(audio[1], O_NONBLOCK);
if (res < 0) {
ast_log(LOG_WARNING, "unable to set audio pipe parameters: %s\n", strerror(errno));
close(fromast[0]);
diff --git a/res/res_http_websocket.c b/res/res_http_websocket.c
index c1f9a29d6..baaa40fd9 100644
--- a/res/res_http_websocket.c
+++ b/res/res_http_websocket.c
@@ -951,17 +951,11 @@ static struct ast_http_uri websocketuri = {
/*! \brief Simple echo implementation which echoes received text and binary frames */
static void websocket_echo_callback(struct ast_websocket *session, struct ast_variable *parameters, struct ast_variable *headers)
{
- int flags, res;
+ int res;
ast_debug(1, "Entering WebSocket echo loop\n");
- if ((flags = fcntl(ast_websocket_fd(session), F_GETFL)) == -1) {
- goto end;
- }
-
- flags |= O_NONBLOCK;
-
- if (fcntl(ast_websocket_fd(session), F_SETFL, flags) == -1) {
+ if (ast_fd_set_flags(ast_websocket_fd(session), O_NONBLOCK)) {
goto end;
}
diff --git a/res/res_musiconhold.c b/res/res_musiconhold.c
index e4bb7a2d9..ef1b81c2a 100644
--- a/res/res_musiconhold.c
+++ b/res/res_musiconhold.c
@@ -922,7 +922,6 @@ static struct mohclass *_get_mohbyname(const char *name, int warn, int flags, co
static struct mohdata *mohalloc(struct mohclass *cl)
{
struct mohdata *moh;
- long flags;
if (!(moh = ast_calloc(1, sizeof(*moh))))
return NULL;
@@ -934,10 +933,8 @@ static struct mohdata *mohalloc(struct mohclass *cl)
}
/* Make entirely non-blocking */
- flags = fcntl(moh->pipe[0], F_GETFL);
- fcntl(moh->pipe[0], F_SETFL, flags | O_NONBLOCK);
- flags = fcntl(moh->pipe[1], F_GETFL);
- fcntl(moh->pipe[1], F_SETFL, flags | O_NONBLOCK);
+ ast_fd_set_flags(moh->pipe[0], O_NONBLOCK);
+ ast_fd_set_flags(moh->pipe[1], O_NONBLOCK);
moh->f.frametype = AST_FRAME_VOICE;
moh->f.subclass.format = cl->format;
diff --git a/res/res_pjsip/config_transport.c b/res/res_pjsip/config_transport.c
index 2f29456ab..a9a90ac92 100644
--- a/res/res_pjsip/config_transport.c
+++ b/res/res_pjsip/config_transport.c
@@ -917,6 +917,12 @@ static int transport_tls_method_handler(const struct aco_option *opt, struct ast
state->tls.method = PJSIP_SSL_UNSPECIFIED_METHOD;
} else if (!strcasecmp(var->value, "tlsv1")) {
state->tls.method = PJSIP_TLSV1_METHOD;
+#ifdef HAVE_PJSIP_TLS_TRANSPORT_PROTO
+ } else if (!strcasecmp(var->value, "tlsv1_1")) {
+ state->tls.method = PJSIP_TLSV1_1_METHOD;
+ } else if (!strcasecmp(var->value, "tlsv1_2")) {
+ state->tls.method = PJSIP_TLSV1_2_METHOD;
+#endif
} else if (!strcasecmp(var->value, "sslv2")) {
state->tls.method = PJSIP_SSLV2_METHOD;
} else if (!strcasecmp(var->value, "sslv3")) {
@@ -933,6 +939,10 @@ static int transport_tls_method_handler(const struct aco_option *opt, struct ast
static const char *tls_method_map[] = {
[PJSIP_SSL_UNSPECIFIED_METHOD] = "unspecified",
[PJSIP_TLSV1_METHOD] = "tlsv1",
+#ifdef HAVE_PJSIP_TLS_TRANSPORT_PROTO
+ [PJSIP_TLSV1_1_METHOD] = "tlsv1_1",
+ [PJSIP_TLSV1_2_METHOD] = "tlsv1_2",
+#endif
[PJSIP_SSLV2_METHOD] = "sslv2",
[PJSIP_SSLV3_METHOD] = "sslv3",
[PJSIP_SSLV23_METHOD] = "sslv23",
diff --git a/res/res_pjsip/pjsip_cli.c b/res/res_pjsip/pjsip_cli.c
index 56ec191ed..4544a1717 100644
--- a/res/res_pjsip/pjsip_cli.c
+++ b/res/res_pjsip/pjsip_cli.c
@@ -82,31 +82,22 @@ int ast_sip_cli_print_sorcery_objectset(void *obj, void *arg, int flags)
return 0;
}
-static char *complete_show_sorcery_object(struct ao2_container *container,
+static void complete_show_sorcery_object(struct ao2_container *container,
struct ast_sip_cli_formatter_entry *formatter_entry,
- const char *word, int state)
+ const char *word)
{
- char *result = NULL;
- int wordlen = strlen(word);
- int which = 0;
-
- struct ao2_iterator i = ao2_iterator_init(container, 0);
+ size_t wordlen = strlen(word);
void *object;
+ struct ao2_iterator i = ao2_iterator_init(container, 0);
while ((object = ao2_t_iterator_next(&i, "iterate thru endpoints table"))) {
const char *id = formatter_entry->get_id(object);
- if (!strncasecmp(word, id, wordlen)
- && ++which > state) {
- result = ast_strdup(id);
+ if (!strncasecmp(word, id, wordlen)) {
+ ast_cli_completion_add(ast_strdup(id));
}
ao2_t_ref(object, -1, "toss iterator endpoint ptr before break");
- if (result) {
- break;
- }
}
ao2_iterator_destroy(&i);
-
- return result;
}
static void dump_str_and_free(int fd, struct ast_str *buf)
@@ -211,7 +202,8 @@ char *ast_sip_cli_traverse_objects(struct ast_cli_entry *e, int cmd, struct ast_
if (cmd == CLI_GENERATE) {
ast_free(context.output_buffer);
- return complete_show_sorcery_object(container, formatter_entry, a->word, a->n);
+ complete_show_sorcery_object(container, formatter_entry, a->word);
+ return NULL;
}
if (is_container) {
diff --git a/res/res_pjsip/pjsip_configuration.c b/res/res_pjsip/pjsip_configuration.c
index e63e158c4..76cf528eb 100644
--- a/res/res_pjsip/pjsip_configuration.c
+++ b/res/res_pjsip/pjsip_configuration.c
@@ -1,8 +1,19 @@
/*
- * sip_cli_commands.c
+ * Asterisk -- An open source telephony toolkit.
*
- * Created on: Jan 25, 2013
- * Author: mjordan
+ * Copyright (C) 2013, Digium, Inc.
+ *
+ * Matt Jordan <mjordan@digium.com>
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE file
+ * at the top of the source tree.
*/
#include "asterisk.h"
diff --git a/res/res_pjsip/pjsip_options.c b/res/res_pjsip/pjsip_options.c
index 662166c89..fbe07d53d 100644
--- a/res/res_pjsip/pjsip_options.c
+++ b/res/res_pjsip/pjsip_options.c
@@ -1147,7 +1147,24 @@ static int qualify_and_schedule_cb_with_aor(void *obj, void *arg, int flags)
static int qualify_and_schedule_cb_without_aor(void *obj, void *arg, int flags)
{
- qualify_and_schedule_contact((struct ast_sip_contact *) obj);
+ /*
+ * These are really dynamic contacts. We need to retrieve the aor associated
+ * with the contact since it's possible some of the aor's fields were updated
+ * since last load.
+ */
+ struct ast_sip_contact *contact = obj;
+ struct ast_sip_aor *aor = ast_sip_location_retrieve_aor(contact->aor);
+
+ if (aor) {
+ qualify_and_schedule_cb_with_aor(obj, aor, flags);
+ ao2_ref(aor, -1);
+ } else {
+ ast_log(LOG_WARNING, "Unable to locate AOR for contact '%s'. Keeping old "
+ "associated settings: frequency=%d, timeout=%f, authenticate=%s\n",
+ contact->uri, contact->qualify_frequency, contact->qualify_timeout,
+ contact->authenticate_qualify ? "yes" : "no");
+ qualify_and_schedule_contact(contact);
+ }
return 0;
}
@@ -1175,32 +1192,21 @@ static int qualify_and_schedule_all_cb(void *obj, void *arg, int flags)
return 0;
}
-/*!
- * \internal
- * \brief Unschedule all existing contacts
- */
-static int unschedule_all_cb(void *obj, void *arg, int flags)
-{
- struct sched_data *data = obj;
-
- AST_SCHED_DEL_UNREF(sched, data->id, ao2_ref(data, -1));
-
- return CMP_MATCH;
-}
-
static void qualify_and_schedule_all(void)
{
- struct ast_variable *var = ast_variable_new("qualify_frequency >", "0", "");
struct ao2_container *aors;
struct ao2_container *contacts;
- if (!var) {
- return;
- }
- aors = ast_sorcery_retrieve_by_fields(ast_sip_get_sorcery(),
- "aor", AST_RETRIEVE_FLAG_MULTIPLE, var);
+ /*
+ * It's possible that the AOR had some of it's fields updated prior to a
+ * reload. For instance qualifying could have been turned on or off by
+ * setting the qualify_frequency. Due to this we have to iterate through
+ * all contacts (static and dynamic), and not just ones where the frequency
+ * is greater than zero, updating any contact fields with the AOR's values.
+ */
- ao2_callback(sched_qualifies, OBJ_NODATA | OBJ_MULTIPLE | OBJ_UNLINK, unschedule_all_cb, NULL);
+ aors = ast_sorcery_retrieve_by_fields(ast_sip_get_sorcery(),
+ "aor", AST_RETRIEVE_FLAG_MULTIPLE | AST_RETRIEVE_FLAG_ALL, NULL);
if (aors) {
ao2_callback(aors, OBJ_NODATA, qualify_and_schedule_all_cb, NULL);
@@ -1208,14 +1214,11 @@ static void qualify_and_schedule_all(void)
}
contacts = ast_sorcery_retrieve_by_fields(ast_sip_get_sorcery(),
- "contact", AST_RETRIEVE_FLAG_MULTIPLE, var);
+ "contact", AST_RETRIEVE_FLAG_MULTIPLE | AST_RETRIEVE_FLAG_ALL, NULL);
if (contacts) {
ao2_callback(contacts, OBJ_NODATA, qualify_and_schedule_cb_without_aor, NULL);
ao2_ref(contacts, -1);
}
-
- ast_variables_destroy(var);
-
}
int ast_sip_format_contact_ami(void *obj, void *arg, int flags)
diff --git a/res/res_pjsip_dlg_options.c b/res/res_pjsip_dlg_options.c
index e2ed29a2c..de1ac97ef 100644
--- a/res/res_pjsip_dlg_options.c
+++ b/res/res_pjsip_dlg_options.c
@@ -99,6 +99,7 @@ static int unload_module(void)
}
AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "SIP OPTIONS in dialog handler",
+ .support_level = AST_MODULE_SUPPORT_CORE,
.load = load_module,
.unload = unload_module,
.load_pri = AST_MODPRI_APP_DEPEND,
diff --git a/res/res_pjsip_outbound_publish.c b/res/res_pjsip_outbound_publish.c
index f1f49d510..e5f12951f 100644
--- a/res/res_pjsip_outbound_publish.c
+++ b/res/res_pjsip_outbound_publish.c
@@ -1697,6 +1697,7 @@ static int reload_module(void)
}
AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_GLOBAL_SYMBOLS | AST_MODFLAG_LOAD_ORDER, "PJSIP Outbound Publish Support",
+ .support_level = AST_MODULE_SUPPORT_CORE,
.load = load_module,
.reload = reload_module,
.unload = unload_module,
diff --git a/res/res_pjsip_phoneprov_provider.c b/res/res_pjsip_phoneprov_provider.c
index eef3a082f..7e082c4b5 100644
--- a/res/res_pjsip_phoneprov_provider.c
+++ b/res/res_pjsip_phoneprov_provider.c
@@ -413,6 +413,7 @@ static int reload_module(void)
}
AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "PJSIP Phoneprov Provider",
+ .support_level = AST_MODULE_SUPPORT_EXTENDED,
.load = load_module,
.reload = reload_module,
.unload = unload_module,
diff --git a/res/res_pjsip_publish_asterisk.c b/res/res_pjsip_publish_asterisk.c
index 72e1e4d7e..53ee60fe4 100644
--- a/res/res_pjsip_publish_asterisk.c
+++ b/res/res_pjsip_publish_asterisk.c
@@ -929,6 +929,7 @@ static int unload_module(void)
}
AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "PJSIP Asterisk Event PUBLISH Support",
+ .support_level = AST_MODULE_SUPPORT_CORE,
.load = load_module,
.reload = reload_module,
.unload = unload_module,
diff --git a/res/res_pjsip_sdp_rtp.c b/res/res_pjsip_sdp_rtp.c
index a87758267..854ed1459 100644
--- a/res/res_pjsip_sdp_rtp.c
+++ b/res/res_pjsip_sdp_rtp.c
@@ -1253,7 +1253,8 @@ static int add_crypto_to_stream(struct ast_sip_session *session,
/* If this is an answer we need to use our current state, if it's an offer we need to use
* the configured value.
*/
- if (pjmedia_sdp_neg_get_state(session->inv_session->neg) != PJMEDIA_SDP_NEG_STATE_DONE) {
+ if (session->inv_session->neg
+ && pjmedia_sdp_neg_get_state(session->inv_session->neg) != PJMEDIA_SDP_NEG_STATE_DONE) {
setup = dtls->get_setup(session_media->rtp);
} else {
setup = session->endpoint->media.rtp.dtls_cfg.default_setup;
diff --git a/res/res_pjsip_session.c b/res/res_pjsip_session.c
index 781d3e4eb..958f2254b 100644
--- a/res/res_pjsip_session.c
+++ b/res/res_pjsip_session.c
@@ -2818,6 +2818,12 @@ static enum sip_get_destination_result get_destination(struct ast_sip_session *s
ast_copy_pj_str(domain, &sip_ruri->host, size);
pbx_builtin_setvar_helper(session->channel, "SIPDOMAIN", domain);
+ /*
+ * Save off the INVITE Request-URI in case it is
+ * needed: CHANNEL(pjsip,request_uri)
+ */
+ session->request_uri = pjsip_uri_clone(session->inv_session->pool, ruri);
+
return SIP_GET_DEST_EXTEN_FOUND;
}
@@ -3872,10 +3878,15 @@ static struct pjmedia_sdp_session *create_local_sdp(pjsip_inv_session *inv, stru
if (!session->pending_media_state->topology || !ast_stream_topology_get_count(session->pending_media_state->topology)) {
/* We've encountered a situation where we have been told to create a local SDP but noone has given us any indication
- * of what kind of stream topology they would like. As a fallback we use the topology from the configured endpoint.
+ * of what kind of stream topology they would like. We try to not alter the current state of the SDP negotiation
+ * by using what is currently negotiated. If this is unavailable we fall back to what is configured on the endpoint.
*/
ast_stream_topology_free(session->pending_media_state->topology);
- session->pending_media_state->topology = ast_stream_topology_clone(session->endpoint->media.topology);
+ if (session->active_media_state->topology) {
+ session->pending_media_state->topology = ast_stream_topology_clone(session->active_media_state->topology);
+ } else {
+ session->pending_media_state->topology = ast_stream_topology_clone(session->endpoint->media.topology);
+ }
if (!session->pending_media_state->topology) {
return NULL;
}
diff --git a/res/res_pktccops.c b/res/res_pktccops.c
index e8d266cda..156c49dc7 100644
--- a/res/res_pktccops.c
+++ b/res/res_pktccops.c
@@ -648,7 +648,7 @@ static struct cops_gate *cops_gate_cmd(int cmd, struct cops_cmts *cmts,
static int cops_connect(char *host, char *port)
{
- int s, sfd = -1, flags;
+ int s, sfd = -1;
struct addrinfo hints;
struct addrinfo *rp;
struct addrinfo *result;
@@ -674,8 +674,7 @@ static int cops_connect(char *host, char *port)
if (sfd == -1) {
ast_log(LOG_WARNING, "Failed socket\n");
}
- flags = fcntl(sfd, F_GETFL);
- fcntl(sfd, F_SETFL, flags | O_NONBLOCK);
+ ast_fd_set_flags(sfd, O_NONBLOCK);
#ifdef HAVE_SO_NOSIGPIPE
setsockopt(sfd, SOL_SOCKET, SO_NOSIGPIPE, &trueval, sizeof(trueval));
#endif
diff --git a/res/res_rtp_asterisk.c b/res/res_rtp_asterisk.c
index 5aeb791d3..bdc83301e 100644
--- a/res/res_rtp_asterisk.c
+++ b/res/res_rtp_asterisk.c
@@ -3048,8 +3048,7 @@ static int create_new_socket(const char *type, int af)
}
ast_log(LOG_WARNING, "Unable to allocate %s socket: %s\n", type, strerror(errno));
} else {
- long flags = fcntl(sock, F_GETFL);
- fcntl(sock, F_SETFL, flags | O_NONBLOCK);
+ ast_fd_set_flags(sock, O_NONBLOCK);
#ifdef SO_NO_CHECK
if (nochecksums) {
setsockopt(sock, SOL_SOCKET, SO_NO_CHECK, &nochecksums, sizeof(nochecksums));
@@ -5170,7 +5169,6 @@ static struct ast_frame *ast_rtcp_interpret(struct ast_rtp_instance *instance, c
unsigned int first_word;
/*! True if we have seen an acceptable SSRC to learn the remote RTCP address */
unsigned int ssrc_seen;
- int report_counter = 0;
struct ast_rtp_rtcp_report_block *report_block;
struct ast_frame *f = &ast_null_frame;
@@ -5414,7 +5412,7 @@ static struct ast_frame *ast_rtcp_interpret(struct ast_rtp_instance *instance, c
}
return &ast_null_frame;
}
- rtcp_report->report_block[report_counter] = report_block;
+ rtcp_report->report_block[0] = report_block;
report_block->source_ssrc = ntohl(rtcpheader[i]);
report_block->lost_count.packets = ntohl(rtcpheader[i + 1]) & 0x00ffffff;
report_block->lost_count.fraction = ((ntohl(rtcpheader[i + 1]) & 0xff000000) >> 24);
@@ -5451,7 +5449,6 @@ static struct ast_frame *ast_rtcp_interpret(struct ast_rtp_instance *instance, c
ast_verbose(" DLSR: %4.4f (sec)\n",(double)report_block->dlsr / 65536.0);
ast_verbose(" RTT: %4.4f(sec)\n", rtp->rtcp->rtt);
}
- report_counter++;
}
/* If and when we handle more than one report block, this should occur outside
* this loop.
@@ -5476,9 +5473,9 @@ static struct ast_frame *ast_rtcp_interpret(struct ast_rtp_instance *instance, c
/* There's always a single report block stored, here */
struct ast_rtp_rtcp_report *rtcp_report2;
report_block = transport_rtp->f.data.ptr + transport_rtp->f.datalen + sizeof(struct ast_rtp_rtcp_report_block *);
- memcpy(report_block, rtcp_report->report_block[report_counter-1], sizeof(struct ast_rtp_rtcp_report_block));
+ memcpy(report_block, rtcp_report->report_block[0], sizeof(struct ast_rtp_rtcp_report_block));
rtcp_report2 = (struct ast_rtp_rtcp_report *)transport_rtp->f.data.ptr;
- rtcp_report2->report_block[report_counter-1] = report_block;
+ rtcp_report2->report_block[0] = report_block;
transport_rtp->f.datalen += sizeof(struct ast_rtp_rtcp_report_block);
}
transport_rtp->f.offset = AST_FRIENDLY_OFFSET;
diff --git a/res/res_sorcery_astdb.c b/res/res_sorcery_astdb.c
index 8b93b57ba..87823be0d 100644
--- a/res/res_sorcery_astdb.c
+++ b/res/res_sorcery_astdb.c
@@ -334,14 +334,14 @@ static void sorcery_astdb_retrieve_prefix(const struct ast_sorcery *sorcery, voi
const char *family_prefix = data;
size_t family_len = strlen(family_prefix) + strlen(type) + 1; /* +1 for slash delimiter */
char family[family_len + 1];
- char tree[prefix_len + sizeof("%")];
+ char tree[prefix_len + 1];
RAII_VAR(struct ast_db_entry *, entries, NULL, ast_db_freetree);
struct ast_db_entry *entry;
- snprintf(tree, sizeof(tree), "%.*s%%", (int) prefix_len, prefix);
+ snprintf(tree, sizeof(tree), "%.*s", (int) prefix_len, prefix);
snprintf(family, sizeof(family), "%s/%s", family_prefix, type);
- if (!(entries = ast_db_gettree(family, tree))) {
+ if (!(entries = ast_db_gettree_by_prefix(family, tree))) {
return;
}
diff --git a/res/res_speech.c b/res/res_speech.c
index d6c532971..31ad61acb 100644
--- a/res/res_speech.c
+++ b/res/res_speech.c
@@ -363,5 +363,5 @@ AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_GLOBAL_SYMBOLS | AST_MODFLAG_LOAD_
.support_level = AST_MODULE_SUPPORT_CORE,
.load = load_module,
.unload = unload_module,
- .load_pri = AST_MODPRI_APP_DEPEND,
+ .load_pri = AST_MODPRI_APP_DEPEND - 1,
);
diff --git a/res/res_stasis.c b/res/res_stasis.c
index f99dcee37..42a19bf56 100644
--- a/res/res_stasis.c
+++ b/res/res_stasis.c
@@ -2155,8 +2155,8 @@ static int load_module(void)
return AST_MODULE_LOAD_SUCCESS;
}
-AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_GLOBAL_SYMBOLS, "Stasis application support",
- .load_pri = AST_MODPRI_APP_DEPEND,
+AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_GLOBAL_SYMBOLS | AST_MODFLAG_LOAD_ORDER, "Stasis application support",
+ .load_pri = AST_MODPRI_APP_DEPEND - 1,
.support_level = AST_MODULE_SUPPORT_CORE,
.load = load_module,
.unload = unload_module,
diff --git a/res/res_timing_pthread.c b/res/res_timing_pthread.c
index 09952f929..f52079643 100644
--- a/res/res_timing_pthread.c
+++ b/res/res_timing_pthread.c
@@ -130,9 +130,7 @@ static void *pthread_timer_open(void)
}
for (i = 0; i < ARRAY_LEN(timer->pipe); ++i) {
- int flags = fcntl(timer->pipe[i], F_GETFL);
- flags |= O_NONBLOCK;
- fcntl(timer->pipe[i], F_SETFL, flags);
+ ast_fd_set_flags(timer->pipe[i], O_NONBLOCK);
}
ao2_lock(pthread_timers);