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);
|
||||
|
||||
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)
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
|
@ -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(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");
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
|
@ -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:
|
||||
|
|
|
@ -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;
|
||||
|
||||
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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
[wrap-git]
|
||||
directory = usrsctp
|
||||
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_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);
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue