summaryrefslogtreecommitdiff
path: root/main/features.c
diff options
context:
space:
mode:
authorMark Michelson <mmichelson@digium.com>2012-03-29 23:36:37 +0000
committerMark Michelson <mmichelson@digium.com>2012-03-29 23:36:37 +0000
commit314d4593174a561ab2ae761ff17262098a54ee9d (patch)
treefea03dd6cf2da1870186aa9971bd9db25d99c991 /main/features.c
parentcc2366bca04631ac828710e08325db779a143ddf (diff)
Fix potential race condition during call pickup.
Prior to this patch, a connected line update was queued during call pickup and then an answer frame was queued. The original caller would presumably then have his connected line updated and then the call would be answered. In actuality, the answer frame was not how the call ended up being answered. Rather, an odd section in app_dial that checks if the called channel's state is up. The result is that the order of the connected line update and the answer were variable. In most cases, this wasn't actually a bad thing. However, if the 'I' option was passed to dial, the connected line update would be inhibited. The fix is to queued the connected line after the answer frame is queued. This way the race in app_dial is between two conditions resulting in an answer. This way the connected line update occurs after the answer every time. (closes issue ASTERISK-19183) Reported by: Thomas Arimont Tested by: Thomas Arimont Mark Michelson Patches: ASTERISK-19183.patch uploaded by Mark Michelson (license 5049) ........ Merged revisions 360884 from http://svn.asterisk.org/svn/asterisk/branches/1.8 ........ Merged revisions 360885 from http://svn.asterisk.org/svn/asterisk/branches/10 git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@360886 65c4cc65-6c06-0410-ace0-fbb531ad65f3
Diffstat (limited to 'main/features.c')
-rw-r--r--main/features.c5
1 files changed, 3 insertions, 2 deletions
diff --git a/main/features.c b/main/features.c
index d23bda4a1..aea0d1e97 100644
--- a/main/features.c
+++ b/main/features.c
@@ -7384,8 +7384,6 @@ int ast_do_pickup(struct ast_channel *chan, struct ast_channel *target)
ast_connected_line_copy_from_caller(&connected_caller, ast_channel_caller(chan));
ast_channel_unlock(chan);
connected_caller.source = AST_CONNECTED_LINE_UPDATE_SOURCE_ANSWER;
- ast_channel_queue_connected_line_update(chan, &connected_caller, NULL);
- ast_party_connected_line_free(&connected_caller);
ast_cel_report_event(target, AST_CEL_PICKUP, NULL, NULL, chan);
@@ -7399,6 +7397,8 @@ int ast_do_pickup(struct ast_channel *chan, struct ast_channel *target)
goto pickup_failed;
}
+ ast_channel_queue_connected_line_update(chan, &connected_caller, NULL);
+
/* setting this flag to generate a reason header in the cancel message to the ringing channel */
ast_set_flag(ast_channel_flags(chan), AST_FLAG_ANSWERED_ELSEWHERE);
@@ -7423,6 +7423,7 @@ pickup_failed:
if (!ast_channel_datastore_remove(target, ds_pickup)) {
ast_datastore_free(ds_pickup);
}
+ ast_party_connected_line_free(&connected_caller);
return res;
}