1# Lint as: python2, python3 2# Copyright (c) 2013 The Chromium OS Authors. All rights reserved. 3# Use of this source code is governed by a BSD-style license that can be 4# found in the LICENSE file. 5 6import logging 7import os 8import shutil 9 10from autotest_lib.client.common_lib import error, utils 11from autotest_lib.client.common_lib.cros import avahi_utils 12from autotest_lib.client.cros import service_stopper, tcpdump 13 14 15P2P_SHARE_PATH = '/var/cache/p2p' 16 17# A path used to store the existing p2p files during the test and restore them 18# once the test finishes. 19P2P_SHARE_BACKUP_PATH = '/var/cache/p2p-backup' 20 21 22def p2p_backup_files(backup_path=P2P_SHARE_BACKUP_PATH): 23 """Backup the P2P shared files and create an empty shared directory. 24 25 p2p-server shall not be running during backup or restore. 26 27 @param backup_path: The path where the files will be moved to. 28 @raise error.TestError 29 """ 30 try: 31 if os.path.exists(backup_path): 32 shutil.rmtree(backup_path) 33 if os.path.exists(P2P_SHARE_PATH): 34 os.rename(P2P_SHARE_PATH, backup_path) 35 except OSError as e: 36 raise error.TestError("Error on P2P files backup: %s" % (str(e))) 37 38 39def p2p_restore_files(backup_path=P2P_SHARE_BACKUP_PATH): 40 """Restore the P2P shared files from a backup and *delete* the backup. 41 42 p2p-server shall not be running during backup or restore. 43 44 @param backup_path: The path where the files will be moved from. 45 """ 46 if os.path.exists(P2P_SHARE_PATH): 47 shutil.rmtree(P2P_SHARE_PATH, ignore_errors=True) 48 if os.path.exists(backup_path): 49 os.rename(backup_path, P2P_SHARE_PATH) 50 51 52class P2PServerOverTap(object): 53 """Manage a p2p-server instance running over a TAP interface. 54 55 This class manages a p2p-server instance configured to run over a TAP 56 interface, useful for any test that needs to interact with the p2p-server 57 (and its p2p-http-server instance) on a controled network environment. 58 """ 59 def __init__(self, tap_ip='169.254.10.1', tap_mask=24, tap_name='faketap'): 60 """Initialize the configuration. 61 62 @param tap_ip: IPv4 address for the TAP interface on the DUT's end. 63 @param tap_mask: Network mask fot the tap_ip address. 64 @param tap_name: The name prefix for the TAP interface. 65 """ 66 # The network 169.254/16 shouldn't clash with other real services and we 67 # use a /24 subnet of it as the default safe value here. 68 self._tap_ip = tap_ip 69 self._tap_mask = tap_mask 70 self._tap_name = tap_name 71 self._services = None 72 self.tap = None 73 self._tcpdump = None 74 75 76 def setup(self, dumpdir=None): 77 """Initializes avahi daemon on a new tap interface. 78 79 @param dumpdir: Directory where the traffic on the new tap interface 80 is recorded. A value of None disables traffic dumping. 81 """ 82 try: 83 from lansim import tuntap 84 except ImportError: 85 logging.exception('Failed to import lansim.') 86 raise error.TestError('Error importing lansim. Did you setup_dep ' 87 'and install_pkg lansim on your test?') 88 89 # Ensure p2p and avahi aren't running. 90 self._services = service_stopper.ServiceStopper(['p2p', 'avahi']) 91 self._services.stop_services() 92 93 # Backup p2p files. 94 p2p_backup_files() 95 96 # Initialize the TAP interface. 97 self.tap = tuntap.TunTap(tuntap.IFF_TAP, name=self._tap_name) 98 self.tap.set_addr(self._tap_ip, self._tap_mask) 99 self.tap.up() 100 101 # Enable traffic dump. 102 if not dumpdir is None: 103 dumpfile = os.path.join(dumpdir, 'dump-%s.pcap' % self.tap.name) 104 self._tcpdump = tcpdump.Tcpdump(self.tap.name, dumpfile) 105 106 # Re-launch avahi-daemon on the TAP interface only. 107 avahi_utils.avahi_start_on_iface(self.tap.name) 108 utils.system("start p2p") 109 110 111 def cleanup(self): 112 """Restore the original environment as before the call to setup(). 113 114 This method makes a best-effort attempt to restore the environment and 115 logs all the errors encountered but doesn't fail. 116 """ 117 try: 118 utils.system('stop p2p') 119 avahi_utils.avahi_stop() 120 except: 121 logging.exception('Failed to stop tested services.') 122 123 if self._tcpdump: 124 self._tcpdump.stop() 125 126 if self.tap: 127 self.tap.down() 128 129 # Restore p2p files. 130 try: 131 p2p_restore_files() 132 except OSError: 133 logging.exception('Failed to restore the P2P backup.') 134 135 if self._services: 136 self._services.restore_services() 137