Commit Graph

56 Commits

Author SHA1 Message Date
Pablo Neira Ayuso dc898ab983 osmux: don't trust AMR FT field
Sanity check that that we have enough bytes in the AMR payload for
this frame-type.
2013-12-16 13:05:31 +01:00
Pablo Neira Ayuso 0094d98b04 osmux: limit RTP messages per batch
The ctr field of the osmux header is 3 bits long, make sure we
don't run over that boundary. This should not happen in practise
unless we have to deal with network congestion or broken RTP
stacks, but osmux should not crash in that case.
2013-12-16 12:55:28 +01:00
Pablo Neira Ayuso d8a8c0db20 osmux: fix handling of old RTP messages
Make sure that osmux_replay_lost_packets() doesn't try to fill gaps
if we see RTP messages whose sequence number is in the past.
2013-12-16 12:55:28 +01:00
Pablo Neira Ayuso 88eae20dc2 osmux: pass rtp header to osmux_batch_add()
This patch is a cleanup. Pass the pointer to the header, so we don't
need to obtain it from the message buffer again.
2013-12-15 22:35:28 +01:00
Pablo Neira Ayuso 84fffecba5 osmux: fix handling of too big RTP message in osmux_xfrm_input()
With this patch, osmux_xfrm_input() returns 0 (means "message has been
processed") instead of 1 (means "retry") if the RTP message is too big
to fit into one osmux batch. This fixes a likely infinite loop in the
caller, which will retry forever for a message does not fit into the
batch.

Unlikely to happen in normal scenario, as RTP+AMR messages are way
smaller than the interface MTU.
2013-12-15 22:27:18 +01:00
Pablo Neira Ayuso 55033742a1 osmux: don't print messages with wrong AMR FT
The AMR FT field is used to infer the length of the payload, if
a value higher than 8 (SID) is received, skip it.

This fixes a possible crash in osmux_snprintf() in case we receive
a malformed osmux header.

This is also addresses the crash described in c733ae5b6e.
2013-12-14 22:36:00 +01:00
Pablo Neira Ayuso c733ae5b6e osmux: fix crash in osmux_snprintf when handling multi-batch messages
valgrind reports the following crash backtrace:

!<001c> osmux.c:687 No room for OSMUX payload: only 49 bytes
==12800==
==12800== Process terminating with default action of signal 11 (SIGSEGV)
==12800==  Access not within mapped region at address 0xDFA8E473
==12800==    at 0x4073FD2: osmux_snprintf (osmux.c:628)
==12800==    by 0x80524F1: osmux_deliver (osmux.c:50)
==12800==    by 0x407371C: osmux_xfrm_input_deliver (osmux.c:302)
==12800==    by 0x4073792: osmux_batch_timer_expired (osmux.c:312)
==12800==    by 0x405A4A0: osmo_timers_update (timer.c:243)
==12800==    by 0x405A79A: osmo_select_main (select.c:133)
==12800==    by 0x8049A53: main (mgcp_main.c:307)

The problem is that osmux_snprintf() is not handling multi-batch
messages (ie. messages that contain several osmux batches). More
specifically, the offset to print the osmux batches was reset
when parsing every osmux batch.

The problem also manifested with wrong outputs.

Reported by Mattias Lundstrom.
2013-12-14 22:01:25 +01:00
Pablo Neira Ayuso 87b3eeaed7 osmux: delete message from output list before calling tx_cb
Valgrind complains about a possible use after free:

==12800== Invalid read of size 4
==12800==    at 0x4073DF6: osmux_tx_sched (linuxlist.h:119)
==12800==    by 0x8052B0F: osmux_read_from_bsc_nat_cb (osmux.c:261)
==12800==    by 0x453F967: ???
==12800==  Address 0x453f710 is 48 bytes inside a block of size 145
+free'd
==12800==    at 0x402750C: free (vg_replace_malloc.c:427)
==12800==    by 0x4064ADE: talloc_free (talloc.c:609)
==12800==    by 0x405AAAA: msgb_free (msgb.c:72)
==12800==    by 0x8052492: scheduled_tx_bts_cb (osmux.c:196)
==12800==    by 0x4072CF8: osmux_tx_cb (osmux.c:554)
==12800==    by 0x4073F03: osmux_tx_sched (osmux.c:582)
==12800==    by 0x8052B0F: osmux_read_from_bsc_nat_cb (osmux.c:261)
==12800==    by 0x453F967: ???

The problem is that osmux_tx_sched may immediately call osmux_tx_cb for
the first extracted RTP message from the osmux batch, which releases the
message after that.

Remove the message from our list of messages to be transmitted before
the message is passed to the tx callback.

Reported by Mattias Lundstrom.
2013-12-13 15:23:04 +01:00
Pablo Neira Ayuso ceda50fa70 osmux: add artificial limit for cloned RTP packets
Avoid spamming lots of cloned RTP packets in case of severe
gaps.
2013-09-12 13:19:32 +02:00
Pablo Neira Ayuso 7b37afba33 osmux: sanity check too big RTP/RTCP messages as input
Holger spotted that the caller may loop forever in case it receives
big RTP/RCTP packets, that are likely to be spoofed.
2013-08-27 17:15:27 +02:00
Pablo Neira Ayuso 8c1f31a3dc osmux: disable timing debugging
Disable timing debugging by default.
2013-05-27 01:30:36 +02:00
Pablo Neira Ayuso 390872055d osmux: nul-terminate all strings generated by _snprintf
Make sure all strings are null-terminated.

Spotted by Holger Hans Peter Freyther.
2013-05-24 12:51:02 +02:00
Pablo Neira Ayuso 70214a15d1 osmux: further sanity checkings for AMR FT
According to RFC3267, AMR FT upper 9 should be discarded. This patch
adds extra validation to make sure that input RTP traffic encapsulating
AMR payload and OSMUX amr_ft field are OK with regards to that
restriction.
2013-05-24 12:16:49 +02:00
Pablo Neira Ayuso 1ee6d39921 osmux: add sanity checking in osmux_xfrm_output_pull
Osmux infers the size of the AMR payload from the FT type.
Make sure we get enough data from the network according to
what we expect.
2013-05-24 10:47:59 +02:00
Pablo Neira Ayuso dd34adea7a osmux: remove trailing line break from osmux_snprintf 2013-05-23 20:59:13 +02:00
Pablo Neira Ayuso 3cf3a732ea osmux: fix warning spotted by clang --analyze
osmux.c:622:20: warning: Value stored to 'osmuxh' during its
      initialization is never read
        struct osmux_hdr *osmuxh = (struct osmux_hdr *)msg->data;
                          ^        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Reported by Holger Hans Peter Freyther.
2013-05-22 02:06:33 +02:00
Pablo Neira Ayuso 56c4681d83 osmux: replay last RTP packet seen under packet loss scenario
If osmux notices a gap between two RTP packets, fill it with
the last RTP packet seen. Without this patch, 10% of packet loss
is enough to get garbage, with it we get glitches in the conversation
with 30%, and pretty much broken conversation with 40% of it.
2013-05-21 00:48:13 +02:00
Pablo Neira Ayuso a9ab95c2c4 osmux: use ccid to identify batches instead of the RTP SSRC
This should reduce the amount of batch nodes that are created
by the maximum number of allowed circuit IDs.
2013-05-20 22:37:31 +02:00
Pablo Neira Ayuso a2c7f909ef osmux: add sanity checking to osmux_snprintf
Add sanity checking to avoid crashes on malformed OSMUX packets
2013-05-12 20:44:00 +02:00
Pablo Neira Ayuso 282aee422f osmux: allow to set initial RTP SSRC
Instead of using the osmuxh->circuit_id.
2013-05-12 19:56:21 +02:00
Pablo Neira Ayuso d32caea9ea osmux: add osmux_snprintf
Useful for debugging purposes. Modify also examples to use it.
2013-02-19 17:14:33 +01:00
Pablo Neira Ayuso e0ae0d25c0 osmux: RTP payload type for voice is dynamic
Don't make any assumption on the payload type.
2013-02-19 16:14:32 +01:00
Pablo Neira Ayuso 5cbdd8797a osmux: add talloc context
Good for debugging leaks.
2013-02-19 13:18:48 +01:00
Pablo Neira Ayuso 01537a3678 osmux: initialize batch appropriately in osmux_xfrm_input_init
Use talloc_size not talloc. Should fix:

0xb779401a in rb_erase (node=0x200200, root=0xb779c908) at rbtree.c:230
0xb779401a in rb_erase (node=0x200200, root=0xb779c908) at rbtree.c:230
0xb778ee48 in osmo_timer_del (timer=0x94aacd0) at timer.c:110
0xb778ef65 in osmo_timer_add (timer=0x94aacd0) at timer.c:72
0xb778f03c in osmo_timer_schedule (timer=0x94aacd0, seconds=0, microseconds=64000)
0xb77360ff in osmux_xfrm_input (h=0x94a4280, msg=0x94b8a50, ccid=18) at osmux.c:390

Due to uninitialization batch structures.
2013-02-19 13:17:02 +01:00
Pablo Neira Ayuso 92601d0a20 osmux: use ft instead of the cmr
The cmr is the requested codec for the other peer, the ft actually
contains the current codec mode. cmr may contain 15 which means
"don't care".
2013-02-12 19:29:42 +01:00
Pablo Neira Ayuso c92810eccd osmux: remove arrays from osmux_out_handle
there will be one osmux_out_handle per endpoint.
2013-02-12 17:24:13 +01:00
Pablo Neira Ayuso 7ff7a5cd6d osmux: allow to pass data to osmux_deliver 2013-02-11 22:49:27 +01:00
Pablo Neira Ayuso 0f1f41411f osmux: fix missing data set in osmux_tx_sched 2012-10-21 04:12:29 +02:00
Pablo Neira Ayuso 5654c43f80 osmux: remove generic functions to register and get ccid
Remove these functions:

- osmux_xfrm_input_get_ccid
- osmux_xfrm_input_register_ccid

The ccid will be managed by the BSC and it will be stored in the
mgcp_endpoint structure.

Also adjust all tests and examples using the API.
2012-10-20 20:17:28 +02:00
Pablo Neira Ayuso 7f9ebe2e56 osmux: fix DELTA_RTP_MSG
It should be 16000 and add DELTA_RTP_TIMESTAMP which is 160.
2012-10-15 23:09:36 +02:00
Pablo Neira Ayuso 8c9caa8607 osmux: rewrite batching function
Rework batching routine to reduce its complexity, updates:

* Now it uses a list of lists to store the messages that will be
  batched.

batch list
    |
    `-> node SSRC=a ---> ... ---> node SSRC=b
            |                         |
        msg seq=x1               msg seq=y1
            |                         |
        msg seq=x2               msg seq=y2
            |                         |
        msg seq=x3               msg seq=y3
            |                         |
        msg seq=x4               msg seq y4

This keeps easier the creation of the final batch that is sent from that
data structure.

* We also detect duplicate messages in the batch, ie. messages with the
  same sequence are skipped.

Still pending to resolve reordering, corruption and omissions (reliability
is desired).
2012-10-15 23:09:36 +02:00
Pablo Neira Ayuso e472f44dd3 osmux: RTP timestamp has to be bumped in 160
Between two RTP messages that were extracted from a batch, the
timestamp difference should be 160.

Signed-off-by: Pablo Neira Ayuso <pablo@gnumonks.org>
2012-10-15 23:09:36 +02:00
Pablo Neira Ayuso 384bdf630a osmux: release of batch message is controled by caller
Instead of internally released. This is required if we use the
osmo_dgram infrastructure, to avoid a double release.

Signed-off-by: Pablo Neira Ayuso <pablo@gnumonks.org>
2012-10-15 18:14:59 +02:00
Pablo Neira Ayuso 6907ac37e1 osmux: use DLMIB instead of internal defined DOSMUX
Signed-off-by: Pablo Neira Ayuso <pablo@gnumonks.org>
2012-10-15 15:59:14 +02:00
Pablo Neira Ayuso 4fd56b6d2f osmux: fix ordering of RTP messages in the batching list
This patch fixes the ordering in RTP sequence number. Before this patch,
the list was inverted.

This also fixes the calculation of the room that still remains in the
batch.
2012-08-06 21:04:25 +02:00
Pablo Neira Ayuso 7a01104b88 osmux: add OSMUX_MAX_CONCURRENT_CALLS which is 8
Instead of harcoding the number all around the code.
2012-08-06 21:04:25 +02:00
Pablo Neira Ayuso 72a0aae500 osmux: support two concurrent calls in output path 2012-08-06 21:04:25 +02:00
Pablo Neira Ayuso b9cf903bbe osmux: add infrastructure to map RTP SSRC and osmux CCID 2012-08-06 21:04:25 +02:00
Pablo Neira Ayuso da0c9ab922 osmux: fix wrong calculation of csrc_count 2012-08-06 21:04:25 +02:00
Pablo Neira Ayuso 468d81b4ac osmux: batching factor can be explicitly configured by caller
Not hardcoded in osmux.c code anymore.
2012-08-06 21:04:25 +02:00
Pablo Neira Ayuso f366c924e2 osmux: store internal batching information in struct osmux_in_handle
The layout is not provided, as it is internal.

Thus, we don't allocate the internal batching information in BSS
anymore.
2012-08-06 21:04:25 +02:00
Pablo Neira Ayuso 6d72b4a729 osmux: print RTP header if debug logging level is set 2012-08-06 21:04:25 +02:00
Pablo Neira Ayuso f4b11c0717 osmux: extend debugging to make sure we don't lag in scheduled transmissions
osmux only lags ~0.15 ms at maximum to transmit one scheduled RTP message
according to my tests with PCAP traces.

Yes, only ~0.15 milliseconds, this is not wrong :-).

This is good news, our timer infrastructure seems to be quite precise.
2012-08-04 21:16:27 +02:00
Pablo Neira Ayuso d2ea108728 osmux: remove timeval parameter from osmux_tx_sched
We can internal allocate this in the stack, no need to expose it to
the caller.
2012-08-04 21:03:56 +02:00
Pablo Neira Ayuso 81979fa80a osmux: fix when to add the osmux header
This needs to be done for the first message in one RTP SSRC series.
Before this patch, it was always included due to wrong aritmethics.
2012-08-04 20:56:53 +02:00
Pablo Neira Ayuso 082d700a8f osmux: fix list ordering for RTP messages that will be included in batch
This fixes the algorithms to include the messages in order in the
batch based on the TRP SSRC (from lower to higher).

This is very important to reduce the amount of bytes that we
spend on the osmux header.
2012-08-04 20:53:57 +02:00
Pablo Neira Ayuso 2cefb116d0 osmux: check for the maximum amount of messages in batch
This should not happen, but make sure our osmux CTR field does not
wrap around.
2012-08-04 20:52:45 +02:00
Pablo Neira Ayuso fe9fccd412 osmux: cleanup tx path
This patch cleans up the transmission path for osmux, this involves
the functions that extract the messages from the batch and the one
that reconstruct the timing.

They now take a list that contains the reconstructed RTP messages:

 osmux_xfrm_output(osmuxh, &h_output, &list);
 osmux_tx_sched(&list, &tv, tx_cb, NULL);
2012-08-04 19:59:33 +02:00
Pablo Neira Ayuso ffd20f3f1c osmux: major rework to reduce batch message size (add counter field)
This patch adds the counter field to the osmux header, so we can
reduce the size of the batch even further, eg.

osmuxhdr (ctr=3)
speech
speech
speech
osmuxhdr (ctr=2)
speech
speech
...

The new header is the following:

 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| FT  | CTR |F|Q|    SeqNR      |  Circuit ID   |AMR-FT |AMR-CMR|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

The counter field is 3 bits long, thus, we can batch up to 8
RTP speech frames into one single batch per circuit ID.

I have also removed the RTP marker, since it can be reconstructed
from the AMR information.

Moreover, the entire workflow has been also reworked. Whenever a
packet arrives, we introduce it into the batch list. This batch
list contains a list of RTP messages ordered by RTP SSRC. Then,
once the batch timer expires or the it gets full, we build the
batch from the list of RTP messages.

Note that this allows us to put several speech frame into one
single osmux header without actually worrying about the amount
of messages that we'll receive.

The functions that reconstruct the RTP messages has been also
adjusted. Now, it returns a list of RTP messages per RTP SSRC
that has been extracted from the batch.
2012-08-02 20:36:19 +02:00
Pablo Neira Ayuso 52c7649e23 osmux: fix wrong maximum batch size
Missing UDP header in calculation.
2012-08-02 20:24:31 +02:00