| OLD | NEW |
| 1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
| 2 # Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. | 2 # Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. |
| 3 # | 3 # |
| 4 # Use of this source code is governed by a BSD-style license | 4 # Use of this source code is governed by a BSD-style license |
| 5 # that can be found in the LICENSE file in the root of the source | 5 # that can be found in the LICENSE file in the root of the source |
| 6 # tree. An additional intellectual property rights grant can be found | 6 # tree. An additional intellectual property rights grant can be found |
| 7 # in the file PATENTS. All contributing project authors may | 7 # in the file PATENTS. All contributing project authors may |
| 8 # be found in the AUTHORS file in the root of the source tree. | 8 # be found in the AUTHORS file in the root of the source tree. |
| 9 | 9 |
| 10 """Script for constraining traffic on the local machine.""" | 10 """Script for constraining traffic on the local machine.""" |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 48 _DEFAULT_PRESET = _PRESETS_DICT[_DEFAULT_PRESET_ID] | 48 _DEFAULT_PRESET = _PRESETS_DICT[_DEFAULT_PRESET_ID] |
| 49 | 49 |
| 50 | 50 |
| 51 class NonStrippingEpilogOptionParser(optparse.OptionParser): | 51 class NonStrippingEpilogOptionParser(optparse.OptionParser): |
| 52 """Custom parser to let us show the epilog without weird line breaking.""" | 52 """Custom parser to let us show the epilog without weird line breaking.""" |
| 53 | 53 |
| 54 def format_epilog(self, formatter): | 54 def format_epilog(self, formatter): |
| 55 return self.epilog | 55 return self.epilog |
| 56 | 56 |
| 57 | 57 |
| 58 def _get_external_ip(): | 58 def _GetExternalIp(): |
| 59 """Finds out the machine's external IP by connecting to google.com.""" | 59 """Finds out the machine's external IP by connecting to google.com.""" |
| 60 external_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) | 60 external_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) |
| 61 external_socket.connect(('google.com', 80)) | 61 external_socket.connect(('google.com', 80)) |
| 62 return external_socket.getsockname()[0] | 62 return external_socket.getsockname()[0] |
| 63 | 63 |
| 64 | 64 |
| 65 def _parse_args(): | 65 def _ParseArgs(): |
| 66 """Define and parse the command-line arguments.""" | 66 """Define and parse the command-line arguments.""" |
| 67 presets_string = '\n'.join(str(p) for p in _PRESETS) | 67 presets_string = '\n'.join(str(p) for p in _PRESETS) |
| 68 parser = NonStrippingEpilogOptionParser(epilog=( | 68 parser = NonStrippingEpilogOptionParser(epilog=( |
| 69 '\nAvailable presets:\n' | 69 '\nAvailable presets:\n' |
| 70 ' Bandwidth (kbps) Packet\n' | 70 ' Bandwidth (kbps) Packet\n' |
| 71 'ID Name Receive Send Queue Delay loss \n' | 71 'ID Name Receive Send Queue Delay loss \n' |
| 72 '-- ---- --------- -------- ----- ------- ------\n' | 72 '-- ---- --------- -------- ----- ------- ------\n' |
| 73 '%s\n' % presets_string)) | 73 '%s\n' % presets_string)) |
| 74 parser.add_option('-p', '--preset', type='int', default=_DEFAULT_PRESET_ID, | 74 parser.add_option('-p', '--preset', type='int', default=_DEFAULT_PRESET_ID, |
| 75 help=('ConnectionConfig configuration, specified by ID. ' | 75 help=('ConnectionConfig configuration, specified by ID. ' |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 116 try: | 116 try: |
| 117 if isinstance(options.port_range, str): | 117 if isinstance(options.port_range, str): |
| 118 options.port_range = tuple(int(port) for port in | 118 options.port_range = tuple(int(port) for port in |
| 119 options.port_range.split(',')) | 119 options.port_range.split(',')) |
| 120 if len(options.port_range) != 2: | 120 if len(options.port_range) != 2: |
| 121 parser.error('Invalid port range specified, please specify two ' | 121 parser.error('Invalid port range specified, please specify two ' |
| 122 'integers separated by a comma.') | 122 'integers separated by a comma.') |
| 123 except ValueError: | 123 except ValueError: |
| 124 parser.error('Invalid port range specified.') | 124 parser.error('Invalid port range specified.') |
| 125 | 125 |
| 126 _set_logger(options.verbose) | 126 _InitLogging(options.verbose) |
| 127 return options | 127 return options |
| 128 | 128 |
| 129 | 129 |
| 130 def _set_logger(verbose): | 130 def _InitLogging(verbose): |
| 131 """Setup logging.""" | 131 """Setup logging.""" |
| 132 log_level = _DEFAULT_LOG_LEVEL | 132 log_level = _DEFAULT_LOG_LEVEL |
| 133 if verbose: | 133 if verbose: |
| 134 log_level = logging.DEBUG | 134 log_level = logging.DEBUG |
| 135 logging.basicConfig(level=log_level, format='%(message)s') | 135 logging.basicConfig(level=log_level, format='%(message)s') |
| 136 | 136 |
| 137 | 137 |
| 138 def _main(): | 138 def main(): |
| 139 options = _parse_args() | 139 options = _ParseArgs() |
| 140 | 140 |
| 141 # Build a configuration object. Override any preset configuration settings if | 141 # Build a configuration object. Override any preset configuration settings if |
| 142 # a value of a setting was also given as a flag. | 142 # a value of a setting was also given as a flag. |
| 143 connection_config = _PRESETS_DICT[options.preset] | 143 connection_config = _PRESETS_DICT[options.preset] |
| 144 if options.receive_bw is not _DEFAULT_PRESET.receive_bw_kbps: | 144 if options.receive_bw is not _DEFAULT_PRESET.receive_bw_kbps: |
| 145 connection_config.receive_bw_kbps = options.receive_bw | 145 connection_config.receive_bw_kbps = options.receive_bw |
| 146 if options.send_bw is not _DEFAULT_PRESET.send_bw_kbps: | 146 if options.send_bw is not _DEFAULT_PRESET.send_bw_kbps: |
| 147 connection_config.send_bw_kbps = options.send_bw | 147 connection_config.send_bw_kbps = options.send_bw |
| 148 if options.delay is not _DEFAULT_PRESET.delay_ms: | 148 if options.delay is not _DEFAULT_PRESET.delay_ms: |
| 149 connection_config.delay_ms = options.delay | 149 connection_config.delay_ms = options.delay |
| 150 if options.packet_loss is not _DEFAULT_PRESET.packet_loss_percent: | 150 if options.packet_loss is not _DEFAULT_PRESET.packet_loss_percent: |
| 151 connection_config.packet_loss_percent = options.packet_loss | 151 connection_config.packet_loss_percent = options.packet_loss |
| 152 if options.queue is not _DEFAULT_PRESET.queue_slots: | 152 if options.queue is not _DEFAULT_PRESET.queue_slots: |
| 153 connection_config.queue_slots = options.queue | 153 connection_config.queue_slots = options.queue |
| 154 emulator = network_emulator.NetworkEmulator(connection_config, | 154 emulator = network_emulator.NetworkEmulator(connection_config, |
| 155 options.port_range) | 155 options.port_range) |
| 156 try: | 156 try: |
| 157 emulator.check_permissions() | 157 emulator.CheckPermissions() |
| 158 except network_emulator.NetworkEmulatorError as e: | 158 except network_emulator.NetworkEmulatorError as e: |
| 159 logging.error('Error: %s\n\nCause: %s', e.fail_msg, e.error) | 159 logging.error('Error: %s\n\nCause: %s', e.fail_msg, e.error) |
| 160 return -1 | 160 return -1 |
| 161 | 161 |
| 162 if not options.target_ip: | 162 if not options.target_ip: |
| 163 external_ip = _get_external_ip() | 163 external_ip = _GetExternalIp() |
| 164 else: | 164 else: |
| 165 external_ip = options.target_ip | 165 external_ip = options.target_ip |
| 166 | 166 |
| 167 logging.info('Constraining traffic to/from IP: %s', external_ip) | 167 logging.info('Constraining traffic to/from IP: %s', external_ip) |
| 168 try: | 168 try: |
| 169 emulator.emulate(external_ip) | 169 emulator.Emulate(external_ip) |
| 170 logging.info('Started network emulation with the following configuration:\n' | 170 logging.info('Started network emulation with the following configuration:\n' |
| 171 ' Receive bandwidth: %s kbps (%s kB/s)\n' | 171 ' Receive bandwidth: %s kbps (%s kB/s)\n' |
| 172 ' Send bandwidth : %s kbps (%s kB/s)\n' | 172 ' Send bandwidth : %s kbps (%s kB/s)\n' |
| 173 ' Delay : %s ms\n' | 173 ' Delay : %s ms\n' |
| 174 ' Packet loss : %s %%\n' | 174 ' Packet loss : %s %%\n' |
| 175 ' Queue slots : %s', | 175 ' Queue slots : %s', |
| 176 connection_config.receive_bw_kbps, | 176 connection_config.receive_bw_kbps, |
| 177 connection_config.receive_bw_kbps/8, | 177 connection_config.receive_bw_kbps/8, |
| 178 connection_config.send_bw_kbps, | 178 connection_config.send_bw_kbps, |
| 179 connection_config.send_bw_kbps/8, | 179 connection_config.send_bw_kbps/8, |
| 180 connection_config.delay_ms, | 180 connection_config.delay_ms, |
| 181 connection_config.packet_loss_percent, | 181 connection_config.packet_loss_percent, |
| 182 connection_config.queue_slots) | 182 connection_config.queue_slots) |
| 183 logging.info('Affected traffic: IP traffic on ports %s-%s', | 183 logging.info('Affected traffic: IP traffic on ports %s-%s', |
| 184 options.port_range[0], options.port_range[1]) | 184 options.port_range[0], options.port_range[1]) |
| 185 raw_input('Press Enter to abort Network Emulation...') | 185 raw_input('Press Enter to abort Network Emulation...') |
| 186 logging.info('Flushing all Dummynet rules...') | 186 logging.info('Flushing all Dummynet rules...') |
| 187 network_emulator.cleanup() | 187 network_emulator.Cleanup() |
| 188 logging.info('Completed Network Emulation.') | 188 logging.info('Completed Network Emulation.') |
| 189 return 0 | 189 return 0 |
| 190 except network_emulator.NetworkEmulatorError as e: | 190 except network_emulator.NetworkEmulatorError as e: |
| 191 logging.error('Error: %s\n\nCause: %s', e.fail_msg, e.error) | 191 logging.error('Error: %s\n\nCause: %s', e.fail_msg, e.error) |
| 192 return -2 | 192 return -2 |
| 193 | 193 |
| 194 if __name__ == '__main__': | 194 if __name__ == '__main__': |
| 195 sys.exit(_main()) | 195 sys.exit(main()) |
| OLD | NEW |