/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 | } |