diff options
author | Jacob Erlbeck <jerlbeck@sysmocom.de> | 2014-03-31 13:42:11 +0200 |
---|---|---|
committer | Holger Hans Peter Freyther <holger@moiji-mobile.com> | 2014-04-01 13:40:59 +0200 |
commit | e827812051f1597db89da2b90e2899b5cd1955ea (patch) | |
tree | 6f1225e43215499ed079688e13fcf41021c465c9 /openbsc/src | |
parent | 8a158bb1ea36d0f88da18d0f034884b30f09fda2 (diff) |
ipa: Use enhanced ipa_msg_recv_buffered() to cope with partioned IPA messages
The old ipa_msg_recv() implementation didn't support partial receive,
so IPA connections got disconnected when this happened.
This patch adds the handling of the temporary message buffers and uses
ipa_msg_recv_buffered().
It has been successfully tested by jerlbeck with osmo-nitb and
osmo-bsc.
Ticket: OW#768
Sponsored-by: On-Waves ehf
Diffstat (limited to 'openbsc/src')
-rw-r--r-- | openbsc/src/libbsc/bsc_msc.c | 10 | ||||
-rw-r--r-- | openbsc/src/libctrl/control_if.c | 5 | ||||
-rw-r--r-- | openbsc/src/osmo-bsc/osmo_bsc_msc.c | 6 | ||||
-rw-r--r-- | openbsc/src/osmo-bsc_nat/bsc_nat.c | 19 | ||||
-rw-r--r-- | openbsc/src/osmo-bsc_nat/bsc_ussd.c | 8 |
5 files changed, 39 insertions, 9 deletions
diff --git a/openbsc/src/libbsc/bsc_msc.c b/openbsc/src/libbsc/bsc_msc.c index 1a0f78aea..a24efabb0 100644 --- a/openbsc/src/libbsc/bsc_msc.c +++ b/openbsc/src/libbsc/bsc_msc.c @@ -42,6 +42,13 @@ static void connection_loss(struct bsc_msc_connection *con) fd = &con->write_queue.bfd; + if (con->pending_msg) { + LOGP(DMSC, LOGL_ERROR, + "MSC(%s) dropping incomplete message.\n", con->name); + msgb_free(con->pending_msg); + con->pending_msg = NULL; + } + close(fd->fd); fd->fd = -1; fd->cb = osmo_wqueue_bfd_cb; @@ -162,6 +169,9 @@ int bsc_msc_connect(struct bsc_msc_connection *con) con->is_connected = 0; + msgb_free(con->pending_msg); + con->pending_msg = NULL; + fd = &con->write_queue.bfd; fd->fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); fd->priv_nr = 1; diff --git a/openbsc/src/libctrl/control_if.c b/openbsc/src/libctrl/control_if.c index 2727d0dd3..ca59d8c6d 100644 --- a/openbsc/src/libctrl/control_if.c +++ b/openbsc/src/libctrl/control_if.c @@ -123,6 +123,7 @@ static void control_close_conn(struct ctrl_connection *ccon) llist_del(&ccon->list_entry); if (ccon->closed_cb) ccon->closed_cb(ccon); + msgb_free(ccon->pending_msg); talloc_free(ccon); } @@ -140,8 +141,10 @@ static int handle_control_read(struct osmo_fd * bfd) queue = container_of(bfd, struct osmo_wqueue, bfd); ccon = container_of(queue, struct ctrl_connection, write_queue); - ret = ipa_msg_recv(bfd->fd, &msg); + ret = ipa_msg_recv_buffered(bfd->fd, &msg, &ccon->pending_msg); if (ret <= 0) { + if (ret == -EAGAIN) + return 0; if (ret == 0) LOGP(DCTRL, LOGL_INFO, "The control connection was closed\n"); else diff --git a/openbsc/src/osmo-bsc/osmo_bsc_msc.c b/openbsc/src/osmo-bsc/osmo_bsc_msc.c index 603398551..04e9cf3a7 100644 --- a/openbsc/src/osmo-bsc/osmo_bsc_msc.c +++ b/openbsc/src/osmo-bsc/osmo_bsc_msc.c @@ -247,13 +247,15 @@ static void osmo_ext_handle(struct osmo_msc_data *msc, struct msgb *msg) static int ipaccess_a_fd_cb(struct osmo_fd *bfd) { - struct msgb *msg; + struct msgb *msg = NULL; struct ipaccess_head *hh; struct osmo_msc_data *data = (struct osmo_msc_data *) bfd->data; int ret; - ret = ipa_msg_recv(bfd->fd, &msg); + ret = ipa_msg_recv_buffered(bfd->fd, &msg, &data->msc_con->pending_msg); if (ret <= 0) { + if (ret == -EAGAIN) + return 0; if (ret == 0) { LOGP(DMSC, LOGL_ERROR, "The connection to the MSC was lost.\n"); bsc_msc_lost(data->msc_con); diff --git a/openbsc/src/osmo-bsc_nat/bsc_nat.c b/openbsc/src/osmo-bsc_nat/bsc_nat.c index d9fc0ca48..524186a55 100644 --- a/openbsc/src/osmo-bsc_nat/bsc_nat.c +++ b/openbsc/src/osmo-bsc_nat/bsc_nat.c @@ -796,14 +796,16 @@ static void msc_send_reset(struct bsc_msc_connection *msc_con) static int ipaccess_msc_read_cb(struct osmo_fd *bfd) { struct bsc_msc_connection *msc_con; - struct msgb *msg; + struct msgb *msg = NULL; struct ipaccess_head *hh; int ret; msc_con = (struct bsc_msc_connection *) bfd->data; - ret = ipa_msg_recv(bfd->fd, &msg); + ret = ipa_msg_recv_buffered(bfd->fd, &msg, &msc_con->pending_msg); if (ret <= 0) { + if (ret == -EAGAIN) + return 0; if (ret == 0) LOGP(DNAT, LOGL_FATAL, "The connection the MSC(%s) was lost, exiting\n", @@ -912,6 +914,13 @@ void bsc_close_connection(struct bsc_connection *connection) osmo_wqueue_clear(&connection->write_queue); llist_del(&connection->list_entry); + if (connection->pending_msg) { + LOGP(DNAT, LOGL_ERROR, "Dropping partial message on connection %d.\n", + connection->cfg->nr); + msgb_free(connection->pending_msg); + connection->pending_msg = NULL; + } + talloc_free(connection); } @@ -1206,13 +1215,15 @@ exit3: static int ipaccess_bsc_read_cb(struct osmo_fd *bfd) { struct bsc_connection *bsc = bfd->data; - struct msgb *msg; + struct msgb *msg = NULL; struct ipaccess_head *hh; struct ipaccess_head_ext *hh_ext; int ret; - ret = ipa_msg_recv(bfd->fd, &msg); + ret = ipa_msg_recv_buffered(bfd->fd, &msg, &bsc->pending_msg); if (ret <= 0) { + if (ret == -EAGAIN) + return 0; if (ret == 0) LOGP(DNAT, LOGL_ERROR, "The connection to the BSC Nr: %d was lost. Cleaning it\n", diff --git a/openbsc/src/osmo-bsc_nat/bsc_ussd.c b/openbsc/src/osmo-bsc_nat/bsc_ussd.c index 8da818119..5f073bf4f 100644 --- a/openbsc/src/osmo-bsc_nat/bsc_ussd.c +++ b/openbsc/src/osmo-bsc_nat/bsc_ussd.c @@ -66,6 +66,8 @@ static void bsc_nat_ussd_destroy(struct bsc_nat_ussd_con *con) osmo_fd_unregister(&con->queue.bfd); osmo_timer_del(&con->auth_timeout); osmo_wqueue_clear(&con->queue); + + msgb_free(con->pending_msg); talloc_free(con); } @@ -117,12 +119,14 @@ static int forward_sccp(struct bsc_nat *nat, struct msgb *msg) static int ussd_read_cb(struct osmo_fd *bfd) { struct bsc_nat_ussd_con *conn = bfd->data; - struct msgb *msg; + struct msgb *msg = NULL; struct ipaccess_head *hh; int ret; - ret = ipa_msg_recv(bfd->fd, &msg); + ret = ipa_msg_recv_buffered(bfd->fd, &msg, &conn->pending_msg); if (ret <= 0) { + if (ret == -EAGAIN) + return 0; LOGP(DNAT, LOGL_ERROR, "USSD Connection was lost.\n"); bsc_nat_ussd_destroy(conn); return -1; |