summaryrefslogtreecommitdiff
path: root/main
diff options
context:
space:
mode:
authorJoshua Colp <jcolp@digium.com>2015-12-14 14:04:15 -0400
committerJoshua Colp <jcolp@digium.com>2015-12-16 15:21:14 -0600
commitd17d9a92886429b185b7bc2e02e429fc43d39652 (patch)
tree689dceca969ae2a0e0b1bcc7074784f5eb98cb34 /main
parent093f14d7f3e6a84fc2e6baf2ff950a915e9f91d8 (diff)
json: Audit ast_json_* usage for thread safety.
The JSON library Asterisk uses, jansson, is not thread safe for us in a few ways. To help with this wrappers for JSON object reference count increasing and decreasing were added which use a global lock to ensure they don't clobber over each other. This does not extend to reference count manipulation within the jansson library itself. This means you can't safely use the object borrowing specifier (O) in ast_json_pack and you can't share JSON instances between objects. This change removes uses of the O specifier and replaces them with the o specifier and an explicit ast_json_ref. Some cases of instance sharing have also been removed. ASTERISK-25601 #close Change-Id: I06550d8b0cc1bfeb56cab580a4e608ae4f1ec7d1
Diffstat (limited to 'main')
-rw-r--r--main/aoc.c20
-rw-r--r--main/loader.c4
-rw-r--r--main/rtp_engine.c14
-rw-r--r--main/stasis.c4
-rw-r--r--main/stasis_channels.c24
5 files changed, 38 insertions, 28 deletions
diff --git a/main/aoc.c b/main/aoc.c
index ba44fbfb9..54edafad6 100644
--- a/main/aoc.c
+++ b/main/aoc.c
@@ -1667,11 +1667,11 @@ static struct ast_json *charge_to_json(const struct ast_aoc_decoded *decoded)
}
return ast_json_pack(
- "{s:s, s:s, s:s, s:O}",
+ "{s:s, s:s, s:s, s:o}",
"Type", aoc_charge_type_str(decoded->charge_type),
"BillingID", aoc_billingid_str(decoded->billing_id),
"TotalType", aoc_type_of_totaling_str(decoded->total_type),
- obj_type, obj);
+ obj_type, ast_json_ref(obj));
}
static struct ast_json *association_to_json(const struct ast_aoc_decoded *decoded)
@@ -1738,10 +1738,10 @@ static struct ast_json *s_to_json(const struct ast_aoc_decoded *decoded)
"Scale", decoded->aoc_s_entries[i].rate.duration.granularity_time_scale);
}
- type = ast_json_pack("{s:O, s:s, s:O, s:O}", "Currency", currency, "ChargingType",
+ type = ast_json_pack("{s:o, s:s, s:o, s:o}", "Currency", ast_json_ref(currency), "ChargingType",
decoded->aoc_s_entries[i].rate.duration.charging_type ?
- "StepFunction" : "ContinuousCharging", "Time", time,
- "Granularity", granularity ? granularity : ast_json_null());
+ "StepFunction" : "ContinuousCharging", "Time", ast_json_ref(time),
+ "Granularity", granularity ? ast_json_ref(granularity) : ast_json_ref(ast_json_null()));
break;
}
@@ -1751,7 +1751,7 @@ static struct ast_json *s_to_json(const struct ast_aoc_decoded *decoded)
decoded->aoc_s_entries[i].rate.flat.amount,
decoded->aoc_s_entries[i].rate.flat.multiplier);
- type = ast_json_pack("{s:O}", "Currency", currency);
+ type = ast_json_pack("{s:o}", "Currency", ast_json_ref(currency));
break;
case AST_AOC_RATE_TYPE_VOLUME:
currency = currency_to_json(
@@ -1760,9 +1760,9 @@ static struct ast_json *s_to_json(const struct ast_aoc_decoded *decoded)
decoded->aoc_s_entries[i].rate.volume.multiplier);
type = ast_json_pack(
- "{s:s, s:O}", "Unit", aoc_volume_unit_str(
+ "{s:s, s:o}", "Unit", aoc_volume_unit_str(
decoded->aoc_s_entries[i].rate.volume.volume_unit),
- "Currency", currency);
+ "Currency", ast_json_ref(currency));
break;
case AST_AOC_RATE_TYPE_SPECIAL_CODE:
type = ast_json_pack("{s:i}", "SpecialCode",
@@ -1772,8 +1772,8 @@ static struct ast_json *s_to_json(const struct ast_aoc_decoded *decoded)
break;
}
- rate = ast_json_pack("{s:s, s:O}", "Chargeable", charge_item,
- aoc_rate_type_str(decoded->aoc_s_entries[i].rate_type), type);
+ rate = ast_json_pack("{s:s, s:o}", "Chargeable", charge_item,
+ aoc_rate_type_str(decoded->aoc_s_entries[i].rate_type), ast_json_ref(type));
if (ast_json_array_append(rates, rate)) {
break;
}
diff --git a/main/loader.c b/main/loader.c
index b2bdd4a3d..954b288b3 100644
--- a/main/loader.c
+++ b/main/loader.c
@@ -846,10 +846,10 @@ static void publish_reload_message(const char *name, enum ast_module_reload_resu
event_object = ast_json_pack("{s: s, s: s}",
"Module", S_OR(name, "All"),
"Status", res_buffer);
- json_object = ast_json_pack("{s: s, s: i, s: O}",
+ json_object = ast_json_pack("{s: s, s: i, s: o}",
"type", "Reload",
"class_type", EVENT_FLAG_SYSTEM,
- "event", event_object);
+ "event", ast_json_ref(event_object));
if (!json_object) {
return;
diff --git a/main/rtp_engine.c b/main/rtp_engine.c
index 24e56b49f..035739f03 100644
--- a/main/rtp_engine.c
+++ b/main/rtp_engine.c
@@ -2493,12 +2493,12 @@ static struct ast_json *rtcp_report_to_json(struct stasis_message *msg,
}
}
- json_rtcp_report = ast_json_pack("{s: i, s: i, s: i, s: O, s: O}",
+ json_rtcp_report = ast_json_pack("{s: i, s: i, s: i, s: o, s: o}",
"ssrc", payload->report->ssrc,
"type", payload->report->type,
"report_count", payload->report->reception_report_count,
- "sender_information", json_rtcp_sender_info ? json_rtcp_sender_info : ast_json_null(),
- "report_blocks", json_rtcp_report_blocks);
+ "sender_information", json_rtcp_sender_info ? ast_json_ref(json_rtcp_sender_info) : ast_json_ref(ast_json_null()),
+ "report_blocks", ast_json_ref(json_rtcp_report_blocks));
if (!json_rtcp_report) {
return NULL;
}
@@ -2510,10 +2510,10 @@ static struct ast_json *rtcp_report_to_json(struct stasis_message *msg,
}
}
- return ast_json_pack("{s: O, s: O, s: O}",
- "channel", payload->snapshot ? json_channel : ast_json_null(),
- "rtcp_report", json_rtcp_report,
- "blob", payload->blob);
+ return ast_json_pack("{s: o, s: o, s: o}",
+ "channel", payload->snapshot ? ast_json_ref(json_channel) : ast_json_ref(ast_json_null()),
+ "rtcp_report", ast_json_ref(json_rtcp_report),
+ "blob", ast_json_deep_copy(payload->blob));
}
static void rtp_rtcp_report_dtor(void *obj)
diff --git a/main/stasis.c b/main/stasis.c
index e168ce93b..fe940d351 100644
--- a/main/stasis.c
+++ b/main/stasis.c
@@ -1274,8 +1274,8 @@ static struct ast_json *multi_user_event_to_json(
ast_json_object_set(out, "type", ast_json_string_create("ChannelUserevent"));
ast_json_object_set(out, "timestamp", ast_json_timeval(*tv, NULL));
- ast_json_object_set(out, "eventname", ast_json_ref(ast_json_object_get(blob, "eventname")));
- ast_json_object_set(out, "userevent", ast_json_ref(blob)); /* eventname gets duplicated, that's ok */
+ ast_json_object_set(out, "eventname", ast_json_string_create(ast_json_string_get((ast_json_object_get(blob, "eventname")))));
+ ast_json_object_set(out, "userevent", ast_json_deep_copy(blob));
for (type = 0; type < STASIS_UMOS_MAX; ++type) {
for (i = 0; i < AST_VECTOR_SIZE(&multi->snapshots[type]); ++i) {
diff --git a/main/stasis_channels.c b/main/stasis_channels.c
index 1a4a90f52..eb1f1bc62 100644
--- a/main/stasis_channels.c
+++ b/main/stasis_channels.c
@@ -1016,6 +1016,10 @@ static struct ast_json *dtmf_end_to_json(
struct ast_channel_snapshot *snapshot = channel_blob->snapshot;
const char *direction =
ast_json_string_get(ast_json_object_get(blob, "direction"));
+ const char *digit =
+ ast_json_string_get(ast_json_object_get(blob, "digit"));
+ long duration_ms =
+ ast_json_integer_get(ast_json_object_get(blob, "duration_ms"));
const struct timeval *tv = stasis_message_timestamp(message);
struct ast_json *json_channel;
@@ -1029,11 +1033,11 @@ static struct ast_json *dtmf_end_to_json(
return NULL;
}
- return ast_json_pack("{s: s, s: o, s: O, s: O, s: o}",
+ return ast_json_pack("{s: s, s: o, s: s, s: i, s: o}",
"type", "ChannelDtmfReceived",
"timestamp", ast_json_timeval(*tv, NULL),
- "digit", ast_json_object_get(blob, "digit"),
- "duration_ms", ast_json_object_get(blob, "duration_ms"),
+ "digit", digit,
+ "duration_ms", duration_ms,
"channel", json_channel);
}
@@ -1057,6 +1061,12 @@ static struct ast_json *dial_to_json(
{
struct ast_multi_channel_blob *payload = stasis_message_data(message);
struct ast_json *blob = ast_multi_channel_blob_get_json(payload);
+ const char *dialstatus =
+ ast_json_string_get(ast_json_object_get(blob, "dialstatus"));
+ const char *forward =
+ ast_json_string_get(ast_json_object_get(blob, "forward"));
+ const char *dialstring =
+ ast_json_string_get(ast_json_object_get(blob, "dialstring"));
struct ast_json *caller_json = ast_channel_snapshot_to_json(ast_multi_channel_blob_get_channel(payload, "caller"), sanitize);
struct ast_json *peer_json = ast_channel_snapshot_to_json(ast_multi_channel_blob_get_channel(payload, "peer"), sanitize);
struct ast_json *forwarded_json = ast_channel_snapshot_to_json(ast_multi_channel_blob_get_channel(payload, "forwarded"), sanitize);
@@ -1064,12 +1074,12 @@ static struct ast_json *dial_to_json(
const struct timeval *tv = stasis_message_timestamp(message);
int res = 0;
- json = ast_json_pack("{s: s, s: o, s: O, s: O, s: O}",
+ json = ast_json_pack("{s: s, s: o, s: s, s: s, s: s}",
"type", "Dial",
"timestamp", ast_json_timeval(*tv, NULL),
- "dialstatus", ast_json_object_get(blob, "dialstatus"),
- "forward", ast_json_object_get(blob, "forward"),
- "dialstring", ast_json_object_get(blob, "dialstring"));
+ "dialstatus", dialstatus,
+ "forward", forward,
+ "dialstring", dialstring);
if (!json) {
ast_json_unref(caller_json);
ast_json_unref(peer_json);