aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJacob Erlbeck <jerlbeck@sysmocom.de>2014-03-31 13:42:11 +0200
committerHarald Welte <laforge@gnumonks.org>2014-08-21 15:34:16 +0200
commit141de62b06000fcbe582713a9f44a809ea2fbd62 (patch)
tree2e0183a31105f74da15026be16ed04f42cc0cdba
parentea62a38b5d770f31e3d3cc635c52d4854f585fb3 (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
-rw-r--r--openbsc/include/openbsc/control_cmd.h3
-rw-r--r--openbsc/src/libctrl/control_if.c5
2 files changed, 7 insertions, 1 deletions
diff --git a/openbsc/include/openbsc/control_cmd.h b/openbsc/include/openbsc/control_cmd.h
index 725dce06..8aede15d 100644
--- a/openbsc/include/openbsc/control_cmd.h
+++ b/openbsc/include/openbsc/control_cmd.h
@@ -39,6 +39,9 @@ struct ctrl_connection {
/* The queue for sending data back */
struct osmo_wqueue write_queue;
+ /* Buffer for partial input data */
+ struct msgb *pending_msg;
+
/* Callback if the connection was closed */
void (*closed_cb)(struct ctrl_connection *conn);
diff --git a/openbsc/src/libctrl/control_if.c b/openbsc/src/libctrl/control_if.c
index 2727d0dd..ca59d8c6 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