Merge "res_rtp_asterisk.c: Fix bridge_p2p_rtp_write() reentrancy potential."
This commit is contained in:
commit
a78ffe96a8
|
@ -5340,7 +5340,7 @@ static int bridge_p2p_rtp_write(struct ast_rtp_instance *instance,
|
||||||
struct ast_rtp_instance *instance1, unsigned int *rtpheader, int len, int hdrlen)
|
struct ast_rtp_instance *instance1, unsigned int *rtpheader, int len, int hdrlen)
|
||||||
{
|
{
|
||||||
struct ast_rtp *rtp = ast_rtp_instance_get_data(instance);
|
struct ast_rtp *rtp = ast_rtp_instance_get_data(instance);
|
||||||
struct ast_rtp *bridged = ast_rtp_instance_get_data(instance1);
|
struct ast_rtp *bridged;
|
||||||
int res = 0, payload = 0, bridged_payload = 0, mark;
|
int res = 0, payload = 0, bridged_payload = 0, mark;
|
||||||
RAII_VAR(struct ast_rtp_payload_type *, payload_type, NULL, ao2_cleanup);
|
RAII_VAR(struct ast_rtp_payload_type *, payload_type, NULL, ao2_cleanup);
|
||||||
int reconstruct = ntohl(rtpheader[0]);
|
int reconstruct = ntohl(rtpheader[0]);
|
||||||
|
@ -5350,7 +5350,7 @@ static int bridge_p2p_rtp_write(struct ast_rtp_instance *instance,
|
||||||
|
|
||||||
/* Get fields from packet */
|
/* Get fields from packet */
|
||||||
payload = (reconstruct & 0x7f0000) >> 16;
|
payload = (reconstruct & 0x7f0000) >> 16;
|
||||||
mark = (((reconstruct & 0x800000) >> 23) != 0);
|
mark = (reconstruct & 0x800000) >> 23;
|
||||||
|
|
||||||
/* Check what the payload value should be */
|
/* Check what the payload value should be */
|
||||||
payload_type = ast_rtp_codecs_get_payload(ast_rtp_instance_get_codecs(instance), payload);
|
payload_type = ast_rtp_codecs_get_payload(ast_rtp_instance_get_codecs(instance), payload);
|
||||||
|
@ -5373,12 +5373,6 @@ static int bridge_p2p_rtp_write(struct ast_rtp_instance *instance,
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If bridged peer is in dtmf, feed all packets to core until it finishes to avoid infinite dtmf */
|
|
||||||
if (bridged->sending_digit) {
|
|
||||||
ast_debug(1, "Feeding packets to core until DTMF finishes\n");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Even if we are no longer in dtmf, we could still be receiving
|
* Even if we are no longer in dtmf, we could still be receiving
|
||||||
* re-transmissions of the last dtmf end still. Feed those to the
|
* re-transmissions of the last dtmf end still. Feed those to the
|
||||||
|
@ -5389,35 +5383,10 @@ static int bridge_p2p_rtp_write(struct ast_rtp_instance *instance,
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (payload_type->asterisk_format) {
|
||||||
ao2_replace(rtp->lastrxformat, payload_type->format);
|
ao2_replace(rtp->lastrxformat, payload_type->format);
|
||||||
ao2_replace(bridged->lasttxformat, payload_type->format);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* If bridged peer has already received rtp, perform the asymmetric codec check
|
|
||||||
* if that feature has been activated
|
|
||||||
*/
|
|
||||||
if (!bridged->asymmetric_codec && bridged->lastrxformat != ast_format_none) {
|
|
||||||
if (ast_format_cmp(bridged->lasttxformat, bridged->lastrxformat) == AST_FORMAT_CMP_NOT_EQUAL) {
|
|
||||||
ast_debug(1, "Asymmetric RTP codecs detected (TX: %s, RX: %s) sending frame to core\n",
|
|
||||||
ast_format_get_name(bridged->lasttxformat),
|
|
||||||
ast_format_get_name(bridged->lastrxformat));
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If the marker bit has been explicitly set turn it on */
|
|
||||||
if (ast_test_flag(rtp, FLAG_NEED_MARKER_BIT)) {
|
|
||||||
mark = 1;
|
|
||||||
ast_clear_flag(rtp, FLAG_NEED_MARKER_BIT);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Reconstruct part of the packet */
|
|
||||||
reconstruct &= 0xFF80FFFF;
|
|
||||||
reconstruct |= (bridged_payload << 16);
|
|
||||||
reconstruct |= (mark << 23);
|
|
||||||
rtpheader[0] = htonl(reconstruct);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We have now determined that we need to send the RTP packet
|
* We have now determined that we need to send the RTP packet
|
||||||
* out the bridged instance to do local bridging so we must unlock
|
* out the bridged instance to do local bridging so we must unlock
|
||||||
|
@ -5433,6 +5402,40 @@ static int bridge_p2p_rtp_write(struct ast_rtp_instance *instance,
|
||||||
ao2_unlock(instance);
|
ao2_unlock(instance);
|
||||||
ao2_lock(instance1);
|
ao2_lock(instance1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Get the peer rtp pointer now to emphasize that using it
|
||||||
|
* must happen while instance1 is locked.
|
||||||
|
*/
|
||||||
|
bridged = ast_rtp_instance_get_data(instance1);
|
||||||
|
|
||||||
|
|
||||||
|
/* If bridged peer is in dtmf, feed all packets to core until it finishes to avoid infinite dtmf */
|
||||||
|
if (bridged->sending_digit) {
|
||||||
|
ast_debug(1, "Feeding packet to core until DTMF finishes\n");
|
||||||
|
ao2_unlock(instance1);
|
||||||
|
ao2_lock(instance);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (payload_type->asterisk_format) {
|
||||||
|
/*
|
||||||
|
* If bridged peer has already received rtp, perform the asymmetric codec check
|
||||||
|
* if that feature has been activated
|
||||||
|
*/
|
||||||
|
if (!bridged->asymmetric_codec
|
||||||
|
&& bridged->lastrxformat != ast_format_none
|
||||||
|
&& ast_format_cmp(payload_type->format, bridged->lastrxformat) == AST_FORMAT_CMP_NOT_EQUAL) {
|
||||||
|
ast_debug(1, "Asymmetric RTP codecs detected (TX: %s, RX: %s) sending frame to core\n",
|
||||||
|
ast_format_get_name(payload_type->format),
|
||||||
|
ast_format_get_name(bridged->lastrxformat));
|
||||||
|
ao2_unlock(instance1);
|
||||||
|
ao2_lock(instance);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
ao2_replace(bridged->lasttxformat, payload_type->format);
|
||||||
|
}
|
||||||
|
|
||||||
ast_rtp_instance_get_remote_address(instance1, &remote_address);
|
ast_rtp_instance_get_remote_address(instance1, &remote_address);
|
||||||
|
|
||||||
if (ast_sockaddr_isnull(&remote_address)) {
|
if (ast_sockaddr_isnull(&remote_address)) {
|
||||||
|
@ -5442,6 +5445,18 @@ static int bridge_p2p_rtp_write(struct ast_rtp_instance *instance,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* If the marker bit has been explicitly set turn it on */
|
||||||
|
if (ast_test_flag(bridged, FLAG_NEED_MARKER_BIT)) {
|
||||||
|
mark = 1;
|
||||||
|
ast_clear_flag(bridged, FLAG_NEED_MARKER_BIT);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Reconstruct part of the packet */
|
||||||
|
reconstruct &= 0xFF80FFFF;
|
||||||
|
reconstruct |= (bridged_payload << 16);
|
||||||
|
reconstruct |= (mark << 23);
|
||||||
|
rtpheader[0] = htonl(reconstruct);
|
||||||
|
|
||||||
/* Send the packet back out */
|
/* Send the packet back out */
|
||||||
res = rtp_sendto(instance1, (void *)rtpheader, len, 0, &remote_address, &ice);
|
res = rtp_sendto(instance1, (void *)rtpheader, len, 0, &remote_address, &ice);
|
||||||
if (res < 0) {
|
if (res < 0) {
|
||||||
|
|
Loading…
Reference in New Issue