summaryrefslogtreecommitdiff
path: root/lib/rconn.c
diff options
context:
space:
mode:
authorBen Pfaff <blp@nicira.com>2012-10-24 09:47:44 -0700
committerBen Pfaff <blp@nicira.com>2013-05-03 13:40:19 -0700
commitf44c514621324d81929f7b0c8e2575c2b1d442d1 (patch)
treee16e1d012cb2df7ec924683cb7b7e81a97b127aa /lib/rconn.c
parent5ac7c4dcf593a4515f9302cd0f5beae3c0290a96 (diff)
downloadopenvswitch-f44c514621324d81929f7b0c8e2575c2b1d442d1.tar.gz
rconn: Discard messages received on monitor connections.
Otherwise, if a monitor connection happens to be talking to a (misguided?) peer that sends it messages, such as replies to what the peer perceives as echo requests meant for it, then the peer will eventually hang trying to send data because the monitor connection never sinks it. Signed-off-by: Ben Pfaff <blp@nicira.com> Acked-by: Ethan Jackson <ethan@nicira.com>
Diffstat (limited to 'lib/rconn.c')
-rw-r--r--lib/rconn.c16
1 files changed, 15 insertions, 1 deletions
diff --git a/lib/rconn.c b/lib/rconn.c
index d7bb0be21..4922a5c65 100644
--- a/lib/rconn.c
+++ b/lib/rconn.c
@@ -513,8 +513,21 @@ rconn_run(struct rconn *rc)
if (rc->vconn) {
vconn_run(rc->vconn);
}
- for (i = 0; i < rc->n_monitors; i++) {
+ for (i = 0; i < rc->n_monitors; ) {
+ struct ofpbuf *msg;
+ int retval;
+
vconn_run(rc->monitors[i]);
+
+ /* Drain any stray message that came in on the monitor connection. */
+ retval = vconn_recv(rc->monitors[i], &msg);
+ if (!retval) {
+ ofpbuf_delete(msg);
+ } else if (retval != EAGAIN) {
+ close_monitor(rc, i, retval);
+ continue;
+ }
+ i++;
}
do {
@@ -545,6 +558,7 @@ rconn_run_wait(struct rconn *rc)
}
for (i = 0; i < rc->n_monitors; i++) {
vconn_run_wait(rc->monitors[i]);
+ vconn_recv_wait(rc->monitors[i]);
}
timeo = timeout(rc);