Coverage Report

Created: 2023-09-25 07:12

/src/open5gs/lib/gtp/path.c
Line
Count
Source (jump to first uncovered line)
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 "ogs-gtp.h"
21
22
ogs_sock_t *ogs_gtp_server(ogs_socknode_t *node)
23
0
{
24
0
    char buf[OGS_ADDRSTRLEN];
25
0
    ogs_sock_t *gtp;
26
0
    ogs_assert(node);
27
28
0
    gtp = ogs_udp_server(node->addr, node->option);
29
0
    if (gtp) {
30
0
        ogs_info("gtp_server() [%s]:%d",
31
0
                OGS_ADDR(node->addr, buf), OGS_PORT(node->addr));
32
33
0
        node->sock = gtp;
34
0
    }
35
36
0
    return gtp;
37
0
}
38
39
int ogs_gtp_connect(ogs_sock_t *ipv4, ogs_sock_t *ipv6, ogs_gtp_node_t *gnode)
40
0
{
41
0
    ogs_sockaddr_t *addr;
42
0
    char buf[OGS_ADDRSTRLEN];
43
44
0
    ogs_assert(ipv4 || ipv6);
45
0
    ogs_assert(gnode);
46
0
    ogs_assert(gnode->sa_list);
47
48
0
    addr = gnode->sa_list;
49
0
    while (addr) {
50
0
        ogs_sock_t *sock = NULL;
51
52
0
        if (addr->ogs_sa_family == AF_INET)
53
0
            sock = ipv4;
54
0
        else if (addr->ogs_sa_family == AF_INET6)
55
0
            sock = ipv6;
56
0
        else
57
0
            ogs_assert_if_reached();
58
59
0
        if (sock) {
60
0
            ogs_info("gtp_connect() [%s]:%d",
61
0
                    OGS_ADDR(addr, buf), OGS_PORT(addr));
62
63
0
            gnode->sock = sock;
64
0
            memcpy(&gnode->addr, addr, sizeof gnode->addr);
65
0
            break;
66
0
        }
67
68
0
        addr = addr->next;
69
0
    }
70
71
0
    if (addr == NULL) {
72
0
        ogs_log_message(OGS_LOG_WARN, ogs_socket_errno,
73
0
                "gtp_connect() [%s]:%d failed",
74
0
                OGS_ADDR(gnode->sa_list, buf), OGS_PORT(gnode->sa_list));
75
0
        return OGS_ERROR;
76
0
    }
77
78
0
    return OGS_OK;
79
0
}
80
81
int ogs_gtp_send(ogs_gtp_node_t *gnode, ogs_pkbuf_t *pkbuf)
82
0
{
83
0
    ssize_t sent;
84
0
    ogs_sock_t *sock = NULL;
85
86
0
    ogs_assert(gnode);
87
0
    ogs_assert(pkbuf);
88
0
    sock = gnode->sock;
89
0
    ogs_assert(sock);
90
91
0
    sent = ogs_send(sock->fd, pkbuf->data, pkbuf->len, 0);
92
0
    if (sent < 0 || sent != pkbuf->len) {
93
0
        if (ogs_socket_errno != OGS_EAGAIN) {
94
0
            ogs_log_message(OGS_LOG_ERROR, ogs_socket_errno,
95
0
                    "ogs_gtp_send() failed");
96
0
        }
97
0
        return OGS_ERROR;
98
0
    }
99
100
0
    return OGS_OK;
101
0
}
102
103
int ogs_gtp_sendto(ogs_gtp_node_t *gnode, ogs_pkbuf_t *pkbuf)
104
0
{
105
0
    ssize_t sent;
106
0
    ogs_sock_t *sock = NULL;
107
0
    ogs_sockaddr_t *addr = NULL;
108
109
0
    ogs_assert(gnode);
110
0
    ogs_assert(pkbuf);
111
0
    sock = gnode->sock;
112
0
    ogs_assert(sock);
113
0
    addr = &gnode->addr;
114
0
    ogs_assert(addr);
115
116
0
    sent = ogs_sendto(sock->fd, pkbuf->data, pkbuf->len, 0, addr);
117
0
    if (sent < 0 || sent != pkbuf->len) {
118
0
        if (ogs_socket_errno != OGS_EAGAIN) {
119
0
            char buf[OGS_ADDRSTRLEN];
120
0
            int err = ogs_socket_errno;
121
0
            ogs_log_message(OGS_LOG_ERROR, err,
122
0
                    "ogs_gtp_sendto(%u, %p, %u, 0, %s:%u) failed",
123
0
                    sock->fd, pkbuf->data, pkbuf->len,
124
0
                    OGS_ADDR(addr, buf), OGS_PORT(addr));
125
0
        }
126
0
        return OGS_ERROR;
127
0
    }
128
129
0
    return OGS_OK;
130
0
}
131
132
void ogs_gtp_send_error_message(
133
        ogs_gtp_xact_t *xact, uint32_t teid, uint8_t type, uint8_t cause_value)
134
0
{
135
0
    switch (xact->gtp_version) {
136
0
    case 1:
137
0
        ogs_gtp1_send_error_message(xact, teid, type, cause_value);
138
0
        break;
139
0
    case 2:
140
0
        ogs_gtp2_send_error_message(xact, teid, type, cause_value);
141
0
        break;
142
0
    }
143
0
}