Coverage Report

Created: 2025-08-26 06:38

/src/rtpproxy/src/rtpp_pipe.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Copyright (c) 2004-2006 Maxim Sobolev <sobomax@FreeBSD.org>
3
 * Copyright (c) 2006-2015 Sippy Software, Inc., http://www.sippysoft.com
4
 * All rights reserved.
5
 *
6
 * Redistribution and use in source and binary forms, with or without
7
 * modification, are permitted provided that the following conditions
8
 * are met:
9
 * 1. Redistributions of source code must retain the above copyright
10
 *    notice, this list of conditions and the following disclaimer.
11
 * 2. Redistributions in binary form must reproduce the above copyright
12
 *    notice, this list of conditions and the following disclaimer in the
13
 *    documentation and/or other materials provided with the distribution.
14
 *
15
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25
 * SUCH DAMAGE.
26
 *
27
 */
28
29
#include <stddef.h>
30
#include <stdint.h>
31
#include <stdlib.h>
32
33
#include "config.h"
34
35
#include "rtpp_debug.h"
36
#include "rtpp_log.h"
37
#include "rtpp_types.h"
38
#include "rtpp_genuid.h"
39
#include "rtpp_mallocs.h"
40
#include "rtpp_pcount.h"
41
#include "rtpp_codeptr.h"
42
#include "rtpp_refcnt.h"
43
#include "rtpp_log_obj.h"
44
#include "rtpp_weakref.h"
45
#include "rtpp_time.h"
46
#include "rtpp_stream.h"
47
#include "rtpp_pipe.h"
48
#include "rtpp_pipe_fin.h"
49
#include "rtpp_ttl.h"
50
#include "rtpp_math.h"
51
#include "rtpp_acct_pipe.h"
52
#include "rtpp_pcnt_strm.h"
53
#include "rtpp_pcnts_strm.h"
54
#include "rtpp_stats.h"
55
#include "rtpp_refcnt.h"
56
#include "advanced/pproc_manager.h"
57
58
struct rtpp_pipe_priv
59
{
60
    struct rtpp_pipe pub;
61
    struct rtpp_weakref *streams_wrt;
62
    int pipe_type;
63
};
64
65
static void rtpp_pipe_dtor(struct rtpp_pipe_priv *);
66
static int rtpp_pipe_get_ttl(struct rtpp_pipe *);
67
static void rtpp_pipe_decr_ttl(struct rtpp_pipe *);
68
static void rtpp_pipe_get_stats(struct rtpp_pipe *, struct rtpp_acct_pipe *);
69
static void rtpp_pipe_upd_cntrs(struct rtpp_pipe *, struct rtpp_acct_pipe *);
70
71
18.4k
#define NO_MED_NM(t) (((t) == PIPE_RTP) ? "nsess_nortp" : "nsess_nortcp")
72
8.96k
#define OW_MED_NM(t) (((t) == PIPE_RTP) ? "nsess_owrtp" : "nsess_owrtcp")
73
74
0
#define MT2RT_NZ(mt) ((mt).wall)
75
0
#define DRTN_NZ(bmt, emt) ((emt).mono == 0.0 || (bmt).mono == 0.0 ? 0.0 : ((emt).mono - (bmt).mono))
76
77
DEFINE_SMETHODS(rtpp_pipe,
78
    .get_ttl = &rtpp_pipe_get_ttl,
79
    .decr_ttl = &rtpp_pipe_decr_ttl,
80
    .get_stats = &rtpp_pipe_get_stats,
81
    .upd_cntrs = &rtpp_pipe_upd_cntrs,
82
);
83
84
struct rtpp_pipe *
85
rtpp_pipe_ctor(const struct r_pipe_ctor_args *ap)
86
45.0k
{
87
45.0k
    struct rtpp_pipe_priv *pvt;
88
45.0k
    int i;
89
90
45.0k
    pvt = rtpp_rzmalloc(sizeof(struct rtpp_pipe_priv), PVT_RCOFFS(pvt));
91
45.0k
    if (pvt == NULL) {
92
0
        goto e0;
93
0
    }
94
95
45.0k
    RTPP_OBJ_BORROW(&pvt->pub, ap->log);
96
45.0k
    pvt->streams_wrt = ap->streams_wrt;
97
98
45.0k
    pvt->pub.ppuid = CALL_SMETHOD(ap->guid, gen);
99
45.0k
    struct r_stream_ctor_args rsca = {
100
45.0k
        .log = ap->log,
101
45.0k
        .proc_servers = ap->proc_servers,
102
45.0k
        .rtpp_stats = ap->rtpp_stats,
103
45.0k
        .pipe_type = ap->pipe_type,
104
45.0k
        .seuid = ap->seuid,
105
45.0k
        .nmodules = ap->nmodules,
106
45.0k
        .pproc_manager = ap->pproc_manager,
107
45.0k
        .guid = ap->guid,
108
45.0k
    };
109
135k
    for (i = 0; i < 2; i++) {
110
90.0k
        rsca.side = i;
111
90.0k
        pvt->pub.stream[i] = rtpp_stream_ctor(&rsca);
112
90.0k
        if (pvt->pub.stream[i] == NULL) {
113
0
            goto e1;
114
0
        }
115
90.0k
        RTPP_OBJ_DTOR_ATTACH_OBJ(&pvt->pub, pvt->pub.stream[i]);
116
90.0k
        if (CALL_SMETHOD(pvt->streams_wrt, reg, pvt->pub.stream[i]->rcnt,
117
90.0k
          pvt->pub.stream[i]->stuid) != 0) {
118
0
            goto e1;
119
0
        }
120
90.0k
    }
121
45.0k
    pvt->pub.stream[0]->stuid_sendr = pvt->pub.stream[1]->stuid;
122
45.0k
    pvt->pub.stream[1]->stuid_sendr = pvt->pub.stream[0]->stuid;
123
45.0k
    pvt->pub.pcount = rtpp_pcount_ctor();
124
45.0k
    if (pvt->pub.pcount == NULL) {
125
0
        goto e1;
126
0
    }
127
45.0k
    RTPP_OBJ_DTOR_ATTACH_OBJ(&pvt->pub, pvt->pub.pcount);
128
135k
    for (i = 0; i < 2; i++) {
129
90.0k
        RTPP_OBJ_BORROW(pvt->pub.stream[i], pvt->pub.pcount);
130
90.0k
        pvt->pub.stream[i]->pcount = pvt->pub.pcount;
131
90.0k
    }
132
45.0k
    pvt->pub.stream[0]->pproc_manager->reverse = pvt->pub.stream[1]->pproc_manager;
133
45.0k
    RTPP_OBJ_BORROW(&pvt->pub, pvt->pub.stream[1]->pproc_manager);
134
45.0k
    pvt->pub.stream[1]->pproc_manager->reverse = pvt->pub.stream[0]->pproc_manager;
135
45.0k
    RTPP_OBJ_BORROW(&pvt->pub, pvt->pub.stream[0]->pproc_manager);
136
45.0k
    pvt->pipe_type = ap->pipe_type;
137
45.0k
    pvt->pub.rtpp_stats = ap->rtpp_stats;
138
45.0k
    pvt->pub.log = ap->log;
139
45.0k
    PUBINST_FININIT(&pvt->pub, pvt, rtpp_pipe_dtor);
140
#if defined(RTPP_DEBUG)
141
    RTPP_OBJ_DTOR_ATTACH(&pvt->pub, rtpp_pipe_fin, &(pvt->pub));
142
#endif
143
45.0k
    return (&pvt->pub);
144
145
0
e1:
146
0
    for (i = 0; i < 2; i++)
147
0
        if (pvt->pub.stream[i] != NULL)
148
0
            CALL_SMETHOD(pvt->streams_wrt, unreg, pvt->pub.stream[i]->stuid);
149
0
    RTPP_OBJ_DECREF(&(pvt->pub));
150
0
e0:
151
0
    return (NULL);
152
0
}
153
154
static void
155
rtpp_pipe_dtor(struct rtpp_pipe_priv *pvt)
156
45.0k
{
157
45.0k
    int i;
158
159
135k
    for (i = 0; i < 2; i++) {
160
90.0k
        CALL_SMETHOD(pvt->streams_wrt, unreg, pvt->pub.stream[i]->stuid);
161
90.0k
    }
162
45.0k
}
163
164
static int
165
rtpp_pipe_get_ttl(struct rtpp_pipe *self)
166
13
{
167
13
    int ttls[2];
168
169
13
    ttls[0] = CALL_SMETHOD(self->stream[0]->ttl, get_remaining);
170
13
    ttls[1] = CALL_SMETHOD(self->stream[1]->ttl, get_remaining);
171
13
    return (MIN(ttls[0], ttls[1]));
172
13
}
173
174
static void
175
rtpp_pipe_decr_ttl(struct rtpp_pipe *self)
176
13
{
177
13
    CALL_SMETHOD(self->stream[0]->ttl, decr);
178
13
    if (self->stream[1]->ttl == self->stream[0]->ttl)
179
13
        return;
180
13
    CALL_SMETHOD(self->stream[1]->ttl, decr);
181
0
}
182
183
static void
184
rtpp_pipe_get_stats(struct rtpp_pipe *self, struct rtpp_acct_pipe *rapp)
185
45.0k
{
186
45.0k
    struct rtpp_pipe_priv *pvt;
187
188
45.0k
    PUB2PVT(self, pvt);
189
190
45.0k
    CALL_SMETHOD(self->pcount, get_stats, rapp->pcnts);
191
45.0k
    CALL_SMETHOD(self->stream[0], get_stats, &rapp->o.hld_stat);
192
45.0k
    CALL_SMETHOD(self->stream[1], get_stats, &rapp->a.hld_stat);
193
45.0k
    CALL_SMETHOD(self->stream[0]->pcnt_strm, get_stats, rapp->o.ps);
194
45.0k
    CALL_SMETHOD(self->stream[1]->pcnt_strm, get_stats, rapp->a.ps);
195
45.0k
    rapp->o.rem_addr = CALL_SMETHOD(self->stream[0], get_rem_addr, 1);
196
45.0k
    rapp->a.rem_addr = CALL_SMETHOD(self->stream[1], get_rem_addr, 1);
197
45.0k
    RTPP_LOG(self->log, RTPP_LOG_INFO, "%s stats: %lu in from callee, %lu "
198
45.0k
      "in from caller, %lu relayed, %lu dropped, %lu ignored",
199
45.0k
      PP_NAME(pvt->pipe_type), rapp->o.ps->npkts_in,
200
45.0k
      rapp->a.ps->npkts_in, rapp->pcnts->nrelayed, rapp->pcnts->ndropped,
201
45.0k
      rapp->pcnts->nignored);
202
45.0k
    if (rapp->pcnts->ndropped > 0) {
203
17.6k
        CALL_SMETHOD(self->pcount, log_drops, self->log);
204
17.6k
    }
205
45.0k
    if (pvt->pipe_type != PIPE_RTP) {
206
22.5k
        return;
207
22.5k
    }
208
22.5k
    if (rapp->o.ps->first_pkt_rcv.mono > 0.0) {
209
0
        RTPP_LOG(self->log, RTPP_LOG_INFO, "RTP times: caller: first in at %f, "
210
0
          "duration %f, longest IPI %f", MT2RT_NZ(rapp->o.ps->first_pkt_rcv),
211
0
          DRTN_NZ(rapp->o.ps->first_pkt_rcv, rapp->o.ps->last_pkt_rcv),
212
0
          rapp->o.ps->longest_ipi);
213
0
    }
214
22.5k
    if (rapp->a.ps->first_pkt_rcv.mono > 0.0) {
215
0
        RTPP_LOG(self->log, RTPP_LOG_INFO, "RTP times: callee: first in at %f, "
216
0
          "duration %f, longest IPI %f", MT2RT_NZ(rapp->a.ps->first_pkt_rcv),
217
0
          DRTN_NZ(rapp->a.ps->first_pkt_rcv, rapp->a.ps->last_pkt_rcv),
218
0
          rapp->a.ps->longest_ipi);
219
0
    }
220
221
22.5k
}
222
223
static void
224
rtpp_pipe_upd_cntrs(struct rtpp_pipe *self, struct rtpp_acct_pipe *rapp)
225
36.0k
{
226
36.0k
    struct rtpp_pipe_priv *pvt;
227
228
36.0k
    PUB2PVT(self, pvt);
229
230
36.0k
    if (rapp->o.ps->npkts_in == 0 && rapp->a.ps->npkts_in == 0) {
231
18.4k
        CALL_SMETHOD(self->rtpp_stats, updatebyname, NO_MED_NM(pvt->pipe_type),
232
18.4k
          1);
233
18.4k
    } else if (rapp->o.ps->npkts_in == 0 || rapp->a.ps->npkts_in == 0) {
234
8.96k
        CALL_SMETHOD(self->rtpp_stats, updatebyname, OW_MED_NM(pvt->pipe_type),
235
8.96k
          1);
236
8.96k
    }
237
36.0k
}