While doing the A/B reassociation during an offer/answer exchange, we
don't (necessarily) want to remove all existing subscriptions. Instead
we cant to unsubscribe all subscribers so we don't do media forking, but
leaving existing subscriptions alone to make early media reception
possible. This mirros the old behaviour.
Change-Id: Ib9e6671ca2d23d1eb4509d7cf939015c816cc622
Also add a safeguard against filling the remote peer address with an
address from the wrong family
closes#1305
Change-Id: Iac18212b4d526a2f7d49a06ddcd724aa89b06060
The contents of the ->next element cannot be accessed completely lock
free as they're zeroed out during call removal. Instead grab a reference
to the linked next call before releasing the lock, and also lock the
next element before moving on. This requires a more granular locking as
not to interfere with call removal: One lock to protect the contained
call and the ->next, and another to protect the ->prev
Change-Id: I5474ea3f88e3276f93ba62a952b3be13c0c182e9
commit b0c722da69ad088a2eddced12b37c0546a514890
Author: Daniel Hauptmann <dhauptmann@sipwise.com>
Date: Mon Jul 26 15:35:51 2021 +0200
changed flag bit length
in call_interfaces.h changed bit length of reuse_codec from 0 to 1
commit 0313a747532d5987f25fa9edb202aa460bf98dd1
Author: Daniel Hauptmann <dhauptmann@sipwise.com>
Date: Mon Jul 26 15:29:20 2021 +0200
inversed reuse_codec logic
in test-transcode.c and call.c, reuse_codec = 0 (default) will now result in using codec_store_populate instead of codec_store_populate_reuse
commit b876bd686bd30df21a5962aca16fc1c85574f554
Author: Daniel Hauptmann <dhauptmann@sipwise.com>
Date: Mon Jul 26 15:18:19 2021 +0200
adding option to minimalize changes in the codec_store_population
added function codec_store_populate_reuse in codec.c which replaces codec_store_populate but makes fewer changes to the GLists with the old and new codecs
added flag to enable this feature (disabled by default)
commit 6fd0b701c9589b2fae00300801e02a9b5cc397ab
Author: Daniel Hauptmann <dhauptmann@sipwise.com>
Date: Mon Jul 26 14:44:42 2021 +0200
Added Option to minimize change in the codecs
In codec.c added function to populate codec store with the fewest changes between the old and new GList which contains the codecs.
Added new testroutine in test-transcode.c line 1500
Added flag to call_interfaces.h to optionally enable this feature
Change-Id: If58d9a07d114b05dfb75553a87eb4372ae949fbb
commit 3bf554a8fbae7e948343699f40d935693618b764
Author: Daniel Hauptmann <dhauptmann@sipwise.com>
Date: Fri Jul 23 13:58:02 2021 +0200
changing codec-exchange behaviour
in codec.c line 3288 function codec_store_populate now doesnt empty dst and copy new codec from src to it, instead codecs from src will be appended to dst and codec from dst, which are not
being contained by src are being removed
Change-Id: Id6b7ee65595f9cc5c71ef557c7bac5ee38f97cbe
Complete overhaul of the codec handling code:
*) obsolete flags `asymmetric codecs`, `symmetric codecs`, `reorder
codecs`
*) support proper codec offer/answer
*) split codec manipulation (strip/offer/accept/etc) into separate
functions for clarity and better code maintenance
*) fully update codec handlers in both directions after an answer
*) explicit allocation and handling of codecs and payload types in a
codec_store object
*) improve codec matchup logic during answer
*) more explicit handling of supplemental codecs (CN/DTMF)
*) remove now obsolete hacks for handling certain use cases
Change-Id: I996705ba8fe339524c2f70e6bb0fd854f9a1f4fb
This solves problems when the same SSRC is looped through the same call
multiple times in different mono/dialogues, with different parameters.
Change-Id: I1d033cb1f012574d82b5bcbfffe11eb5f983cfd8
The JSON context is already in an object, therefore skip the surrounding
{} enclosure.
Also don't run the global MQTT timer when MQTT is disabled.
closes#1290
Change-Id: I63c622bd339545e625ee18def33f21de2533f949
This makes the type in line with string(3) functions and eliminates some
compiler warnings.
Also update the related bencode data type.
Change-Id: I7ef4024f4b5a0f737b3dbe03bcd078032395bce6
If we receive an SDP with a DTLS fingerprint, by default we adopt the
hash function used for that fingerprint in subsequent communication with
that peer. However, if the SDP is an answer, and we previously used a
different hash function in the offer towards that peer, then a later
re-invite offer would be sent with a different fingerprint, causing an
unexpected DTLS restart. Instead, make sure we don't change fingerprints
if one was already sent.
Change-Id: I603bb86ce2d7121556c161749ed08128dd0b63b2
Avoid using an explicit test for the trickle ICE endpoint address and
instead use the TRICKLE_ICE flag.
Change-Id: I821ced7e77c798004c9d88ec072848b7f6e24a85
When set to `false`, no changes at all. (default)
When set to `true`, bind only one desired family local address.
Also add info in rtpengine.pod file.
Also add log for sfd with no call.
If a supplemental codec was removed by the codec tracker, we must reset
any codec handlers on the opposite side that were using this output
codec.
Change-Id: I7fb9d0ec7a061682fe3b28d9ead14ac263aff7c3
add explicit flag for fingerprint length instead of using the hash
function
restart DTLS after a shutdown due to a reset
clear fingerprint buffer when running the hash
suppress stray log message when no fingerprint was seen yet
add option to test script
closes#1095
Change-Id: Ic58ea6c5aa48a215743d6a3c1b371fc4a5ea77ce
An endpoint switching protocols is normally passed through to the peer,
but in an answer that is usually not desirable. Change the default
behaviour to stick to the original protocol that was offered even if the
answerer changes protocols.
Change-Id: Ib288549f4b1c9ab57a6333c6b7dd511537af96f7
Initially created branches don't have a tag associated with them, so
they don't appear in `other_tags`. We need to keep track of which
branches were created from a single from-tag through their via-branch
values so we know when all branches have been deleted.
closes#1037
Change-Id: I4c6ce602b99a9104de98098cd06ca399eb28e1b2
1) In an SRTP re-invite offer, fixes not a full set of crypto suites
being present
2) In a re-invite offer that switches from RTP to SRTP, fixes SRTP not
being initialised at all
Change-Id: I911442d2cba17ecf6af482cfe922d4e9db2eda8d
In case of an offer with a via-branch followed by a delete without a
via-branch (cancelled call), the call erroneously remains open after
deleting one half of the call. The reason is that un-answered branches
do not appear in the `other_tags` list and so are left out from being
checked.
Change-Id: Ib008f32ef5ee06a7ca997c900c9a3adc85b0f10d
fix cleanup being skipped on redis slaves
fixes an SDES related Redis mem leak
adds a hash for the ports free list to avoid duplicate entries
fixes#898
Change-Id: I34aad67290ff5ef8824142682aac03cb600d0ecb
Untagged branches (only known by via-branch) don't appear in the `tags`
hash and don't have any `other_tags`. The logic to determine whether the
call is completely finished therefore must take these into account
separately.
We take care to remove destroyed monologues from the `viabranches` hash
to keep the count up to date, and determine whether a call is terminated
when there is no more than 1 tagged monologue left and no untagged
monologues.
Closes#875
Change-Id: I6b9618d598f4a95970cd2a452f06574423932b09
If B accepts a crypto suite that was not listed as the first, in order
to support SRTP passthrough, we correctly answer to A with only that one
crypto suite. But we must also remove all other crypto suites from our
list of supported crypto suites internally, because we use the first one
to init our crypto contexts.
fixes#829
Change-Id: Id07343d7b24648208e3a4b4e0b246949dce0385e
Move the RTCP_MUX_OVERRIDE flag to the opposite side of the dialogue to
preserve options given during a branched call.
closes#793
Change-Id: I0bd7621ba22fbfe4f41d115ec2e5dab65283ae01
Every packet_stream gets a send_timer allocated, but the teardown
routine skips the refcount decrease for fallback RTCP streams (when
rtcp-mux is in use), resulting in mem leak
fixes#753
Change-Id: Ib3a4ef8a81135918f08e28e127e4bb557b8ea05d
Adds a new option ptime-reverse to complement setting of ptime towards
the offerer. This and ptime setting are now ignored in answers.
Change-Id: Icbc04f191cbc194b75b72a97832fcaba58feb10e
When we receive an incoming SDES parameter, we must match them against the
previously sent outgoing SDES parameters, choose the one that matches
what we just received and eliminate all others. This is a no-op if none
were sent previously (original offer).
Issue only appears in a re-invite when the first offered crypto suite is
accepted.
fixes#631
Change-Id: I4991d0aaf0b29c1ba66045ed0e5281fc18c8af2e
We should offer all crypto suites that we support. If passing through
SDES, we should amend the list of crypto suites with all additional ones
that we support that weren't included in the received offer.
closes#577
Change-Id: I9b6c16e8eadecf01cdbc8043bd8361e0f683e456
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.
instead of outright rejecting local endpoints advertised by remote
clients (to allow for deliberately daisy chaining packet streams), we
flag them for checking against actual packet loops as we did before
Change-Id: I5652e86e12f3c1c5053ea70b01e8d128ebf47751
fixes#65
this also obsoletes the old loop detection
Change-Id: I850d81500c45828af2c4d50d80278ec2d599c2a0
(cherry picked from commit 3254278cfd55167fb881cc665328744183773728)
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 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.
File system code is now in fs.{h|c}. This includes:
- spool directory setup
- metadata file management
- pcap file creation and writing
Random hex string generation is now in str.h.
We create a metadata file for each call. The metadata files will all end up
in a spool directory for the rtpengine.
Each in-progress file has the format: "rtpengine-meta-$RANDHEX.tmp" and
goes in /tmp/. When a call finishes, it is moved to the spool directory
in sub-directory /var/spool/rtpengine/metadata/ and we change the file
extension to ".txt".
The metadata file contains references to all PCAP recording files associated
with a call, and it includes generic metadata at the tail of the file.
One absolute path for a PCAP file per line, followed by two blank lines,
followed by the metadata passed in to the rtpengine through an external
command.
RTP Engine checks for the spool directory "/var/spool/rtpengine" on startup.
If it's not there, it fails. If it's there, it sets up "metadata" and
"recordings" inner directories. This is where RTP Engine will write call
metadata files and PCAP files.
Creating a random filename with a prefix and a suffix is now done through a
generic function. We use this to create pcap recording files in the /tmp/
directory, and will soon use it to create metadata files.
RTP Engine creates PCAP files for recorded calls on offer answer instead
of initial offer.
We make up bogus values for the nonessential parts of the PCAP, UDP, and
IP headers. We might be able to pull these from other parts of the RTP
Engine, but that information was unnecessary for recording calls so they
can be recorded to audio files.
If you change the packet headers, be really careful about byte order and
datatype size!
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.
supports aliasing a local interface multiple times with the same local
address for different advertised addresses
closes#216
Change-Id: I6f98d1a17290b0bb1831e48ad89fc61d8b2d7914
Thoughts on that topic so far:
There's one thing to keep also in mind. What do we do if the call
changes (streams) and the backup node is notified ? Currently we only
know (by subscribing to the 'notifier-' prefix that in fact it has
changed, but we don't know what has changed in detail. Subscribing to
everything would lead to the problem that we have to take care about
synchronising the the new streams with the old ones. Without having a
look at the code that might be a lot of effort and ... I guess that's
why richard likes to ... have clean states of the calls. Synchronizing
is always a mess. Easier to delete and setup new.
I thought about the following solution for makes things more abstract
and easier to understand:
1. Whenever that call on a backup node (foreign call) has seen a packet
(also timers are started then), we do not process any notification by a
redis notification for this call (caus' the RTP-IP has already been
switched). More precise and abstract that means: If a node has taken
over the responsibility for that call (by having seen a packet), it
assumes that notifications from the former node to be dropped. The call
will be deleted when either the timer fires or (for other companies) the
control channel address has also been switched and via that channel the
call is deleted.
2. If a call has not seen a packet (inactive call on the backup node,
seen as not responsible for that call but could become so), we accept
all commands for that call on the backup node in the same way as on the
original node. That means also deletions in-between and so on. I mean if
the original node does it, why not accepting to do the same way on the
backup node ?
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
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)
Avoid buffer overflows.
Also make cdrbuffend -= 1; append spaces to the TRUNCATED message because
syslog trims the output to 8205 chars on a line for big log buffers.
The payload types are not saved and retrieved from redis. Used a hash to
store the payload types in the form (0, payload_value0), (1, payload_value1)
for every media.
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 0e81dc98285d81cf8014034a698bc57e6af14c98
Author: Richard Fuchs <rfuchs@sipwise.com>
Date: Thu May 21 11:06:15 2015 -0400
fix segfault due to missing reverse tagging
commit cd7a26314b3406faac910897d96cd4d7586fc567
Author: Richard Fuchs <rfuchs@sipwise.com>
Date: Thu May 21 08:57:42 2015 -0400
support branched offer with previously unseen to-tag
commit 77da616dd2be230b03cc480ad6dd810b2742f5aa
Author: Richard Fuchs <rfuchs@sipwise.com>
Date: Wed Apr 29 11:15:37 2015 -0400
implement via-branch handling