diff options
author | Pau Espin Pedrol <pespin@sysmocom.de> | 2022-11-16 14:24:09 +0100 |
---|---|---|
committer | Pau Espin Pedrol <pespin@sysmocom.de> | 2022-11-16 19:54:16 +0100 |
commit | b8ef4a085373ca268026942840c828296e83f78b (patch) | |
tree | f31afece1ccfcf170d8cde29d0cf18dd4796b51f /src | |
parent | 8e4f8574d15842a8b99b63c746deb90fc4f820ff (diff) |
osmux: Set M bit in osmuxhdr if seqnum hole found encoding RTP pkts
So far only small intra-batch seqnum jumps are filled in with forged RTP
packets when storing the incoming RTP packets.
Under some conditions, holes may still exist in the queue of RTP packets
for a stream:
* Seqnum detected when first incoming RTP in batch is queued (this can
be improved in the future).
* Big seqnum jumps > batch_factor or simply filling out of bounds for currently
enqueued batch.
Specially the second case can come from long network dropouts, or simply
due to a bug in the RTP being feed to osmux layer (be it from local code
or peer). In that case (long jumps) we don't want to generate tons of
packets filling in several entire batches (potentially incredibly big
amount of batches).
Instead, in these scenarios, simply let the osmux peer know there was a
jump by setting the M bit on the next osmux header for that circuit
after the seq jump has been detected.
Related: SYS#6161
Change-Id: I05b1eae400cb60d1f4e927f853619d5ff470163f
Diffstat (limited to 'src')
-rw-r--r-- | src/osmux_input.c | 10 |
1 files changed, 9 insertions, 1 deletions
diff --git a/src/osmux_input.c b/src/osmux_input.c index 3e6f4b7..aa07fc9 100644 --- a/src/osmux_input.c +++ b/src/osmux_input.c @@ -85,6 +85,7 @@ struct osmux_circuit { int nmsgs; int dummy; uint8_t seq; + int32_t last_transmitted_rtp_seq; /* -1 = unset */ }; /* Used internally to temporarily cache all parsed content of an RTP pkt from user to be transmitted as Osmux */ @@ -148,13 +149,17 @@ struct osmux_input_state { static int osmux_link_put(struct osmux_link *link, struct osmux_input_state *state) { + uint16_t rtp_seqnum = ntohs(state->rtph->sequence); + if (state->add_osmux_hdr) { + bool seq_jump = state->circuit->last_transmitted_rtp_seq != -1 && + ((state->circuit->last_transmitted_rtp_seq + 1) & 0xffff) != rtp_seqnum; struct osmux_hdr *osmuxh; osmuxh = (struct osmux_hdr *)msgb_put(state->out_msg, sizeof(struct osmux_hdr)); osmuxh->ft = OSMUX_FT_VOICE_AMR; osmuxh->ctr = 0; - osmuxh->rtp_m = state->rtph->marker; + osmuxh->rtp_m = state->rtph->marker || seq_jump; osmuxh->seq = state->circuit->seq++; osmuxh->circuit_id = state->circuit->ccid; osmuxh->amr_ft = state->amrh->ft; @@ -179,6 +184,8 @@ static int osmux_link_put(struct osmux_link *link, struct osmux_input_state *sta state->amr_payload_len); msgb_put(state->out_msg, state->amr_payload_len); + /* Update circuit state of last transmitted incoming RTP seqnum: */ + state->circuit->last_transmitted_rtp_seq = rtp_seqnum; return 0; } @@ -753,6 +760,7 @@ int osmux_xfrm_input_open_circuit(struct osmux_in_handle *h, int ccid, circuit->ccid = ccid; circuit->seq = h->osmux_seq; + circuit->last_transmitted_rtp_seq = -1; /* field unset */ INIT_LLIST_HEAD(&circuit->msg_list); llist_add_tail(&circuit->head, &link->circuit_list); |