Coverage Report

Created: 2026-03-14 06:51

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/rtpproxy/src/rtp_packet.c
Line
Count
Source
1
/*
2
 * Copyright (c) 2007-2019 Sippy Software, Inc., http://www.sippysoft.com
3
 * All rights reserved.
4
 *
5
 * Redistribution and use in source and binary forms, with or without
6
 * modification, are permitted provided that the following conditions
7
 * are met:
8
 * 1. Redistributions of source code must retain the above copyright
9
 *    notice, this list of conditions and the following disclaimer.
10
 * 2. Redistributions in binary form must reproduce the above copyright
11
 *    notice, this list of conditions and the following disclaimer in the
12
 *    documentation and/or other materials provided with the distribution.
13
 *
14
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24
 * SUCH DAMAGE.
25
 *
26
 */
27
28
#include <stdbool.h>
29
#include <stdlib.h>
30
#include <string.h>
31
#include <sys/types.h>
32
#include <netinet/in.h>
33
#include <assert.h>
34
#include <stddef.h>
35
36
#include "rtpp_types.h"
37
#include "rtp.h"
38
#include "rtp_info.h"
39
#include "rtpp_time.h"
40
#include "rtp_packet.h"
41
#include "rtpp_packetops.h"
42
#include "rtpp_mallocs.h"
43
#include "rtpp_refcnt.h"
44
45
#include "rtpp_wi.h"
46
#include "rtpp_wi_private.h"
47
48
#include "advanced/pproc_manager.h"
49
50
struct rtp_packet_full;
51
52
struct rtp_packet_priv {
53
    struct rtpp_wi *wi;
54
    struct rtp_info rinfo;
55
    struct rtpp_wi_pvt wip;
56
};
57
58
struct rtp_packet_full {
59
    struct rtp_packet pub;
60
    struct rtp_packet_priv pvt;
61
};
62
63
void
64
rtp_packet_dup(struct rtp_packet *dpkt, const struct rtp_packet *spkt, int flags)
65
0
{
66
0
    int csize, offst;
67
0
    struct rtp_packet_full *dpkt_full, *spkt_full;
68
69
0
    csize = offsetof(struct rtp_packet, data.buf) + spkt->size;
70
0
    if ((flags & RTPP_DUP_HDRONLY) != 0) {
71
0
        assert(spkt->parse_result == RTP_PARSER_OK);
72
0
        csize -= spkt->parsed->data_size;
73
0
    }
74
0
    offst = RTP_PKT_COPYOFF(spkt);
75
0
    memcpy(((char *)dpkt) + offst, ((char *)spkt) + offst, csize - offst);
76
0
    if (spkt->parsed == NULL) {
77
0
        return;
78
0
    }
79
0
    PUB2PVT(dpkt, dpkt_full);
80
0
    PUB2PVT(spkt, spkt_full);
81
0
    dpkt_full->pvt.rinfo = spkt_full->pvt.rinfo;
82
0
    dpkt->parsed = &(dpkt_full->pvt.rinfo);
83
0
    if ((flags & RTPP_DUP_HDRONLY) != 0) {
84
0
        dpkt->size -= dpkt->parsed->data_size;
85
0
        dpkt->parsed->data_size = 0;
86
0
        dpkt->parsed->nsamples = 0;
87
0
    }
88
0
}
89
90
struct rtp_packet *
91
rtp_packet_alloc()
92
491k
{
93
491k
    struct rtp_packet_full *pkt;
94
95
491k
    pkt = rtpp_rzmalloc(sizeof(*pkt), PVT_RCOFFS(pkt));
96
491k
    if (pkt == NULL) {
97
0
        return (NULL);
98
0
    }
99
100
491k
    return &(pkt->pub);
101
491k
}
102
103
static void
104
rp_wi_free(void *wi)
105
0
{
106
107
0
    free(wi);
108
0
}
109
110
struct rtpp_wi *
111
rtp_packet_get_wi(struct rtp_packet *pub)
112
108k
{
113
108k
    struct rtp_packet_full *pkt;
114
108k
    struct rtpp_wi *wi;
115
116
108k
    PUB2PVT(pub, pkt);
117
108k
    if (pkt->pvt.wi == NULL) {
118
108k
        pkt->pvt.wi = &(pkt->pvt.wip.pub);
119
108k
        wi = pkt->pvt.wi;
120
18.4E
    } else {
121
18.4E
        wi = rtpp_zmalloc(sizeof(pkt->pvt.wip));
122
18.4E
        if (wi == NULL)
123
0
            goto e0;
124
18.4E
        if (RTPP_OBJ_DTOR_ATTACH(pub, (rtpp_refcnt_dtor_t)&rp_wi_free, wi) != 0)
125
0
            goto e1;
126
18.4E
    }
127
108k
    return (wi);
128
0
e1:
129
0
    rp_wi_free(wi);
130
0
e0:
131
0
    return (NULL);
132
0
}
133
134
void 
135
rtp_packet_set_seq(struct rtp_packet *p, uint16_t seq)
136
0
{
137
138
0
    p->parsed->seq = seq;
139
0
    p->data.header.seq = htons(seq);
140
0
}
141
142
void 
143
rtp_packet_set_ts(struct rtp_packet *p, uint32_t ts)
144
0
{
145
146
0
    p->parsed->ts = ts;
147
0
    p->data.header.ts = htonl(ts);
148
0
}
149
150
rtp_parser_err_t
151
rtp_packet_parse(struct rtp_packet *pkt)
152
297k
{
153
297k
    struct rtp_packet_full *pkt_full;
154
297k
    struct rtp_info *rinfo;
155
156
297k
    if (pkt->parse_result != RTP_PARSER_NOTPARSED) {
157
10.5k
        return (pkt->parse_result);
158
10.5k
    }
159
297k
    assert(pkt->parsed == NULL);
160
287k
    pkt_full = (void *)pkt;
161
287k
    rinfo = &(pkt_full->pvt.rinfo);
162
287k
    if (rtp_packet_is_rtcp(pkt)) {
163
493
        pkt->parse_result = RTP_PARSER_ISRTCP;
164
493
        return (pkt->parse_result);
165
493
    }
166
286k
    pkt->parse_result = rtp_packet_parse_raw(pkt->data.buf, pkt->size, rinfo);
167
286k
    if (pkt->parse_result == RTP_PARSER_OK) {
168
60.2k
        pkt->parsed = rinfo;
169
60.2k
    }
170
286k
    return (pkt->parse_result);
171
287k
}
172
173
262k
#define RTCP_PT_SR  200
174
13.6k
#define RTCP_PR_SNM 213
175
176
int
177
rtp_packet_is_rtcp(const struct rtp_packet *pkt)
178
287k
{
179
287k
    if (pkt->size < 2)
180
89.5k
        return false;
181
182
197k
    uint8_t version = (pkt->data.buf[0] >> 6) & 0b11;
183
197k
    uint8_t packet_type = pkt->data.buf[1];
184
185
    // Version should be 2 and RTCP packet types are in the range 200-213
186
    // https://www.iana.org/assignments/rtp-parameters/rtp-parameters.txt
187
197k
    if (version == 2 && packet_type >= RTCP_PT_SR && packet_type <= RTCP_PR_SNM)
188
493
        return true;
189
197k
    return false;
190
197k
}
191
192
int
193
rtpp_is_rtcp_tst(struct pkt_proc_ctx *pktx)
194
0
{
195
0
    return rtp_packet_is_rtcp(pktx->pktp);
196
0
}
197
198
12.3k
#define STUN_MAGIC 0x2112A442
199
200
int
201
rtp_packet_is_stun(const struct rtp_packet *pkt)
202
47.8k
{
203
47.8k
    if (pkt->size < 20)
204
35.4k
        return (false);
205
206
12.3k
    if (ntohl(*(uint32_t *)(pkt->data.buf + 4)) != STUN_MAGIC)
207
4.26k
        return (false);
208
8.04k
    return (true);
209
12.3k
}
210
211
int
212
rtpp_is_stun_tst(struct pkt_proc_ctx *pktx)
213
47.8k
{
214
47.8k
    return rtp_packet_is_stun(pktx->pktp);
215
47.8k
}
216
217
int
218
rtp_packet_is_dtls(const struct rtp_packet *pkt)
219
143k
{
220
143k
    uint8_t b;
221
222
143k
    if (pkt->size < 13)
223
61.7k
        return false;
224
225
81.6k
    b = pkt->data.buf[0];
226
227
81.6k
    return (19 < b && b < 64);
228
143k
}
229
230
int
231
rtpp_is_dtls_tst(struct pkt_proc_ctx *pktx)
232
143k
{
233
143k
    return rtp_packet_is_dtls(pktx->pktp);
234
143k
}