blob: 21393d8deba5e4a3080df03184c153406eec9484 [file] [log] [blame]
James Kuszmaul82f6c042021-01-17 11:30:16 -08001/**
2 * @file srtp/stream.c Secure Real-time Transport Protocol (SRTP) -- stream
3 *
4 * Copyright (C) 2010 Creytiv.com
5 */
6#include <re_types.h>
7#include <re_mem.h>
8#include <re_mbuf.h>
9#include <re_list.h>
10#include <re_aes.h>
11#include <re_srtp.h>
12#include "srtp.h"
13
14
15/** SRTP protocol values */
16#ifndef SRTP_MAX_STREAMS
17#define SRTP_MAX_STREAMS (8) /**< Maximum number of SRTP streams */
18#endif
19
20
21static void stream_destructor(void *arg)
22{
23 struct srtp_stream *strm = arg;
24
25 list_unlink(&strm->le);
26}
27
28
29static struct srtp_stream *stream_find(struct srtp *srtp, uint32_t ssrc)
30{
31 struct le *le;
32
33 for (le = srtp->streaml.head; le; le = le->next) {
34
35 struct srtp_stream *strm = le->data;
36
37 if (strm->ssrc == ssrc)
38 return strm;
39 }
40
41 return NULL;
42}
43
44
45static int stream_new(struct srtp_stream **strmp, struct srtp *srtp,
46 uint32_t ssrc)
47{
48 struct srtp_stream *strm;
49
50 if (list_count(&srtp->streaml) >= SRTP_MAX_STREAMS)
51 return ENOSR;
52
53 strm = mem_zalloc(sizeof(*strm), stream_destructor);
54 if (!strm)
55 return ENOMEM;
56
57 strm->ssrc = ssrc;
58 srtp_replay_init(&strm->replay_rtp);
59 srtp_replay_init(&strm->replay_rtcp);
60
61 list_append(&srtp->streaml, &strm->le, strm);
62
63 if (strmp)
64 *strmp = strm;
65
66 return 0;
67}
68
69
70int stream_get(struct srtp_stream **strmp, struct srtp *srtp, uint32_t ssrc)
71{
72 struct srtp_stream *strm;
73
74 if (!strmp || !srtp)
75 return EINVAL;
76
77 strm = stream_find(srtp, ssrc);
78 if (strm) {
79 *strmp = strm;
80 return 0;
81 }
82
83 return stream_new(strmp, srtp, ssrc);
84}
85
86
87int stream_get_seq(struct srtp_stream **strmp, struct srtp *srtp,
88 uint32_t ssrc, uint16_t seq)
89{
90 struct srtp_stream *strm;
91 int err;
92
93 if (!strmp || !srtp)
94 return EINVAL;
95
96 err = stream_get(&strm, srtp, ssrc);
97 if (err)
98 return err;
99
100 /* Set the initial sequence number once only */
101 if (!strm->s_l_set) {
102 strm->s_l = seq;
103 strm->s_l_set = true;
104 }
105
106 *strmp = strm;
107
108 return 0;
109}