mirror of
https://github.com/openvswitch/ovs
synced 2025-09-04 16:25:17 +00:00
socket-util: Report POLLHUP as an error while connection completion checking.
Otherwise failed non-blocking connection could be reported as connected. This causes errors in all following operations with the socket. At least this is true on FreeBSD, where POLLHUP could be set without POLLERR. For example, stream_open_block() tests fails with the following error reporting successful connection to the 'WRONG_PORT': ./ovsdb-idl.at:1817: $PYTHON2 $srcdir/test-stream.py tcp:127.0.0.1:$WRONG_PORT stdout: ./ovsdb-idl.at:1817: exit code was 0, expected 1 2399. ovsdb-idl.at:1817: FAILED (ovsdb-idl.at:1817) Also added new tests to track this issue in C library: 'Check Stream open block - C - tcp' 'Check Stream open block - C - tcp6' CC: Numan Siddique <nusiddiq@redhat.com> Fixes:c1aa16d191
("ovs python: ovs.stream.open_block() returns success even if the remote is unreachable") Fixes:d6cedfd9d2
("socket-util: Avoid using SO_ERROR.") Signed-off-by: Ilya Maximets <i.maximets@samsung.com> Signed-off-by: Ben Pfaff <blp@ovn.org>
This commit is contained in:
@@ -285,7 +285,7 @@ check_connection_completion(int fd)
|
||||
}
|
||||
#endif
|
||||
if (retval == 1) {
|
||||
if (pfd.revents & POLLERR) {
|
||||
if (pfd.revents & (POLLERR | POLLHUP)) {
|
||||
ssize_t n = send(fd, "", 1, 0);
|
||||
if (n < 0) {
|
||||
return sock_errno();
|
||||
|
@@ -178,7 +178,7 @@ def check_connection_completion(sock):
|
||||
pfds = p.poll(0)
|
||||
if len(pfds) == 1:
|
||||
revents = pfds[0][1]
|
||||
if revents & ovs.poller.POLLERR:
|
||||
if revents & ovs.poller.POLLERR or revents & ovs.poller.POLLHUP:
|
||||
try:
|
||||
# The following should raise an exception.
|
||||
sock.send("\0".encode(), socket.MSG_DONTWAIT)
|
||||
|
1
tests/.gitignore
vendored
1
tests/.gitignore
vendored
@@ -51,6 +51,7 @@
|
||||
/test-sha1
|
||||
/test-skiplist
|
||||
/test-stp
|
||||
/test-stream
|
||||
/test-strtok_r
|
||||
/test-timeval
|
||||
/test-type-props
|
||||
|
@@ -436,6 +436,10 @@ endif
|
||||
|
||||
tests_ovstest_LDADD = lib/libopenvswitch.la ovn/lib/libovn.la
|
||||
|
||||
noinst_PROGRAMS += tests/test-stream
|
||||
tests_test_stream_SOURCES = tests/test-stream.c
|
||||
tests_test_stream_LDADD = lib/libopenvswitch.la
|
||||
|
||||
noinst_PROGRAMS += tests/test-strtok_r
|
||||
tests_test_strtok_r_SOURCES = tests/test-strtok_r.c
|
||||
|
||||
|
@@ -1785,6 +1785,23 @@ OVSDB_CHECK_IDL_COMPOUND_INDEX_WITH_REF([set, simple3 idl-compound-index-with-re
|
||||
008: End test
|
||||
]])
|
||||
|
||||
m4_define([CHECK_STREAM_OPEN_BLOCK],
|
||||
[AT_SETUP([Check Stream open block - C - $1])
|
||||
AT_SKIP_IF([test "$1" = "tcp6" && test "$IS_WIN32" = "yes"])
|
||||
AT_SKIP_IF([test "$1" = "tcp6" && test "$HAVE_IPV6" = "no"])
|
||||
AT_KEYWORDS([Check Stream open block $1])
|
||||
AT_CHECK([ovsdb_start_idltest "ptcp:0:$2"])
|
||||
PARSE_LISTENING_PORT([ovsdb-server.log], [TCP_PORT])
|
||||
WRONG_PORT=$(($TCP_PORT+1))
|
||||
AT_CHECK([test-stream tcp:$2:$TCP_PORT], [0], [ignore])
|
||||
AT_CHECK([test-stream tcp:$2:$WRONG_PORT], [1], [ignore], [ignore])
|
||||
OVSDB_SERVER_SHUTDOWN
|
||||
AT_CHECK([test-stream tcp:$2:$TCP_PORT], [1], [ignore], [ignore])
|
||||
AT_CLEANUP])
|
||||
|
||||
CHECK_STREAM_OPEN_BLOCK([tcp], [127.0.0.1])
|
||||
CHECK_STREAM_OPEN_BLOCK([tcp6], [[[::1]]])
|
||||
|
||||
m4_define([CHECK_STREAM_OPEN_BLOCK_PY],
|
||||
[AT_SETUP([$1])
|
||||
AT_SKIP_IF([test $2 = no])
|
||||
|
46
tests/test-stream.c
Normal file
46
tests/test-stream.c
Normal file
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Copyright (c) 2018 Ilya Maximets <i.maximets@samsung.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include "fatal-signal.h"
|
||||
#include "openvswitch/vlog.h"
|
||||
#include "stream.h"
|
||||
#include "util.h"
|
||||
|
||||
VLOG_DEFINE_THIS_MODULE(test_stream);
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
int error;
|
||||
struct stream *stream;
|
||||
|
||||
fatal_ignore_sigpipe();
|
||||
set_program_name(argv[0]);
|
||||
|
||||
if (argc < 2) {
|
||||
ovs_fatal(0, "usage: %s REMOTE", argv[0]);
|
||||
}
|
||||
|
||||
error = stream_open_block(stream_open(argv[1], &stream, DSCP_DEFAULT),
|
||||
&stream);
|
||||
if (error) {
|
||||
VLOG_ERR("stream_open_block(%s) failure: %s",
|
||||
argv[1], ovs_strerror(error));
|
||||
}
|
||||
return (error || !stream) ? 1 : 0;
|
||||
}
|
Reference in New Issue
Block a user