MT#55283 media_socket: lock sink earlier when kernelizing

To not come across the sink's mutation (e.g. `endpoint.address.family`)
just lock way earlier, before to start processing and
translating endpoint to the kernel related structs.

Otherwise the other signaling path may mutate something
which will make the sink unactual and provide
to the `__re_address_translate_ep()` NULLed or garbage structs.

Change-Id: I88d87ae88abe4e37aaa5d3cdda76ed0ca82e4842
(cherry picked from commit e16a2309e0)
mr14.1
Donat Zenichev 3 weeks ago
parent 2cb146e392
commit ba2834314e

@ -1784,8 +1784,17 @@ static const char *kernelize_one(kernelize_state *s,
if (MEDIA_ISSET(sink_media, BLOCK_EGRESS))
return NULL;
if (!sink->endpoint.address.family)
/* XXX nested lock, avoid possible deadlock. should be reworked not to
* require a nested lock */
if (sink != stream && mutex_trylock(&sink->lock)) {
return ""; // indicate deadlock
}
if (!sink->endpoint.address.family) {
if (sink != stream)
mutex_unlock(&sink->lock);
return NULL;
}
if (sink->selected_sfd)
ilog(LOG_INFO, "Kernelizing media stream: %s%s%s -> %s | %s -> %s%s%s",
@ -1800,16 +1809,25 @@ static const char *kernelize_one(kernelize_state *s,
const struct streamhandler *handler = determine_sink_handler(stream, sink_handler);
if (!handler->out->kernel)
if (!handler->out->kernel) {
if (sink != stream)
mutex_unlock(&sink->lock);
return "protocol not supported by kernel module";
}
__auto_type reti = &s->reti.target;
// any output at all?
if (s->non_forwarding || !sink->selected_sfd || !sink->selected_sfd->socket.family)
if (s->non_forwarding || !sink->selected_sfd || !sink->selected_sfd->socket.family) {
if (sink != stream)
mutex_unlock(&sink->lock);
return NULL; // no output
if (!PS_ISSET(sink, FILLED))
}
if (!PS_ISSET(sink, FILLED)) {
if (sink != stream)
mutex_unlock(&sink->lock);
return NULL;
}
// fill output struct
__auto_type credi = g_new0(struct rtpengine_command_destination, 1);
@ -1850,13 +1868,6 @@ static const char *kernelize_one(kernelize_state *s,
if (MEDIA_ISSET(media, ECHO) || sink_handler->attrs.transcoding)
redi->output.ssrc_subst = 1;
// XXX nested lock, avoid possible deadlock. should be reworked not to
// require a nested lock
if (sink != stream && mutex_trylock(&sink->lock)) {
g_free(credi);
return ""; // indicate deadlock
}
__re_address_translate_ep(&redi->output.dst_addr, &sink->endpoint);
__re_address_translate_ep(&redi->output.src_addr, &sink->selected_sfd->socket.local);
redi->output.iface_stats = sink->selected_sfd->local_intf->stats;

Loading…
Cancel
Save