ConfBridge possible race condition? name_rec deleted before playing on leave?

Hello! :slight_smile:

TL;DR:

  • I use ConfBridge for conference
  • Participants record their names before entering so that their name gets played in the conference before joining (set parameters announce_join_leave, announce_join_leave_review)
  • But when user leave the conference, sometimes I get an error that the recorded name file doesn’t exist (anymore) and so it cannot played to the conference participants (i.e.: “john has left the conference” becomes to just “has left the conference” )

In detail:

I am trying to build a conference solution using ConfBridge. I set the following ConfBridge parameters in the dialplan:
// user settings
Set(CONFBRIDGE(user,announce_user_count)=yes);
Set(CONFBRIDGE(user,announce_only_user)=yes);

// allow users record and review their name recording, and rerecording, etc..
Set(CONFBRIDGE(user,announce_join_leave)=yes);
Set(CONFBRIDGE(user,announce_join_leave_review)=yes);

Set(CONFBRIDGE(user,denoise)=yes);
Set(CONFBRIDGE(user,dsp_drop_silence)=yes); // do not feed silence into conference

// bridge settings (custom audio..)
Set(CONFBRIDGE(bridge,max_members)=50);

Set(CONFBRIDGE(bridge,sound_only_person)=01_inbound_konferenz/konferenzraum___derzeit_der_einzige_teilnehmer);
Set(CONFBRIDGE(bridge,sound_only_one)=01_inbound_konferenz/konferenzraum___ein_weiterer_teilnehmer);
Set(CONFBRIDGE(bridge,sound_has_joined)=01_inbound_konferenz/konferenzraum___ist_der_konferenz_beigetreten);
Set(CONFBRIDGE(bridge,sound_has_left)=01_inbound_konferenz/konferenzraum___hat_die_konferenz_verlassen);
Set(CONFBRIDGE(bridge,sound_there_are)=01_inbound_konferenz/konferenzraum___derzeit_befinden_sich);
Set(CONFBRIDGE(bridge,sound_other_in_party)=01_inbound_konferenz/konferenzraum___andere_teilnehmer_in_der_konferenz);

// other sounds should be played in german
Set(CONFBRIDGE(bridge,language)=de);

before I start the actual conference:

ConfBridge(1016001);

Everything works fine, users can record their names before entering the conference, and other participiants hear it.

But sometimes when somebody leaves the conference (by hangup), the other participants only hear the sound file sound_has_left but not the actual recorded name.

In these cases I get the following error on the asterisk console and in the logfile:

[Dec 20 16:03:10] WARNING[2808] file.c: File /var/spool/asterisk/confbridge/confbridge-name-1016001-1482249738.117 does not exist in any format
[Dec 20 16:03:10] WARNING[2808] file.c: Unable to open /var/spool/asterisk/confbridge/confbridge-name-1016001-1482249738.117 (format (slin)): No such file or directory

When I check in the /var/spool/asterisk/confbridge directory I can see that the file exists until the moment the caller hung up. So it looks for me like some race condition. Is this possible?


My setup:

I am currently just testing around with asterisk and run it within a Docker container (containing Debian stretch). I installed the following asterisk packages via _apt-get_ from the Debian package repository:
apt-get install -y asterisk asterisk-config asterisk-modules asterisk-mp3 \
    asterisk-mysql asterisk-voicemail asterisk-core-sounds-en-wav \
    asterisk-prompt-de asterisk-moh-opsound-wav

The version string as reported by the running asterisk:

Asterisk 13.12.2~dfsg-2 built by buildd @ x86-ubc-01 on a x86_64 running Linux on 2016-12-02 15:30:58 UTC

I have looked into the source of app_confbridge.c in the mirrored Github-repo. I think this is the line here where it’s checked if the user has a recording: app_confbridge.c#L2397 and async_play_sound_file is called.

Later down in the same function the file seems to get deleted here: app_confbridge.c#L2429.

I don’t really understand the codebase yet, but the function name “async_play_sound_file” makes me think this could possibly be a race condition (i.e. maybe the file gets deleted before the async_play actually starts?).

These lines also seem to be the same in the latest master branch.


My questions:

As I don't find any other reports about such an issue, I assume that I've something wrong in my setup. Does anybody know what could cause the behaviour I am experiencing? Any hints on how to debug this further or how to avoid it?

Hi john, we are seeing the exact issue on a virtual machine install.
we are running asterisk 13.13.1 via the freepbx 10.13.66-64 iso
Im going to try and revert to a older version of confbridge and confirm if the problem goes away.

WARNING[3726] file.c: File /var/spool/asterisk/confbridge/confbridge-name-600-1484788451.7 does not exist in any format
[2017-01-19 12:14:28] WARNING[3726] file.c: Unable to open /var/spool/asterisk/confbridge/confbridge-name-600-1484788451.7 (format (slin)): No such file or directory

Thanks, John.

Hi!

Thanks for confirming my observation. :slight_smile:

As I didn’t find a clean solution for the problem, but needed this working, I decided to compile Asterisk myself from sources (as part of my Docker build) and wrote a very simple patch which simply inserts a “usleep” before the file gets deleted. This seems to fix the race-condition for my situation (at least it’s working now).

Here is the simple workaround patch (for Asterisk certified 13.8-cert4):

--- apps/app_confbridge_ORIGINAL.c	2016-12-22 07:51:44.831223469 +0000
+++ apps/app_confbridge.c	2016-12-22 07:54:33.522115277 +0000
@@ -2411,6 +2411,11 @@
 	}
 
 	if (!ast_strlen_zero(user.name_rec_location)) {
+		// == START OF PATCH ==
+		// J. Zweng: prevent the name file to be deleted to early
+		// ugly workaround: just sleep 2500ms here to prevent race condition:
+		usleep(2500);
+		// == END OF PATCH ==
 		ast_filedelete(user.name_rec_location, NULL);
 	}
1 Like