diff --git a/src/mme/ogs-sctp.h b/src/mme/ogs-sctp.h index 853638f62..4eddb616b 100644 --- a/src/mme/ogs-sctp.h +++ b/src/mme/ogs-sctp.h @@ -33,6 +33,14 @@ extern "C" { #if HAVE_USRSCTP #undef MSG_NOTIFICATION #define MSG_NOTIFICATION 0x2000 + +#ifndef INET +#define INET 1 +#endif +#ifndef INET6 +#define INET6 1 +#endif +#include #endif #define DEFAULT_SCTP_MAX_NUM_OF_OSTREAMS 30 diff --git a/src/mme/ogs-usrsctp.c b/src/mme/ogs-usrsctp.c index 9d7ff9c12..c6d49992c 100644 --- a/src/mme/ogs-usrsctp.c +++ b/src/mme/ogs-usrsctp.c @@ -1,19 +1,5 @@ #include "ogs-sctp.h" -#if HAVE_NETDB_H -#include -#endif - -#if HAVE_USRSCTP -#ifndef INET -#define INET 1 -#endif -#ifndef INET6 -#define INET6 1 -#endif -#include -#endif - static void ogs_debug_printf(const char *format, ...); int ogs_sctp_init(uint16_t port) @@ -30,8 +16,7 @@ int ogs_sctp_init(uint16_t port) void ogs_sctp_final() { - while(usrsctp_finish() != 0) - { + while (usrsctp_finish() != 0) { ogs_warn("try to finsih SCTP"); ogs_msleep(1000); } @@ -146,7 +131,7 @@ ogs_sock_t *ogs_sctp_server(int type, ogs_socknode_t *node) ogs_assert(node->addr); addr = node->addr; - while(addr) { + while (addr) { sock = ogs_sctp_socket(addr->ogs_sa_family, type, node); if (sock) { if (ogs_sctp_bind(sock, addr) == OGS_OK) { @@ -186,7 +171,7 @@ ogs_sock_t *ogs_sctp_client(int type, ogs_socknode_t *node) ogs_assert(node->addr); addr = node->addr; - while(addr) { + while (addr) { sock = ogs_sctp_socket(addr->ogs_sa_family, type, node); if (sock) { if (ogs_sctp_connect(sock, addr) == OGS_OK) { diff --git a/src/mme/s1ap_lksctp.c b/src/mme/s1ap_lksctp.c index 732563edd..c41a96678 100644 --- a/src/mme/s1ap_lksctp.c +++ b/src/mme/s1ap_lksctp.c @@ -25,44 +25,6 @@ void s1ap_server(ogs_socknode_t *node, int type) OGS_ADDR(node->addr, buf), OGS_PORT(node->addr)); } -int s1ap_send(ogs_sock_t *sock, ogs_pkbuf_t *pkbuf, - ogs_sockaddr_t *addr, uint16_t stream_no) -{ - int sent; - - ogs_assert(sock); - ogs_assert(pkbuf); - - sent = ogs_sctp_sendmsg(sock, pkbuf->data, pkbuf->len, - addr, SCTP_S1AP_PPID, stream_no); - if (sent < 0 || sent != pkbuf->len) - { - ogs_error("ogs_sctp_sendmsg error (%d:%s)", errno, strerror(errno)); - return OGS_ERROR; - } - ogs_pkbuf_free(pkbuf); - - return OGS_OK; -} - -int s1ap_recv(ogs_sock_t *sock, ogs_pkbuf_t *pkbuf) -{ - int size; - - ogs_assert(sock); - ogs_assert(pkbuf); - - size = ogs_sctp_recvdata(sock, pkbuf->data, MAX_SDU_LEN, NULL, NULL); - if (size <= 0) - { - ogs_error("s1ap_recv() failed"); - return OGS_ERROR; - } - - ogs_pkbuf_trim(pkbuf, size); - return OGS_OK;; -} - static void accept_handler(short when, ogs_socket_t fd, void *data) { char buf[OGS_ADDRSTRLEN]; diff --git a/src/mme/s1ap_path.c b/src/mme/s1ap_path.c index 799161c41..efd39201b 100644 --- a/src/mme/s1ap_path.c +++ b/src/mme/s1ap_path.c @@ -1,3 +1,5 @@ +#include "ogs-sctp.h" + #include "mme_event.h" #include "nas_security.h" @@ -44,6 +46,42 @@ static int s1ap_server_list(ogs_list_t *list, int type) return OGS_OK; } +int s1ap_send(ogs_sock_t *sock, ogs_pkbuf_t *pkbuf, + ogs_sockaddr_t *addr, uint16_t stream_no) +{ + int sent; + + ogs_assert(sock); + ogs_assert(pkbuf); + + sent = ogs_sctp_sendmsg(sock, pkbuf->data, pkbuf->len, + addr, SCTP_S1AP_PPID, stream_no); + if (sent < 0 || sent != pkbuf->len) { + ogs_error("ogs_sctp_sendmsg error (%d:%s)", errno, strerror(errno)); + return OGS_ERROR; + } + ogs_pkbuf_free(pkbuf); + + return OGS_OK; +} + +int s1ap_recv(ogs_sock_t *sock, ogs_pkbuf_t *pkbuf) +{ + int size; + + ogs_assert(sock); + ogs_assert(pkbuf); + + size = ogs_sctp_recvdata(sock, pkbuf->data, MAX_SDU_LEN, NULL, NULL); + if (size <= 0) { + ogs_error("s1ap_recv() failed"); + return OGS_ERROR; + } + + ogs_pkbuf_trim(pkbuf, size); + return OGS_OK;; +} + int s1ap_send_to_enb(mme_enb_t *enb, ogs_pkbuf_t *pkbuf, uint16_t stream_no) { char buf[OGS_ADDRSTRLEN]; diff --git a/src/mme/s1ap_usrsctp.c b/src/mme/s1ap_usrsctp.c index 1bf813402..ba232d661 100644 --- a/src/mme/s1ap_usrsctp.c +++ b/src/mme/s1ap_usrsctp.c @@ -5,20 +5,6 @@ #include "s1ap_path.h" -#if HAVE_NETDB_H -#include -#endif - -#if HAVE_USRSCTP -#ifndef INET -#define INET 1 -#endif -#ifndef INET6 -#define INET6 1 -#endif -#include -#endif - int s1ap_usrsctp_recv_handler(struct socket *sock, union sctp_sockstore addr, void *data, size_t datalen, struct sctp_rcvinfo rcv, int flags, void *ulp_info); @@ -43,163 +29,42 @@ void s1ap_server(ogs_socknode_t *node, int type) OGS_ADDR(node->addr, buf), OGS_PORT(node->addr)); } -int s1ap_send(ogs_sock_t *sock, ogs_pkbuf_t *pkbuf, - ogs_sockaddr_t *addr, uint16_t stream_no) -{ - ssize_t sent; - struct socket *socket = (struct socket *)sock; - struct sctp_sndinfo sndinfo; - - ogs_assert(socket); - ogs_assert(pkbuf); - - memset((void *)&sndinfo, 0, sizeof(struct sctp_sndinfo)); - sndinfo.snd_ppid = htonl(SCTP_S1AP_PPID); - sndinfo.snd_sid = stream_no; - sent = usrsctp_sendv(socket, pkbuf->data, pkbuf->len, - addr ? &addr->sa : NULL, addr ? 1 : 0, - (void *)&sndinfo, (socklen_t)sizeof(struct sctp_sndinfo), - SCTP_SENDV_SNDINFO, 0); - - if (sent < 0 || sent != pkbuf->len) - { - ogs_error("sent : %d, pkbuf->len : %d", (int)sent, pkbuf->len); - return OGS_ERROR; - } - ogs_pkbuf_free(pkbuf); - - return OGS_OK; -} - -int s1ap_recv(ogs_sock_t *sock, ogs_pkbuf_t *pkbuf) -{ - struct socket *socket = (struct socket *)sock; - ogs_sockaddr_t addr; - ssize_t n = 0; - int flags = 0; - socklen_t from_len; - socklen_t infolen; - struct sctp_rcvinfo rcv_info; - unsigned int infotype = 0; - - while(1) - { - n = usrsctp_recvv(socket, pkbuf->data, MAX_SDU_LEN, - &addr.sa, &from_len, (void *)&rcv_info, - &infolen, &infotype, &flags); - if (n > 0) - { -#undef MSG_NOTIFICATION -#define MSG_NOTIFICATION 0x2000 - if (flags & MSG_NOTIFICATION) - { - /* Nothing to do */ - } - else if (flags & MSG_EOR) - { - break; - } - } - } - - ogs_pkbuf_trim(pkbuf, n); - return OGS_OK; -} - int s1ap_usrsctp_recv_handler(struct socket *sock, union sctp_sockstore store, void *data, size_t datalen, struct sctp_rcvinfo rcv, int flags, void *ulp_info) { - if (data) - { + if (data) { int rv; mme_event_t *e = NULL; -#undef MSG_NOTIFICATION -#define MSG_NOTIFICATION 0x2000 - if (flags & MSG_NOTIFICATION) - { + 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) + if (not->sn_header.sn_length == (uint32_t)datalen) { + switch(not->sn_header.sn_type) { + case SCTP_ASSOC_CHANGE : { - 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); + 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) - { - ogs_sockaddr_t *addr = - 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"); - - e = mme_event_new(MME_EVT_S1AP_LO_CONNREFUSED); - ogs_assert(e); - e->enb_sock = (ogs_sock_t *)sock; - e->enb_addr = addr; - rv = ogs_queue_push(mme_self()->queue, e); - if (rv != OGS_OK) { - ogs_warn("ogs_queue_push() failed:%d", (int)rv); - ogs_free(e->enb_addr); - mme_event_free(e); - } else { - ogs_pollset_notify(mme_self()->pollset); - } - } - else if (not->sn_assoc_change.sac_state == SCTP_COMM_UP) - { - ogs_sockaddr_t *addr = - usrsctp_remote_addr(&store); - ogs_assert(addr); - - ogs_debug("SCTP_COMM_UP"); - - e = mme_event_new(MME_EVT_S1AP_LO_SCTP_COMM_UP); - ogs_assert(e); - e->enb_sock = (ogs_sock_t *)sock; - e->enb_addr = addr; - e->inbound_streams = - not->sn_assoc_change.sac_inbound_streams; - e->outbound_streams = - not->sn_assoc_change.sac_outbound_streams; - rv = ogs_queue_push(mme_self()->queue, e); - if (rv != OGS_OK) { - ogs_warn("ogs_queue_push() failed:%d", (int)rv); - ogs_free(e->enb_addr); - mme_event_free(e); - } else { - ogs_pollset_notify(mme_self()->pollset); - } - } - break; - } - case SCTP_SHUTDOWN_EVENT : - { - ogs_sockaddr_t *addr = usrsctp_remote_addr(&store); + if (not->sn_assoc_change.sac_state == + SCTP_SHUTDOWN_COMP || + not->sn_assoc_change.sac_state == + SCTP_COMM_LOST) { + ogs_sockaddr_t *addr = + usrsctp_remote_addr(&store); ogs_assert(addr); - 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_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"); e = mme_event_new(MME_EVT_S1AP_LO_CONNREFUSED); ogs_assert(e); @@ -213,43 +78,84 @@ int s1ap_usrsctp_recv_handler(struct socket *sock, } else { ogs_pollset_notify(mme_self()->pollset); } - break; + } else if (not->sn_assoc_change.sac_state == SCTP_COMM_UP) { + ogs_sockaddr_t *addr = + usrsctp_remote_addr(&store); + ogs_assert(addr); + + ogs_debug("SCTP_COMM_UP"); + + e = mme_event_new(MME_EVT_S1AP_LO_SCTP_COMM_UP); + ogs_assert(e); + e->enb_sock = (ogs_sock_t *)sock; + e->enb_addr = addr; + e->inbound_streams = + not->sn_assoc_change.sac_inbound_streams; + e->outbound_streams = + not->sn_assoc_change.sac_outbound_streams; + rv = ogs_queue_push(mme_self()->queue, e); + if (rv != OGS_OK) { + ogs_warn("ogs_queue_push() failed:%d", (int)rv); + ogs_free(e->enb_addr); + mme_event_free(e); + } else { + ogs_pollset_notify(mme_self()->pollset); + } } - 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; + break; + } + case SCTP_SHUTDOWN_EVENT : + { + ogs_sockaddr_t *addr = usrsctp_remote_addr(&store); + ogs_assert(addr); + + 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); + + e = mme_event_new(MME_EVT_S1AP_LO_CONNREFUSED); + ogs_assert(e); + e->enb_sock = (ogs_sock_t *)sock; + e->enb_addr = addr; + rv = ogs_queue_push(mme_self()->queue, e); + if (rv != OGS_OK) { + ogs_warn("ogs_queue_push() failed:%d", (int)rv); + ogs_free(e->enb_addr); + mme_event_free(e); + } else { + ogs_pollset_notify(mme_self()->pollset); } - 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; - } - case 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); - break; - } - default : - ogs_error("Discarding event with " - "unknown flags:0x%x type:0x%x", - flags, not->sn_header.sn_type); - break; + 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_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; + case 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); + 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) - { + } else if (flags & MSG_EOR) { ogs_pkbuf_t *pkbuf; ogs_sockaddr_t *addr = NULL; @@ -273,9 +179,7 @@ int s1ap_usrsctp_recv_handler(struct socket *sock, } else { ogs_pollset_notify(mme_self()->pollset); } - } - else - { + } else { ogs_error("Not engough buffer. Need more recv : 0x%x", flags); } free(data); @@ -293,16 +197,15 @@ static ogs_sockaddr_t *usrsctp_remote_addr(union sctp_sockstore *store) ogs_assert(addr); addr->ogs_sa_family = store->sin.sin_family; - switch(addr->ogs_sa_family) - { - case AF_INET: - memcpy(&addr->sin, &store->sin, sizeof(struct sockaddr_in)); - break; - case AF_INET6: - memcpy(&addr->sin6, &store->sin6, sizeof(struct sockaddr_in6)); - break; - default: - ogs_assert_if_reached(); + switch(addr->ogs_sa_family) { + case AF_INET: + memcpy(&addr->sin, &store->sin, sizeof(struct sockaddr_in)); + break; + case AF_INET6: + memcpy(&addr->sin6, &store->sin6, sizeof(struct sockaddr_in6)); + break; + default: + ogs_assert_if_reached(); } return addr;