forked from acouzens/open5gs
Build with usrsctp source using MESON Subproject
This commit is contained in:
parent
b47e0e510e
commit
9f1a5d19a4
|
@ -35,8 +35,7 @@ ogs_pollset_t *ogs_pollset_create(void)
|
||||||
|
|
||||||
ogs_pool_init(&pollset->pool, ogs_core()->socket.pool);
|
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)
|
#if defined(HAVE_KQUEUE)
|
||||||
ogs_pollset_actions = ogs_kqueue_actions;;
|
ogs_pollset_actions = ogs_kqueue_actions;;
|
||||||
#elif defined(HAVE_EPOLL)
|
#elif defined(HAVE_EPOLL)
|
||||||
|
|
|
@ -278,6 +278,7 @@ ssize_t ogs_recvfrom(ogs_socket_t fd,
|
||||||
ogs_assert(fd != INVALID_SOCKET);
|
ogs_assert(fd != INVALID_SOCKET);
|
||||||
ogs_assert(from);
|
ogs_assert(from);
|
||||||
|
|
||||||
|
memset(from, 0, sizeof *from);
|
||||||
size = recvfrom(fd, buf, len, flags, &from->sa, &addrlen);
|
size = recvfrom(fd, buf, len, flags, &from->sa, &addrlen);
|
||||||
if (size < 0) {
|
if (size < 0) {
|
||||||
ogs_log_message(OGS_LOG_ERROR, ogs_socket_errno,
|
ogs_log_message(OGS_LOG_ERROR, ogs_socket_errno,
|
||||||
|
|
|
@ -51,10 +51,8 @@ void ogs_socknode_free(ogs_socknode_t *node)
|
||||||
ogs_assert(node);
|
ogs_assert(node);
|
||||||
|
|
||||||
ogs_freeaddrinfo(node->addr);
|
ogs_freeaddrinfo(node->addr);
|
||||||
if (node->pollin.poll)
|
if (node->poll)
|
||||||
ogs_pollset_remove(node->pollin.poll);
|
ogs_pollset_remove(node->poll);
|
||||||
if (node->pollout.poll)
|
|
||||||
ogs_pollset_remove(node->pollout.poll);
|
|
||||||
if (node->sock) {
|
if (node->sock) {
|
||||||
if (node->cleanup)
|
if (node->cleanup)
|
||||||
node->cleanup(node->sock);
|
node->cleanup(node->sock);
|
||||||
|
@ -279,46 +277,3 @@ void ogs_socknode_set_cleanup(
|
||||||
|
|
||||||
node->cleanup = 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);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
|
@ -55,13 +55,7 @@ typedef struct ogs_socknode_s {
|
||||||
|
|
||||||
ogs_sock_t *sock;
|
ogs_sock_t *sock;
|
||||||
void (*cleanup)(ogs_sock_t *sock);
|
void (*cleanup)(ogs_sock_t *sock);
|
||||||
|
ogs_poll_t *poll;
|
||||||
struct {
|
|
||||||
ogs_pollset_t *set;
|
|
||||||
ogs_poll_t *poll;
|
|
||||||
void *handler;
|
|
||||||
void *data;
|
|
||||||
} pollin, pollout;
|
|
||||||
|
|
||||||
ogs_sockopt_t option;
|
ogs_sockopt_t option;
|
||||||
} ogs_socknode_t;
|
} ogs_socknode_t;
|
||||||
|
@ -84,9 +78,6 @@ void ogs_socknode_linger(ogs_socknode_t *node, int onoff, int linger);
|
||||||
|
|
||||||
void ogs_socknode_set_cleanup(
|
void ogs_socknode_set_cleanup(
|
||||||
ogs_socknode_t *node, void (*cleanup)(ogs_sock_t *));
|
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
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|
|
@ -63,8 +63,6 @@ ogs_sock_t *ogs_tcp_server(ogs_socknode_t *node)
|
||||||
|
|
||||||
node->sock = new;
|
node->sock = new;
|
||||||
|
|
||||||
ogs_socknode_install_poll(node);
|
|
||||||
|
|
||||||
return new;
|
return new;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -102,7 +100,5 @@ ogs_sock_t *ogs_tcp_client(ogs_socknode_t *node)
|
||||||
|
|
||||||
node->sock = new;
|
node->sock = new;
|
||||||
|
|
||||||
ogs_socknode_install_poll(node);
|
|
||||||
|
|
||||||
return new;
|
return new;
|
||||||
}
|
}
|
||||||
|
|
|
@ -71,8 +71,6 @@ ogs_sock_t *ogs_udp_server(ogs_socknode_t *node)
|
||||||
|
|
||||||
node->sock = new;
|
node->sock = new;
|
||||||
|
|
||||||
ogs_socknode_install_poll(node);
|
|
||||||
|
|
||||||
return new;
|
return new;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -110,8 +108,6 @@ ogs_sock_t *ogs_udp_client(ogs_socknode_t *node)
|
||||||
|
|
||||||
node->sock = new;
|
node->sock = new;
|
||||||
|
|
||||||
ogs_socknode_install_poll(node);
|
|
||||||
|
|
||||||
return new;
|
return new;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -38,17 +38,13 @@ libsctp_dep = cc.find_library('sctp', required : false)
|
||||||
if libsctp_dep.found()
|
if libsctp_dep.found()
|
||||||
libsctp_sources += files('ogs-lksctp.c')
|
libsctp_sources += files('ogs-lksctp.c')
|
||||||
else
|
else
|
||||||
libsctp_dep = cc.find_library('usrsctp', required : false)
|
libsctp_dep = dependency('usrsctp',
|
||||||
if not libsctp_dep.found()
|
version: ['>=1.0.0', '<2'],
|
||||||
# sctp_debug = get_option('debug_level') >= 7
|
fallback: ['usrsctp', 'usrsctp_dep'],
|
||||||
libsctp_dep = dependency('usrsctp',
|
default_options: [
|
||||||
version: ['>=1.0.0', '<2'],
|
'sctp_build_programs=false',
|
||||||
fallback: ['usrsctp', 'usrsctp_dep'],
|
# 'sctp_debug=@0@'.format(true),
|
||||||
default_options: [
|
])
|
||||||
'sctp_build_programs=false',
|
|
||||||
# 'sctp_debug=@0@'.format(sctp_debug),
|
|
||||||
])
|
|
||||||
endif
|
|
||||||
|
|
||||||
libsctp_sources += files('ogs-usrsctp.c')
|
libsctp_sources += files('ogs-usrsctp.c')
|
||||||
libsctp_conf.set('HAVE_USRSCTP', 1)
|
libsctp_conf.set('HAVE_USRSCTP', 1)
|
||||||
|
|
|
@ -119,8 +119,6 @@ ogs_sock_t *ogs_sctp_server(int type, ogs_socknode_t *node)
|
||||||
|
|
||||||
node->sock = new;
|
node->sock = new;
|
||||||
|
|
||||||
ogs_socknode_install_poll(node);
|
|
||||||
|
|
||||||
return new;
|
return new;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -158,8 +156,6 @@ ogs_sock_t *ogs_sctp_client(int type, ogs_socknode_t *node)
|
||||||
|
|
||||||
node->sock = new;
|
node->sock = new;
|
||||||
|
|
||||||
ogs_socknode_install_poll(node);
|
|
||||||
|
|
||||||
return new;
|
return new;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -222,14 +218,16 @@ int ogs_sctp_recvmsg(ogs_sock_t *sock, void *msg, size_t len,
|
||||||
{
|
{
|
||||||
int size;
|
int size;
|
||||||
socklen_t addrlen = sizeof(struct sockaddr_storage);
|
socklen_t addrlen = sizeof(struct sockaddr_storage);
|
||||||
|
ogs_sockaddr_t addr;
|
||||||
|
|
||||||
int flags = 0;
|
int flags = 0;
|
||||||
struct sctp_sndrcvinfo sndrcvinfo;
|
struct sctp_sndrcvinfo sndrcvinfo;
|
||||||
|
|
||||||
ogs_assert(sock);
|
ogs_assert(sock);
|
||||||
|
|
||||||
size = sctp_recvmsg(sock->fd, msg, len,
|
memset(&sndrcvinfo, 0, sizeof sndrcvinfo);
|
||||||
from ? &from->sa : NULL, from ? &addrlen : NULL,
|
memset(&addr, 0, sizeof addr);
|
||||||
|
size = sctp_recvmsg(sock->fd, msg, len, &addr.sa, &addrlen,
|
||||||
&sndrcvinfo, &flags);
|
&sndrcvinfo, &flags);
|
||||||
if (size < 0) {
|
if (size < 0) {
|
||||||
ogs_log_message(OGS_LOG_ERROR, ogs_socket_errno,
|
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;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (from) {
|
||||||
|
memcpy(from, &addr, sizeof(ogs_sockaddr_t));
|
||||||
|
}
|
||||||
|
|
||||||
if (msg_flags) {
|
if (msg_flags) {
|
||||||
*msg_flags = flags;
|
*msg_flags = flags;
|
||||||
}
|
}
|
||||||
|
|
|
@ -73,7 +73,7 @@ ogs_sock_t *ogs_sctp_socket(int family, int type, ogs_socknode_t *node)
|
||||||
ogs_sctp_set_option(&option, node);
|
ogs_sctp_set_option(&option, node);
|
||||||
|
|
||||||
if (!(socket = usrsctp_socket(family, type, IPPROTO_SCTP,
|
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");
|
ogs_error("ogs_sctp_socket() failed");
|
||||||
return NULL;
|
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),
|
(void *)&sndinfo, (socklen_t)sizeof(struct sctp_sndinfo),
|
||||||
SCTP_SENDV_SNDINFO, 0);
|
SCTP_SENDV_SNDINFO, 0);
|
||||||
|
|
||||||
if (sent < 0 || sent != len)
|
if (sent < 0 || sent != len) {
|
||||||
{
|
|
||||||
ogs_error("sent : %d, len : %d", (int)sent, (int)len);
|
ogs_error("sent : %d, len : %d", (int)sent, (int)len);
|
||||||
return OGS_ERROR;
|
return OGS_ERROR;
|
||||||
}
|
}
|
||||||
|
@ -365,6 +364,7 @@ int ogs_sctp_recvmsg(ogs_sock_t *sock, void *msg, size_t len,
|
||||||
ogs_assert(socket);
|
ogs_assert(socket);
|
||||||
|
|
||||||
memset(&rcv_info, 0, sizeof rcv_info);
|
memset(&rcv_info, 0, sizeof rcv_info);
|
||||||
|
memset(&addr, 0, sizeof addr);
|
||||||
n = usrsctp_recvv(socket, msg, len,
|
n = usrsctp_recvv(socket, msg, len,
|
||||||
&addr.sa, &addrlen,
|
&addr.sa, &addrlen,
|
||||||
(void *)&rcv_info,
|
(void *)&rcv_info,
|
||||||
|
|
|
@ -51,11 +51,13 @@ libmme_sources = files('''
|
||||||
s1ap-sm.c
|
s1ap-sm.c
|
||||||
s1ap-build.c
|
s1ap-build.c
|
||||||
s1ap-handler.c
|
s1ap-handler.c
|
||||||
|
s1ap-sctp.c
|
||||||
s1ap-path.c
|
s1ap-path.c
|
||||||
sgsap-sm.c
|
sgsap-sm.c
|
||||||
sgsap-build.c
|
sgsap-build.c
|
||||||
sgsap-handler.c
|
sgsap-handler.c
|
||||||
sgsap-conv.c
|
sgsap-conv.c
|
||||||
|
sgsap-sctp.c
|
||||||
sgsap-path.c
|
sgsap-path.c
|
||||||
mme-fd-path.c
|
mme-fd-path.c
|
||||||
mme-s6a-handler.c
|
mme-s6a-handler.c
|
||||||
|
@ -75,14 +77,6 @@ libmme_sources = files('''
|
||||||
sbc-handler.c
|
sbc-handler.c
|
||||||
'''.split())
|
'''.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',
|
libmme = static_library('mme',
|
||||||
sources : libmme_sources,
|
sources : libmme_sources,
|
||||||
dependencies : [libapp_dep,
|
dependencies : [libapp_dep,
|
||||||
|
|
|
@ -1722,8 +1722,7 @@ void mme_vlr_remove(mme_vlr_t *vlr)
|
||||||
|
|
||||||
ogs_list_remove(&self.vlr_list, vlr);
|
ogs_list_remove(&self.vlr_list, vlr);
|
||||||
|
|
||||||
if (vlr->node)
|
mme_vlr_close(vlr);
|
||||||
mme_vlr_free_node(vlr);
|
|
||||||
|
|
||||||
ogs_freeaddrinfo(vlr->sa_list);
|
ogs_freeaddrinfo(vlr->sa_list);
|
||||||
|
|
||||||
|
@ -1738,27 +1737,14 @@ void mme_vlr_remove_all()
|
||||||
mme_vlr_remove(vlr);
|
mme_vlr_remove(vlr);
|
||||||
}
|
}
|
||||||
|
|
||||||
ogs_socknode_t *mme_vlr_new_node(mme_vlr_t *vlr)
|
void mme_vlr_close(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)
|
|
||||||
{
|
{
|
||||||
ogs_assert(vlr);
|
ogs_assert(vlr);
|
||||||
ogs_assert(vlr->node);
|
|
||||||
|
|
||||||
ogs_socknode_free(vlr->node);
|
if (vlr->poll)
|
||||||
vlr->node = NULL;
|
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)
|
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) {
|
if (enb->sock_type == SOCK_STREAM) {
|
||||||
enb->poll = ogs_pollset_add(mme_self()->pollset,
|
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);
|
ogs_assert(enb->poll);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -201,8 +201,9 @@ typedef struct mme_vlr_s {
|
||||||
|
|
||||||
ogs_sockaddr_t *sa_list; /* VLR SGsAP Socket Address List */
|
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_sockaddr_t *addr; /* VLR SGsAP Connected Socket Address */
|
||||||
|
ogs_poll_t *poll; /* VLR SGsAP Poll */
|
||||||
} mme_vlr_t;
|
} mme_vlr_t;
|
||||||
|
|
||||||
typedef struct mme_csmap_s {
|
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);
|
mme_vlr_t *mme_vlr_add(ogs_sockaddr_t *addr);
|
||||||
void mme_vlr_remove(mme_vlr_t *vlr);
|
void mme_vlr_remove(mme_vlr_t *vlr);
|
||||||
void mme_vlr_remove_all(void);
|
void mme_vlr_remove_all(void);
|
||||||
|
void mme_vlr_close(mme_vlr_t *vlr);
|
||||||
ogs_socknode_t *mme_vlr_new_node(mme_vlr_t *vlr);
|
|
||||||
void mme_vlr_free_node(mme_vlr_t *vlr);
|
|
||||||
mme_vlr_t *mme_vlr_find_by_addr(ogs_sockaddr_t *addr);
|
mme_vlr_t *mme_vlr_find_by_addr(ogs_sockaddr_t *addr);
|
||||||
|
|
||||||
mme_csmap_t *mme_csmap_add(mme_vlr_t *vlr);
|
mme_csmap_t *mme_csmap_add(mme_vlr_t *vlr);
|
||||||
|
|
|
@ -65,18 +65,18 @@ int mme_gtp_open(void)
|
||||||
mme_sgw_t *sgw = NULL;
|
mme_sgw_t *sgw = NULL;
|
||||||
|
|
||||||
ogs_list_for_each(&mme_self()->gtpc_list, node) {
|
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);
|
sock = ogs_gtp_server(node);
|
||||||
ogs_assert(sock);
|
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_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);
|
sock = ogs_gtp_server(node);
|
||||||
ogs_assert(sock);
|
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);
|
mme_self()->gtpc_sock = ogs_gtp_local_sock_first(&mme_self()->gtpc_list);
|
||||||
|
|
|
@ -552,7 +552,6 @@ void mme_state_operational(ogs_fsm_t *s, mme_event_t *e)
|
||||||
ogs_assert(pkbuf);
|
ogs_assert(pkbuf);
|
||||||
|
|
||||||
vlr = mme_vlr_find_by_addr(addr);
|
vlr = mme_vlr_find_by_addr(addr);
|
||||||
ogs_assert(vlr);
|
|
||||||
ogs_free(addr);
|
ogs_free(addr);
|
||||||
|
|
||||||
ogs_assert(vlr);
|
ogs_assert(vlr);
|
||||||
|
|
|
@ -35,8 +35,7 @@ int s1ap_open(void);
|
||||||
void s1ap_close(void);
|
void s1ap_close(void);
|
||||||
|
|
||||||
ogs_sock_t *s1ap_server(ogs_socknode_t *node);
|
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,
|
int s1ap_send(ogs_sock_t *sock,
|
||||||
ogs_pkbuf_t *pkbuf, ogs_sockaddr_t *addr, uint16_t stream_no);
|
ogs_pkbuf_t *pkbuf, ogs_sockaddr_t *addr, uint16_t stream_no);
|
||||||
|
|
||||||
|
|
|
@ -22,7 +22,14 @@
|
||||||
#include "mme-event.h"
|
#include "mme-event.h"
|
||||||
#include "s1ap-path.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)
|
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_sctp_option(node, &ogs_config()->sockopt);
|
||||||
ogs_socknode_nodelay(node, true);
|
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);
|
sock = ogs_sctp_server(SOCK_STREAM, node);
|
||||||
ogs_assert(sock);
|
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_info("s1ap_server() [%s]:%d",
|
||||||
OGS_ADDR(node->addr, buf), OGS_PORT(node->addr));
|
OGS_ADDR(node->addr, buf), OGS_PORT(node->addr));
|
||||||
|
@ -45,17 +58,43 @@ ogs_sock_t *s1ap_server(ogs_socknode_t *node)
|
||||||
return sock;
|
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];
|
char buf[OGS_ADDRSTRLEN];
|
||||||
ogs_socknode_t *node = data;
|
|
||||||
ogs_sock_t *sock = NULL;
|
|
||||||
ogs_sock_t *new = NULL;
|
ogs_sock_t *new = NULL;
|
||||||
|
|
||||||
ogs_assert(node);
|
|
||||||
sock = node->sock;
|
|
||||||
ogs_assert(sock);
|
ogs_assert(sock);
|
||||||
ogs_assert(fd != INVALID_SOCKET);
|
|
||||||
|
|
||||||
new = ogs_sock_accept(sock);
|
new = ogs_sock_accept(sock);
|
||||||
if (new) {
|
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;
|
ogs_pkbuf_t *pkbuf;
|
||||||
int size;
|
int size;
|
||||||
ogs_sock_t *sock = data;
|
|
||||||
ogs_sockaddr_t *addr = NULL;
|
ogs_sockaddr_t *addr = NULL;
|
||||||
|
ogs_sockaddr_t from;
|
||||||
ogs_sctp_info_t sinfo;
|
ogs_sctp_info_t sinfo;
|
||||||
int flags = 0;
|
int flags = 0;
|
||||||
|
|
||||||
ogs_assert(sock);
|
ogs_assert(sock);
|
||||||
ogs_assert(fd != INVALID_SOCKET);
|
|
||||||
|
|
||||||
pkbuf = ogs_pkbuf_alloc(NULL, OGS_MAX_SDU_LEN);
|
pkbuf = ogs_pkbuf_alloc(NULL, OGS_MAX_SDU_LEN);
|
||||||
ogs_pkbuf_put(pkbuf, OGS_MAX_SDU_LEN);
|
ogs_pkbuf_put(pkbuf, OGS_MAX_SDU_LEN);
|
||||||
size = ogs_sctp_recvmsg(
|
size = ogs_sctp_recvmsg(
|
||||||
sock, pkbuf->data, pkbuf->len, NULL, &sinfo, &flags);
|
sock, pkbuf->data, pkbuf->len, &from, &sinfo, &flags);
|
||||||
if (size < 0) {
|
if (size < 0) {
|
||||||
ogs_error("ogs_sctp_recvmsg(%d) failed(%d:%s)",
|
ogs_error("ogs_sctp_recvmsg(%d) failed(%d:%s)",
|
||||||
size, errno, strerror(errno));
|
size, errno, strerror(errno));
|
||||||
|
ogs_pkbuf_free(pkbuf);
|
||||||
return;
|
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));
|
addr = ogs_calloc(1, sizeof(ogs_sockaddr_t));
|
||||||
ogs_assert(addr);
|
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,
|
s1ap_event_push(MME_EVT_S1AP_LO_SCTP_COMM_UP,
|
||||||
sock, addr, NULL,
|
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));
|
addr = ogs_calloc(1, sizeof(ogs_sockaddr_t));
|
||||||
ogs_assert(addr);
|
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,
|
s1ap_event_push(MME_EVT_S1AP_LO_CONNREFUSED,
|
||||||
sock, addr, NULL, 0, 0);
|
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_flags,
|
||||||
not->sn_shutdown_event.sse_length);
|
not->sn_shutdown_event.sse_length);
|
||||||
if (not->sn_header.sn_type == SCTP_SEND_FAILED)
|
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]",
|
ogs_error("SCTP_SEND_FAILED:[T:%d, F:0x%x, S:%d]",
|
||||||
not->sn_send_failed.ssf_type,
|
not->sn_send_failed.ssf_type,
|
||||||
not->sn_send_failed.ssf_flags,
|
not->sn_send_failed.ssf_flags,
|
||||||
not->sn_send_failed.ssf_error);
|
not->sn_send_failed.ssf_error);
|
||||||
|
#endif
|
||||||
|
|
||||||
addr = ogs_calloc(1, sizeof(ogs_sockaddr_t));
|
addr = ogs_calloc(1, sizeof(ogs_sockaddr_t));
|
||||||
ogs_assert(addr);
|
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,
|
s1ap_event_push(MME_EVT_S1AP_LO_CONNREFUSED,
|
||||||
sock, addr, NULL, 0, 0);
|
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));
|
addr = ogs_calloc(1, sizeof(ogs_sockaddr_t));
|
||||||
ogs_assert(addr);
|
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);
|
s1ap_event_push(MME_EVT_S1AP_MESSAGE, sock, addr, pkbuf, 0, 0);
|
||||||
return;
|
return;
|
|
@ -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);
|
|
||||||
}
|
|
|
@ -85,13 +85,11 @@ int sgsap_send_to_vlr_with_sid(
|
||||||
|
|
||||||
ogs_assert(vlr);
|
ogs_assert(vlr);
|
||||||
ogs_assert(pkbuf);
|
ogs_assert(pkbuf);
|
||||||
node = vlr->node;
|
sock = vlr->sock;
|
||||||
ogs_assert(node);
|
|
||||||
sock = node->sock;
|
|
||||||
ogs_assert(sock);
|
ogs_assert(sock);
|
||||||
|
|
||||||
ogs_debug(" VLR-IP[%s]", OGS_ADDR(node->addr, buf));
|
ogs_debug(" VLR-IP[%s]", OGS_ADDR(vlr->addr, buf));
|
||||||
rv = sgsap_send(sock, pkbuf, node->addr, stream_no);
|
rv = sgsap_send(sock, pkbuf, vlr->addr, stream_no);
|
||||||
if (rv != OGS_OK) {
|
if (rv != OGS_OK) {
|
||||||
ogs_error("sgsap_send() failed");
|
ogs_error("sgsap_send() failed");
|
||||||
|
|
||||||
|
|
|
@ -33,7 +33,6 @@ int sgsap_open(void);
|
||||||
void sgsap_close(void);
|
void sgsap_close(void);
|
||||||
|
|
||||||
ogs_sock_t *sgsap_client(mme_vlr_t *vlr);
|
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,
|
int sgsap_send(ogs_sock_t *sock,
|
||||||
ogs_pkbuf_t *pkbuf, ogs_sockaddr_t *addr, uint16_t stream_no);
|
ogs_pkbuf_t *pkbuf, ogs_sockaddr_t *addr, uint16_t stream_no);
|
||||||
|
|
|
@ -24,54 +24,89 @@
|
||||||
#include "mme-event.h"
|
#include "mme-event.h"
|
||||||
#include "s1ap-path.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)
|
ogs_sock_t *sgsap_client(mme_vlr_t *vlr)
|
||||||
{
|
{
|
||||||
char buf[OGS_ADDRSTRLEN];
|
char buf[OGS_ADDRSTRLEN];
|
||||||
ogs_socknode_t *node = NULL;
|
ogs_socknode_t node;
|
||||||
ogs_sock_t *sock = NULL;
|
ogs_sock_t *sock = NULL;
|
||||||
|
|
||||||
node = mme_vlr_new_node(vlr);
|
ogs_assert(vlr);
|
||||||
ogs_assert(node);
|
|
||||||
|
|
||||||
ogs_socknode_sctp_option(node, &ogs_config()->sockopt);
|
memset(&node, 0, sizeof node);
|
||||||
ogs_socknode_nodelay(node, true);
|
node.addr = vlr->sa_list;
|
||||||
ogs_socknode_set_poll(node, mme_self()->pollset,
|
|
||||||
OGS_POLLIN, recv_handler, node);
|
|
||||||
|
|
||||||
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) {
|
if (sock) {
|
||||||
ogs_info("sgsap client() [%s]:%d",
|
vlr->sock = sock;
|
||||||
OGS_ADDR(node->addr, buf), OGS_PORT(node->addr));
|
#if HAVE_USRSCTP
|
||||||
|
vlr->addr = node.addr;
|
||||||
|
usrsctp_set_upcall((struct socket *)sock, usrsctp_recv_handler, NULL);
|
||||||
|
#else
|
||||||
vlr->addr = &sock->remote_addr;
|
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;
|
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;
|
ogs_pkbuf_t *pkbuf;
|
||||||
int size;
|
int size;
|
||||||
ogs_socknode_t *node = data;
|
|
||||||
ogs_sock_t *sock = NULL;
|
|
||||||
ogs_sockaddr_t *addr = NULL;
|
ogs_sockaddr_t *addr = NULL;
|
||||||
|
ogs_sockaddr_t from;
|
||||||
ogs_sctp_info_t sinfo;
|
ogs_sctp_info_t sinfo;
|
||||||
int flags = 0;
|
int flags = 0;
|
||||||
|
|
||||||
ogs_assert(node);
|
|
||||||
sock = node->sock;
|
|
||||||
ogs_assert(sock);
|
ogs_assert(sock);
|
||||||
ogs_assert(fd != INVALID_SOCKET);
|
|
||||||
|
|
||||||
pkbuf = ogs_pkbuf_alloc(NULL, OGS_MAX_SDU_LEN);
|
pkbuf = ogs_pkbuf_alloc(NULL, OGS_MAX_SDU_LEN);
|
||||||
ogs_pkbuf_put(pkbuf, OGS_MAX_SDU_LEN);
|
ogs_pkbuf_put(pkbuf, OGS_MAX_SDU_LEN);
|
||||||
size = ogs_sctp_recvmsg(
|
size = ogs_sctp_recvmsg(
|
||||||
sock, pkbuf->data, pkbuf->len, NULL, &sinfo, &flags);
|
sock, pkbuf->data, pkbuf->len, &from, &sinfo, &flags);
|
||||||
if (size < 0) {
|
if (size < 0) {
|
||||||
ogs_error("ogs_sctp_recvmsg(%d) failed(%d:%s)",
|
ogs_error("ogs_sctp_recvmsg(%d) failed(%d:%s)",
|
||||||
size, errno, strerror(errno));
|
size, errno, strerror(errno));
|
||||||
|
ogs_pkbuf_free(pkbuf);
|
||||||
return;
|
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));
|
addr = ogs_calloc(1, sizeof(ogs_sockaddr_t));
|
||||||
ogs_assert(addr);
|
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,
|
sgsap_event_push(MME_EVT_SGSAP_LO_SCTP_COMM_UP,
|
||||||
sock, addr, NULL,
|
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));
|
addr = ogs_calloc(1, sizeof(ogs_sockaddr_t));
|
||||||
ogs_assert(addr);
|
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,
|
sgsap_event_push(MME_EVT_SGSAP_LO_CONNREFUSED,
|
||||||
sock, addr, NULL, 0, 0);
|
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_flags,
|
||||||
not->sn_shutdown_event.sse_length);
|
not->sn_shutdown_event.sse_length);
|
||||||
if (not->sn_header.sn_type == SCTP_SEND_FAILED)
|
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]",
|
ogs_error("SCTP_SEND_FAILED:[T:%d, F:0x%x, S:%d]",
|
||||||
not->sn_send_failed.ssf_type,
|
not->sn_send_failed.ssf_type,
|
||||||
not->sn_send_failed.ssf_flags,
|
not->sn_send_failed.ssf_flags,
|
||||||
not->sn_send_failed.ssf_error);
|
not->sn_send_failed.ssf_error);
|
||||||
|
#endif
|
||||||
|
|
||||||
addr = ogs_calloc(1, sizeof(ogs_sockaddr_t));
|
addr = ogs_calloc(1, sizeof(ogs_sockaddr_t));
|
||||||
ogs_assert(addr);
|
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,
|
sgsap_event_push(MME_EVT_SGSAP_LO_CONNREFUSED,
|
||||||
sock, addr, NULL, 0, 0);
|
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));
|
addr = ogs_calloc(1, sizeof(ogs_sockaddr_t));
|
||||||
ogs_assert(addr);
|
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);
|
sgsap_event_push(MME_EVT_SGSAP_MESSAGE, sock, addr, pkbuf, 0, 0);
|
||||||
return;
|
return;
|
|
@ -64,7 +64,6 @@ void sgsap_state_will_connect(ogs_fsm_t *s, mme_event_t *e)
|
||||||
char buf[OGS_ADDRSTRLEN];
|
char buf[OGS_ADDRSTRLEN];
|
||||||
|
|
||||||
mme_vlr_t *vlr = NULL;
|
mme_vlr_t *vlr = NULL;
|
||||||
ogs_socknode_t *node = NULL;
|
|
||||||
ogs_sockaddr_t *addr = NULL;
|
ogs_sockaddr_t *addr = NULL;
|
||||||
ogs_assert(s);
|
ogs_assert(s);
|
||||||
ogs_assert(e);
|
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:
|
case MME_TIMER_SGS_CLI_CONN_TO_SRV:
|
||||||
vlr = e->vlr;
|
vlr = e->vlr;
|
||||||
ogs_assert(vlr);
|
ogs_assert(vlr);
|
||||||
node = vlr->node;
|
addr = vlr->addr;
|
||||||
ogs_assert(node);
|
|
||||||
addr = node->addr;
|
|
||||||
ogs_assert(addr);
|
ogs_assert(addr);
|
||||||
|
|
||||||
ogs_warn("[SGsAP] Connect to VLR [%s]:%d failed",
|
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,
|
ogs_timer_start(vlr->t_conn,
|
||||||
mme_timer_cfg(MME_TIMER_SGS_CLI_CONN_TO_SRV)->duration);
|
mme_timer_cfg(MME_TIMER_SGS_CLI_CONN_TO_SRV)->duration);
|
||||||
|
|
||||||
mme_vlr_free_node(vlr);
|
mme_vlr_close(vlr);
|
||||||
sgsap_client(vlr);
|
sgsap_client(vlr);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -139,7 +136,7 @@ void sgsap_state_connected(ogs_fsm_t *s, mme_event_t *e)
|
||||||
case OGS_FSM_EXIT_SIG:
|
case OGS_FSM_EXIT_SIG:
|
||||||
break;
|
break;
|
||||||
case MME_EVT_SGSAP_LO_CONNREFUSED:
|
case MME_EVT_SGSAP_LO_CONNREFUSED:
|
||||||
mme_vlr_free_node(vlr);
|
mme_vlr_close(vlr);
|
||||||
OGS_FSM_TRAN(s, sgsap_state_will_connect);
|
OGS_FSM_TRAN(s, sgsap_state_will_connect);
|
||||||
break;
|
break;
|
||||||
case MME_EVT_SGSAP_MESSAGE:
|
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:
|
case SGSAP_RESET_INDICATION:
|
||||||
sgsap_handle_reset_indication(vlr, pkbuf);
|
sgsap_handle_reset_indication(vlr, pkbuf);
|
||||||
|
|
||||||
mme_vlr_free_node(vlr);
|
mme_vlr_close(vlr);
|
||||||
OGS_FSM_TRAN(s, sgsap_state_will_connect);
|
OGS_FSM_TRAN(s, sgsap_state_will_connect);
|
||||||
break;
|
break;
|
||||||
case SGSAP_RELEASE_REQUEST:
|
case SGSAP_RELEASE_REQUEST:
|
||||||
|
|
|
@ -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);
|
|
||||||
}
|
|
|
@ -209,18 +209,18 @@ int pgw_gtp_open(void)
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
ogs_list_for_each(&pgw_self()->gtpc_list, node) {
|
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);
|
sock = ogs_gtp_server(node);
|
||||||
ogs_assert(sock);
|
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_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);
|
sock = ogs_gtp_server(node);
|
||||||
ogs_assert(sock);
|
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);
|
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_assert(pgw_self()->gtpc_addr || pgw_self()->gtpc_addr6);
|
||||||
|
|
||||||
ogs_list_for_each(&pgw_self()->gtpu_list, node) {
|
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);
|
sock = ogs_gtp_server(node);
|
||||||
ogs_assert(sock);
|
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_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);
|
sock = ogs_gtp_server(node);
|
||||||
ogs_assert(sock);
|
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);
|
pgw_self()->gtpu_sock = ogs_gtp_local_sock_first(&pgw_self()->gtpu_list);
|
||||||
|
|
|
@ -265,18 +265,18 @@ int sgw_gtp_open(void)
|
||||||
packet_pool = ogs_pkbuf_pool_create(&config);
|
packet_pool = ogs_pkbuf_pool_create(&config);
|
||||||
|
|
||||||
ogs_list_for_each(&sgw_self()->gtpc_list, node) {
|
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);
|
sock = ogs_gtp_server(node);
|
||||||
ogs_assert(sock);
|
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_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);
|
sock = ogs_gtp_server(node);
|
||||||
ogs_assert(sock);
|
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);
|
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_assert(sgw_self()->gtpc_addr || sgw_self()->gtpc_addr6);
|
||||||
|
|
||||||
ogs_list_for_each(&sgw_self()->gtpu_list, node) {
|
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);
|
sock = ogs_gtp_server(node);
|
||||||
ogs_assert(sock);
|
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_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);
|
sock = ogs_gtp_server(node);
|
||||||
ogs_assert(sock);
|
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);
|
sgw_self()->gtpu_sock = ogs_gtp_local_sock_first(&sgw_self()->gtpu_list);
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
[wrap-git]
|
[wrap-git]
|
||||||
directory = usrsctp
|
directory = usrsctp
|
||||||
url = https://github.com/sctplab/usrsctp.git
|
url = https://github.com/sctplab/usrsctp.git
|
||||||
revision = master
|
revision = 09768bfcf22f91f6e43f0e692fc612564621d02f
|
||||||
|
|
|
@ -285,6 +285,7 @@ static void test4_func(abts_case *tc, void *data)
|
||||||
ogs_sock_t *udp;
|
ogs_sock_t *udp;
|
||||||
ogs_sockaddr_t *addr;
|
ogs_sockaddr_t *addr;
|
||||||
ogs_socknode_t *node;
|
ogs_socknode_t *node;
|
||||||
|
ogs_poll_t *poll;
|
||||||
ogs_pollset_t *pollset = ogs_pollset_create();
|
ogs_pollset_t *pollset = ogs_pollset_create();
|
||||||
ABTS_PTR_NOTNULL(tc, pollset);
|
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);
|
ABTS_INT_EQUAL(tc, OGS_OK, rv);
|
||||||
node = ogs_socknode_new(addr);
|
node = ogs_socknode_new(addr);
|
||||||
ABTS_PTR_NOTNULL(tc, node);
|
ABTS_PTR_NOTNULL(tc, node);
|
||||||
ogs_socknode_set_poll(node, pollset, OGS_POLLIN, test4_handler, tc);
|
|
||||||
udp = ogs_udp_server(node);
|
udp = ogs_udp_server(node);
|
||||||
ABTS_PTR_NOTNULL(tc, udp);
|
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);
|
test4_thread = ogs_thread_create(test4_main, tc);
|
||||||
ABTS_INT_EQUAL(tc, OGS_OK, rv);
|
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_thread_destroy(test4_thread);
|
||||||
|
|
||||||
|
ogs_pollset_remove(poll);
|
||||||
ogs_socknode_free(node);
|
ogs_socknode_free(node);
|
||||||
|
|
||||||
ogs_pollset_destroy(pollset);
|
ogs_pollset_destroy(pollset);
|
||||||
|
|
|
@ -224,10 +224,6 @@ static void test4_func(abts_case *tc, void *data)
|
||||||
ogs_sctp_info_t sinfo;
|
ogs_sctp_info_t sinfo;
|
||||||
char buf[OGS_ADDRSTRLEN];
|
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);
|
rv = ogs_getaddrinfo(&addr, AF_INET6, NULL, TEST4_PORT, AI_PASSIVE);
|
||||||
ABTS_INT_EQUAL(tc, OGS_OK, rv);
|
ABTS_INT_EQUAL(tc, OGS_OK, rv);
|
||||||
node = ogs_socknode_new(addr);
|
node = ogs_socknode_new(addr);
|
||||||
|
|
Loading…
Reference in New Issue