Coverage Report

Created: 2025-12-03 06:26

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/rtpproxy/src/rtpp_proc_ttl.c
Line
Count
Source
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
#if defined(LINUX_XXX) && !defined(_GNU_SOURCE)
30
#define _GNU_SOURCE /* pthread_setname_np() */
31
#endif
32
33
#include <assert.h>
34
#include <pthread.h>
35
#include <stdatomic.h>
36
#include <stddef.h>
37
#include <stdint.h>
38
#include <stdlib.h>
39
40
#include <elperiodic.h>
41
42
#include "config.h"
43
44
#include "rtpp_cfg.h"
45
#include "rtpp_log.h"
46
#include "rtpp_types.h"
47
#include "rtpp_log_obj.h"
48
#include "rtpp_notify.h"
49
#include "rtpp_session.h"
50
#include "rtpp_stats.h"
51
#include "rtpp_hash_table.h"
52
#include "rtpp_weakref.h"
53
#include "rtpp_proc_ttl.h"
54
#include "rtpp_codeptr.h"
55
#include "rtpp_refcnt.h"
56
#include "rtpp_mallocs.h"
57
#include "rtpp_pipe.h"
58
#include "rtpp_timeout_data.h"
59
#include "rtpp_locking.h"
60
#include "rtpp_threads.h"
61
62
struct foreach_args {
63
    struct rtpp_notify *rtpp_notify_cf;
64
    struct rtpp_stats *rtpp_stats;
65
    struct rtpp_weakref *sessions_wrt;
66
};
67
68
struct rtpp_proc_ttl_pvt {
69
    struct rtpp_proc_ttl pub;
70
    pthread_t thread_id;
71
    struct rtpp_anetio_cf *op;
72
    _Atomic(int) tstate;
73
    void *elp;
74
    struct rtpp_hash_table *sessions_ht;
75
    struct foreach_args fa;
76
};
77
78
static void rtpp_proc_ttl(struct rtpp_hash_table *, const struct foreach_args *);
79
80
static const char *notyfy_type = "timeout";
81
82
static int
83
rtpp_proc_ttl_foreach(void *dp, void *ap)
84
14
{
85
14
    const struct foreach_args *fap;
86
14
    const struct rtpp_session *sp;
87
88
14
    fap = (const struct foreach_args *)ap;
89
    /*
90
     * This method does not need us to bump ref, since we are in the
91
     * locked context of the rtpp_hash_table, which holds its own ref.
92
     */
93
14
    sp = (const struct rtpp_session *)dp;
94
95
14
    if (CALL_SMETHOD(sp->rtp, get_ttl) == 0) {
96
0
        RTPP_LOG(sp->log, RTPP_LOG_INFO, "session timeout");
97
0
        if (sp->timeout_data != NULL) {
98
0
            CALL_METHOD(fap->rtpp_notify_cf, schedule,
99
0
              sp->timeout_data->notify_target, sp->timeout_data->notify_tag,
100
0
              notyfy_type);
101
0
        }
102
0
        CALL_SMETHOD(fap->rtpp_stats, updatebyname, "nsess_timeout", 1);
103
0
        CALL_SMETHOD(fap->sessions_wrt, unreg, sp->seuid);
104
0
        return (RTPP_HT_MATCH_DEL);
105
14
    } else {
106
14
        CALL_SMETHOD(sp->rtp, decr_ttl);
107
14
    }
108
14
    return (RTPP_HT_MATCH_CONT);
109
14
}
110
111
static void
112
rtpp_proc_ttl(struct rtpp_hash_table *sessions_ht, const struct foreach_args *fap)
113
20
{
114
115
20
    CALL_SMETHOD(sessions_ht, foreach, rtpp_proc_ttl_foreach, (void *)fap, NULL);
116
20
}
117
118
static void
119
rtpp_proc_ttl_run(void *arg)
120
4
{
121
4
    struct rtpp_proc_ttl_pvt *proc_cf;
122
4
    int tstate;
123
124
4
    proc_cf = (struct rtpp_proc_ttl_pvt *)arg;
125
126
24
    for (;;) {
127
24
        tstate = atomic_load(&proc_cf->tstate);
128
24
        if (tstate == TSTATE_CEASE) {
129
4
            break;
130
4
        }
131
20
        prdic_procrastinate(proc_cf->elp);
132
20
        rtpp_proc_ttl(proc_cf->sessions_ht, &proc_cf->fa);
133
20
    }
134
4
}
135
136
static void
137
rtpp_proc_ttl_dtor(struct rtpp_proc_ttl *pub)
138
4
{
139
4
    struct rtpp_proc_ttl_pvt *proc_cf;
140
4
    int tstate;
141
142
4
    PUB2PVT(pub, proc_cf);
143
4
    tstate = atomic_load(&proc_cf->tstate);
144
4
    assert(tstate == TSTATE_RUN);
145
4
    atomic_store(&proc_cf->tstate, TSTATE_CEASE);
146
4
    pthread_join(proc_cf->thread_id, NULL);
147
4
    RTPP_OBJ_DECREF(proc_cf->sessions_ht);
148
4
    RTPP_OBJ_DECREF(proc_cf->fa.sessions_wrt);
149
4
    RTPP_OBJ_DECREF(proc_cf->fa.rtpp_notify_cf);
150
4
    RTPP_OBJ_DECREF(proc_cf->fa.rtpp_stats);
151
4
    prdic_free(proc_cf->elp);
152
4
    free(proc_cf);
153
4
}
154
155
struct rtpp_proc_ttl *
156
rtpp_proc_ttl_ctor(const struct rtpp_cfg *cfsp)
157
4
{
158
4
    struct rtpp_proc_ttl_pvt *proc_cf;
159
160
4
    proc_cf = rtpp_zmalloc(sizeof(*proc_cf));
161
4
    if (proc_cf == NULL)
162
0
        return (NULL);
163
164
4
    proc_cf->elp = prdic_init(1.0, 0.0);
165
4
    if (proc_cf->elp == NULL) {
166
0
        goto e0;
167
0
    }
168
169
4
    proc_cf->fa.rtpp_notify_cf = cfsp->rtpp_notify_cf;
170
4
    RTPP_OBJ_INCREF(cfsp->rtpp_notify_cf);
171
4
    proc_cf->fa.rtpp_stats = cfsp->rtpp_stats;
172
4
    RTPP_OBJ_INCREF(cfsp->rtpp_stats);
173
4
    proc_cf->fa.sessions_wrt = cfsp->sessions_wrt;
174
4
    RTPP_OBJ_INCREF(cfsp->sessions_wrt);
175
4
    proc_cf->sessions_ht = cfsp->sessions_ht;
176
4
    RTPP_OBJ_INCREF(cfsp->sessions_ht);
177
178
4
    if (pthread_create(&proc_cf->thread_id, NULL, (void *(*)(void *))&rtpp_proc_ttl_run, proc_cf) != 0) {
179
0
        goto e1;
180
0
    }
181
4
#if HAVE_PTHREAD_SETNAME_NP
182
4
    (void)pthread_setname_np(proc_cf->thread_id, "rtpp_proc_ttl");
183
4
#endif
184
4
    proc_cf->pub.dtor = &rtpp_proc_ttl_dtor;
185
4
    return (&proc_cf->pub);
186
0
e1:
187
0
    RTPP_OBJ_DECREF(cfsp->rtpp_stats);
188
0
    RTPP_OBJ_DECREF(cfsp->sessions_ht);
189
0
    RTPP_OBJ_DECREF(cfsp->sessions_wrt);
190
0
    RTPP_OBJ_DECREF(cfsp->rtpp_notify_cf);
191
0
    prdic_free(proc_cf->elp);
192
0
e0:
193
0
    free(proc_cf);
194
    return (NULL);
195
0
}