From 68375f6c35b2a3ec1377a4bf63bbb89e73ef7ac2 Mon Sep 17 00:00:00 2001 From: Sukchan Lee Date: Wed, 25 Dec 2024 11:09:07 +0900 Subject: [PATCH] [SGsAP] Change SCTP socket to SOCK_STREAM and remove 'addr' field (#3344) Addressed feedback on commit 33532a5 by switching SGsAP's SCTP socket from SOCK_SEQPACKET to SOCK_STREAM. This change eliminates the need for the 'addr' field, as SOCK_STREAM does not require specifying the address in sctp_sendmsg. All references to the 'addr' field have been removed from the VLR structure and related functions, simplifying SCTP message handling and ensuring better compatibility with multiple addresses. Updated `sgsap-sctp.c` accordingly to reflect these changes and improve the reliability of SCTP connections. --- lib/core/ogs-sockaddr.c | 28 +++++++++++++++++++++++++++ lib/core/ogs-sockaddr.h | 1 + lib/sctp/ogs-lksctp.c | 34 +++++++++++++++++++------------- lib/sctp/ogs-usrsctp.c | 40 ++++++++++++++++++++++++-------------- src/mme/mme-context.c | 2 -- src/mme/mme-context.h | 1 - src/mme/mme-event.c | 1 - src/mme/mme-sm.c | 43 ++++++++++------------------------------- src/mme/sgsap-path.c | 14 ++++++++------ src/mme/sgsap-path.h | 3 +-- src/mme/sgsap-sctp.c | 37 ++++++++++------------------------- 11 files changed, 105 insertions(+), 99 deletions(-) diff --git a/lib/core/ogs-sockaddr.c b/lib/core/ogs-sockaddr.c index fb8dbeb8c..fb25ecd22 100644 --- a/lib/core/ogs-sockaddr.c +++ b/lib/core/ogs-sockaddr.c @@ -666,3 +666,31 @@ char *ogs_ipstrdup(ogs_sockaddr_t *addr) return ogs_strdup(buf); } + +char *ogs_sockaddr_strdup(ogs_sockaddr_t *sa_list) +{ + char dumpstr[OGS_HUGE_LEN]; + char *p, *last; + ogs_sockaddr_t *addr = NULL; + + last = dumpstr + OGS_HUGE_LEN; + p = dumpstr; + + addr = (ogs_sockaddr_t *)sa_list; + while (addr) { + char buf[OGS_ADDRSTRLEN]; + p = ogs_slprintf(p, last, "[%s]:%d ", + OGS_ADDR(addr, buf), OGS_PORT(addr)); + addr = addr->next; + } + + if (p > dumpstr) { + /* If there is more than one addr, remove the last character */ + *(p-1) = 0; + + return ogs_strdup(dumpstr); + } + + /* No address */ + return NULL; +} diff --git a/lib/core/ogs-sockaddr.h b/lib/core/ogs-sockaddr.h index a28e5b570..817b68df1 100644 --- a/lib/core/ogs-sockaddr.h +++ b/lib/core/ogs-sockaddr.h @@ -125,6 +125,7 @@ int ogs_ipsubnet(ogs_ipsubnet_t *ipsub, char *ogs_gethostname(ogs_sockaddr_t *addr); char *ogs_ipstrdup(ogs_sockaddr_t *addr); +char *ogs_sockaddr_strdup(ogs_sockaddr_t *sa_list); #ifdef __cplusplus } diff --git a/lib/sctp/ogs-lksctp.c b/lib/sctp/ogs-lksctp.c index e4e0a85e4..27aa00b8c 100644 --- a/lib/sctp/ogs-lksctp.c +++ b/lib/sctp/ogs-lksctp.c @@ -168,7 +168,7 @@ ogs_sock_t *ogs_sctp_server( ogs_sockopt_t *socket_option) { int rv; - char buf[OGS_ADDRSTRLEN]; + char *sa_list_str = NULL; ogs_sock_t *new_sock = NULL; ogs_sockopt_t option; @@ -249,8 +249,9 @@ ogs_sock_t *ogs_sctp_server( /* * Log debug info: only the first address is shown here as an example. */ - ogs_debug("sctp_server() [%s]:%d (bound %d addresses)", - OGS_ADDR(sa_list, buf), OGS_PORT(sa_list), addr_count); + sa_list_str = ogs_sockaddr_strdup(sa_list); + ogs_debug("sctp_server() %s (bound %d addresses)", sa_list_str, addr_count); + ogs_free(sa_list_str); /* Start listening for connections. */ rv = ogs_sock_listen(new_sock); @@ -270,9 +271,11 @@ err: * On failure, log an error based on the first address * in sa_list (customize as needed). */ + sa_list_str = ogs_sockaddr_strdup(sa_list); ogs_log_message(OGS_LOG_ERROR, ogs_socket_errno, - "sctp_server() [%s]:%d failed", - OGS_ADDR(sa_list, buf), OGS_PORT(sa_list)); + "sctp_server() %s failed", sa_list_str); + ogs_free(sa_list_str); + return NULL; } @@ -283,7 +286,7 @@ ogs_sock_t *ogs_sctp_client( ogs_sockopt_t *socket_option) { int rv; - char buf[OGS_ADDRSTRLEN]; + char *sa_list_str = NULL; ogs_sock_t *new_sock = NULL; ogs_sockopt_t option; @@ -387,8 +390,9 @@ ogs_sock_t *ogs_sctp_client( } /* Debug log for the first remote address. */ - ogs_debug("sctp_client() connected to [%s]:%d", - OGS_ADDR(sa_list, buf), OGS_PORT(sa_list)); + sa_list_str = ogs_sockaddr_strdup(sa_list); + ogs_debug("sctp_client() connected to %s", sa_list_str); + ogs_free(sa_list_str); /* Success: free buffers and return the new socket. */ if (local_buf) @@ -409,16 +413,18 @@ err: * On failure, log an error based on the first remote address. * Adjust to your needs, e.g., log local too if necessary. */ + sa_list_str = ogs_sockaddr_strdup(sa_list); ogs_log_message(OGS_LOG_ERROR, ogs_socket_errno, - "sctp_client() [%s]:%d failed", - OGS_ADDR(sa_list, buf), - OGS_PORT(sa_list)); + "sctp_client() %s failed", sa_list_str); + ogs_free(sa_list_str); + return NULL; } int ogs_sctp_connect(ogs_sock_t *sock, ogs_sockaddr_t *sa_list) { ogs_sockaddr_t *addr; + char *sa_list_str = NULL; char buf[OGS_ADDRSTRLEN]; ogs_assert(sock); @@ -439,9 +445,11 @@ int ogs_sctp_connect(ogs_sock_t *sock, ogs_sockaddr_t *sa_list) } if (addr == NULL) { + sa_list_str = ogs_sockaddr_strdup(sa_list); ogs_log_message(OGS_LOG_ERROR, ogs_socket_errno, - "sctp_connect() [%s]:%d failed", - OGS_ADDR(sa_list, buf), OGS_PORT(sa_list)); + "sctp_connect() %s failed", sa_list_str); + ogs_free(sa_list_str); + return OGS_ERROR; } diff --git a/lib/sctp/ogs-usrsctp.c b/lib/sctp/ogs-usrsctp.c index 066fecafa..323118a19 100644 --- a/lib/sctp/ogs-usrsctp.c +++ b/lib/sctp/ogs-usrsctp.c @@ -93,6 +93,7 @@ ogs_sock_t *ogs_sctp_server( int type, ogs_sockaddr_t *sa_list, ogs_sockopt_t *socket_option) { int rv; + char *sa_list_str = NULL; char buf[OGS_ADDRSTRLEN]; ogs_sock_t *new = NULL; @@ -142,8 +143,10 @@ ogs_sock_t *ogs_sctp_server( } if (addr == NULL) { - ogs_error("sctp_server [%s]:%d failed", - OGS_ADDR(sa_list, buf), OGS_PORT(sa_list)); + sa_list_str = ogs_sockaddr_strdup(sa_list); + ogs_error("sctp_server %s failed", sa_list_str); + ogs_free(sa_list_str); + return NULL; } @@ -161,6 +164,7 @@ ogs_sock_t *ogs_sctp_client( ogs_sockopt_t *socket_option) { int rv; + char *sa_list_str = NULL; char buf[OGS_ADDRSTRLEN]; ogs_sock_t *new = NULL; @@ -210,8 +214,10 @@ ogs_sock_t *ogs_sctp_client( } if (addr == NULL) { - ogs_error("sctp_client [%s]:%d failed", - OGS_ADDR(sa_list, buf), OGS_PORT(sa_list)); + sa_list_str = ogs_sockaddr_strdup(sa_list); + ogs_error("sctp_client %s failed", sa_list_str); + ogs_free(sa_list_str); + return NULL; } @@ -221,7 +227,7 @@ ogs_sock_t *ogs_sctp_client( int ogs_sctp_bind(ogs_sock_t *sock, ogs_sockaddr_t *sa_list) { struct socket *socket = (struct socket *)sock; - char buf[OGS_ADDRSTRLEN]; + char *sa_list_str = NULL; socklen_t addrlen; ogs_assert(socket); @@ -231,13 +237,16 @@ int ogs_sctp_bind(ogs_sock_t *sock, ogs_sockaddr_t *sa_list) ogs_assert(addrlen); if (usrsctp_bind(socket, &sa_list->sa, addrlen) != 0) { - ogs_error("sctp_bind() [%s]:%d failed", - OGS_ADDR(sa_list, buf), OGS_PORT(sa_list)); + sa_list_str = ogs_sockaddr_strdup(sa_list); + ogs_error("sctp_bind() %s failed", sa_list_str); + ogs_free(sa_list_str); + return OGS_ERROR; } - ogs_debug("sctp_bind() [%s]:%d", - OGS_ADDR(sa_list, buf), OGS_PORT(sa_list)); + sa_list_str = ogs_sockaddr_strdup(sa_list); + ogs_debug("sctp_bind() %s", sa_list_str); + ogs_free(sa_list_str); return OGS_OK; } @@ -245,7 +254,7 @@ int ogs_sctp_bind(ogs_sock_t *sock, ogs_sockaddr_t *sa_list) int ogs_sctp_connect(ogs_sock_t *sock, ogs_sockaddr_t *sa_list) { struct socket *socket = (struct socket *)sock; - char buf[OGS_ADDRSTRLEN]; + char *sa_list_str = NULL; socklen_t addrlen; ogs_assert(socket); @@ -255,13 +264,16 @@ int ogs_sctp_connect(ogs_sock_t *sock, ogs_sockaddr_t *sa_list) ogs_assert(addrlen); if (usrsctp_connect(socket, &sa_list->sa, addrlen) != 0) { - ogs_error("sctp_connect() [%s]:%d", - OGS_ADDR(sa_list, buf), OGS_PORT(sa_list)); + sa_list_str = ogs_sockaddr_strdup(sa_list); + ogs_error("sctp_connect() %s", sa_list_str); + ogs_free(sa_list_str); + return OGS_ERROR; } - ogs_debug("sctp_connect() [%s]:%d", - OGS_ADDR(sa_list, buf), OGS_PORT(sa_list)); + sa_list_str = ogs_sockaddr_strdup(sa_list); + ogs_debug("sctp_connect() %s", sa_list_str); + ogs_free(sa_list_str); return OGS_OK; } diff --git a/src/mme/mme-context.c b/src/mme/mme-context.c index 84038a524..426ea274a 100644 --- a/src/mme/mme-context.c +++ b/src/mme/mme-context.c @@ -2816,8 +2816,6 @@ void mme_vlr_remove(mme_vlr_t *vlr) ogs_freeaddrinfo(vlr->sa_list); ogs_freeaddrinfo(vlr->local_sa_list); - if (vlr->addr) - ogs_free(vlr->addr); if (vlr->option) ogs_free(vlr->option); diff --git a/src/mme/mme-context.h b/src/mme/mme-context.h index ab27c093a..4452bbbed 100644 --- a/src/mme/mme-context.h +++ b/src/mme/mme-context.h @@ -219,7 +219,6 @@ typedef struct mme_vlr_s { ogs_sockaddr_t *local_sa_list; /* VLR SGsAP Socket Local Address List */ ogs_sock_t *sock; /* VLR SGsAP Socket */ - ogs_sockaddr_t *addr; /* VLR SGsAP Socket Address */ ogs_sockopt_t *option; /* VLR SGsAP Socket Option */ ogs_poll_t *poll; /* VLR SGsAP Poll */ } mme_vlr_t; diff --git a/src/mme/mme-event.c b/src/mme/mme-event.c index 483b02b12..42ce405d7 100644 --- a/src/mme/mme-event.c +++ b/src/mme/mme-event.c @@ -117,7 +117,6 @@ void mme_sctp_event_push(mme_event_e id, ogs_assert(id); ogs_assert(sock); - ogs_assert(addr); e = mme_event_new(id); ogs_assert(e); diff --git a/src/mme/mme-sm.c b/src/mme/mme-sm.c index 36e313309..fbf74506b 100644 --- a/src/mme/mme-sm.c +++ b/src/mme/mme-sm.c @@ -54,6 +54,7 @@ void mme_state_final(ogs_fsm_t *s, mme_event_t *e) void mme_state_operational(ogs_fsm_t *s, mme_event_t *e) { int rv; + char *sa_list_str = NULL; char buf[OGS_ADDRSTRLEN]; ogs_sock_t *sock = NULL; @@ -970,11 +971,6 @@ cleanup: case MME_EVENT_SGSAP_LO_SCTP_COMM_UP: sock = e->sock; ogs_assert(sock); - addr = e->addr; - ogs_assert(addr); - - ogs_assert(addr->ogs_sa_family == AF_INET || - addr->ogs_sa_family == AF_INET6); max_num_of_ostreams = e->max_num_of_ostreams; @@ -982,15 +978,13 @@ cleanup: ogs_assert(vlr); ogs_assert(OGS_FSM_STATE(&vlr->sm)); - if (vlr->addr) - ogs_free(vlr->addr); - vlr->addr = addr; - vlr->max_num_of_ostreams = ogs_min(max_num_of_ostreams, vlr->max_num_of_ostreams); - ogs_debug("VLR-SGs SCTP_COMM_UP[%s] Max Num of Outbound Streams[%d]", - OGS_ADDR(vlr->addr, buf), vlr->max_num_of_ostreams); + sa_list_str = ogs_sockaddr_strdup(vlr->sa_list); + ogs_debug("VLR-SGs SCTP_COMM_UP %s Max Num of Outbound Streams[%d]", + sa_list_str, vlr->max_num_of_ostreams); + ogs_free(sa_list_str); e->vlr = vlr; ogs_fsm_dispatch(&vlr->sm, e); @@ -999,52 +993,35 @@ cleanup: case MME_EVENT_SGSAP_LO_CONNREFUSED: sock = e->sock; ogs_assert(sock); - addr = e->addr; - ogs_assert(addr); - - ogs_assert(addr->ogs_sa_family == AF_INET || - addr->ogs_sa_family == AF_INET6); vlr = mme_vlr_find_by_sock(sock); ogs_assert(vlr); ogs_assert(OGS_FSM_STATE(&vlr->sm)); - if (vlr->addr) - ogs_free(vlr->addr); - vlr->addr = addr; - + sa_list_str = ogs_sockaddr_strdup(vlr->sa_list); if (OGS_FSM_CHECK(&vlr->sm, sgsap_state_connected)) { e->vlr = vlr; ogs_fsm_dispatch(&vlr->sm, e); - ogs_info("VLR-SGs[%s] connection refused!!!", - OGS_ADDR(vlr->addr, buf)); + ogs_info("VLR-SGs %s connection refused!!!", sa_list_str); } else { - ogs_warn("VLR-SGs[%s] connection refused, Already Removed!", - OGS_ADDR(vlr->addr, buf)); + ogs_warn("VLR-SGs %s connection refused, Already Removed!", + sa_list_str); } + ogs_free(sa_list_str); break; case MME_EVENT_SGSAP_MESSAGE: sock = e->sock; ogs_assert(sock); - addr = e->addr; - ogs_assert(addr); pkbuf = e->pkbuf; ogs_assert(pkbuf); - ogs_assert(addr->ogs_sa_family == AF_INET || - addr->ogs_sa_family == AF_INET6); - vlr = mme_vlr_find_by_sock(sock); ogs_assert(vlr); ogs_assert(OGS_FSM_STATE(&vlr->sm)); - if (vlr->addr) - ogs_free(vlr->addr); - vlr->addr = addr; - e->vlr = vlr; ogs_fsm_dispatch(&vlr->sm, e); diff --git a/src/mme/sgsap-path.c b/src/mme/sgsap-path.c index a42915aa1..b3e70a4f9 100644 --- a/src/mme/sgsap-path.c +++ b/src/mme/sgsap-path.c @@ -53,8 +53,7 @@ void sgsap_close(void) } } -int sgsap_send(ogs_sock_t *sock, ogs_pkbuf_t *pkbuf, - ogs_sockaddr_t *addr, uint16_t stream_no) +int sgsap_send(ogs_sock_t *sock, ogs_pkbuf_t *pkbuf, uint16_t stream_no) { int sent; @@ -62,7 +61,7 @@ int sgsap_send(ogs_sock_t *sock, ogs_pkbuf_t *pkbuf, ogs_assert(pkbuf); sent = ogs_sctp_sendmsg(sock, pkbuf->data, pkbuf->len, - addr, OGS_SCTP_SGSAP_PPID, stream_no); + NULL, OGS_SCTP_SGSAP_PPID, stream_no); if (sent < 0 || sent != pkbuf->len) { ogs_error("ogs_sctp_sendmsg(len:%d,ssn:%d) error (%d:%s)", pkbuf->len, stream_no, errno, strerror(errno)); @@ -77,7 +76,7 @@ int sgsap_send(ogs_sock_t *sock, ogs_pkbuf_t *pkbuf, int sgsap_send_to_vlr_with_sid( mme_vlr_t *vlr, ogs_pkbuf_t *pkbuf, uint16_t stream_no) { - char buf[OGS_ADDRSTRLEN]; + char *sa_list_str = NULL; ogs_sock_t *sock = NULL;; ogs_assert(vlr); @@ -85,8 +84,11 @@ int sgsap_send_to_vlr_with_sid( sock = vlr->sock; ogs_assert(sock); - ogs_debug(" VLR-IP[%s]", OGS_ADDR(vlr->addr, buf)); - return sgsap_send(sock, pkbuf, vlr->addr, stream_no); + sa_list_str = ogs_sockaddr_strdup(vlr->sa_list); + ogs_debug(" StreamNO[%d] VLR-IP[%s]", stream_no, sa_list_str); + ogs_free(sa_list_str); + + return sgsap_send(sock, pkbuf, stream_no); } int sgsap_send_to_vlr(mme_ue_t *mme_ue, ogs_pkbuf_t *pkbuf) diff --git a/src/mme/sgsap-path.h b/src/mme/sgsap-path.h index 0c22996a8..897019c9b 100644 --- a/src/mme/sgsap-path.h +++ b/src/mme/sgsap-path.h @@ -36,8 +36,7 @@ void sgsap_close(void); ogs_sock_t *sgsap_client(mme_vlr_t *vlr); -int sgsap_send(ogs_sock_t *sock, - ogs_pkbuf_t *pkbuf, ogs_sockaddr_t *addr, uint16_t stream_no); +int sgsap_send(ogs_sock_t *sock, ogs_pkbuf_t *pkbuf, uint16_t stream_no); int sgsap_send_to_vlr_with_sid( mme_vlr_t *vlr, ogs_pkbuf_t *pkbuf, uint16_t stream_no); diff --git a/src/mme/sgsap-sctp.c b/src/mme/sgsap-sctp.c index 3b8c680e1..0b21a1b60 100644 --- a/src/mme/sgsap-sctp.c +++ b/src/mme/sgsap-sctp.c @@ -34,12 +34,12 @@ static void recv_handler(ogs_sock_t *sock); ogs_sock_t *sgsap_client(mme_vlr_t *vlr) { - char buf[OGS_ADDRSTRLEN]; + char *sa_list_str = NULL; ogs_sock_t *sock = NULL; ogs_assert(vlr); - sock = ogs_sctp_client(SOCK_SEQPACKET, + sock = ogs_sctp_client(SOCK_STREAM, vlr->sa_list, vlr->local_sa_list, vlr->option); if (sock) { vlr->sock = sock; @@ -51,8 +51,9 @@ ogs_sock_t *sgsap_client(mme_vlr_t *vlr) OGS_POLLIN, sock->fd, lksctp_recv_handler, sock); ogs_assert(vlr->poll); #endif - ogs_info("sgsap client() [%s]:%d", - OGS_ADDR(vlr->sa_list, buf), OGS_PORT(vlr->sa_list)); + sa_list_str = ogs_sockaddr_strdup(vlr->sa_list); + ogs_info("sgsap client() %s", sa_list_str); + ogs_free(sa_list_str); } return sock; @@ -85,8 +86,6 @@ static void recv_handler(ogs_sock_t *sock) { ogs_pkbuf_t *pkbuf; int size; - ogs_sockaddr_t *addr = NULL; - ogs_sockaddr_t from; ogs_sctp_info_t sinfo; int flags = 0; @@ -96,7 +95,7 @@ static void recv_handler(ogs_sock_t *sock) ogs_assert(pkbuf); ogs_pkbuf_put(pkbuf, OGS_MAX_SDU_LEN); size = ogs_sctp_recvmsg( - sock, pkbuf->data, pkbuf->len, &from, &sinfo, &flags); + sock, pkbuf->data, pkbuf->len, NULL, &sinfo, &flags); if (size < 0 || size >= OGS_MAX_SDU_LEN) { ogs_error("ogs_sctp_recvmsg(%d) failed(%d:%s)", size, errno, strerror(errno)); @@ -121,12 +120,8 @@ static void recv_handler(ogs_sock_t *sock) if (not->sn_assoc_change.sac_state == SCTP_COMM_UP) { ogs_debug("SCTP_COMM_UP"); - addr = ogs_calloc(1, sizeof(ogs_sockaddr_t)); - ogs_assert(addr); - memcpy(addr, &from, sizeof(ogs_sockaddr_t)); - sgsap_event_push(MME_EVENT_SGSAP_LO_SCTP_COMM_UP, - sock, addr, NULL, + sock, NULL, NULL, not->sn_assoc_change.sac_inbound_streams, not->sn_assoc_change.sac_outbound_streams); } else if (not->sn_assoc_change.sac_state == SCTP_SHUTDOWN_COMP || @@ -137,12 +132,8 @@ static void recv_handler(ogs_sock_t *sock) if (not->sn_assoc_change.sac_state == SCTP_COMM_LOST) ogs_debug("SCTP_COMM_LOST"); - addr = ogs_calloc(1, sizeof(ogs_sockaddr_t)); - ogs_assert(addr); - memcpy(addr, &from, sizeof(ogs_sockaddr_t)); - sgsap_event_push(MME_EVENT_SGSAP_LO_CONNREFUSED, - sock, addr, NULL, 0, 0); + sock, NULL, NULL, 0, 0); } break; case SCTP_SHUTDOWN_EVENT : @@ -165,12 +156,8 @@ static void recv_handler(ogs_sock_t *sock) not->sn_send_failed.ssf_error); #endif - addr = ogs_calloc(1, sizeof(ogs_sockaddr_t)); - ogs_assert(addr); - memcpy(addr, &from, sizeof(ogs_sockaddr_t)); - sgsap_event_push(MME_EVENT_SGSAP_LO_CONNREFUSED, - sock, addr, NULL, 0, 0); + sock, NULL, NULL, 0, 0); break; case SCTP_PEER_ADDR_CHANGE: ogs_warn("SCTP_PEER_ADDR_CHANGE:[T:%d, F:0x%x, S:%d]", @@ -192,11 +179,7 @@ static void recv_handler(ogs_sock_t *sock) } else if (flags & MSG_EOR) { ogs_pkbuf_trim(pkbuf, size); - addr = ogs_calloc(1, sizeof(ogs_sockaddr_t)); - ogs_assert(addr); - memcpy(addr, &from, sizeof(ogs_sockaddr_t)); - - sgsap_event_push(MME_EVENT_SGSAP_MESSAGE, sock, addr, pkbuf, 0, 0); + sgsap_event_push(MME_EVENT_SGSAP_MESSAGE, sock, NULL, pkbuf, 0, 0); return; } else { if (ogs_socket_errno != OGS_EAGAIN) {