blob: d254cfbc049d82abe83c2ce4c55a6fc1db2024eb [file] [log] [blame]
# Copyright 2014 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
import contextlib
import logging
import socket
from telemetry.core import exceptions
from telemetry.core import util
from telemetry.internal import forwarders
class Error(Exception):
"""Base class for exceptions in this module."""
pass
class PortsMismatchError(Error):
"""Raised when local and remote ports are not equal."""
pass
class ConnectionError(Error):
"""Raised when unable to connect to local TCP ports."""
pass
class DoNothingForwarderFactory(forwarders.ForwarderFactory):
def Create(self, port_pair):
return DoNothingForwarder(port_pair)
class DoNothingForwarder(forwarders.Forwarder):
"""Check that no forwarding is needed for the given port pairs.
The local and remote ports must be equal. Otherwise, the "do nothing"
forwarder does not make sense. (Raises PortsMismatchError.)
Also, check that all TCP ports support connections. (Raises ConnectionError.)
"""
def __init__(self, port_pair):
super(DoNothingForwarder, self).__init__(port_pair)
self._CheckPortPair()
def _CheckPortPair(self):
if self._port_pair.local_port != self._port_pair.remote_port:
raise PortsMismatchError('Local port forwarding is not supported')
try:
self._WaitForConnectionEstablished(
(self.host_ip, self._port_pair.local_port), timeout=10)
logging.debug(
'Connection test succeeded for %s:%d',
self.host_ip, self._port_pair.local_port)
except exceptions.TimeoutException:
raise ConnectionError(
'Unable to connect to address: %s:%d',
self.host_ip, self._port_pair.local_port)
def _WaitForConnectionEstablished(self, address, timeout):
def CanConnect():
with contextlib.closing(socket.socket()) as s:
return s.connect_ex(address) == 0
util.WaitFor(CanConnect, timeout)