Coverage Report

Created: 2025-10-12 06:12

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/open5gs/lib/core/ogs-socket.c
Line
Count
Source
1
/*
2
 * Copyright (C) 2019 by Sukchan Lee <acetcom@gmail.com>
3
 *
4
 * This file is part of Open5GS.
5
 *
6
 * This program is free software: you can redistribute it and/or modify
7
 * it under the terms of the GNU Affero General Public License as published by
8
 * the Free Software Foundation, either version 3 of the License, or
9
 * (at your option) any later version.
10
 *
11
 * This program is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU General Public License
17
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
18
 */
19
20
#include "core-config-private.h"
21
22
#if HAVE_FCNTL_H
23
#include <fcntl.h>
24
#endif
25
26
#if HAVE_UNISTD_H
27
#include <unistd.h>
28
#endif
29
30
#include "ogs-core.h"
31
32
#undef OGS_LOG_DOMAIN
33
0
#define OGS_LOG_DOMAIN __ogs_sock_domain
34
35
void ogs_socket_init(void)
36
2
{
37
#if _WIN32
38
    WORD wVersionRequested;
39
    WSADATA wsaData;
40
    int err;
41
42
    wVersionRequested = MAKEWORD(2, 2);
43
44
    err = WSAStartup(wVersionRequested, &wsaData);
45
    ogs_assert(err == 0);
46
#endif
47
2
}
48
49
void ogs_socket_final(void)
50
0
{
51
0
}
52
53
ogs_sock_t *ogs_sock_create(void)
54
0
{
55
0
    ogs_sock_t *sock = NULL;
56
57
0
    sock = ogs_calloc(1, sizeof(*sock));
58
0
    if (!sock) {
59
0
        ogs_error("ogs_calloc() failed");
60
0
        return NULL;
61
0
    }
62
63
0
    sock->fd = INVALID_SOCKET;
64
65
0
    return sock;
66
0
}
67
68
void ogs_sock_destroy(ogs_sock_t *sock)
69
0
{
70
0
    ogs_assert(sock);
71
72
0
    if (sock->fd != INVALID_SOCKET) {
73
0
        ogs_closesocket(sock->fd);
74
0
    }
75
0
    sock->fd = INVALID_SOCKET;
76
77
0
    ogs_free(sock);
78
0
}
79
80
ogs_sock_t *ogs_sock_socket(int family, int type, int protocol)
81
0
{
82
0
    ogs_sock_t *sock = NULL;
83
84
0
    sock = ogs_sock_create();
85
0
    ogs_assert(sock);
86
87
0
    sock->family = family;
88
0
    sock->fd = socket(sock->family, type, protocol);
89
0
    if (sock->fd < 0) {
90
0
        ogs_sock_destroy(sock);
91
        
92
0
        ogs_log_message(OGS_LOG_ERROR, ogs_socket_errno,
93
0
            "socket create(%d:%d:%d) failed", sock->family, type, protocol);
94
0
        return NULL;
95
0
    }
96
97
0
    ogs_debug("socket create(%d:%d:%d)", sock->family, type, protocol);
98
99
0
    return sock;
100
0
}
101
102
int ogs_sock_bind(ogs_sock_t *sock, ogs_sockaddr_t *addr)
103
0
{
104
0
    char buf[OGS_ADDRSTRLEN];
105
0
    socklen_t addrlen;
106
107
0
    ogs_assert(sock);
108
0
    ogs_assert(addr);
109
110
0
    addrlen = ogs_sockaddr_len(addr);
111
0
    ogs_assert(addrlen);
112
113
0
    if (bind(sock->fd, &addr->sa, addrlen) != 0) {
114
0
        ogs_log_message(OGS_LOG_ERROR, ogs_socket_errno,
115
0
                "socket bind(%d) [%s]:%d failed",
116
0
                addr->ogs_sa_family, OGS_ADDR(addr, buf), OGS_PORT(addr));
117
0
        return OGS_ERROR;
118
0
    }
119
120
0
    memcpy(&sock->local_addr, addr, sizeof(sock->local_addr));
121
122
0
    ogs_debug("socket bind %s:%d", OGS_ADDR(addr, buf), OGS_PORT(addr));
123
124
0
    return OGS_OK;
125
0
}
126
127
int ogs_sock_connect(ogs_sock_t *sock, ogs_sockaddr_t *addr)
128
0
{
129
0
    char buf[OGS_ADDRSTRLEN];
130
0
    socklen_t addrlen;
131
132
0
    ogs_assert(sock);
133
0
    ogs_assert(addr);
134
135
0
    addrlen = ogs_sockaddr_len(addr);
136
0
    ogs_assert(addrlen);
137
138
0
    if (connect(sock->fd, &addr->sa, addrlen) != 0) {
139
0
        ogs_log_message(OGS_LOG_ERROR, ogs_socket_errno,
140
0
                "socket connect[%s]:%d failed",
141
0
                OGS_ADDR(addr, buf), OGS_PORT(addr));
142
0
        return OGS_ERROR;
143
0
    }
144
145
0
    memcpy(&sock->remote_addr, addr, sizeof(sock->remote_addr));
146
147
0
    ogs_debug("socket connect %s:%d\n", OGS_ADDR(addr, buf), OGS_PORT(addr));
148
149
0
    return OGS_OK;
150
0
}
151
152
int ogs_sock_listen(ogs_sock_t *sock)
153
0
{
154
0
    int rc;
155
0
    ogs_assert(sock);
156
157
0
    rc = listen(sock->fd, 5);
158
0
    if (rc < 0) {
159
0
        ogs_log_message(OGS_LOG_ERROR, ogs_socket_errno, "listen failed");
160
0
        return OGS_ERROR;
161
0
    }
162
163
0
    return OGS_OK;
164
0
}
165
166
ogs_sock_t *ogs_sock_accept(ogs_sock_t *sock)
167
0
{
168
0
    ogs_sock_t *new_sock = NULL;
169
170
0
    int new_fd = -1;
171
0
    ogs_sockaddr_t addr;
172
0
    socklen_t addrlen;
173
174
0
    ogs_assert(sock);
175
176
0
    memset(&addr, 0, sizeof(addr));
177
0
    addrlen = sizeof(addr.ss);
178
179
0
    new_fd = accept(sock->fd, &addr.sa, &addrlen);
180
0
    if (new_fd < 0) {
181
0
        return NULL;
182
0
    }
183
184
0
    new_sock = ogs_sock_create();
185
0
    ogs_assert(new_sock);
186
187
0
    new_sock->family = sock->family;
188
0
    new_sock->fd = new_fd;
189
190
0
    memcpy(&new_sock->remote_addr, &addr, sizeof(new_sock->remote_addr));
191
192
0
    return new_sock;
193
0
}
194
195
ssize_t ogs_write(ogs_socket_t fd, const void *buf, size_t len)
196
0
{
197
0
    ogs_assert(fd != INVALID_SOCKET);
198
199
0
    return write(fd, buf, len);
200
0
}
201
202
ssize_t ogs_read(ogs_socket_t fd, void *buf, size_t len)
203
0
{
204
0
    ogs_assert(fd != INVALID_SOCKET);
205
206
0
    return read(fd, buf, len);
207
0
}
208
209
ssize_t ogs_send(ogs_socket_t fd, const void *buf, size_t len, int flags)
210
0
{
211
0
    ogs_assert(fd != INVALID_SOCKET);
212
213
0
    return send(fd, buf, len, flags);
214
0
}
215
216
ssize_t ogs_sendto(ogs_socket_t fd,
217
        const void *buf, size_t len, int flags, const ogs_sockaddr_t *to)
