Asterisk answer with fork problem

Hello,

This is a rather technical issue that I thought might be most appropriate for the development forum.Please let me know if it’s best logged elsewhere or as an Asterisk bug.

We have an issue with the answer of a call when using Asterisk AGI and forking child processes. Inbound calls route to an AGI, which then sends the call to a telephone using Dial. The Dial also says to run a macro when the call is answered, and the macro runs an AGI. If the AGI completes quickly then there’s no problem - when the destination telephone answers they can talk with the caller, and all is well.

However if the AGI run on call answer forks a child process, and the child process is delayed in exiting for some reason, then even when the destination telephone has answered the call, the fact that the call is answered is not relayed back to the caller until the child process exits. Below is a link to a program which reproduces the problem as simply as possible. In production our AGI makes an HTTP POST request, but in the sample program it just does a sleep for 10 seconds.

You’ll see that the child process does a double fork, which is the standard Linux method of orphaning a process so that it’s adopted by init and no longer belongs to the original parent. We even run setpgrp() and setsid() to try and ensure the child is in a separate process group and session, but this doesn’t seem to help.

Somehow despite the double fork Asterisk knows that the child process exists, and waits for it to exit before passing on the call answer event to the caller. The question is, how does Asterisk know this, and how can we prevent it? Thank you in advance!

Here is a link to the AGI program: fork.pl - Google Drive

The Asterisk contexts used are:
[call-start]
exten => _., 1, AGI(/usr/local/bin/fork.pl)

[call-answered]
exten => _., 1, AGI(/usr/local/bin/fork.pl)

David,

Can you make the code public so we can try to re-produce?

Apologies, try now. You’ll need to make sure that /var/log/fork.log is writable by the Asterisk user.

David,

I am able to re-produce this with 20.2.0 using PJSIP. When I initially tested I was wondering to see if perhaps it was a chan_sip issue. I had a similar issue in the past. I had two ways to work around this.

From the agi use the system function to call an external bash script that would call the URL. At the end if the system call I had & which caused it to run in the background so the script would continue.

The second work around was to Dial to the desired location and at the same time do a Local call (e.g. Dial(SIP/123@1.1.1.1&Dial(Local/abc@special-context). In special-context the call would always fail. I would then launch an agi from the hangup extension.

It’s a big hacky but it does the trick. You can also try calling the URl with a handler (see Dialplan handler routines allow customization ⋆ Asterisk)

David,

I found a fix for you. Simple add open STDOUT, '>/dev/null'; after setsid(); and that should fix the issue for you.

1 Like

Thank you very much for that, I appreciate it!
It did fix our sample AGI. Our more complex AGI still had a problem, but closing all file descriptors as follows fixed it there:

for (glob "/proc/$/fd/*") { POSIX::close($1) if m{/(\d+)$}; }
1 Like

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.