|
|
@ -12,7 +12,6 @@ |
|
|
#include "log.h" |
|
|
#include "log.h" |
|
|
#include "redis.h" |
|
|
#include "redis.h" |
|
|
#include "sdp.h" |
|
|
#include "sdp.h" |
|
|
#include "bencode.h" |
|
|
|
|
|
#include "str.h" |
|
|
#include "str.h" |
|
|
#include "control_tcp.h" |
|
|
#include "control_tcp.h" |
|
|
#include "control_udp.h" |
|
|
#include "control_udp.h" |
|
|
@ -56,11 +55,11 @@ INLINE int call_ng_flags_prefix(ng_parser_ctx_t *, str *s_ori, const char *prefi |
|
|
void (*cb)(ng_parser_ctx_t *, str *, helper_arg), helper_arg); |
|
|
void (*cb)(ng_parser_ctx_t *, str *, helper_arg), helper_arg); |
|
|
static void call_ng_flags_str_ht(ng_parser_ctx_t *, str *s, helper_arg); |
|
|
static void call_ng_flags_str_ht(ng_parser_ctx_t *, str *s, helper_arg); |
|
|
static void call_ng_flags_str_q_multi(ng_parser_ctx_t *, str *s, helper_arg); |
|
|
static void call_ng_flags_str_q_multi(ng_parser_ctx_t *, str *s, helper_arg); |
|
|
static void call_ng_flags_str_list(ng_parser_ctx_t *, bencode_item_t *list, |
|
|
|
|
|
|
|
|
static void call_ng_flags_str_list(ng_parser_ctx_t *, parser_arg list, |
|
|
void (*callback)(ng_parser_ctx_t *, str *, helper_arg), helper_arg); |
|
|
void (*callback)(ng_parser_ctx_t *, str *, helper_arg), helper_arg); |
|
|
static void call_ng_flags_list(ng_parser_ctx_t *, bencode_item_t *list, |
|
|
|
|
|
|
|
|
static void call_ng_flags_list(ng_parser_ctx_t *, parser_arg list, |
|
|
void (*str_callback)(ng_parser_ctx_t *, str *, helper_arg), |
|
|
void (*str_callback)(ng_parser_ctx_t *, str *, helper_arg), |
|
|
void (*item_callback)(ng_parser_ctx_t *, bencode_item_t *, helper_arg), |
|
|
|
|
|
|
|
|
void (*item_callback)(ng_parser_ctx_t *, parser_arg, helper_arg), |
|
|
helper_arg); |
|
|
helper_arg); |
|
|
static void call_ng_flags_esc_str_list(ng_parser_ctx_t *out, str *s, helper_arg); |
|
|
static void call_ng_flags_esc_str_list(ng_parser_ctx_t *out, str *s, helper_arg); |
|
|
static void ng_stats_ssrc(const ng_parser_t *parser, parser_arg dict, struct ssrc_hash *ht); |
|
|
static void ng_stats_ssrc(const ng_parser_t *parser, parser_arg dict, struct ssrc_hash *ht); |
|
|
@ -481,7 +480,7 @@ void calls_status_tcp(struct streambuf_stream *s) { |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
INLINE void call_bencode_hold_ref(call_t *c, ng_buffer *ngb) { |
|
|
|
|
|
|
|
|
INLINE void call_ngb_hold_ref(call_t *c, ng_buffer *ngb) { |
|
|
/* We cannot guarantee that the "call" structures are still around at the time |
|
|
/* We cannot guarantee that the "call" structures are still around at the time |
|
|
* when the bencode reply is finally read and sent out. Since we use scatter/gather |
|
|
* when the bencode reply is finally read and sent out. Since we use scatter/gather |
|
|
* to avoid duplication of strings and stuff, we reserve a reference to the call |
|
|
* to avoid duplication of strings and stuff, we reserve a reference to the call |
|
|
@ -620,32 +619,38 @@ static void call_ng_flags_str_pair_ht(ng_parser_ctx_t *out, str *s, helper_arg a |
|
|
t_hash_table_replace(*ht, str_dup(&token), s_copy); |
|
|
t_hash_table_replace(*ht, str_dup(&token), s_copy); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
static void call_ng_flags_item_pair_ht(ng_parser_ctx_t *out, bencode_item_t *it, helper_arg arg) { |
|
|
|
|
|
str from; |
|
|
|
|
|
str to; |
|
|
|
|
|
|
|
|
static void call_ng_flags_item_pair_ht_iter(ng_parser_ctx_t *ctx, str *key, helper_arg arg) { |
|
|
|
|
|
str *from_to = arg.strs; |
|
|
|
|
|
if (from_to[0].len == 0) |
|
|
|
|
|
from_to[0] = *key; |
|
|
|
|
|
else if (from_to[1].len == 0) |
|
|
|
|
|
from_to[1] = *key; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
if (it->type != BENCODE_LIST |
|
|
|
|
|
|| !it->child |
|
|
|
|
|
|| !it->child->sibling |
|
|
|
|
|
|| !bencode_get_str(it->child, &from) |
|
|
|
|
|
|| !bencode_get_str(it->child->sibling, &to) |
|
|
|
|
|
|| from.len == 0 |
|
|
|
|
|
|| to.len == 0) |
|
|
|
|
|
{ |
|
|
|
|
|
ilog(LOG_WARN, "SDP manipulations: Ignoring invalid contents of string-pair list"); |
|
|
|
|
|
return; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
static void call_ng_flags_item_pair_ht(ng_parser_ctx_t *out, parser_arg it, helper_arg arg) { |
|
|
|
|
|
str from_to[2] = {0}; |
|
|
|
|
|
|
|
|
|
|
|
if (!out->parser->is_list(it)) |
|
|
|
|
|
goto err; |
|
|
|
|
|
out->parser->list_iter(out, it, call_ng_flags_item_pair_ht_iter, NULL, from_to); |
|
|
|
|
|
if (from_to[0].len == 0 || from_to[1].len == 0) |
|
|
|
|
|
goto err; |
|
|
|
|
|
|
|
|
str * s_copy_from = str_dup_escape(&from); |
|
|
|
|
|
str * s_copy_to = str_dup_escape(&to); |
|
|
|
|
|
|
|
|
str * s_copy_from = str_dup_escape(&from_to[0]); |
|
|
|
|
|
str * s_copy_to = str_dup_escape(&from_to[1]); |
|
|
|
|
|
|
|
|
str_case_value_ht *ht = arg.svt; |
|
|
str_case_value_ht *ht = arg.svt; |
|
|
if (!t_hash_table_is_set(*ht)) |
|
|
if (!t_hash_table_is_set(*ht)) |
|
|
*ht = str_case_value_ht_new(); |
|
|
*ht = str_case_value_ht_new(); |
|
|
t_hash_table_replace(*ht, s_copy_from, s_copy_to); |
|
|
t_hash_table_replace(*ht, s_copy_from, s_copy_to); |
|
|
|
|
|
|
|
|
|
|
|
return; |
|
|
|
|
|
|
|
|
|
|
|
err: |
|
|
|
|
|
ilog(LOG_WARN, "SDP manipulations: Ignoring invalid contents of string-pair list"); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
static void ng_sdp_attr_media_iter(ng_parser_ctx_t *ctx, str *command_type, bencode_item_t *command_value, |
|
|
|
|
|
|
|
|
static void ng_sdp_attr_media_iter(ng_parser_ctx_t *ctx, str *command_type, parser_arg command_value, |
|
|
helper_arg arg) |
|
|
helper_arg arg) |
|
|
{ |
|
|
{ |
|
|
struct sdp_manipulations *sm = arg.sm; |
|
|
struct sdp_manipulations *sm = arg.sm; |
|
|
@ -669,7 +674,7 @@ static void ng_sdp_attr_media_iter(ng_parser_ctx_t *ctx, str *command_type, benc |
|
|
ilog(LOG_WARN, "SDP manipulations: Unknown SDP manipulation command type."); |
|
|
ilog(LOG_WARN, "SDP manipulations: Unknown SDP manipulation command type."); |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
static void ng_sdp_attr_manipulations_iter(ng_parser_ctx_t *ctx, str *media_type, bencode_item_t *command_action, |
|
|
|
|
|
|
|
|
static void ng_sdp_attr_manipulations_iter(ng_parser_ctx_t *ctx, str *media_type, parser_arg command_action, |
|
|
helper_arg arg) |
|
|
helper_arg arg) |
|
|
{ |
|
|
{ |
|
|
struct sdp_manipulations *sm = sdp_manipulations_get_by_name(ctx->flags, media_type); |
|
|
struct sdp_manipulations *sm = sdp_manipulations_get_by_name(ctx->flags, media_type); |
|
|
@ -682,7 +687,7 @@ static void ng_sdp_attr_manipulations_iter(ng_parser_ctx_t *ctx, str *media_type |
|
|
if (!ctx->parser->dict_iter(ctx, command_action, ng_sdp_attr_media_iter, sm)) |
|
|
if (!ctx->parser->dict_iter(ctx, command_action, ng_sdp_attr_media_iter, sm)) |
|
|
ilog(LOG_WARN, "SDP manipulations: Wrong content for SDP section."); |
|
|
ilog(LOG_WARN, "SDP manipulations: Wrong content for SDP section."); |
|
|
} |
|
|
} |
|
|
INLINE void ng_sdp_attr_manipulations(ng_parser_ctx_t *ctx, bencode_item_t *value) { |
|
|
|
|
|
|
|
|
INLINE void ng_sdp_attr_manipulations(ng_parser_ctx_t *ctx, parser_arg value) { |
|
|
if (!ctx->parser->dict_iter(ctx, value, ng_sdp_attr_manipulations_iter, NULL)) |
|
|
if (!ctx->parser->dict_iter(ctx, value, ng_sdp_attr_manipulations_iter, NULL)) |
|
|
ilog(LOG_WARN, "SDP manipulations: Wrong type for this type of command."); |
|
|
ilog(LOG_WARN, "SDP manipulations: Wrong type for this type of command."); |
|
|
} |
|
|
} |
|
|
@ -766,9 +771,9 @@ INLINE void ng_t38_option(ng_parser_ctx_t *ctx, str *s, helper_arg dummy) { |
|
|
#endif |
|
|
#endif |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static void call_ng_flags_list(ng_parser_ctx_t *ctx, bencode_item_t *list, |
|
|
|
|
|
|
|
|
static void call_ng_flags_list(ng_parser_ctx_t *ctx, parser_arg list, |
|
|
void (*str_callback)(ng_parser_ctx_t *, str *, helper_arg), |
|
|
void (*str_callback)(ng_parser_ctx_t *, str *, helper_arg), |
|
|
void (*item_callback)(ng_parser_ctx_t *, bencode_item_t *, helper_arg), |
|
|
|
|
|
|
|
|
void (*item_callback)(ng_parser_ctx_t *, parser_arg, helper_arg), |
|
|
helper_arg arg) |
|
|
helper_arg arg) |
|
|
{ |
|
|
{ |
|
|
const ng_parser_t *parser = ctx->parser; |
|
|
const ng_parser_t *parser = ctx->parser; |
|
|
@ -785,7 +790,7 @@ static void call_ng_flags_list(ng_parser_ctx_t *ctx, bencode_item_t *list, |
|
|
} |
|
|
} |
|
|
parser->list_iter(ctx, list, str_callback, item_callback, arg); |
|
|
parser->list_iter(ctx, list, str_callback, item_callback, arg); |
|
|
} |
|
|
} |
|
|
static void call_ng_flags_str_list(ng_parser_ctx_t *ctx, bencode_item_t *list, |
|
|
|
|
|
|
|
|
static void call_ng_flags_str_list(ng_parser_ctx_t *ctx, parser_arg list, |
|
|
void (*callback)(ng_parser_ctx_t *ctx, str *, helper_arg), helper_arg arg) |
|
|
void (*callback)(ng_parser_ctx_t *ctx, str *, helper_arg), helper_arg arg) |
|
|
{ |
|
|
{ |
|
|
call_ng_flags_list(ctx, list, callback, NULL, arg); |
|
|
call_ng_flags_list(ctx, list, callback, NULL, arg); |
|
|
@ -1287,14 +1292,14 @@ static void call_ng_direction_flag_iter(ng_parser_ctx_t *ctx, str *s, helper_arg |
|
|
ctx->flags->direction[*arg.i] = *s; |
|
|
ctx->flags->direction[*arg.i] = *s; |
|
|
(*arg.i)++; |
|
|
(*arg.i)++; |
|
|
} |
|
|
} |
|
|
void call_ng_direction_flag(ng_parser_ctx_t *ctx, bencode_item_t *value) |
|
|
|
|
|
|
|
|
void call_ng_direction_flag(ng_parser_ctx_t *ctx, parser_arg value) |
|
|
{ |
|
|
{ |
|
|
if (!ctx->parser->is_list(value)) |
|
|
if (!ctx->parser->is_list(value)) |
|
|
return; |
|
|
return; |
|
|
int diridx = 0; |
|
|
int diridx = 0; |
|
|
ctx->parser->list_iter(ctx, value, call_ng_direction_flag_iter, NULL, &diridx); |
|
|
ctx->parser->list_iter(ctx, value, call_ng_direction_flag_iter, NULL, &diridx); |
|
|
} |
|
|
} |
|
|
void call_ng_codec_flags(ng_parser_ctx_t *ctx, str *key, bencode_item_t *value, helper_arg arg) { |
|
|
|
|
|
|
|
|
void call_ng_codec_flags(ng_parser_ctx_t *ctx, str *key, parser_arg value, helper_arg arg) { |
|
|
sdp_ng_flags *out = ctx->flags; |
|
|
sdp_ng_flags *out = ctx->flags; |
|
|
switch (__csh_lookup(key)) { |
|
|
switch (__csh_lookup(key)) { |
|
|
case CSH_LOOKUP("except"): |
|
|
case CSH_LOOKUP("except"): |
|
|
@ -1374,11 +1379,11 @@ static void call_ng_parse_block_mode(str *s, enum block_dtmf_mode *output) { |
|
|
} |
|
|
} |
|
|
#endif |
|
|
#endif |
|
|
|
|
|
|
|
|
static void call_ng_flags_freqs(ng_parser_ctx_t *ctx, bencode_item_t *value); |
|
|
|
|
|
static void call_ng_flags_freqs_iter(ng_parser_ctx_t *ctx, bencode_item_t *item, helper_arg arg) { |
|
|
|
|
|
|
|
|
static void call_ng_flags_freqs(ng_parser_ctx_t *ctx, parser_arg value); |
|
|
|
|
|
static void call_ng_flags_freqs_iter(ng_parser_ctx_t *ctx, parser_arg item, helper_arg arg) { |
|
|
call_ng_flags_freqs(ctx, item); |
|
|
call_ng_flags_freqs(ctx, item); |
|
|
} |
|
|
} |
|
|
static void call_ng_flags_freqs(ng_parser_ctx_t *ctx, bencode_item_t *value) { |
|
|
|
|
|
|
|
|
static void call_ng_flags_freqs(ng_parser_ctx_t *ctx, parser_arg value) { |
|
|
sdp_ng_flags *out = ctx->flags; |
|
|
sdp_ng_flags *out = ctx->flags; |
|
|
const ng_parser_t *parser = ctx->parser; |
|
|
const ng_parser_t *parser = ctx->parser; |
|
|
unsigned int val; |
|
|
unsigned int val; |
|
|
@ -1412,7 +1417,7 @@ static void call_ng_received_from_iter(ng_parser_ctx_t *ctx, str *key, helper_ar |
|
|
break; |
|
|
break; |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
void call_ng_main_flags(ng_parser_ctx_t *ctx, str *key, bencode_item_t *value, helper_arg arg) { |
|
|
|
|
|
|
|
|
void call_ng_main_flags(ng_parser_ctx_t *ctx, str *key, parser_arg value, helper_arg arg) { |
|
|
str s = STR_NULL; |
|
|
str s = STR_NULL; |
|
|
sdp_ng_flags *out = ctx->flags; |
|
|
sdp_ng_flags *out = ctx->flags; |
|
|
const ng_parser_t *parser = ctx->parser; |
|
|
const ng_parser_t *parser = ctx->parser; |
|
|
@ -2191,7 +2196,7 @@ static const char *call_offer_answer_ng(ng_parser_ctx_t *ctx, enum call_opmode o |
|
|
|
|
|
|
|
|
/* At least the random ICE strings are contained within the call struct, so we |
|
|
/* At least the random ICE strings are contained within the call struct, so we |
|
|
* need to hold a ref until we're done sending the reply */ |
|
|
* need to hold a ref until we're done sending the reply */ |
|
|
call_bencode_hold_ref(call, ctx->ngbuf); |
|
|
|
|
|
|
|
|
call_ngb_hold_ref(call, ctx->ngbuf); |
|
|
|
|
|
|
|
|
errstr = "Invalid dialogue association"; |
|
|
errstr = "Invalid dialogue association"; |
|
|
if (call_get_mono_dialogue(monologues, call, &flags.from_tag, &flags.to_tag, |
|
|
if (call_get_mono_dialogue(monologues, call, &flags.from_tag, &flags.to_tag, |
|
|
@ -2684,7 +2689,7 @@ void ng_call_stats(ng_parser_ctx_t *ctx, call_t *call, const str *fromtag, const |
|
|
if (!ctx) |
|
|
if (!ctx) |
|
|
goto stats; |
|
|
goto stats; |
|
|
|
|
|
|
|
|
call_bencode_hold_ref(call, ctx->ngbuf); |
|
|
|
|
|
|
|
|
call_ngb_hold_ref(call, ctx->ngbuf); |
|
|
|
|
|
|
|
|
ctx->parser->dict_add_int(ctx->resp, "created", call->created.tv_sec); |
|
|
ctx->parser->dict_add_int(ctx->resp, "created", call->created.tv_sec); |
|
|
ctx->parser->dict_add_int(ctx->resp, "created_us", call->created.tv_usec); |
|
|
ctx->parser->dict_add_int(ctx->resp, "created_us", call->created.tv_usec); |
|
|
|