218
0
{
219
0
    socklen_t addrlen;
220
221
0
    ogs_assert(fd != INVALID_SOCKET);
222
0
    ogs_assert(to);
223
224
0
    addrlen = ogs_sockaddr_len(to);
225
0
    ogs_assert(addrlen);
226
227
0
    return sendto(fd, buf, len, flags, &to->sa, addrlen);
228
0
}
229
230
ssize_t ogs_recv(ogs_socket_t fd, void *buf, size_t len, int flags)
231
0
{
232
0
    ogs_assert(fd != INVALID_SOCKET);
233
0
    return recv(fd, buf, len, flags);
234
0
}
235
236
ssize_t ogs_recvfrom(ogs_socket_t fd,
237
        void *buf, size_t len, int flags, ogs_sockaddr_t *from)
238
0
{
239
0
    socklen_t addrlen = sizeof(struct sockaddr_storage);
240
241
0
    ogs_assert(fd != INVALID_SOCKET);
242
0
    ogs_assert(from);
243
244
0
    memset(from, 0, sizeof *from);
245
0
    return recvfrom(fd, buf, len, flags, &from->sa, &addrlen);
246
0
}
247
248
int ogs_closesocket(ogs_socket_t fd)
249
0
{
250
0
    int r;
251
#ifdef _WIN32
252
    r = closesocket(fd);
253
#else
254
0
    r = close(fd);
255
0
#endif
256
0
    if (r != 0) {
257
0
        ogs_log_message(OGS_LOG_ERROR, ogs_socket_errno, "closesocket failed");
258
0
        return OGS_ERROR;
259
0
    }
260
261
0
    return OGS_OK;
262
0
}