Fix establishing UDP connection
Previously, in establish_connection() for UDP protocol data were sent but never read on peer socket. That lead to successful read on peer side if this connection was filtered. Having constant testing string masked this issue as we can't distinguish to which test of connectivity data belong. This patch makes unique data string per test_connectivity() and also makes establish_connection() to create an ASSURED entry in conntrack table. Finally, in last test after firewall filter was removed, connection is re-established in order to avoid troubles with terminated processes or TCP continuing sending packets which weren't successfully delivered. Closes-Bug: 1478847 Change-Id: I2920d587d8df8d96dc1c752c28f48ba495f3cf0f
This commit is contained in:
parent
cd4d889374
commit
78aed58edb
|
@ -252,7 +252,6 @@ class RootHelperProcess(subprocess.Popen):
|
|||
|
||||
|
||||
class NetcatTester(object):
|
||||
TESTING_STRING = 'foo'
|
||||
TCP = n_const.PROTO_NAME_TCP
|
||||
UDP = n_const.PROTO_NAME_UDP
|
||||
|
||||
|
@ -325,21 +324,30 @@ class NetcatTester(object):
|
|||
self.client_namespace,
|
||||
address=self.address)
|
||||
if self.protocol == self.UDP:
|
||||
# Create an entry in conntrack table for UDP packets
|
||||
self.client_process.writeline(self.TESTING_STRING)
|
||||
# Create an ASSURED entry in conntrack table for UDP packets,
|
||||
# that requires 3-way communcation
|
||||
# 1st transmission creates UNREPLIED
|
||||
# 2nd transmission removes UNREPLIED
|
||||
# 3rd transmission creates ASSURED
|
||||
data = 'foo'
|
||||
self.client_process.writeline(data)
|
||||
self.server_process.read_stdout(READ_TIMEOUT)
|
||||
self.server_process.writeline(data)
|
||||
self.client_process.read_stdout(READ_TIMEOUT)
|
||||
self.client_process.writeline(data)
|
||||
self.server_process.read_stdout(READ_TIMEOUT)
|
||||
|
||||
def test_connectivity(self, respawn=False):
|
||||
stop_required = (respawn and self._client_process and
|
||||
self._client_process.poll() is not None)
|
||||
if stop_required:
|
||||
testing_string = uuidutils.generate_uuid()
|
||||
if respawn:
|
||||
self.stop_processes()
|
||||
|
||||
self.client_process.writeline(self.TESTING_STRING)
|
||||
self.client_process.writeline(testing_string)
|
||||
message = self.server_process.read_stdout(READ_TIMEOUT).strip()
|
||||
self.server_process.writeline(message)
|
||||
message = self.client_process.read_stdout(READ_TIMEOUT).strip()
|
||||
|
||||
return message == self.TESTING_STRING
|
||||
return message == testing_string
|
||||
|
||||
def _spawn_nc_in_namespace(self, namespace, address, listen=False):
|
||||
cmd = ['nc', address, self.dst_port]
|
||||
|
|
|
@ -88,6 +88,8 @@ class IptablesManagerTestCase(functional_base.BaseSudoTestCase):
|
|||
self.assertTrue(netcat.test_connectivity(),
|
||||
'Failed connectivity check before applying a filter '
|
||||
'with %s' % filter_params)
|
||||
# REVISIT(jlibosva): Make sure we have ASSURED conntrack entry for
|
||||
# given connection
|
||||
self.filter_add_rule(
|
||||
fw_manager, self.server.ip, direction, protocol, port)
|
||||
with testtools.ExpectedException(
|
||||
|
@ -97,6 +99,9 @@ class IptablesManagerTestCase(functional_base.BaseSudoTestCase):
|
|||
netcat.test_connectivity()
|
||||
self.filter_remove_rule(
|
||||
fw_manager, self.server.ip, direction, protocol, port)
|
||||
# With TCP packets will get through after firewall was removed, so we
|
||||
# would get old data on socket and with UDP process died, so we need to
|
||||
# respawn processes to have clean sockets
|
||||
self.assertTrue(netcat.test_connectivity(True),
|
||||
'Failed connectivity check after removing a filter '
|
||||
'with %s' % filter_params)
|
||||
|
|
Loading…
Reference in New Issue