laforge has uploaded this change for review. ( https://gerrit.osmocom.org/c/libosmo-sccp/+/36187?usp=email )
Change subject: Revert "xua + ipa: Add support for I/O in OSMO_IO mode" ......................................................................
Revert "xua + ipa: Add support for I/O in OSMO_IO mode"
This reverts commit d4ec8e7f9f90c99e3d01765ee63d21a158ec67dd which caused severe regressions in the TTCN-3 tests: All STP_Tests_M3UA are failing, as are STP_Tests.* and SCCP_Tests_RAW.TC_process_rx_ludt
Change-Id: I708a5fe0481b14e1b0cdc86149ffc86ee7b5be59 --- M TODO-RELEASE M src/osmo_ss7_asp.c M src/osmo_ss7_xua_srv.c M src/ss7_internal.h 4 files changed, 248 insertions(+), 75 deletions(-)
git pull ssh://gerrit.osmocom.org:29418/libosmo-sccp refs/changes/87/36187/1
diff --git a/TODO-RELEASE b/TODO-RELEASE index 0c3e87e..7785711 100644 --- a/TODO-RELEASE +++ b/TODO-RELEASE @@ -17,4 +17,3 @@ libosmo-sigtran API added osmo_ss7_asp_get_trans_proto() libosmo-sigtran API added osmo_ss7_asp_{find2,find_or_create2}() libosmo-sigtran API added osmo_ss7_xua_server_{find2,create2}() -libosmo-netif >1.4.0 osmo_io SCTP support diff --git a/src/osmo_ss7_asp.c b/src/osmo_ss7_asp.c index c5a2fc5..5bab5ff 100644 --- a/src/osmo_ss7_asp.c +++ b/src/osmo_ss7_asp.c @@ -601,11 +601,10 @@ talloc_free(asp); }
-static int xua_cli_read_cb(struct osmo_stream_cli *conn, struct msgb *msg); -static int ipa_cli_read_cb(struct osmo_stream_cli *conn, struct msgb *msg); -static int m3ua_tcp_cli_read_cb(struct osmo_stream_cli *conn, struct msgb *msg); +static int xua_cli_read_cb(struct osmo_stream_cli *conn); +static int ipa_cli_read_cb(struct osmo_stream_cli *conn); +static int m3ua_tcp_cli_read_cb(struct osmo_stream_cli *conn); static int xua_cli_connect_cb(struct osmo_stream_cli *cli); -static int xua_cli_close_and_reconnect(struct osmo_stream_cli *cli);
int osmo_ss7_asp_restart(struct osmo_ss7_asp *asp) { @@ -643,27 +642,22 @@ osmo_stream_cli_set_proto(asp->client, asp->cfg.trans_proto); osmo_stream_cli_set_reconnect_timeout(asp->client, 5); osmo_stream_cli_set_connect_cb(asp->client, xua_cli_connect_cb); - osmo_stream_cli_set_disconnect_cb(asp->client, xua_cli_close_and_reconnect); switch (asp->cfg.proto) { case OSMO_SS7_ASP_PROT_IPA: OSMO_ASSERT(asp->cfg.trans_proto == IPPROTO_TCP); - osmo_stream_cli_set_read_cb2(asp->client, ipa_cli_read_cb); - osmo_stream_cli_set_segmentation_cb(asp->client, osmo_ipa_segmentation_cb); + osmo_stream_cli_set_read_cb(asp->client, ipa_cli_read_cb); break; case OSMO_SS7_ASP_PROT_M3UA: - if (asp->cfg.trans_proto == IPPROTO_SCTP) { - osmo_stream_cli_set_read_cb2(asp->client, xua_cli_read_cb); - osmo_stream_cli_set_segmentation_cb(asp->client, NULL); - } else if (asp->cfg.trans_proto == IPPROTO_TCP) { - osmo_stream_cli_set_read_cb2(asp->client, m3ua_tcp_cli_read_cb); - osmo_stream_cli_set_segmentation_cb(asp->client, xua_tcp_segmentation_cb); - } else + if (asp->cfg.trans_proto == IPPROTO_SCTP) + osmo_stream_cli_set_read_cb(asp->client, xua_cli_read_cb); + else if (asp->cfg.trans_proto == IPPROTO_TCP) + osmo_stream_cli_set_read_cb(asp->client, m3ua_tcp_cli_read_cb); + else OSMO_ASSERT(0); break; default: OSMO_ASSERT(asp->cfg.trans_proto == IPPROTO_SCTP); - osmo_stream_cli_set_read_cb2(asp->client, xua_cli_read_cb); - osmo_stream_cli_set_segmentation_cb(asp->client, NULL); + osmo_stream_cli_set_read_cb(asp->client, xua_cli_read_cb); break; } osmo_stream_cli_set_data(asp->client, asp); @@ -795,11 +789,33 @@ }
/* netif code tells us we can read something from the socket */ -int ss7_asp_ipa_srv_conn_cb(struct osmo_stream_srv *conn, struct msgb *msg) +int ss7_asp_ipa_srv_conn_cb(struct osmo_stream_srv *conn) { int fd = osmo_stream_srv_get_fd(conn); struct osmo_ss7_asp *asp = osmo_stream_srv_get_data(conn); + struct msgb *msg = NULL; + int rc;
+ OSMO_ASSERT(fd >= 0); + + /* read IPA message from socket and process it */ + rc = ipa_msg_recv_buffered(fd, &msg, &asp->pending_msg); + LOGPASP(asp, DLSS7, LOGL_DEBUG, "%s(): ipa_msg_recv_buffered() returned %d\n", + __func__, rc); + if (rc <= 0) { + if (rc == -EAGAIN) { + /* more data needed */ + return 0; + } + osmo_stream_srv_destroy(conn); + return rc; + } + if (osmo_ipa_process_msg(msg) < 0) { + LOGPASP(asp, DLSS7, LOGL_ERROR, "Bad IPA message\n"); + osmo_stream_srv_destroy(conn); + msgb_free(msg); + return -1; + } msg->dst = asp; rate_ctr_inc2(asp->ctrg, SS7_ASP_CTR_PKT_RX_TOTAL); /* we can use the 'fd' return value of osmo_stream_srv_get_fd() here unverified as all we do @@ -808,14 +824,19 @@ }
/* netif code tells us we can read something from the socket */ -int ss7_asp_xua_srv_conn_cb(struct osmo_stream_srv *conn, struct msgb *msg) +int ss7_asp_xua_srv_conn_cb(struct osmo_stream_srv *conn) { struct osmo_ss7_asp *asp = osmo_stream_srv_get_data(conn); + struct msgb *msg = m3ua_msgb_alloc("xUA Server Rx"); unsigned int ppid; int flags; - int rc = 0; + int rc;
- /* process the received xUA message */ + if (!msg) + return -ENOMEM; + + /* read xUA message from socket and process it */ + rc = osmo_stream_srv_recv(conn, msg); flags = msgb_sctp_msg_flags(msg);
LOGPASP(asp, DLSS7, LOGL_DEBUG, "%s(): sctp_recvmsg() returned %d (flags=0x%x)\n", @@ -834,6 +855,22 @@ default: break; } + + if (rc == 0) { + osmo_stream_srv_destroy(conn); + rc = -EBADF; + } else { + rc = 0; + } + goto out; + } + if (rc < 0) { + osmo_stream_srv_destroy(conn); + rc = -EBADF; + goto out; + } else if (rc == 0) { + osmo_stream_srv_destroy(conn); + rc = -EBADF; goto out; }
@@ -853,38 +890,73 @@ return rc; }
-int xua_tcp_segmentation_cb(struct msgb *msg) -{ - const struct xua_common_hdr *hdr; - size_t msg_length; - - if (msgb_length(msg) < sizeof(*hdr)) - return -EAGAIN; - - hdr = (const struct xua_common_hdr *) msg->data; - msg_length = ntohl(hdr->msg_length); /* includes sizeof(*hdr) */ - - return msg_length; -} - /* netif code tells us we can read something from the socket */ -int ss7_asp_m3ua_tcp_srv_conn_cb(struct osmo_stream_srv *conn, struct msgb *msg) +int ss7_asp_m3ua_tcp_srv_conn_cb(struct osmo_stream_srv *conn) { struct osmo_ss7_asp *asp = osmo_stream_srv_get_data(conn); + int fd = osmo_stream_srv_get_fd(conn); + struct msgb *msg = asp->pending_msg; const struct xua_common_hdr *hdr; + size_t msg_length; int rc;
+ OSMO_ASSERT(fd >= 0); + + if (msg == NULL) { + msg = m3ua_msgb_alloc(__func__); + asp->pending_msg = msg; + } + + /* read message header first */ + if (msg->len < sizeof(*hdr)) { + errno = 0; + rc = recv(fd, msg->tail, sizeof(*hdr) - msg->len, 0); + if (rc <= 0) { + if (errno == EAGAIN || errno == EINTR) + return 0; /* need more data */ + osmo_stream_srv_destroy(conn); + asp->pending_msg = NULL; + msgb_free(msg); + return rc; + } + + msgb_put(msg, rc); + if (msg->len < sizeof(*hdr)) + return 0; /* need more data */ + } + + hdr = (const struct xua_common_hdr *)msg->data; + msg_length = ntohl(hdr->msg_length); /* includes sizeof(*hdr) */ + + /* read the rest of the message */ + if (msg->len < msg_length) { + errno = 0; + rc = recv(fd, msg->tail, msg_length - msg->len, 0); + if (rc <= 0) { + if (errno == EAGAIN || errno == EINTR) + return 0; /* need more data */ + osmo_stream_srv_destroy(conn); + asp->pending_msg = NULL; + msgb_free(msg); + return rc; + } + + msgb_put(msg, rc); + if (msg->len < msg_length) + return 0; /* need more data */ + } + msg->dst = asp; rate_ctr_inc2(asp->ctrg, SS7_ASP_CTR_PKT_RX_TOTAL);
/* spoof SCTP Stream ID */ - hdr = (const struct xua_common_hdr *)msg->data; if (hdr->msg_class == M3UA_MSGC_XFER) msgb_sctp_stream(msg) = 1; else msgb_sctp_stream(msg) = 0;
rc = m3ua_rx_msg(asp, msg); + asp->pending_msg = NULL; msgb_free(msg);
return rc; @@ -937,19 +1009,40 @@ xua_asp_send_xlm_prim_simple(asp, OSMO_XLM_PRIM_M_SCTP_RELEASE, PRIM_OP_INDICATION); }
-static int xua_cli_close_and_reconnect(struct osmo_stream_cli *cli) +static void xua_cli_close_and_reconnect(struct osmo_stream_cli *cli) { xua_cli_close(cli); osmo_stream_cli_reconnect(cli); - return 0; }
/* read call-back for IPA/SCCPlite socket */ -static int ipa_cli_read_cb(struct osmo_stream_cli *conn, struct msgb *msg) +static int ipa_cli_read_cb(struct osmo_stream_cli *conn) { int fd = osmo_stream_cli_get_fd(conn); struct osmo_ss7_asp *asp = osmo_stream_cli_get_data(conn); + struct msgb *msg = NULL; + int rc;
+ OSMO_ASSERT(fd >= 0); + + /* read IPA message from socket and process it */ + rc = ipa_msg_recv_buffered(fd, &msg, &asp->pending_msg); + LOGPASP(asp, DLSS7, LOGL_DEBUG, "%s(): ipa_msg_recv_buffered() returned %d\n", + __func__, rc); + if (rc <= 0) { + if (rc == -EAGAIN) { + /* more data needed */ + return 0; + } + xua_cli_close_and_reconnect(conn); + return rc; + } + if (osmo_ipa_process_msg(msg) < 0) { + LOGPASP(asp, DLSS7, LOGL_ERROR, "Bad IPA message\n"); + xua_cli_close_and_reconnect(conn); + msgb_free(msg); + return -1; + } msg->dst = asp; rate_ctr_inc2(asp->ctrg, SS7_ASP_CTR_PKT_RX_TOTAL); /* we can use the 'fd' return value of osmo_stream_srv_get_fd() here unverified as all we do @@ -958,34 +1051,94 @@ }
/* read call-back for M3UA-over-TCP socket */ -static int m3ua_tcp_cli_read_cb(struct osmo_stream_cli *conn, struct msgb *msg) +static int m3ua_tcp_cli_read_cb(struct osmo_stream_cli *conn) { + struct osmo_ss7_asp *asp = osmo_stream_cli_get_data(conn); + int fd = osmo_stream_cli_get_fd(conn); + struct msgb *msg = asp->pending_msg; const struct xua_common_hdr *hdr; + size_t msg_length; + int rc;
- /* spoof SCTP PPID */ - msgb_sctp_ppid(msg) = M3UA_PPID; + OSMO_ASSERT(fd >= 0); + + if (msg == NULL) { + msg = m3ua_msgb_alloc(__func__); + asp->pending_msg = msg; + } + + /* read message header first */ + if (msg->len < sizeof(*hdr)) { + errno = 0; + rc = recv(fd, msg->tail, sizeof(*hdr) - msg->len, 0); + if (rc <= 0) { + if (errno == EAGAIN || errno == EINTR) + return 0; /* need more data */ + xua_cli_close_and_reconnect(conn); + asp->pending_msg = NULL; + msgb_free(msg); + return rc; + } + + msgb_put(msg, rc); + if (msg->len < sizeof(*hdr)) + return 0; /* need more data */ + } + + hdr = (const struct xua_common_hdr *)msg->data; + msg_length = ntohl(hdr->msg_length); /* includes sizeof(*hdr) */ + + /* read the rest of the message */ + if (msg->len < msg_length) { + errno = 0; + rc = recv(fd, msg->tail, msg_length - msg->len, 0); + if (rc <= 0) { + if (errno == EAGAIN || errno == EINTR) + return 0; /* need more data */ + xua_cli_close_and_reconnect(conn); + asp->pending_msg = NULL; + msgb_free(msg); + return rc; + } + + msgb_put(msg, rc); + if (msg->len < msg_length) + return 0; /* need more data */ + } + + msg->dst = asp; + rate_ctr_inc2(asp->ctrg, SS7_ASP_CTR_PKT_RX_TOTAL);
/* spoof SCTP Stream ID */ - hdr = (const struct xua_common_hdr *) msg->data; if (hdr->msg_class == M3UA_MSGC_XFER) msgb_sctp_stream(msg) = 1; else msgb_sctp_stream(msg) = 0;
- return xua_cli_read_cb(conn, msg); + rc = m3ua_rx_msg(asp, msg); + asp->pending_msg = NULL; + msgb_free(msg); + + return rc; }
-static int xua_cli_read_cb(struct osmo_stream_cli *conn, struct msgb *msg) +static int xua_cli_read_cb(struct osmo_stream_cli *conn) { struct osmo_ss7_asp *asp = osmo_stream_cli_get_data(conn); + struct msgb *msg = m3ua_msgb_alloc("xUA Client Rx"); unsigned int ppid; int flags; int rc;
+ if (!msg) + return -ENOMEM; + + /* read xUA message from socket and process it */ + rc = osmo_stream_cli_recv(conn, msg); flags = msgb_sctp_msg_flags(msg);
LOGPASP(asp, DLSS7, LOGL_DEBUG, "%s(): sctp_recvmsg() returned %d (flags=0x%x)\n", - __func__, msgb_length(msg), flags); + __func__, rc, flags);
if (flags & OSMO_STREAM_SCTP_MSG_FLAGS_NOTIFICATION) { union sctp_notification *notif = (union sctp_notification *) msgb_data(msg); @@ -1000,6 +1153,17 @@ default: break; } + + if (rc == 0) + xua_cli_close_and_reconnect(conn); + rc = 0; + goto out; + } + if (rc < 0) { + xua_cli_close_and_reconnect(conn); + goto out; + } else if (rc == 0) { + xua_cli_close_and_reconnect(conn); goto out; }
diff --git a/src/osmo_ss7_xua_srv.c b/src/osmo_ss7_xua_srv.c index e8e01b3..6da7b7a 100644 --- a/src/osmo_ss7_xua_srv.c +++ b/src/osmo_ss7_xua_srv.c @@ -67,11 +67,32 @@ struct osmo_ss7_asp *asp; char *sock_name = osmo_sock_get_name(link, fd); const char *proto_name = get_value_string(osmo_ss7_asp_protocol_vals, oxs->cfg.proto); + int (*read_cb)(struct osmo_stream_srv *conn) = NULL; int rc = 0;
LOGP(DLSS7, LOGL_INFO, "%s: New %s connection accepted\n", sock_name, proto_name);
- srv = osmo_stream_srv_create2(oxs, link, fd, NULL); + switch (oxs->cfg.proto) { + case OSMO_SS7_ASP_PROT_IPA: + OSMO_ASSERT(oxs->cfg.trans_proto == IPPROTO_TCP); + read_cb = &ss7_asp_ipa_srv_conn_cb; + break; + case OSMO_SS7_ASP_PROT_M3UA: + if (oxs->cfg.trans_proto == IPPROTO_SCTP) + read_cb = &ss7_asp_xua_srv_conn_cb; + else if (oxs->cfg.trans_proto == IPPROTO_TCP) + read_cb = &ss7_asp_m3ua_tcp_srv_conn_cb; + else + OSMO_ASSERT(0); + break; + default: + OSMO_ASSERT(oxs->cfg.trans_proto == IPPROTO_SCTP); + read_cb = &ss7_asp_xua_srv_conn_cb; + break; + } + + srv = osmo_stream_srv_create(oxs, link, fd, read_cb, + &ss7_asp_xua_srv_conn_closed_cb, NULL); if (!srv) { LOGP(DLSS7, LOGL_ERROR, "%s: Unable to create stream server " "for connection\n", sock_name); @@ -80,28 +101,6 @@ return -1; }
- switch (oxs->cfg.proto) { - case OSMO_SS7_ASP_PROT_IPA: - osmo_stream_srv_set_read_cb(srv, ss7_asp_ipa_srv_conn_cb); - osmo_stream_srv_set_segmentation_cb(srv, osmo_ipa_segmentation_cb); - break; - case OSMO_SS7_ASP_PROT_M3UA: - if (oxs->cfg.trans_proto == IPPROTO_SCTP) - osmo_stream_srv_set_read_cb(srv, &ss7_asp_xua_srv_conn_cb); - else if (oxs->cfg.trans_proto == IPPROTO_TCP) { - osmo_stream_srv_set_read_cb(srv, &ss7_asp_m3ua_tcp_srv_conn_cb); - osmo_stream_srv_set_segmentation_cb(srv, xua_tcp_segmentation_cb); - } else - OSMO_ASSERT(0); - break; - default: - OSMO_ASSERT(oxs->cfg.trans_proto == IPPROTO_SCTP); - osmo_stream_srv_set_read_cb(srv, &ss7_asp_xua_srv_conn_cb); - osmo_stream_srv_set_segmentation_cb(srv, NULL); - break; - } - osmo_stream_srv_set_closed_cb(srv, ss7_asp_xua_srv_conn_closed_cb); - asp = ss7_asp_find_by_socket_addr(fd, oxs->cfg.trans_proto); if (asp) { LOGP(DLSS7, LOGL_INFO, "%s: matched connection to ASP %s\n", diff --git a/src/ss7_internal.h b/src/ss7_internal.h index 67c0ee3..758da90 100644 --- a/src/ss7_internal.h +++ b/src/ss7_internal.h @@ -24,9 +24,9 @@
bool ss7_asp_protocol_check_trans_proto(enum osmo_ss7_asp_protocol proto, int trans_proto); int ss7_default_trans_proto_for_asp_proto(enum osmo_ss7_asp_protocol proto); -int ss7_asp_ipa_srv_conn_cb(struct osmo_stream_srv *conn, struct msgb *msg); -int ss7_asp_xua_srv_conn_cb(struct osmo_stream_srv *conn, struct msgb *msg); -int ss7_asp_m3ua_tcp_srv_conn_cb(struct osmo_stream_srv *conn, struct msgb *msg); +int ss7_asp_ipa_srv_conn_cb(struct osmo_stream_srv *conn); +int ss7_asp_xua_srv_conn_cb(struct osmo_stream_srv *conn); +int ss7_asp_m3ua_tcp_srv_conn_cb(struct osmo_stream_srv *conn); int ss7_asp_xua_srv_conn_closed_cb(struct osmo_stream_srv *srv); int ss7_asp_apply_peer_primary_address(const struct osmo_ss7_asp *asp); int ss7_asp_apply_primary_address(const struct osmo_ss7_asp *asp); @@ -38,8 +38,6 @@
bool ss7_xua_server_set_default_local_hosts(struct osmo_xua_server *oxs);
-int xua_tcp_segmentation_cb(struct msgb *msg); - enum ss7_as_ctr { SS7_AS_CTR_RX_MSU_TOTAL, SS7_AS_CTR_TX_MSU_TOTAL,