diff options
Diffstat (limited to 'main')
-rw-r--r-- | main/app.c | 26 | ||||
-rw-r--r-- | main/asterisk.c | 1 | ||||
-rw-r--r-- | main/astobj2.c | 13 | ||||
-rw-r--r-- | main/channel.c | 10 | ||||
-rw-r--r-- | main/format_compatibility.c | 4 | ||||
-rw-r--r-- | main/frame.c | 69 | ||||
-rw-r--r-- | main/libasteriskpj.c | 2 | ||||
-rw-r--r-- | main/strings.c | 21 |
8 files changed, 97 insertions, 49 deletions
diff --git a/main/app.c b/main/app.c index 58aa3a0fd..ee7cef26b 100644 --- a/main/app.c +++ b/main/app.c @@ -1422,22 +1422,20 @@ static struct ast_frame *make_silence(const struct ast_frame *orig) size_t size; size_t datalen; size_t samples = 0; - struct ast_frame *next; if (!orig) { return NULL; } + do { + if (ast_format_cmp(orig->subclass.format, ast_format_slin) == AST_FORMAT_CMP_NOT_EQUAL) { + ast_log(LOG_WARNING, "Attempting to silence non-slin frame\n"); + return NULL; + } - if (ast_format_cmp(orig->subclass.format, ast_format_slin) == AST_FORMAT_CMP_NOT_EQUAL) { - ast_log(LOG_WARNING, "Attempting to silence non-slin frame\n"); - return NULL; - } - - for (next = AST_LIST_NEXT(orig, frame_list); - orig; - orig = next, next = orig ? AST_LIST_NEXT(orig, frame_list) : NULL) { samples += orig->samples; - } + + orig = AST_LIST_NEXT(orig, frame_list); + } while (orig); ast_verb(4, "Silencing %zu samples\n", samples); @@ -1455,7 +1453,7 @@ static struct ast_frame *make_silence(const struct ast_frame *orig) silence->samples = samples; silence->datalen = datalen; - silence->subclass.format = ast_format_slin; + silence->subclass.format = ao2_bump(ast_format_slin); return silence; } @@ -1661,14 +1659,13 @@ static int __ast_play_and_record(struct ast_channel *chan, const char *playfile, /* It's all good */ res = 0; } else { - RAII_VAR(struct ast_frame *, silence, NULL, ast_frame_dtor); + struct ast_frame *silence = NULL; struct ast_frame *orig = f; if (muted) { silence = make_silence(orig); if (!silence) { - ast_log(LOG_WARNING, - "Error creating silence\n"); + ast_log(LOG_WARNING, "Error creating silence\n"); break; } f = silence; @@ -1679,6 +1676,7 @@ static int __ast_play_and_record(struct ast_channel *chan, const char *playfile, } res = ast_writestream(others[x], f); } + ast_frame_dtor(silence); f = orig; } diff --git a/main/asterisk.c b/main/asterisk.c index 2236e8c69..994dfbeb7 100644 --- a/main/asterisk.c +++ b/main/asterisk.c @@ -325,6 +325,7 @@ int ast_verb_sys_level; int option_verbose; /*!< Verbosity level */ int option_debug; /*!< Debug level */ +int ast_pjproject_max_log_level = -1;/* Default to -1 to know if we have read the level from pjproject yet. */ int ast_option_pjproject_log_level; double ast_option_maxload; /*!< Max load avg on system */ int ast_option_maxcalls; /*!< Max number of active calls */ diff --git a/main/astobj2.c b/main/astobj2.c index 7320c5efb..569db0b7b 100644 --- a/main/astobj2.c +++ b/main/astobj2.c @@ -421,6 +421,19 @@ static int internal_ao2_ref(void *user_data, int delta, const char *file, int li if (0 < current_value) { /* The object still lives. */ +#define EXCESSIVE_REF_COUNT 100000 + + if (EXCESSIVE_REF_COUNT <= current_value && ret < EXCESSIVE_REF_COUNT) { + char excessive_ref_buf[100]; + + /* We just reached or went over the excessive ref count trigger */ + snprintf(excessive_ref_buf, sizeof(excessive_ref_buf), + "Excessive refcount %d reached on ao2 object %p", + current_value, user_data); + ast_log(__LOG_ERROR, file, line, func, "%s\n", excessive_ref_buf); + + __ast_assert_failed(0, excessive_ref_buf, file, line, func); + } return ret; } diff --git a/main/channel.c b/main/channel.c index 637488a9c..f305cc8bb 100644 --- a/main/channel.c +++ b/main/channel.c @@ -4889,16 +4889,18 @@ int ast_sendtext(struct ast_channel *chan, const char *text) if (ast_channel_tech(chan)->write_text && (ast_format_cap_has_type(ast_channel_nativeformats(chan), AST_MEDIA_TYPE_TEXT))) { struct ast_frame f; + memset(&f, 0, sizeof(f)); f.frametype = AST_FRAME_TEXT; f.src = "DIALPLAN"; f.mallocd = AST_MALLOCD_DATA; f.datalen = strlen(text); f.data.ptr = ast_strdup(text); - f.offset = 0; - f.seqno = 0; - f.subclass.format = ast_format_t140; - res = ast_channel_tech(chan)->write_text(chan, &f); + + if (f.data.ptr) { + res = ast_channel_tech(chan)->write_text(chan, &f); + ast_frfree(&f); + } } else if (ast_channel_tech(chan)->send_text) { res = ast_channel_tech(chan)->send_text(chan, text); } diff --git a/main/format_compatibility.c b/main/format_compatibility.c index cf66af282..0f1dff7c8 100644 --- a/main/format_compatibility.c +++ b/main/format_compatibility.c @@ -264,10 +264,10 @@ struct ast_format *ast_format_compatibility_bitfield2format(uint64_t bitfield) /*! T.140 RED Text format RFC 4103 */ case AST_FORMAT_T140_RED: - return ast_format_t140; + return ast_format_t140_red; /*! T.140 Text format - ITU T.140, RFC 4103 */ case AST_FORMAT_T140: - return ast_format_t140_red; + return ast_format_t140; } return NULL; } diff --git a/main/frame.c b/main/frame.c index b5ab9853d..4261b04dd 100644 --- a/main/frame.c +++ b/main/frame.c @@ -84,9 +84,9 @@ static struct ast_frame *ast_frame_header_new(void) if ((frames = ast_threadstorage_get(&frame_cache, sizeof(*frames)))) { if ((f = AST_LIST_REMOVE_HEAD(&frames->list, frame_list))) { size_t mallocd_len = f->mallocd_hdr_len; + memset(f, 0, sizeof(*f)); f->mallocd_hdr_len = mallocd_len; - f->mallocd = AST_MALLOCD_HDR; frames->size--; return f; } @@ -141,12 +141,12 @@ static void __frame_free(struct ast_frame *fr, int cache) #endif if (fr->mallocd & AST_MALLOCD_DATA) { - if (fr->data.ptr) + if (fr->data.ptr) { ast_free(fr->data.ptr - fr->offset); + } } if (fr->mallocd & AST_MALLOCD_SRC) { - if (fr->src) - ast_free((void *) fr->src); + ast_free((void *) fr->src); } if (fr->mallocd & AST_MALLOCD_HDR) { if ((fr->frametype == AST_FRAME_VOICE) || (fr->frametype == AST_FRAME_VIDEO) || @@ -208,14 +208,14 @@ struct ast_frame *ast_frisolate(struct ast_frame *fr) return NULL; } out->frametype = fr->frametype; + out->subclass = fr->subclass; if ((fr->frametype == AST_FRAME_VOICE) || (fr->frametype == AST_FRAME_VIDEO) || (fr->frametype == AST_FRAME_IMAGE)) { - out->subclass.format = ao2_bump(fr->subclass.format); - } else { - memcpy(&out->subclass, &fr->subclass, sizeof(out->subclass)); + ao2_bump(out->subclass.format); } out->datalen = fr->datalen; out->samples = fr->samples; + out->mallocd = AST_MALLOCD_HDR; out->offset = fr->offset; /* Copy the timing data */ ast_copy_flags(out, fr, AST_FLAGS_ALL); @@ -228,47 +228,64 @@ struct ast_frame *ast_frisolate(struct ast_frame *fr) out = fr; } - if (!(fr->mallocd & AST_MALLOCD_SRC) && fr->src) { - if (!(out->src = ast_strdup(fr->src))) { - if (out != fr) { - ast_free(out); + if (fr->src) { + /* The original frame has a source string */ + if (!(fr->mallocd & AST_MALLOCD_SRC)) { + /* + * The original frame has a non-malloced source string. + * + * Duplicate the string and put it into the isolated frame + * which may also be the original frame. + */ + newdata = ast_strdup(fr->src); + if (!newdata) { + if (out != fr) { + ast_frame_free(out, 0); + } + return NULL; } - return NULL; + out->src = newdata; + out->mallocd |= AST_MALLOCD_SRC; + } else if (out != fr) { + /* Steal the source string from the original frame. */ + out->src = fr->src; + fr->src = NULL; + fr->mallocd &= ~AST_MALLOCD_SRC; + out->mallocd |= AST_MALLOCD_SRC; } - } else { - out->src = fr->src; - fr->src = NULL; - fr->mallocd &= ~AST_MALLOCD_SRC; } if (!(fr->mallocd & AST_MALLOCD_DATA)) { + /* The original frame has a non-malloced data buffer. */ if (!fr->datalen) { + /* Actually it's just an int so we can simply copy it. */ out->data.uint32 = fr->data.uint32; - out->mallocd = AST_MALLOCD_HDR | AST_MALLOCD_SRC; return out; } - if (!(newdata = ast_malloc(fr->datalen + AST_FRIENDLY_OFFSET))) { - if (out->src != fr->src) { - ast_free((void *) out->src); - } + /* + * Duplicate the data buffer and put it into the isolated frame + * which may also be the original frame. + */ + newdata = ast_malloc(fr->datalen + AST_FRIENDLY_OFFSET); + if (!newdata) { if (out != fr) { - ast_free(out); + ast_frame_free(out, 0); } return NULL; } newdata += AST_FRIENDLY_OFFSET; out->offset = AST_FRIENDLY_OFFSET; - out->datalen = fr->datalen; memcpy(newdata, fr->data.ptr, fr->datalen); out->data.ptr = newdata; - } else { + out->mallocd |= AST_MALLOCD_DATA; + } else if (out != fr) { + /* Steal the data buffer from the original frame. */ out->data = fr->data; memset(&fr->data, 0, sizeof(fr->data)); fr->mallocd &= ~AST_MALLOCD_DATA; + out->mallocd |= AST_MALLOCD_DATA; } - out->mallocd = AST_MALLOCD_HDR | AST_MALLOCD_SRC | AST_MALLOCD_DATA; - return out; } diff --git a/main/libasteriskpj.c b/main/libasteriskpj.c index 2d92b599d..80c4d1896 100644 --- a/main/libasteriskpj.c +++ b/main/libasteriskpj.c @@ -47,7 +47,7 @@ ASTERISK_REGISTER_FILE() int ast_pj_init(void) { #ifdef HAVE_PJPROJECT_BUNDLED - pj_log_set_level(ast_option_pjproject_log_level); + AST_PJPROJECT_INIT_LOG_LEVEL(); pj_init(); #endif return 0; diff --git a/main/strings.c b/main/strings.c index 7cb55def0..7f2025abe 100644 --- a/main/strings.c +++ b/main/strings.c @@ -186,15 +186,32 @@ static int str_hash(const void *obj, const int flags) return ast_str_hash(obj); } +static int str_sort(const void *lhs, const void *rhs, int flags) +{ + if ((flags & OBJ_SEARCH_MASK) == OBJ_SEARCH_PARTIAL_KEY) { + return strncmp(lhs, rhs, strlen(rhs)); + } else { + return strcmp(lhs, rhs); + } +} + static int str_cmp(void *lhs, void *rhs, int flags) { - return strcmp(lhs, rhs) ? 0 : CMP_MATCH; + int cmp = 0; + + if ((flags & OBJ_SEARCH_MASK) == OBJ_SEARCH_PARTIAL_KEY) { + cmp = strncmp(lhs, rhs, strlen(rhs)); + } else { + cmp = strcmp(lhs, rhs); + } + + return cmp ? 0 : CMP_MATCH; } //struct ao2_container *ast_str_container_alloc_options(enum ao2_container_opts opts, int buckets) struct ao2_container *ast_str_container_alloc_options(enum ao2_alloc_opts opts, int buckets) { - return ao2_container_alloc_options(opts, buckets, str_hash, str_cmp); + return ao2_container_alloc_hash(opts, 0, buckets, str_hash, str_sort, str_cmp); } int ast_str_container_add(struct ao2_container *str_container, const char *add) |