The redis onekey concepts is introduced to reduce traffic to redis
and redis notification traffic.
It modifies the current structure for one call in redis, which are
multiple keys with pre- and postfixes and the callid in between to
one key with the structure "json-<callid>". The value is a json
formatted string with the previous multi-key identifiers in it.
This flag can be used by the signaling proxy in order to tell rtpengine not to persist the call into Redis upon receiving offer/answer() control commands
Updating, freeing, and writing the recording metadata is now
threadsafe. This is in regards to the metadata that we receive from
the `rtpengine_offer` or `rtpengine_answer` commands, not the
`meta_fp` file.
We can simply use the `call->master_lock` variable for protecting
updates to the recording metadata. We had to move the metadata
handling code in call_interfaces.c up into the master_lock guarded
section. The code in "recording.c:meta_finish_file" is called with
master_lock protection already.
We write out what RTP packet number the SDP came before. When we receive
an SDP offer or answer, we write out the RTP packet number that the SDP
preceeded. This will let us split the RTP recording PCAP around SDP
renegotiation for things like hold/unhold.
Also write out whether the SDP was an offer or an answer.
We want to be able to match up the source and target <IP>:<PORT> with
the IP and port info sent in SDP. I adjusted the source and target
<IP>:<PORT> we write to the IP and UDP headers in the PCAP file.
I added the offer SDP (in addition to the already written answer SDP)
to the metadata file.
As a consequence of writing out the offer SDP, we will have empty PCAP
files and associated metadata files for calls that are never answered.
squash! Fixes to match PCAP packets with SDP
Added comments detailing the types of endpoint IP/port values we can
use.
We had initialization code for recording scattered through
"call_interfaces.c", "call.c", and "recording.c". I moved more of the
actual code into functions within recording.c under the parent function
`detect_setup_recording`. We call this function from "call_interfaces.c".
I moved the disjointed bit of PCAP initialization to occur right below
where we toggle recording on or off.
We record the answer SDP (not offer) to the metadata file, separeted by
newlines. It is after the PCAP file URL and before the timestamps. Maybe
we should be writing the rewritten SDP.
I refactored the handling of the "record-call" flag in the
"rtpengine_offer" and "rtpengine_answer" handler. We now set the
recording data structures in a function called `set_record_call`.
We also only handle "record-call" flags on OP_ANSWER for SDP answers.
When we receive an offer or an answer, we will only turn recording on if
it contains the "record-call=yes" flag. Likewise, we only turn recording
off if it contains the "record-call=no" flag. If no flag is specified,
the call keeps its current recording status. It used to be the case that
not specifying "record-call=yes" would turn off call recording.
This fix is necessary to account for SDP renegotiation during
hold/unhold. If the call system sends over another offer during SDP
renegotiation to hold and then unhold, we don't want to change recording
behavior unless the call system specifically says so.
We want to be able to associate call files with a call without the
presence of identifying metadata within the metadata file. To accomplish
this, we prepend the call-id to the start of the pcap recording files
and the call metadata files.
Even though call-id is supposed to be unique, because of paranoia we
keep some of the random affix hex string, but we reduced it down to an
8-byte random value.
Also, some minor argument ordering and name refactoring for random
string generation functions.
We used to sometimes free the generic metadata (passed in through
rtpengine commands) before writing it to disk. Then we were writing
blank metadata to our metadata files. We fixed the ordering of
our `free` operations.
This involved moving all code from fs.(c|h) to recording.(c|h).
We still spoof packets, so the UDP will look like all monologues are coming
over the same port and will probably look like they are all one stream if
you look at the PCAP file.
Command line option is "--recording-dir".
Renamed inner recording spool "recordings" to "pcaps".
This is to avoid name sharing conflicts with the "--recording-dir" command
line option, which specifies the recordings spool directory, and the
"$RECORDING_DIR/recordings" inner directory. Changing the inner directory
name to "pcaps" removes this name collision.
In the process, I changed the function names in fs.h to be consistent with
other functions. The names are structure like "$OBJECT_$VERB".
Fixes and changes:
- Only create the metadata file if the call is being recorded.
- Only write to the metadata file if we actually created it (NULL check).
- Make sure we have metadata before putting it on the call object
- Correctly overwrite recording metadata without leaking memory
- Set the no kernalization flag per call instead of for *every* packet.
- Logging cleanup.
Pass in "record-call" flag over `rtpengine_offer` or `rtpengine_answer`
message. RTP Engine tracks files used to record pcaps and send them back
in the response message.
Pipes call audio (unencrypted from both ends) to recording files.
Sets up file descriptors for local files to dump RTP recordings.
A file and a file descriptor per monologue in a call.
Recorded streams will be running in user daemon mode, not in kernel mode.
This removes first 12 octets from packet to record just the rtp.
- add --subscribe_keyspace list config parameter.
- don't delete foreign calls by timers
- fix synchronization of foreign calls (use a separate redis_notify database)
- fix statistics for control channel calls.
- fix deletion of foreign calls upon del notifications
- update rtpengine-ctl tool
Removes the explicit redis-read-db configuration and reduces the option
to one redis DB and one redis write DB. If only the redis DB is
configured, then it will be used for all operations. If both are
configured, then the redis DB will be used for reading and the write DB
will be used for writing (updates).
Change-Id: I8d5a32c53c9416b514c98d69c3afe7c547e530ad
The session limit is only for calls an rtpengine is responsible for.
Foreign calls (coming in via redis notification) are not counted as
long as the rtpengine is not responsible for those calls.
At least that means that the limit may exceed if the calls the rtpengine
is responsible for plus the former foreign calls are greater than the limit.
This will happen suddenly when the rtpengine becomes responsible for the
foreign calls.
Currently, every rtpengine will subscribe to redis-keyspace notification
so it will receive a notification when an call is inserted. If the call
is not already handeled by the rtpengine, the call will be restored.
The reason for this is to have in-place redundancy. Imagine you have
multiple rtpengines running, eachone will have all calls of the others.
When one rtpengine fails somehow, infrastructure guys use BGP in order to
'move' the IP address from one rtpengine to another. Thisone can handle
the new calls instantly since they're already recovered by
redis-notification feature.
Next step is internally identify those calls in order to prevent some
timers to delete the calls where no RTP flows. Second will be
something we call 'partitioning'. It means that the subscription
to a redis notify will only be for the keyspace a dedicated rtpengine
writes to. This leads to the point that you can make redundancy groups
(partitions) of the rtpengines.
This brings master up to date with branch `rfuchs/socket-rework` at
commit `b1bcc096b7`. The branches have diverged too much for a proper
merge, so this is a manual (squashed) merge.
The old master before this merge can be found in branch
`old-master-before-socket-rework` (commit `82199216b2`).
This is a complete rewrite of all socket handling routines. The most
important functional change is that sockets aren't indiscriminately
bound to INADDR_ANY (or rather in6addr_any), but instead are always
bound to their respective local interface address and with the correct
address family.
Side effects of this are that in multi-homed environments, multiple
sockets must be opened (one per interface address and family) which must
be taken into account when considering RLIMIT_NOFILE values. As a
benefit, this change allows rtpengine to utilize the full UDP port space
per interface address, instead of just one port space per machine.
The socket abstraction also makes it possible to support RTP over TCP in
the future.
Change-Id: If6cf4f42136229490186d2d2482fb4fc140c2b53
* 0 will allow 0 sessions (e.g. can be used for draining rtpengine)
* -1 will disable the feature and will be treated the same way as if
MAX_SESSIONS variable has not been set via configuration file
(or has been set to -1 in configuration file)
* < -1 will not be taken into consideration
* add check for minint range also
This enables switching over the endpoint of a dialogue to a new client
with potentially different capabilities
Change-Id: I973b3c5d004014cc73e6ebc3e87d03c742bc1951
(cherry picked from commit 69b7586aa4)
(cherry picked from commit 93332f0f6e)
use via-branches to predict different destinations for branched SDP
offers without knowing the respective to-tag ahead of time.
Squashed commit of the following:
commit 0e81dc9828
Author: Richard Fuchs <rfuchs@sipwise.com>
Date: Thu May 21 11:06:15 2015 -0400
fix segfault due to missing reverse tagging
commit cd7a26314b
Author: Richard Fuchs <rfuchs@sipwise.com>
Date: Thu May 21 08:57:42 2015 -0400
support branched offer with previously unseen to-tag
commit 77da616dd2
Author: Richard Fuchs <rfuchs@sipwise.com>
Date: Wed Apr 29 11:15:37 2015 -0400
implement via-branch handling