Coverage Report

Created: 2025-11-09 07:06

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/rtpproxy/src/rtpp_netaddr.c
Line
Count
Source
1
/*
2
 * Copyright (c) 2016 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 <sys/types.h>
29
#include <sys/socket.h>
30
#include <pthread.h>
31
#include <stddef.h>
32
#include <stdint.h>
33
#include <stdlib.h>
34
#include <string.h>
35
36
#include "rtpp_types.h"
37
#include "rtpp_codeptr.h"
38
#include "rtpp_refcnt.h"
39
#include "rtpp_mallocs.h"
40
#include "rtpp_netaddr.h"
41
#include "rtpp_netaddr_fin.h"
42
#include "rtpp_network.h"
43
#include "rtpp_debug.h"
44
45
struct rtpp_netaddr_priv {
46
    struct rtpp_netaddr pub;
47
    struct sockaddr_storage sas;
48
    socklen_t rlen;
49
    pthread_mutex_t lock;
50
};
51
52
static void rtpp_netaddr_set(struct rtpp_netaddr *, const struct sockaddr *, size_t);
53
static void rtpp_netaddr_dtor(struct rtpp_netaddr_priv *);
54
static void rtpp_netaddr_set(struct rtpp_netaddr *, const struct sockaddr *, size_t);
55
static int rtpp_netaddr_isempty(struct rtpp_netaddr *);
56
static int rtpp_netaddr_cmp(struct rtpp_netaddr *, const struct sockaddr *, size_t);
57
static int rtpp_netaddr_isaddrseq(struct rtpp_netaddr *, const struct sockaddr *);
58
static int rtpp_netaddr_cmphost(struct rtpp_netaddr *, const struct sockaddr *);
59
static void rtpp_netaddr_copy(struct rtpp_netaddr *, struct rtpp_netaddr *);
60
static size_t rtpp_netaddr_get(struct rtpp_netaddr *, struct sockaddr *, size_t);
61
static size_t rtpp_netaddr_sip_print(struct rtpp_netaddr *, char *, size_t,
62
  char);
63
64
DEFINE_SMETHODS(rtpp_netaddr,
65
    .set = &rtpp_netaddr_set,
66
    .isempty = &rtpp_netaddr_isempty,
67
    .cmp = &rtpp_netaddr_cmp,
68
    .isaddrseq = &rtpp_netaddr_isaddrseq,
69
    .cmphost = &rtpp_netaddr_cmphost,
70
    .copy = &rtpp_netaddr_copy,
71
    .get = &rtpp_netaddr_get,
72
    .sip_print = &rtpp_netaddr_sip_print
73
);
74
75
struct rtpp_netaddr *
76
rtpp_netaddr_ctor(void)
77
0
{
78
0
    struct rtpp_netaddr_priv *pvt;
79
80
0
    pvt = rtpp_rzmalloc(sizeof(struct rtpp_netaddr_priv), PVT_RCOFFS(pvt));
81
0
    if (pvt == NULL) {
82
0
        goto e0;
83
0
    }
84
0
    if (pthread_mutex_init(&pvt->lock, NULL) != 0) {
85
0
        goto e1;
86
0
    }
87
0
    PUBINST_FININIT(&pvt->pub, pvt, rtpp_netaddr_dtor);
88
0
    return ((&pvt->pub));
89
90
0
e1:
91
0
    RTPP_OBJ_DECREF(&(pvt->pub));
92
0
e0:
93
0
    return (NULL);
94
0
}
95
96
static void
97
rtpp_netaddr_set(struct rtpp_netaddr *self, const struct sockaddr *addr, size_t alen)
98
0
{
99
0
    struct rtpp_netaddr_priv *pvt;
100
101
0
    PUB2PVT(self, pvt);
102
0
    RTPP_DBG_ASSERT(alen <= sizeof(pvt->sas));
103
104
0
    pthread_mutex_lock(&pvt->lock);
105
0
    memcpy(&pvt->sas, addr, alen);
106
0
    pvt->rlen = alen;
107
0
    pthread_mutex_unlock(&pvt->lock);
108
0
}
109
110
static void
111
rtpp_netaddr_dtor(struct rtpp_netaddr_priv *pvt)
112
0
{
113
114
0
    rtpp_netaddr_fin(&(pvt->pub));
115
0
    pthread_mutex_destroy(&pvt->lock);
116
0
}
117
118
static int
119
rtpp_netaddr_isempty(struct rtpp_netaddr *self)
120
0
{
121
0
    struct rtpp_netaddr_priv *pvt;
122
0
    int rval;
123
124
0
    RTPP_DBG_ASSERT(self != NULL);
125
0
    PUB2PVT(self, pvt);
126
0
    pthread_mutex_lock(&pvt->lock);
127
0
    rval = (pvt->rlen == 0);
128
0
    pthread_mutex_unlock(&pvt->lock);
129
0
    return (rval);
130
0
}
131
132
static int
133
rtpp_netaddr_cmp(struct rtpp_netaddr *self, const struct sockaddr *sap, size_t salen)
134
0
{
135
0
    struct rtpp_netaddr_priv *pvt;
136
0
    int rval;
137
138
0
    PUB2PVT(self, pvt);
139
0
    RTPP_DBG_ASSERT(salen <= sizeof(pvt->sas));
140
0
    pthread_mutex_lock(&pvt->lock);
141
0
    if (salen != pvt->rlen) {
142
0
        rval = -1;
143
0
        goto unlock_and_return;
144
0
    }
145
0
    rval = memcmp(&pvt->sas, sap, salen);
146
0
unlock_and_return:
147
0
    pthread_mutex_unlock(&pvt->lock);
148
0
    return (rval);
149
0
}
150
151
static int
152
rtpp_netaddr_isaddrseq(struct rtpp_netaddr *self, const struct sockaddr *sap)
153
0
{
154
0
    struct rtpp_netaddr_priv *pvt;
155
0
    int rval;
156
157
0
    PUB2PVT(self, pvt);
158
0
    pthread_mutex_lock(&pvt->lock);
159
0
    RTPP_DBG_ASSERT(pvt->rlen > 0);
160
0
    rval = isaddrseq(sstosa(&pvt->sas), sap);
161
0
    pthread_mutex_unlock(&pvt->lock);
162
0
    return (rval);
163
0
}
164
165
static int
166
rtpp_netaddr_cmphost(struct rtpp_netaddr *self, const struct sockaddr *sap)
167
0
{
168
0
    struct rtpp_netaddr_priv *pvt;
169
0
    int rval;
170
171
0
    PUB2PVT(self, pvt);
172
0
    pthread_mutex_lock(&pvt->lock);
173
0
    RTPP_DBG_ASSERT(pvt->rlen > 0);
174
0
    rval = ishostseq(sstosa(&pvt->sas), sap);
175
0
    pthread_mutex_unlock(&pvt->lock);
176
0
    return (rval);
177
0
}
178
179
static void
180
rtpp_netaddr_copy(struct rtpp_netaddr *self, struct rtpp_netaddr *other)
181
0
{
182
0
    struct sockaddr_storage tmp;
183
0
    socklen_t rlen;
184
185
0
    rlen = CALL_SMETHOD(other, get, sstosa(&tmp), sizeof(tmp));
186
0
    rtpp_netaddr_set(self, sstosa(&tmp), rlen);
187
0
}
188
189
static size_t
190
rtpp_netaddr_get(struct rtpp_netaddr *self, struct sockaddr *sap, size_t salen)
191
0
{
192
0
    struct rtpp_netaddr_priv *pvt;
193
194
0
    PUB2PVT(self, pvt);
195
0
    pthread_mutex_lock(&pvt->lock);
196
0
    RTPP_DBG_ASSERT((salen >= pvt->rlen) && (pvt->rlen > 0));
197
0
    memcpy(sap, &pvt->sas, pvt->rlen);
198
0
    pthread_mutex_unlock(&pvt->lock);
199
0
    return (pvt->rlen);
200
0
}
201
202
static size_t
203
rtpp_netaddr_sip_print(struct rtpp_netaddr *self, char *buf, size_t blen,
204
  char portsep)
205
0
{
206
0
    char *rval;
207
0
    struct rtpp_netaddr_priv *pvt;
208
209
0
    PUB2PVT(self, pvt);
210
0
    pthread_mutex_lock(&pvt->lock);
211
0
    RTPP_DBG_ASSERT(pvt->rlen > 0);
212
0
    rval = addrport2char_r(sstosa(&pvt->sas), buf, blen, portsep);
213
0
    pthread_mutex_unlock(&pvt->lock);
214
0
    RTPP_DBG_ASSERT(rval != NULL);
215
0
    return (strlen(rval));
216
0
}