From b21540e68268fb51ec57dd8c29c861e5a8ff34b3 Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Sun, 17 Mar 2019 15:26:34 +0200 Subject: [PATCH] tests: Close wpa_supplicant control interface more robustly Some of the test cases left behind attached control interface monitor sockets that could result in hitting the wpa_supplicant socket TX queue limit. Try to be a bit more careful about detaching and closing the sockets to avoid this. Signed-off-by: Jouni Malinen --- tests/hwsim/p2p_utils.py | 3 +- tests/hwsim/run-tests.py | 7 +- tests/hwsim/test_macsec.py | 17 +++-- tests/hwsim/wpasupplicant.py | 120 +++++++++++++++++++++++++---------- 4 files changed, 105 insertions(+), 42 deletions(-) diff --git a/tests/hwsim/p2p_utils.py b/tests/hwsim/p2p_utils.py index 510385c2b..df9f7f971 100644 --- a/tests/hwsim/p2p_utils.py +++ b/tests/hwsim/p2p_utils.py @@ -1,5 +1,5 @@ # P2P helper functions -# Copyright (c) 2013-2015, Jouni Malinen +# Copyright (c) 2013-2019, Jouni Malinen # # This software may be distributed under the terms of the BSD license. # See README for more details. @@ -105,6 +105,7 @@ def go_neg_pin_authorized_persistent(i_dev, r_dev, i_intent=None, r_intent=None, def terminate_group(go, cli): logger.info("Terminate persistent group") + cli.close_monitor_group() go.remove_group() cli.wait_go_ending_session() diff --git a/tests/hwsim/run-tests.py b/tests/hwsim/run-tests.py index 2627c57a5..b49e9d644 100755 --- a/tests/hwsim/run-tests.py +++ b/tests/hwsim/run-tests.py @@ -1,7 +1,7 @@ #!/usr/bin/env python3 # # Test case executor -# Copyright (c) 2013-2015, Jouni Malinen +# Copyright (c) 2013-2019, Jouni Malinen # # This software may be distributed under the terms of the BSD license. # See README for more details. @@ -63,6 +63,7 @@ def reset_devs(dev, apdev): pass if wpas: wpas.close_ctrl() + del wpas try: hapd = HostapdGlobal() @@ -560,7 +561,8 @@ def main(): reset_ok = reset_devs(dev, apdev) wpas = None try: - wpas = WpaSupplicant(global_iface="/tmp/wpas-wlan5") + wpas = WpaSupplicant(global_iface="/tmp/wpas-wlan5", + monitor=False) rename_log(args.logdir, 'log5', name, wpas) if not args.no_reset: wpas.remove_ifname() @@ -568,6 +570,7 @@ def main(): pass if wpas: wpas.close_ctrl() + del wpas for i in range(0, 3): rename_log(args.logdir, 'log' + str(i), name, dev[i]) diff --git a/tests/hwsim/test_macsec.py b/tests/hwsim/test_macsec.py index c81490762..6c284fcf6 100644 --- a/tests/hwsim/test_macsec.py +++ b/tests/hwsim/test_macsec.py @@ -1,5 +1,5 @@ # Test cases for MACsec/MKA -# Copyright (c) 2018, Jouni Malinen +# Copyright (c) 2018-2019, Jouni Malinen # # This software may be distributed under the terms of the BSD license. # See README for more details. @@ -17,9 +17,10 @@ import hwsim_utils from utils import HwsimSkip, alloc_fail, fail_test, wait_fail_trigger def cleanup_macsec(): - wpas = WpaSupplicant(global_iface='/tmp/wpas-wlan5') + wpas = WpaSupplicant(global_iface='/tmp/wpas-wlan5', monitor=False) wpas.interface_remove("veth0") wpas.interface_remove("veth1") + del wpas subprocess.call(["ip", "link", "del", "veth0"], stderr=open('/dev/null', 'w')) @@ -34,8 +35,9 @@ def test_macsec_psk_mka_life_time(dev, apdev, params): """MACsec PSK - MKA life time""" try: run_macsec_psk(dev, apdev, params, "macsec_psk_mka_life_time") - wpas = WpaSupplicant(global_iface='/tmp/wpas-wlan5') + wpas = WpaSupplicant(global_iface='/tmp/wpas-wlan5', monitor=False) wpas.interface_remove("veth1") + del wpas # Wait for live peer to be removed on veth0 time.sleep(6.1) finally: @@ -319,7 +321,7 @@ def run_macsec_psk(dev, apdev, params, prefix, integ_only=False, port0=None, cmd[i].terminate() def cleanup_macsec_br(count): - wpas = WpaSupplicant(global_iface='/tmp/wpas-wlan5') + wpas = WpaSupplicant(global_iface='/tmp/wpas-wlan5', monitor=False) for i in range(count): wpas.interface_remove("veth%d" % i) subprocess.call(["ip", "link", "del", "veth%d" % i], @@ -428,8 +430,9 @@ def run_macsec_psk_br(dev, apdev, count, mka_priority): logger.info("Data traffic test failed - ignore for now for >= 3 device cases") for i in range(count): - wpa[i].dump_monitor() + wpa[i].close_monitor() for i in range(count): + wpa[0].close_control() del wpa[0] def test_macsec_psk_ns(dev, apdev, params): @@ -651,9 +654,13 @@ def run_macsec_psk_ns(dev, apdev, params): if "2 packets transmitted, 2 received" not in res: raise Exception("ping did not work") + wpas0.close_monitor() wpas0.request("TERMINATE") + wpas0.close_control() del wpas0 + wpas1.close_monitor() wpas1.request("TERMINATE") + wpas1.close_control() del wpas1 time.sleep(1) diff --git a/tests/hwsim/wpasupplicant.py b/tests/hwsim/wpasupplicant.py index 06405df1f..125867ef9 100644 --- a/tests/hwsim/wpasupplicant.py +++ b/tests/hwsim/wpasupplicant.py @@ -23,7 +23,12 @@ class WpaSupplicant: self.monitor = monitor self.hostname = hostname self.group_ifname = None + self.global_mon = None + self.global_ctrl = None self.gctrl_mon = None + self.ctrl = None + self.mon = None + self.ifname = None self.host = remotehost.Host(hostname, ifname) self._group_dbg = None if ifname: @@ -33,12 +38,9 @@ class WpaSupplicant: self.p2p_dev_ifname = 'p2p-dev-' + self.ifname else: self.p2p_dev_ifname = ifname - else: - self.ifname = None self.global_iface = global_iface if global_iface: - self.global_mon = None if hostname != None: self.global_ctrl = wpaspy.Ctrl(hostname, global_port) if self.monitor: @@ -51,8 +53,77 @@ class WpaSupplicant: self.global_dbg = "" if self.monitor: self.global_mon.attach() - else: - self.global_mon = None + + def __del__(self): + self.close_monitor() + self.close_control() + + def close_control_ctrl(self): + if self.ctrl: + del self.ctrl + self.ctrl = None + + def close_control_global(self): + if self.global_ctrl: + del self.global_ctrl + self.global_ctrl = None + + def close_control(self): + self.close_control_ctrl() + self.close_control_global() + + def close_monitor_mon(self): + if not self.mon: + return + try: + while self.mon.pending(): + ev = self.mon.recv() + logger.debug(self.dbg + ": " + ev) + except: + pass + try: + self.mon.detach() + except ConnectionRefusedError: + pass + del self.mon + self.mon = None + + def close_monitor_global(self): + if not self.global_mon: + return + try: + while self.global_mon.pending(): + ev = self.global_mon.recv() + logger.debug(self.global_dbg + ": " + ev) + except: + pass + try: + self.global_mon.detach() + except ConnectionRefusedError: + pass + del self.global_mon + self.global_mon = None + + def close_monitor_group(self): + if not self.gctrl_mon: + return + try: + while self.gctrl_mon.pending(): + ev = self.gctrl_mon.recv() + logger.debug(self.dbg + ": " + ev) + except: + pass + try: + self.gctrl_mon.detach() + except: + pass + del self.gctrl_mon + self.gctrl_mon = None + + def close_monitor(self): + self.close_monitor_mon() + self.close_monitor_global() + self.close_monitor_group() def cmd_execute(self, cmd_array, shell=False): if self.hostname is None: @@ -70,19 +141,17 @@ class WpaSupplicant: def terminate(self): if self.global_mon: - self.global_mon.detach() - self.global_mon = None + self.close_monitor_global() self.global_ctrl.terminate() self.global_ctrl = None def close_ctrl(self): - if self.global_mon: - self.global_mon.detach() - self.global_mon = None - self.global_ctrl = None + self.close_monitor_global() + self.close_control_global() self.remove_ifname() def set_ifname(self, ifname, hostname=None, port=9877): + self.remove_ifname() self.ifname = ifname if hostname != None: self.ctrl = wpaspy.Ctrl(hostname, port) @@ -99,11 +168,9 @@ class WpaSupplicant: self.mon.attach() def remove_ifname(self): - if self.ifname: - self.mon.detach() - self.mon = None - self.ctrl = None - self.ifname = None + self.close_monitor_mon() + self.close_control_ctrl() + self.ifname = None def get_ctrl_iface_port(self, ifname): if self.hostname is None: @@ -217,12 +284,7 @@ class WpaSupplicant: self.global_request("REMOVE_NETWORK all") self.global_request("SET p2p_no_group_iface 1") self.global_request("P2P_FLUSH") - if self.gctrl_mon: - try: - self.gctrl_mon.detach() - except: - pass - self.gctrl_mon = None + self.close_monitor_group() self.group_ifname = None self.dump_monitor() @@ -814,12 +876,7 @@ class WpaSupplicant: return self.wait_event(events, timeout) def wait_go_ending_session(self): - if self.gctrl_mon: - try: - self.gctrl_mon.detach() - except: - pass - self.gctrl_mon = None + self.close_monitor_group() timeout = 3 if self.hostname is None else 10 ev = self.wait_global_event(["P2P-GROUP-REMOVED"], timeout=timeout) if ev is None: @@ -841,12 +898,7 @@ class WpaSupplicant: return (count_iface, count_global) def remove_group(self, ifname=None): - if self.gctrl_mon: - try: - self.gctrl_mon.detach() - except: - pass - self.gctrl_mon = None + self.close_monitor_group() if ifname is None: ifname = self.group_ifname if self.group_ifname else self.ifname if "OK" not in self.global_request("P2P_GROUP_REMOVE " + ifname):