Build with usrsctp source using MESON Subproject

This commit is contained in:
Sukchan Lee 2019-10-31 14:17:43 +09:00
parent b47e0e510e
commit 9f1a5d19a4
27 changed files with 204 additions and 546 deletions

View File

@ -35,8 +35,7 @@ ogs_pollset_t *ogs_pollset_create(void)
ogs_pool_init(&pollset->pool, ogs_core()->socket.pool);
if (ogs_pollset_actions_initialized == false)
{
if (ogs_pollset_actions_initialized == false) {
#if defined(HAVE_KQUEUE)
ogs_pollset_actions = ogs_kqueue_actions;;
#elif defined(HAVE_EPOLL)

View File

@ -278,6 +278,7 @@ ssize_t ogs_recvfrom(ogs_socket_t fd,
ogs_assert(fd != INVALID_SOCKET);
ogs_assert(from);
memset(from, 0, sizeof *from);
size = recvfrom(fd, buf, len, flags, &from->sa, &addrlen);
if (size < 0) {
ogs_log_message(OGS_LOG_ERROR, ogs_socket_errno,

View File

@ -51,10 +51,8 @@ void ogs_socknode_free(ogs_socknode_t *node)
ogs_assert(node);
ogs_freeaddrinfo(node->addr);
if (node->pollin.poll)
ogs_pollset_remove(node->pollin.poll);
if (node->pollout.poll)
ogs_pollset_remove(node->pollout.poll);
if (node->poll)
ogs_pollset_remove(node->poll);
if (node->sock) {
if (node->cleanup)
node->cleanup(node->sock);
@ -279,46 +277,3 @@ void ogs_socknode_set_cleanup(
node->cleanup = cleanup;
}
void ogs_socknode_set_poll(ogs_socknode_t *node,
ogs_pollset_t *set, short when, void *handler, void *data)
{
ogs_assert(node);
ogs_assert(set);
ogs_assert(handler);
if (when == OGS_POLLIN) {
node->pollin.set = set;
node->pollin.handler = handler;
node->pollin.data = data;
} else if (when == OGS_POLLOUT) {
node->pollout.set = set;
node->pollout.handler = handler;
node->pollout.data = data;
}
}
void ogs_socknode_install_poll(ogs_socknode_t *node)
{
ogs_assert(node);
if (node->pollin.handler) {
ogs_assert(node->sock);
ogs_assert(node->pollin.set);
ogs_assert(node->pollin.handler);
node->pollin.poll = ogs_pollset_add(node->pollin.set,
OGS_POLLIN, node->sock->fd, node->pollin.handler, node->pollin.data);
ogs_assert(node->pollin.poll);
}
if (node->pollout.handler) {
ogs_assert(node->sock);
ogs_assert(node->pollout.set);
ogs_assert(node->pollout.handler);
node->pollout.poll = ogs_pollset_add(node->pollout.set,
OGS_POLLOUT, node->sock->fd, node->pollout.handler, node->pollout.data);
ogs_assert(node->pollout.poll);
}
}

View File

@ -55,13 +55,7 @@ typedef struct ogs_socknode_s {
ogs_sock_t *sock;
void (*cleanup)(ogs_sock_t *sock);
struct {
ogs_pollset_t *set;
ogs_poll_t *poll;
void *handler;
void *data;
} pollin, pollout;
ogs_poll_t *poll;
ogs_sockopt_t option;
} ogs_socknode_t;
@ -84,9 +78,6 @@ void ogs_socknode_linger(ogs_socknode_t *node, int onoff, int linger);
void ogs_socknode_set_cleanup(
ogs_socknode_t *node, void (*cleanup)(ogs_sock_t *));
void ogs_socknode_set_poll(ogs_socknode_t *node,
ogs_pollset_t *set, short when, void *handler, void *data);
void ogs_socknode_install_poll(ogs_socknode_t *node);
#ifdef __cplusplus
}

View File

@ -63,8 +63,6 @@ ogs_sock_t *ogs_tcp_server(ogs_socknode_t *node)
node->sock = new;
ogs_socknode_install_poll(node);
return new;
}
@ -102,7 +100,5 @@ ogs_sock_t *ogs_tcp_client(ogs_socknode_t *node)
node->sock = new;
ogs_socknode_install_poll(node);
return new;
}

View File

@ -71,8 +71,6 @@ ogs_sock_t *ogs_udp_server(ogs_socknode_t *node)
node->sock = new;
ogs_socknode_install_poll(node);
return new;
}
@ -110,8 +108,6 @@ ogs_sock_t *ogs_udp_client(ogs_socknode_t *node)
node->sock = new;
ogs_socknode_install_poll(node);
return new;
}

View File

@ -38,17 +38,13 @@ libsctp_dep = cc.find_library('sctp', required : false)
if libsctp_dep.found()
libsctp_sources += files('ogs-lksctp.c')
else
libsctp_dep = cc.find_library('usrsctp', required : false)
if not libsctp_dep.found()
# sctp_debug = get_option('debug_level') >= 7
libsctp_dep = dependency('usrsctp',
version: ['>=1.0.0', '<2'],
fallback: ['usrsctp', 'usrsctp_dep'],
default_options: [
'sctp_build_programs=false',
# 'sctp_debug=@0@'.format(sctp_debug),
])
endif
libsctp_dep = dependency('usrsctp',
version: ['>=1.0.0', '<2'],
fallback: ['usrsctp', 'usrsctp_dep'],
default_options: [
'sctp_build_programs=false',
# 'sctp_debug=@0@'.format(true),
])
libsctp_sources += files('ogs-usrsctp.c')
libsctp_conf.set('HAVE_USRSCTP', 1)

View File

@ -119,8 +119,6 @@ ogs_sock_t *ogs_sctp_server(int type, ogs_socknode_t *node)
node->sock = new;
ogs_socknode_install_poll(node);
return new;
}
@ -158,8 +156,6 @@ ogs_sock_t *ogs_sctp_client(int type, ogs_socknode_t *node)
node->sock = new;
ogs_socknode_install_poll(node);
return new;
}
@ -222,14 +218,16 @@ int ogs_sctp_recvmsg(ogs_sock_t *sock, void *msg, size_t len,
{
int size;
socklen_t addrlen = sizeof(struct sockaddr_storage);
ogs_sockaddr_t addr;
int flags = 0;
struct sctp_sndrcvinfo sndrcvinfo;
ogs_assert(sock);
size = sctp_recvmsg(sock->fd, msg, len,
from ? &from->sa : NULL, from ? &addrlen : NULL,
memset(&sndrcvinfo, 0, sizeof sndrcvinfo);
memset(&addr, 0, sizeof addr);
size = sctp_recvmsg(sock->fd, msg, len, &addr.sa, &addrlen,
&sndrcvinfo, &flags);
if (size < 0) {
ogs_log_message(OGS_LOG_ERROR, ogs_socket_errno,
@ -237,6 +235,10 @@ int ogs_sctp_recvmsg(ogs_sock_t *sock, void *msg, size_t len,
return size;
}
if (from) {
memcpy(from, &addr, sizeof(ogs_sockaddr_t));
}
if (msg_flags) {
*msg_flags = flags;
}

View File

@ -73,7 +73,7 @@ ogs_sock_t *ogs_sctp_socket(int family, int type, ogs_socknode_t *node)
ogs_sctp_set_option(&option, node);
if (!(socket = usrsctp_socket(family, type, IPPROTO_SCTP,
node ? node->pollin.handler : NULL, NULL, 0, NULL))) {
NULL, NULL, 0, NULL))) {
ogs_error("ogs_sctp_socket() failed");
return NULL;
}
@ -341,8 +341,7 @@ int ogs_sctp_sendmsg(ogs_sock_t *sock, const void *msg, size_t len,
(void *)&sndinfo, (socklen_t)sizeof(struct sctp_sndinfo),
SCTP_SENDV_SNDINFO, 0);
if (sent < 0 || sent != len)
{
if (sent < 0 || sent != len) {
ogs_error("sent : %d, len : %d", (int)sent, (int)len);
return OGS_ERROR;
}
@ -365,6 +364,7 @@ int ogs_sctp_recvmsg(ogs_sock_t *sock, void *msg, size_t len,
ogs_assert(socket);
memset(&rcv_info, 0, sizeof rcv_info);
memset(&addr, 0, sizeof addr);
n = usrsctp_recvv(socket, msg, len,
&addr.sa, &addrlen,
(void *)&rcv_info,

View File

@ -51,11 +51,13 @@ libmme_sources = files('''
s1ap-sm.c
s1ap-build.c
s1ap-handler.c
s1ap-sctp.c
s1ap-path.c
sgsap-sm.c
sgsap-build.c
sgsap-handler.c
sgsap-conv.c
sgsap-sctp.c
sgsap-path.c
mme-fd-path.c
mme-s6a-handler.c
@ -75,14 +77,6 @@ libmme_sources = files('''
sbc-handler.c
'''.split())
if libsctp_conf.has('HAVE_USRSCTP')
libmme_sources += files('s1ap-usrpath.c')
libmme_sources += files('sgsap-usrpath.c')
else
libmme_sources += files('s1ap-lkpath.c')
libmme_sources += files('sgsap-lkpath.c')
endif
libmme = static_library('mme',
sources : libmme_sources,
dependencies : [libapp_dep,

View File

@ -1722,8 +1722,7 @@ void mme_vlr_remove(mme_vlr_t *vlr)
ogs_list_remove(&self.vlr_list, vlr);
if (vlr->node)
mme_vlr_free_node(vlr);
mme_vlr_close(vlr);
ogs_freeaddrinfo(vlr->sa_list);
@ -1738,27 +1737,14 @@ void mme_vlr_remove_all()
mme_vlr_remove(vlr);
}
ogs_socknode_t *mme_vlr_new_node(mme_vlr_t *vlr)
{
ogs_sockaddr_t *addr = NULL;
ogs_assert(vlr);
ogs_copyaddrinfo(&addr, vlr->sa_list);
ogs_assert(vlr->node == NULL);
vlr->node = ogs_socknode_new(addr);
ogs_assert(vlr->node);
return vlr->node;
}
void mme_vlr_free_node(mme_vlr_t *vlr)
void mme_vlr_close(mme_vlr_t *vlr)
{
ogs_assert(vlr);
ogs_assert(vlr->node);
ogs_socknode_free(vlr->node);
vlr->node = NULL;
if (vlr->poll)
ogs_pollset_remove(vlr->poll);
if (vlr->sock)
ogs_sctp_destroy(vlr->sock);
}
mme_vlr_t *mme_vlr_find_by_addr(ogs_sockaddr_t *addr)
@ -1865,7 +1851,7 @@ mme_enb_t *mme_enb_add(ogs_sock_t *sock, ogs_sockaddr_t *addr)
if (enb->sock_type == SOCK_STREAM) {
enb->poll = ogs_pollset_add(mme_self()->pollset,
OGS_POLLIN, sock->fd, s1ap_recv_handler, sock);
OGS_POLLIN, sock->fd, s1ap_recv_upcall, sock);
ogs_assert(enb->poll);
}

View File

@ -201,8 +201,9 @@ typedef struct mme_vlr_s {
ogs_sockaddr_t *sa_list; /* VLR SGsAP Socket Address List */
ogs_socknode_t *node; /* VLR SGsAP Node */
ogs_sock_t *sock; /* VLR SGsAP Socket */
ogs_sockaddr_t *addr; /* VLR SGsAP Connected Socket Address */
ogs_poll_t *poll; /* VLR SGsAP Poll */
} mme_vlr_t;
typedef struct mme_csmap_s {
@ -654,9 +655,7 @@ ogs_sockaddr_t *mme_pgw_addr_find_by_apn(
mme_vlr_t *mme_vlr_add(ogs_sockaddr_t *addr);
void mme_vlr_remove(mme_vlr_t *vlr);
void mme_vlr_remove_all(void);
ogs_socknode_t *mme_vlr_new_node(mme_vlr_t *vlr);
void mme_vlr_free_node(mme_vlr_t *vlr);
void mme_vlr_close(mme_vlr_t *vlr);
mme_vlr_t *mme_vlr_find_by_addr(ogs_sockaddr_t *addr);
mme_csmap_t *mme_csmap_add(mme_vlr_t *vlr);

View File

@ -65,18 +65,18 @@ int mme_gtp_open(void)
mme_sgw_t *sgw = NULL;
ogs_list_for_each(&mme_self()->gtpc_list, node) {
ogs_socknode_set_poll(node, mme_self()->pollset,
OGS_POLLIN, _gtpv2_c_recv_cb, NULL);
sock = ogs_gtp_server(node);
ogs_assert(sock);
node->poll = ogs_pollset_add(mme_self()->pollset,
OGS_POLLIN, sock->fd, _gtpv2_c_recv_cb, NULL);
}
ogs_list_for_each(&mme_self()->gtpc_list6, node) {
ogs_socknode_set_poll(node, mme_self()->pollset,
OGS_POLLIN, _gtpv2_c_recv_cb, NULL);
sock = ogs_gtp_server(node);
ogs_assert(sock);
node->poll = ogs_pollset_add(mme_self()->pollset,
OGS_POLLIN, sock->fd, _gtpv2_c_recv_cb, NULL);
}
mme_self()->gtpc_sock = ogs_gtp_local_sock_first(&mme_self()->gtpc_list);

View File

@ -552,7 +552,6 @@ void mme_state_operational(ogs_fsm_t *s, mme_event_t *e)
ogs_assert(pkbuf);
vlr = mme_vlr_find_by_addr(addr);
ogs_assert(vlr);
ogs_free(addr);
ogs_assert(vlr);

View File

@ -35,8 +35,7 @@ int s1ap_open(void);
void s1ap_close(void);
ogs_sock_t *s1ap_server(ogs_socknode_t *node);
void s1ap_recv_handler(short when, ogs_socket_t fd, void *data);
void s1ap_recv_upcall(short when, ogs_socket_t fd, void *data);
int s1ap_send(ogs_sock_t *sock,
ogs_pkbuf_t *pkbuf, ogs_sockaddr_t *addr, uint16_t stream_no);

View File

@ -22,7 +22,14 @@
#include "mme-event.h"
#include "s1ap-path.h"
static void accept_handler(short when, ogs_socket_t fd, void *data);
#if HAVE_USRSCTP
static void usrsctp_recv_handler(struct socket *socket, void *data, int flags);
#else
static void lksctp_accept_handler(short when, ogs_socket_t fd, void *data);
#endif
void s1ap_accept_handler(ogs_sock_t *sock);
void s1ap_recv_handler(ogs_sock_t *sock);
ogs_sock_t *s1ap_server(ogs_socknode_t *node)
{
@ -33,11 +40,17 @@ ogs_sock_t *s1ap_server(ogs_socknode_t *node)
ogs_socknode_sctp_option(node, &ogs_config()->sockopt);
ogs_socknode_nodelay(node, true);
ogs_socknode_set_poll(node, mme_self()->pollset,
OGS_POLLIN, accept_handler, node);
#if HAVE_USRSCTP
sock = ogs_sctp_server(SOCK_SEQPACKET, node);
ogs_assert(sock);
usrsctp_set_upcall((struct socket *)sock, usrsctp_recv_handler, NULL);
#else
sock = ogs_sctp_server(SOCK_STREAM, node);
ogs_assert(sock);
node->poll = ogs_pollset_add(mme_self()->pollset,
OGS_POLLIN, sock->fd, lksctp_accept_handler, sock);
#endif
ogs_info("s1ap_server() [%s]:%d",
OGS_ADDR(node->addr, buf), OGS_PORT(node->addr));
@ -45,17 +58,43 @@ ogs_sock_t *s1ap_server(ogs_socknode_t *node)
return sock;
}
static void accept_handler(short when, ogs_socket_t fd, void *data)
void s1ap_recv_upcall(short when, ogs_socket_t fd, void *data)
{
ogs_sock_t *sock = NULL;
ogs_assert(fd != INVALID_SOCKET);
sock = data;
ogs_assert(sock);
s1ap_recv_handler(sock);
}
#if HAVE_USRSCTP
static void usrsctp_recv_handler(struct socket *socket, void *data, int flags)
{
int events;
while ((events = usrsctp_get_events(socket)) &&
(events & SCTP_EVENT_READ)) {
s1ap_recv_handler((ogs_sock_t *)socket);
}
}
#else
static void lksctp_accept_handler(short when, ogs_socket_t fd, void *data)
{
ogs_assert(data);
ogs_assert(fd != INVALID_SOCKET);
s1ap_accept_handler(data);
}
#endif
void s1ap_accept_handler(ogs_sock_t *sock)
{
char buf[OGS_ADDRSTRLEN];
ogs_socknode_t *node = data;
ogs_sock_t *sock = NULL;
ogs_sock_t *new = NULL;
ogs_assert(node);
sock = node->sock;
ogs_assert(sock);
ogs_assert(fd != INVALID_SOCKET);
new = ogs_sock_accept(sock);
if (new) {
@ -75,25 +114,25 @@ static void accept_handler(short when, ogs_socket_t fd, void *data)
}
}
void s1ap_recv_handler(short when, ogs_socket_t fd, void *data)
void s1ap_recv_handler(ogs_sock_t *sock)
{
ogs_pkbuf_t *pkbuf;
int size;
ogs_sock_t *sock = data;
ogs_sockaddr_t *addr = NULL;
ogs_sockaddr_t from;
ogs_sctp_info_t sinfo;
int flags = 0;
ogs_assert(sock);
ogs_assert(fd != INVALID_SOCKET);
pkbuf = ogs_pkbuf_alloc(NULL, OGS_MAX_SDU_LEN);
ogs_pkbuf_put(pkbuf, OGS_MAX_SDU_LEN);
size = ogs_sctp_recvmsg(
sock, pkbuf->data, pkbuf->len, NULL, &sinfo, &flags);
sock, pkbuf->data, pkbuf->len, &from, &sinfo, &flags);
if (size < 0) {
ogs_error("ogs_sctp_recvmsg(%d) failed(%d:%s)",
size, errno, strerror(errno));
ogs_pkbuf_free(pkbuf);
return;
}
@ -116,7 +155,7 @@ void s1ap_recv_handler(short when, ogs_socket_t fd, void *data)
addr = ogs_calloc(1, sizeof(ogs_sockaddr_t));
ogs_assert(addr);
memcpy(addr, &sock->remote_addr, sizeof(ogs_sockaddr_t));
memcpy(addr, &from, sizeof(ogs_sockaddr_t));
s1ap_event_push(MME_EVT_S1AP_LO_SCTP_COMM_UP,
sock, addr, NULL,
@ -132,7 +171,7 @@ void s1ap_recv_handler(short when, ogs_socket_t fd, void *data)
addr = ogs_calloc(1, sizeof(ogs_sockaddr_t));
ogs_assert(addr);
memcpy(addr, &sock->remote_addr, sizeof(ogs_sockaddr_t));
memcpy(addr, &from, sizeof(ogs_sockaddr_t));
s1ap_event_push(MME_EVT_S1AP_LO_CONNREFUSED,
sock, addr, NULL, 0, 0);
@ -146,14 +185,21 @@ void s1ap_recv_handler(short when, ogs_socket_t fd, void *data)
not->sn_shutdown_event.sse_flags,
not->sn_shutdown_event.sse_length);
if (not->sn_header.sn_type == SCTP_SEND_FAILED)
#if HAVE_USRSCTP
ogs_error("SCTP_SEND_FAILED:[T:%d, F:0x%x, S:%d]",
not->sn_send_failed_event.ssfe_type,
not->sn_send_failed_event.ssfe_flags,
not->sn_send_failed_event.ssfe_error);
#else
ogs_error("SCTP_SEND_FAILED:[T:%d, F:0x%x, S:%d]",
not->sn_send_failed.ssf_type,
not->sn_send_failed.ssf_flags,
not->sn_send_failed.ssf_error);
#endif
addr = ogs_calloc(1, sizeof(ogs_sockaddr_t));
ogs_assert(addr);
memcpy(addr, &sock->remote_addr, sizeof(ogs_sockaddr_t));
memcpy(addr, &from, sizeof(ogs_sockaddr_t));
s1ap_event_push(MME_EVT_S1AP_LO_CONNREFUSED,
sock, addr, NULL, 0, 0);
@ -180,7 +226,7 @@ void s1ap_recv_handler(short when, ogs_socket_t fd, void *data)
addr = ogs_calloc(1, sizeof(ogs_sockaddr_t));
ogs_assert(addr);
memcpy(addr, &sock->remote_addr, sizeof(ogs_sockaddr_t));
memcpy(addr, &from, sizeof(ogs_sockaddr_t));
s1ap_event_push(MME_EVT_S1AP_MESSAGE, sock, addr, pkbuf, 0, 0);
return;

View File

@ -1,171 +0,0 @@
/*
* Copyright (C) 2019 by Sukchan Lee <acetcom@gmail.com>
*
* This file is part of Open5GS.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#include "ogs-sctp.h"
#include "mme-event.h"
#include "s1ap-path.h"
static int usrsctp_recv_handler(struct socket *sock,
union sctp_sockstore addr, void *data, size_t datalen,
struct sctp_rcvinfo rcv, int flags, void *ulp_info);
ogs_sock_t *s1ap_server(ogs_socknode_t *node)
{
char buf[OGS_ADDRSTRLEN];
ogs_sock_t *sock = NULL;
ogs_assert(node);
ogs_socknode_sctp_option(node, &ogs_config()->sockopt);
ogs_socknode_nodelay(node, true);
ogs_socknode_set_poll(node, mme_self()->pollset,
OGS_POLLIN, usrsctp_recv_handler, node);
/* FIXME : libsctp 0.9.3.0 is not properly working in SOCK_STREAM */
sock = ogs_sctp_server(SOCK_SEQPACKET, node);
ogs_assert(sock);
ogs_info("s1ap_server() [%s]:%d",
OGS_ADDR(node->addr, buf), OGS_PORT(node->addr));
return sock;
}
void s1ap_recv_handler(short when, ogs_socket_t fd, void *data)
{
/* At this point, open5gs does not use SOCK_STREAM in libusrsctp */
ogs_assert_if_reached();
}
static int usrsctp_recv_handler(struct socket *sock,
union sctp_sockstore store, void *data, size_t datalen,
struct sctp_rcvinfo rcv, int flags, void *ulp_info)
{
ogs_sockaddr_t *addr = NULL;
if (data) {
if (flags & MSG_NOTIFICATION) {
union sctp_notification *not = (union sctp_notification *)data;
if (not->sn_header.sn_length == (uint32_t)datalen) {
switch(not->sn_header.sn_type) {
case SCTP_ASSOC_CHANGE :
ogs_debug("SCTP_ASSOC_CHANGE:"
"[T:%d, F:0x%x, S:%d, I/O:%d/%d]",
not->sn_assoc_change.sac_type,
not->sn_assoc_change.sac_flags,
not->sn_assoc_change.sac_state,
not->sn_assoc_change.sac_inbound_streams,
not->sn_assoc_change.sac_outbound_streams);
if (not->sn_assoc_change.sac_state ==
SCTP_SHUTDOWN_COMP ||
not->sn_assoc_change.sac_state ==
SCTP_COMM_LOST) {
addr = ogs_usrsctp_remote_addr(&store);
ogs_assert(addr);
if (not->sn_assoc_change.sac_state ==
SCTP_SHUTDOWN_COMP)
ogs_debug("SCTP_SHUTDOWN_COMP");
if (not->sn_assoc_change.sac_state ==
SCTP_COMM_LOST)
ogs_debug("SCTP_COMM_LOST");
s1ap_event_push(MME_EVT_S1AP_LO_CONNREFUSED,
sock, addr, NULL, 0, 0);
} else if (not->sn_assoc_change.sac_state == SCTP_COMM_UP) {
addr = ogs_usrsctp_remote_addr(&store);
ogs_assert(addr);
ogs_debug("SCTP_COMM_UP");
s1ap_event_push(MME_EVT_S1AP_LO_SCTP_COMM_UP,
sock, addr, NULL,
not->sn_assoc_change.sac_inbound_streams,
not->sn_assoc_change.sac_outbound_streams);
}
break;
case SCTP_SHUTDOWN_EVENT :
case SCTP_SEND_FAILED :
addr = ogs_usrsctp_remote_addr(&store);
ogs_assert(addr);
if (not->sn_header.sn_type == SCTP_SHUTDOWN_EVENT)
ogs_debug("SCTP_SHUTDOWN_EVENT:"
"[T:0x%x, F:0x%x, L:0x%x]",
not->sn_shutdown_event.sse_type,
not->sn_shutdown_event.sse_flags,
not->sn_shutdown_event.sse_length);
if (not->sn_header.sn_type == SCTP_SEND_FAILED)
ogs_error("SCTP_SEND_FAILED:[T:%d, F:0x%x, S:%d]",
not->sn_send_failed_event.ssfe_type,
not->sn_send_failed_event.ssfe_flags,
not->sn_send_failed_event.ssfe_error);
s1ap_event_push(MME_EVT_S1AP_LO_CONNREFUSED,
sock, addr, NULL, 0, 0);
break;
case SCTP_PEER_ADDR_CHANGE:
ogs_warn("SCTP_PEER_ADDR_CHANGE:"
"[T:%d, F:0x%x, S:%d]",
not->sn_paddr_change.spc_type,
not->sn_paddr_change.spc_flags,
not->sn_paddr_change.spc_error);
break;
case SCTP_ADAPTATION_INDICATION :
ogs_info("SCTP_ADAPTATION_INDICATION:"
"[T:%d, F:0x%x, S:%d, I:%d]",
not->sn_adaptation_event.sai_type,
not->sn_adaptation_event.sai_flags,
not->sn_adaptation_event.sai_length,
not->sn_adaptation_event.sai_adaptation_ind);
break;
case SCTP_REMOTE_ERROR:
ogs_warn("SCTP_REMOTE_ERROR:[T:%d, F:0x%x, S:%d]",
not->sn_remote_error.sre_type,
not->sn_remote_error.sre_flags,
not->sn_remote_error.sre_error);
break;
break;
default :
ogs_error("Discarding event with "
"unknown flags:0x%x type:0x%x",
flags, not->sn_header.sn_type);
break;
}
}
} else if (flags & MSG_EOR) {
ogs_pkbuf_t *pkbuf;
pkbuf = ogs_pkbuf_alloc(NULL, OGS_MAX_SDU_LEN);
ogs_pkbuf_put_data(pkbuf, data, datalen);
addr = ogs_usrsctp_remote_addr(&store);
ogs_assert(addr);
s1ap_event_push(MME_EVT_S1AP_MESSAGE, sock, addr, pkbuf, 0, 0);
} else {
ogs_error("Not engough buffer. Need more recv : 0x%x", flags);
}
free(data);
}
return (1);
}

View File

@ -85,13 +85,11 @@ int sgsap_send_to_vlr_with_sid(
ogs_assert(vlr);
ogs_assert(pkbuf);
node = vlr->node;
ogs_assert(node);
sock = node->sock;
sock = vlr->sock;
ogs_assert(sock);
ogs_debug(" VLR-IP[%s]", OGS_ADDR(node->addr, buf));
rv = sgsap_send(sock, pkbuf, node->addr, stream_no);
ogs_debug(" VLR-IP[%s]", OGS_ADDR(vlr->addr, buf));
rv = sgsap_send(sock, pkbuf, vlr->addr, stream_no);
if (rv != OGS_OK) {
ogs_error("sgsap_send() failed");

View File

@ -33,7 +33,6 @@ int sgsap_open(void);
void sgsap_close(void);
ogs_sock_t *sgsap_client(mme_vlr_t *vlr);
void sgsap_recv_handler(short when, ogs_socket_t fd, void *data);
int sgsap_send(ogs_sock_t *sock,
ogs_pkbuf_t *pkbuf, ogs_sockaddr_t *addr, uint16_t stream_no);

View File

@ -24,54 +24,89 @@
#include "mme-event.h"
#include "s1ap-path.h"
static void recv_handler(short when, ogs_socket_t fd, void *data);
#if HAVE_USRSCTP
static void usrsctp_recv_handler(struct socket *socket, void *data, int flags);
#else
static void lksctp_recv_handler(short when, ogs_socket_t fd, void *data);
#endif
static void recv_handler(ogs_sock_t *sock);
ogs_sock_t *sgsap_client(mme_vlr_t *vlr)
{
char buf[OGS_ADDRSTRLEN];
ogs_socknode_t *node = NULL;
ogs_socknode_t node;
ogs_sock_t *sock = NULL;
node = mme_vlr_new_node(vlr);
ogs_assert(node);
ogs_assert(vlr);
ogs_socknode_sctp_option(node, &ogs_config()->sockopt);
ogs_socknode_nodelay(node, true);
ogs_socknode_set_poll(node, mme_self()->pollset,
OGS_POLLIN, recv_handler, node);
memset(&node, 0, sizeof node);
node.addr = vlr->sa_list;
sock = ogs_sctp_client(SOCK_SEQPACKET, node);
ogs_socknode_sctp_option(&node, &ogs_config()->sockopt);
ogs_socknode_nodelay(&node, true);
ogs_socknode_linger(&node, true, 0);
sock = ogs_sctp_client(SOCK_SEQPACKET, &node);
if (sock) {
ogs_info("sgsap client() [%s]:%d",
OGS_ADDR(node->addr, buf), OGS_PORT(node->addr));
vlr->sock = sock;
#if HAVE_USRSCTP
vlr->addr = node.addr;
usrsctp_set_upcall((struct socket *)sock, usrsctp_recv_handler, NULL);
#else
vlr->addr = &sock->remote_addr;
vlr->poll = ogs_pollset_add(mme_self()->pollset,
OGS_POLLIN, sock->fd, lksctp_recv_handler, sock);
#endif
ogs_info("sgsap client() [%s]:%d",
OGS_ADDR(vlr->addr, buf), OGS_PORT(vlr->addr));
}
return sock;
}
static void recv_handler(short when, ogs_socket_t fd, void *data)
#if HAVE_USRSCTP
static void usrsctp_recv_handler(struct socket *socket, void *data, int flags)
{
int events;
while ((events = usrsctp_get_events(socket)) &&
(events & SCTP_EVENT_READ)) {
recv_handler((ogs_sock_t *)socket);
}
}
#else
static void lksctp_recv_handler(short when, ogs_socket_t fd, void *data)
{
ogs_sock_t *sock = NULL;
sock = data;
ogs_assert(fd != INVALID_SOCKET);
ogs_assert(sock);
recv_handler(sock);
}
#endif
static void recv_handler(ogs_sock_t *sock)
{
ogs_pkbuf_t *pkbuf;
int size;
ogs_socknode_t *node = data;
ogs_sock_t *sock = NULL;
ogs_sockaddr_t *addr = NULL;
ogs_sockaddr_t from;
ogs_sctp_info_t sinfo;
int flags = 0;
ogs_assert(node);
sock = node->sock;
ogs_assert(sock);
ogs_assert(fd != INVALID_SOCKET);
pkbuf = ogs_pkbuf_alloc(NULL, OGS_MAX_SDU_LEN);
ogs_pkbuf_put(pkbuf, OGS_MAX_SDU_LEN);
size = ogs_sctp_recvmsg(
sock, pkbuf->data, pkbuf->len, NULL, &sinfo, &flags);
sock, pkbuf->data, pkbuf->len, &from, &sinfo, &flags);
if (size < 0) {
ogs_error("ogs_sctp_recvmsg(%d) failed(%d:%s)",
size, errno, strerror(errno));
ogs_pkbuf_free(pkbuf);
return;
}
@ -94,7 +129,7 @@ static void recv_handler(short when, ogs_socket_t fd, void *data)
addr = ogs_calloc(1, sizeof(ogs_sockaddr_t));
ogs_assert(addr);
memcpy(addr, &sock->remote_addr, sizeof(ogs_sockaddr_t));
memcpy(addr, &from, sizeof(ogs_sockaddr_t));
sgsap_event_push(MME_EVT_SGSAP_LO_SCTP_COMM_UP,
sock, addr, NULL,
@ -110,7 +145,7 @@ static void recv_handler(short when, ogs_socket_t fd, void *data)
addr = ogs_calloc(1, sizeof(ogs_sockaddr_t));
ogs_assert(addr);
memcpy(addr, &sock->remote_addr, sizeof(ogs_sockaddr_t));
memcpy(addr, &from, sizeof(ogs_sockaddr_t));
sgsap_event_push(MME_EVT_SGSAP_LO_CONNREFUSED,
sock, addr, NULL, 0, 0);
@ -124,14 +159,21 @@ static void recv_handler(short when, ogs_socket_t fd, void *data)
not->sn_shutdown_event.sse_flags,
not->sn_shutdown_event.sse_length);
if (not->sn_header.sn_type == SCTP_SEND_FAILED)
#if HAVE_USRSCTP
ogs_error("SCTP_SEND_FAILED:[T:%d, F:0x%x, S:%d]",
not->sn_send_failed_event.ssfe_type,
not->sn_send_failed_event.ssfe_flags,
not->sn_send_failed_event.ssfe_error);
#else
ogs_error("SCTP_SEND_FAILED:[T:%d, F:0x%x, S:%d]",
not->sn_send_failed.ssf_type,
not->sn_send_failed.ssf_flags,
not->sn_send_failed.ssf_error);
#endif
addr = ogs_calloc(1, sizeof(ogs_sockaddr_t));
ogs_assert(addr);
memcpy(addr, &sock->remote_addr, sizeof(ogs_sockaddr_t));
memcpy(addr, &from, sizeof(ogs_sockaddr_t));
sgsap_event_push(MME_EVT_SGSAP_LO_CONNREFUSED,
sock, addr, NULL, 0, 0);
@ -158,7 +200,7 @@ static void recv_handler(short when, ogs_socket_t fd, void *data)
addr = ogs_calloc(1, sizeof(ogs_sockaddr_t));
ogs_assert(addr);
memcpy(addr, &sock->remote_addr, sizeof(ogs_sockaddr_t));
memcpy(addr, &from, sizeof(ogs_sockaddr_t));
sgsap_event_push(MME_EVT_SGSAP_MESSAGE, sock, addr, pkbuf, 0, 0);
return;

View File

@ -64,7 +64,6 @@ void sgsap_state_will_connect(ogs_fsm_t *s, mme_event_t *e)
char buf[OGS_ADDRSTRLEN];
mme_vlr_t *vlr = NULL;
ogs_socknode_t *node = NULL;
ogs_sockaddr_t *addr = NULL;
ogs_assert(s);
ogs_assert(e);
@ -90,9 +89,7 @@ void sgsap_state_will_connect(ogs_fsm_t *s, mme_event_t *e)
case MME_TIMER_SGS_CLI_CONN_TO_SRV:
vlr = e->vlr;
ogs_assert(vlr);
node = vlr->node;
ogs_assert(node);
addr = node->addr;
addr = vlr->addr;
ogs_assert(addr);
ogs_warn("[SGsAP] Connect to VLR [%s]:%d failed",
@ -102,7 +99,7 @@ void sgsap_state_will_connect(ogs_fsm_t *s, mme_event_t *e)
ogs_timer_start(vlr->t_conn,
mme_timer_cfg(MME_TIMER_SGS_CLI_CONN_TO_SRV)->duration);
mme_vlr_free_node(vlr);
mme_vlr_close(vlr);
sgsap_client(vlr);
break;
default:
@ -139,7 +136,7 @@ void sgsap_state_connected(ogs_fsm_t *s, mme_event_t *e)
case OGS_FSM_EXIT_SIG:
break;
case MME_EVT_SGSAP_LO_CONNREFUSED:
mme_vlr_free_node(vlr);
mme_vlr_close(vlr);
OGS_FSM_TRAN(s, sgsap_state_will_connect);
break;
case MME_EVT_SGSAP_MESSAGE:
@ -166,7 +163,7 @@ void sgsap_state_connected(ogs_fsm_t *s, mme_event_t *e)
case SGSAP_RESET_INDICATION:
sgsap_handle_reset_indication(vlr, pkbuf);
mme_vlr_free_node(vlr);
mme_vlr_close(vlr);
OGS_FSM_TRAN(s, sgsap_state_will_connect);
break;
case SGSAP_RELEASE_REQUEST:

View File

@ -1,164 +0,0 @@
/*
* Copyright (C) 2019 by Sukchan Lee <acetcom@gmail.com>
*
* This file is part of Open5GS.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#include "ogs-sctp.h"
#include "mme-context.h"
#include "mme-event.h"
#include "sgsap-path.h"
static int usrsctp_recv_handler(struct socket *sock,
union sctp_sockstore addr, void *data, size_t datalen,
struct sctp_rcvinfo rcv, int flags, void *ulp_info);
ogs_sock_t *sgsap_client(mme_vlr_t *vlr)
{
char buf[OGS_ADDRSTRLEN];
ogs_socknode_t *node = NULL;
ogs_sock_t *sock = NULL;
node = mme_vlr_new_node(vlr);
ogs_assert(node);
ogs_socknode_sctp_option(node, &ogs_config()->sockopt);
ogs_socknode_nodelay(node, true);
ogs_socknode_linger(node, true, 0);
ogs_socknode_set_poll(node, mme_self()->pollset,
OGS_POLLIN, usrsctp_recv_handler, node);
sock = ogs_sctp_client(SOCK_SEQPACKET, node);
if (sock) {
ogs_info("sgsap_client() [%s]:%d",
OGS_ADDR(node->addr, buf), OGS_PORT(node->addr));
vlr->addr = node->addr;
}
return sock;
}
static int usrsctp_recv_handler(struct socket *sock,
union sctp_sockstore store, void *data, size_t datalen,
struct sctp_rcvinfo rcv, int flags, void *ulp_info)
{
ogs_sockaddr_t *addr = NULL;
if (data) {
if (flags & MSG_NOTIFICATION) {
union sctp_notification *not = (union sctp_notification *)data;
if (not->sn_header.sn_length == (uint32_t)datalen) {
switch(not->sn_header.sn_type) {
case SCTP_ASSOC_CHANGE :
ogs_debug("SCTP_ASSOC_CHANGE:"
"[T:%d, F:0x%x, S:%d, I/O:%d/%d]",
not->sn_assoc_change.sac_type,
not->sn_assoc_change.sac_flags,
not->sn_assoc_change.sac_state,
not->sn_assoc_change.sac_inbound_streams,
not->sn_assoc_change.sac_outbound_streams);
if (not->sn_assoc_change.sac_state == SCTP_SHUTDOWN_COMP ||
not->sn_assoc_change.sac_state == SCTP_COMM_LOST) {
addr = ogs_usrsctp_remote_addr(&store);
ogs_assert(addr);
if (not->sn_assoc_change.sac_state ==
SCTP_SHUTDOWN_COMP)
ogs_debug("SCTP_SHUTDOWN_COMP");
if (not->sn_assoc_change.sac_state ==
SCTP_COMM_LOST)
ogs_debug("SCTP_COMM_LOST");
sgsap_event_push(MME_EVT_SGSAP_LO_CONNREFUSED,
sock, addr, NULL, 0, 0);
} else if (not->sn_assoc_change.sac_state == SCTP_COMM_UP) {
addr = ogs_usrsctp_remote_addr(&store);
ogs_assert(addr);
ogs_debug("SCTP_COMM_UP");
sgsap_event_push(MME_EVT_SGSAP_LO_SCTP_COMM_UP,
sock, addr, NULL,
not->sn_assoc_change.sac_inbound_streams,
not->sn_assoc_change.sac_outbound_streams);
}
break;
case SCTP_SHUTDOWN_EVENT :
case SCTP_SEND_FAILED :
addr = ogs_usrsctp_remote_addr(&store);
ogs_assert(addr);
if (not->sn_header.sn_type == SCTP_SHUTDOWN_EVENT)
ogs_debug("SCTP_SHUTDOWN_EVENT:[T:%d, F:0x%x, L:%d]",
not->sn_shutdown_event.sse_type,
not->sn_shutdown_event.sse_flags,
not->sn_shutdown_event.sse_length);
if (not->sn_header.sn_type == SCTP_SEND_FAILED)
ogs_error("SCTP_SEND_FAILED:[T:%d, F:0x%x, S:%d]",
not->sn_send_failed_event.ssfe_type,
not->sn_send_failed_event.ssfe_flags,
not->sn_send_failed_event.ssfe_error);
sgsap_event_push(MME_EVT_SGSAP_LO_CONNREFUSED,
sock, addr, NULL, 0, 0);
break;
case SCTP_PEER_ADDR_CHANGE:
ogs_warn("SCTP_PEER_ADDR_CHANGE:"
"[T:%d, F:0x%x, S:%d]",
not->sn_paddr_change.spc_type,
not->sn_paddr_change.spc_flags,
not->sn_paddr_change.spc_error);
break;
case SCTP_ADAPTATION_INDICATION :
ogs_info("SCTP_ADAPTATION_INDICATION:"
"[T:%d, F:0x%x, S:%d, I:%d]",
not->sn_adaptation_event.sai_type,
not->sn_adaptation_event.sai_flags,
not->sn_adaptation_event.sai_length,
not->sn_adaptation_event.sai_adaptation_ind);
break;
case SCTP_REMOTE_ERROR:
ogs_warn("SCTP_REMOTE_ERROR:[T:%d, F:0x%x, S:%d]",
not->sn_remote_error.sre_type,
not->sn_remote_error.sre_flags,
not->sn_remote_error.sre_error);
break;
default :
ogs_error("Discarding event with "
"unknown flags:0x%x type:0x%x",
flags, not->sn_header.sn_type);
break;
}
}
} else if (flags & MSG_EOR) {
ogs_pkbuf_t *pkbuf;
pkbuf = ogs_pkbuf_alloc(NULL, OGS_MAX_SDU_LEN);
ogs_pkbuf_put_data(pkbuf, data, datalen);
addr = ogs_usrsctp_remote_addr(&store);
ogs_assert(addr);
sgsap_event_push(MME_EVT_SGSAP_MESSAGE, sock, addr, pkbuf, 0, 0);
} else {
ogs_error("Not engough buffer. Need more recv : 0x%x", flags);
}
free(data);
}
return (1);
}

View File

@ -209,18 +209,18 @@ int pgw_gtp_open(void)
int rc;
ogs_list_for_each(&pgw_self()->gtpc_list, node) {
ogs_socknode_set_poll(node, pgw_self()->pollset,
OGS_POLLIN, _gtpv2_c_recv_cb, NULL);
sock = ogs_gtp_server(node);
ogs_assert(sock);
node->poll = ogs_pollset_add(pgw_self()->pollset,
OGS_POLLIN, sock->fd, _gtpv2_c_recv_cb, NULL);
}
ogs_list_for_each(&pgw_self()->gtpc_list6, node) {
ogs_socknode_set_poll(node, pgw_self()->pollset,
OGS_POLLIN, _gtpv2_c_recv_cb, NULL);
sock = ogs_gtp_server(node);
ogs_assert(sock);
node->poll = ogs_pollset_add(pgw_self()->pollset,
OGS_POLLIN, sock->fd, _gtpv2_c_recv_cb, NULL);
}
pgw_self()->gtpc_sock = ogs_gtp_local_sock_first(&pgw_self()->gtpc_list);
@ -231,18 +231,18 @@ int pgw_gtp_open(void)
ogs_assert(pgw_self()->gtpc_addr || pgw_self()->gtpc_addr6);
ogs_list_for_each(&pgw_self()->gtpu_list, node) {
ogs_socknode_set_poll(node, pgw_self()->pollset,
OGS_POLLIN, _gtpv1_u_recv_cb, NULL);
sock = ogs_gtp_server(node);
ogs_assert(sock);
node->poll = ogs_pollset_add(pgw_self()->pollset,
OGS_POLLIN, sock->fd, _gtpv1_u_recv_cb, NULL);
}
ogs_list_for_each(&pgw_self()->gtpu_list6, node) {
ogs_socknode_set_poll(node, pgw_self()->pollset,
OGS_POLLIN, _gtpv1_u_recv_cb, NULL);
sock = ogs_gtp_server(node);
ogs_assert(sock);
node->poll = ogs_pollset_add(pgw_self()->pollset,
OGS_POLLIN, sock->fd, _gtpv1_u_recv_cb, NULL);
}
pgw_self()->gtpu_sock = ogs_gtp_local_sock_first(&pgw_self()->gtpu_list);

View File

@ -265,18 +265,18 @@ int sgw_gtp_open(void)
packet_pool = ogs_pkbuf_pool_create(&config);
ogs_list_for_each(&sgw_self()->gtpc_list, node) {
ogs_socknode_set_poll(node, sgw_self()->pollset,
OGS_POLLIN, _gtpv2_c_recv_cb, NULL);
sock = ogs_gtp_server(node);
ogs_assert(sock);
node->poll = ogs_pollset_add(sgw_self()->pollset,
OGS_POLLIN, sock->fd, _gtpv2_c_recv_cb, NULL);
}
ogs_list_for_each(&sgw_self()->gtpc_list6, node) {
ogs_socknode_set_poll(node, sgw_self()->pollset,
OGS_POLLIN, _gtpv2_c_recv_cb, NULL);
sock = ogs_gtp_server(node);
ogs_assert(sock);
node->poll = ogs_pollset_add(sgw_self()->pollset,
OGS_POLLIN, sock->fd, _gtpv2_c_recv_cb, NULL);
}
sgw_self()->gtpc_sock = ogs_gtp_local_sock_first(&sgw_self()->gtpc_list);
@ -287,18 +287,18 @@ int sgw_gtp_open(void)
ogs_assert(sgw_self()->gtpc_addr || sgw_self()->gtpc_addr6);
ogs_list_for_each(&sgw_self()->gtpu_list, node) {
ogs_socknode_set_poll(node, sgw_self()->pollset,
OGS_POLLIN, _gtpv1_u_recv_cb, NULL);
sock = ogs_gtp_server(node);
ogs_assert(sock);
node->poll = ogs_pollset_add(sgw_self()->pollset,
OGS_POLLIN, sock->fd, _gtpv1_u_recv_cb, NULL);
}
ogs_list_for_each(&sgw_self()->gtpu_list6, node) {
ogs_socknode_set_poll(node, sgw_self()->pollset,
OGS_POLLIN, _gtpv1_u_recv_cb, NULL);
sock = ogs_gtp_server(node);
ogs_assert(sock);
node->poll = ogs_pollset_add(sgw_self()->pollset,
OGS_POLLIN, sock->fd, _gtpv1_u_recv_cb, NULL);
}
sgw_self()->gtpu_sock = ogs_gtp_local_sock_first(&sgw_self()->gtpu_list);

View File

@ -1,4 +1,4 @@
[wrap-git]
directory = usrsctp
url = https://github.com/sctplab/usrsctp.git
revision = master
revision = 09768bfcf22f91f6e43f0e692fc612564621d02f

View File

@ -285,6 +285,7 @@ static void test4_func(abts_case *tc, void *data)
ogs_sock_t *udp;
ogs_sockaddr_t *addr;
ogs_socknode_t *node;
ogs_poll_t *poll;
ogs_pollset_t *pollset = ogs_pollset_create();
ABTS_PTR_NOTNULL(tc, pollset);
@ -292,9 +293,9 @@ static void test4_func(abts_case *tc, void *data)
ABTS_INT_EQUAL(tc, OGS_OK, rv);
node = ogs_socknode_new(addr);
ABTS_PTR_NOTNULL(tc, node);
ogs_socknode_set_poll(node, pollset, OGS_POLLIN, test4_handler, tc);
udp = ogs_udp_server(node);
ABTS_PTR_NOTNULL(tc, udp);
poll = ogs_pollset_add(pollset, OGS_POLLIN, udp->fd, test4_handler, tc);
test4_thread = ogs_thread_create(test4_main, tc);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
@ -304,6 +305,7 @@ static void test4_func(abts_case *tc, void *data)
ogs_thread_destroy(test4_thread);
ogs_pollset_remove(poll);
ogs_socknode_free(node);
ogs_pollset_destroy(pollset);

View File

@ -224,10 +224,6 @@ static void test4_func(abts_case *tc, void *data)
ogs_sctp_info_t sinfo;
char buf[OGS_ADDRSTRLEN];
#if HAVE_USRSCTP /* FIXME : USRSCTP work-around */
ogs_msleep(10);
#endif
rv = ogs_getaddrinfo(&addr, AF_INET6, NULL, TEST4_PORT, AI_PASSIVE);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
node = ogs_socknode_new(addr);