From 48d84b1706f76882bc5265c09257e70899fb9c41 Mon Sep 17 00:00:00 2001 From: Ben Pfaff Date: Tue, 7 Aug 2012 11:45:44 -0700 Subject: [PATCH] vconn: Ensure that vconn_run() is enough to complete a connection. Until now, it seems that all vconn users have immediately started reading messages from the connection. Today, however, I added a new user that only wants to read packets after the OpenFlow version is negotiated, so it never called vconn_recv() before that happened. It turns out that if you do this, the version never gets negotiated at all. This commit fixes the problem by ensuring that vconn_run() will continue version negotiation if it isn't done yet. This changes the error return that I get for Unix sockets in the test-vconn "accept-then-close" test from EPIPE to ECONNRESET, so this commit also adjusts that test to accept either error code; both of them seem reasonable enough to me. Signed-off-by: Ben Pfaff --- lib/vconn.c | 12 ++++++++++++ tests/test-vconn.c | 18 ++++++++++++------ 2 files changed, 24 insertions(+), 6 deletions(-) diff --git a/lib/vconn.c b/lib/vconn.c index 6fd73d60..eb848ba8 100644 --- a/lib/vconn.c +++ b/lib/vconn.c @@ -262,6 +262,12 @@ error: void vconn_run(struct vconn *vconn) { + if (vconn->state == VCS_CONNECTING || + vconn->state == VCS_SEND_HELLO || + vconn->state == VCS_RECV_HELLO) { + vconn_connect(vconn); + } + if (vconn->class->run) { (vconn->class->run)(vconn); } @@ -272,6 +278,12 @@ vconn_run(struct vconn *vconn) void vconn_run_wait(struct vconn *vconn) { + if (vconn->state == VCS_CONNECTING || + vconn->state == VCS_SEND_HELLO || + vconn->state == VCS_RECV_HELLO) { + vconn_connect_wait(vconn); + } + if (vconn->class->run_wait) { (vconn->class->run_wait)(vconn); } diff --git a/tests/test-vconn.c b/tests/test-vconn.c index 377f9fa9..5dd38f0f 100644 --- a/tests/test-vconn.c +++ b/tests/test-vconn.c @@ -174,13 +174,9 @@ static void test_accept_then_close(int argc OVS_UNUSED, char *argv[]) { const char *type = argv[1]; - int expected_error; struct fake_pvconn fpv; struct vconn *vconn; - - expected_error = (!strcmp(type, "unix") ? EPIPE - : !strcmp(type, "tcp") ? ECONNRESET - : EPROTO); + int error; fpv_create(type, &fpv); CHECK_ERRNO(vconn_open(fpv.vconn_name, OFP10_VERSION, &vconn, @@ -188,7 +184,17 @@ test_accept_then_close(int argc OVS_UNUSED, char *argv[]) vconn_run(vconn); stream_close(fpv_accept(&fpv)); fpv_close(&fpv); - CHECK_ERRNO(vconn_connect(vconn), expected_error); + + error = vconn_connect_block(vconn); + if (!strcmp(type, "tcp") || !strcmp(type, "unix")) { + if (error != ECONNRESET && error != EPIPE) { + ovs_fatal(0, "unexpected vconn_connect() return value %d (%s)", + error, strerror(error)); + } + } else { + CHECK_ERRNO(error, EPROTO); + } + vconn_close(vconn); fpv_destroy(&fpv); } -- 2.30.2