def test_cannot_listen(self):
"""
When the program is run with an argument and a listen address specified
with a port that we can't listen on (e.g. port 1), a CannotListenError
is expected to be logged and the program should stop.
"""
temp_dir = self.useFixture(TempDir())
yield main(reactor, raw_args=[
temp_dir.path,
'--listen', ':1', # A port we can't listen on
])
# Expect a 'certs' directory to be created
self.assertThat(os.path.isdir(temp_dir.join('certs')), Equals(True))
# Expect a default certificate to be created
self.assertThat(os.path.isfile(temp_dir.join('default.pem')),
Equals(True))
# Expect to be unable to listen
flush_logged_errors(CannotListenError)
python类CannotListenError()的实例源码
def handle_disconnected_startListening(self):
log.msg("%s starting on %s" % (self.factory.__class__, self.getOwnPort()))
try:
skt = socket.socket(*self.sockinfo)
skt.bind(self.addr)
except socket.error, le:
raise error.CannotListenError, (None, None, le)
# Make sure that if we listened on port 0, we update that to
# reflect what the OS actually assigned us.
self._realPortNumber = skt.getsockname()[1]
log.msg("%s starting on %s" % (self.factory.__class__, self._realPortNumber))
self.factory.doStart()
skt.listen(self.backlog)
self.socket = skt
self.state = "listening"
self.startAccepting()
def _bindSocket(self):
log.msg("%s starting on %s"%(self.protocol.__class__, repr(self.port)))
try:
skt = self.createInternetSocket() # XXX: haha misnamed method
if self.port:
skt.bind(self.port)
except socket.error, le:
raise error.CannotListenError, (None, self.port, le)
if self.port:
try:
os.chmod(self.port, self.mode)
except: # probably not a visible filesystem name
pass
self.connected = 1
self.socket = skt
self.fileno = self.socket.fileno
def testBindError(self):
server = Server()
d = server.startedDeferred = defer.Deferred()
port = reactor.listenUDP(0, server, interface='127.0.0.1')
def cbStarted(ignored):
self.assertEquals(port.getHost(), server.transport.getHost())
server2 = Server()
self.assertRaises(
error.CannotListenError,
reactor.listenUDP, port.getHost().port, server2,
interface='127.0.0.1')
d.addCallback(cbStarted)
def cbFinished(ignored):
return port.stopListening()
d.addCallback(cbFinished)
return d
def setUp(self):
self.factory = server.DNSServerFactory([
test_domain_com, reverse_domain, my_domain_com
], verbose=2)
p = dns.DNSDatagramProtocol(self.factory)
while 1:
self.listenerTCP = reactor.listenTCP(0, self.factory, interface="127.0.0.1")
port = self.listenerTCP.getHost().port
try:
self.listenerUDP = reactor.listenUDP(port, p, interface="127.0.0.1")
except error.CannotListenError:
self.listenerTCP.stopListening()
else:
break
self.resolver = client.Resolver(servers=[('127.0.0.1', port)])
def handle_disconnected_startListening(self):
log.msg("%s starting on %s" % (self.factory.__class__, self.getOwnPort()))
try:
skt = socket.socket(*self.sockinfo)
skt.bind(self.addr)
except socket.error, le:
raise error.CannotListenError, (None, None, le)
# Make sure that if we listened on port 0, we update that to
# reflect what the OS actually assigned us.
self._realPortNumber = skt.getsockname()[1]
log.msg("%s starting on %s" % (self.factory.__class__, self._realPortNumber))
self.factory.doStart()
skt.listen(self.backlog)
self.socket = skt
self.state = "listening"
self.startAccepting()
def _bindSocket(self):
log.msg("%s starting on %s"%(self.protocol.__class__, repr(self.port)))
try:
skt = self.createInternetSocket() # XXX: haha misnamed method
if self.port:
skt.bind(self.port)
except socket.error, le:
raise error.CannotListenError, (None, self.port, le)
if self.port:
try:
os.chmod(self.port, self.mode)
except: # probably not a visible filesystem name
pass
self.connected = 1
self.socket = skt
self.fileno = self.socket.fileno
def testBindError(self):
server = Server()
d = server.startedDeferred = defer.Deferred()
port = reactor.listenUDP(0, server, interface='127.0.0.1')
def cbStarted(ignored):
self.assertEquals(port.getHost(), server.transport.getHost())
server2 = Server()
self.assertRaises(
error.CannotListenError,
reactor.listenUDP, port.getHost().port, server2,
interface='127.0.0.1')
d.addCallback(cbStarted)
def cbFinished(ignored):
return port.stopListening()
d.addCallback(cbFinished)
return d
def setUp(self):
self.factory = server.DNSServerFactory([
test_domain_com, reverse_domain, my_domain_com
], verbose=2)
p = dns.DNSDatagramProtocol(self.factory)
while 1:
self.listenerTCP = reactor.listenTCP(0, self.factory, interface="127.0.0.1")
port = self.listenerTCP.getHost().port
try:
self.listenerUDP = reactor.listenUDP(port, p, interface="127.0.0.1")
except error.CannotListenError:
self.listenerTCP.stopListening()
else:
break
self.resolver = client.Resolver(servers=[('127.0.0.1', port)])
def _bindSocket(self):
try:
skt = self.createSocket()
skt.bind((self.interface, self.port))
except socket.error as le:
raise error.CannotListenError(self.interface, self.port, le)
# Make sure that if we listened on port 0, we update that to
# reflect what the OS actually assigned us.
self._realPortNumber = skt.getsockname()[1]
log.msg("%s starting on %s" % (
self._getLogPrefix(self.protocol), self._realPortNumber))
self.connected = True
self.socket = skt
self.getFileHandle = self.socket.fileno
def test_endpointListenFailure(self):
"""
When an endpoint tries to listen on an already listening port, a
C{CannotListenError} failure is errbacked.
"""
factory = object()
exception = error.CannotListenError('', 80, factory)
mreactor = RaisingMemoryReactor(listenException=exception)
ep, ignoredArgs, ignoredDest = self.createServerEndpoint(
mreactor, factory)
d = ep.listen(object())
receivedExceptions = []
def checkFailure(f):
receivedExceptions.append(f.value)
d.addErrback(checkFailure)
self.assertEqual(receivedExceptions, [exception])
def test_cannotBind(self):
"""
L{IReactorTCP.listenTCP} raises L{error.CannotListenError} if the
address to listen on is already in use.
"""
f = MyServerFactory()
p1 = reactor.listenTCP(0, f, interface='127.0.0.1')
self.addCleanup(p1.stopListening)
n = p1.getHost().port
dest = p1.getHost()
self.assertEqual(dest.type, "TCP")
self.assertEqual(dest.host, "127.0.0.1")
self.assertEqual(dest.port, n)
# make sure new listen raises error
self.assertRaises(error.CannotListenError,
reactor.listenTCP, n, f, interface='127.0.0.1')
def test_socketLocking(self):
"""
L{IReactorUNIX.listenUNIX} raises L{error.CannotListenError} if passed
the name of a file on which a server is already listening.
"""
filename = self.mktemp()
serverFactory = MyServerFactory()
unixPort = reactor.listenUNIX(filename, serverFactory, wantPID=True)
self.assertRaises(
error.CannotListenError,
reactor.listenUNIX, filename, serverFactory, wantPID=True)
def stoppedListening(ign):
unixPort = reactor.listenUNIX(filename, serverFactory, wantPID=True)
return unixPort.stopListening()
return unixPort.stopListening().addCallback(stoppedListening)
def test_bindError(self):
"""
A L{CannotListenError} exception is raised when attempting to bind a
second protocol instance to an already bound port
"""
server = Server()
d = server.startedDeferred = defer.Deferred()
port = reactor.listenUDP(0, server, interface='127.0.0.1')
def cbStarted(ignored):
self.assertEqual(port.getHost(), server.transport.getHost())
server2 = Server()
self.assertRaises(
error.CannotListenError,
reactor.listenUDP, port.getHost().port, server2,
interface='127.0.0.1')
d.addCallback(cbStarted)
def cbFinished(ignored):
return port.stopListening()
d.addCallback(cbFinished)
return d
def _bindSocket(self):
"""
Open the tunnel.
"""
log.msg(
format="%(protocol)s starting on %(interface)s",
protocol=self.protocol.__class__,
interface=self.interface)
try:
fileno, interface = self._openTunnel(
self.interface, self._mode | TunnelFlags.IFF_NO_PI)
except (IOError, OSError) as e:
raise error.CannotListenError(None, self.interface, e)
self.interface = interface
self._fileno = fileno
self.connected = 1
def test_disallowedPort(self):
"""
If a port number is initially selected which cannot be bound, the
L{CannotListenError} is handled and another port number is attempted.
"""
ports = []
class FakeReactor(object):
def listenUDP(self, port, *args, **kwargs):
ports.append(port)
if len(ports) == 1:
raise CannotListenError(None, port, None)
resolver = client.Resolver(servers=[('example.com', 53)])
resolver._reactor = FakeReactor()
resolver._connectedProtocol()
self.assertEqual(len(set(ports)), 2)
def _bindSocket(self):
"""
_bindSocket taken from Twisted 13.1.0 to suppress logging.
"""
try:
skt = self.createInternetSocket()
skt.bind((self.interface, self.port))
except socket.error as le:
raise error.CannotListenError(self.interface, self.port, le)
# Make sure that if we listened on port 0, we update that to
# reflect what the OS actually assigned us.
self._realPortNumber = skt.getsockname()[1]
# Here we remove the logging.
# log.msg("%s starting on %s" % (
# self._getLogPrefix(self.protocol), self._realPortNumber))
self.connected = 1
self.socket = skt
self.fileno = self.socket.fileno
def startListening(self):
"""Create and bind my socket, and begin listening on it.
This is called on unserialization, and must be called after creating a
server to begin listening on the specified port.
"""
try:
skt = self.createInternetSocket()
skt.bind((self.interface, self.port))
except socket.error, le:
raise CannotListenError, (self.interface, self.port, le)
# Make sure that if we listened on port 0, we update that to
# reflect what the OS actually assigned us.
self._realPortNumber = skt.getsockname()[1]
log.msg("%s starting on %s" % (self.factory.__class__, self._realPortNumber))
# The order of the next 6 lines is kind of bizarre. If no one
# can explain it, perhaps we should re-arrange them.
self.factory.doStart()
skt.listen(self.backlog)
self.connected = 1
self.socket = skt
self.fileno = self.socket.fileno
self.numberAccepts = 100
self.startReading()
def _bindSocket(self):
try:
skt = socket.socket(*self.sockinfo)
skt.bind(self.bindAddress)
# print "bound %s to %s" % (skt.fileno(), self.bindAddress)
except socket.error, le:
raise error.CannotListenError, (None, None, le)
# Make sure that if we listened on port 0, we update that to
# reflect what the OS actually assigned us.
self._realPortNumber = skt.getsockname()[1]
log.msg("%s starting on %s"%(self.protocol.__class__, self._realPortNumber))
self.socket = skt
def testSocketLocking(self):
filename = self.mktemp()
f = Factory(self, filename)
l = reactor.listenUNIX(filename, f, wantPID=True)
self.assertRaises(
error.CannotListenError,
reactor.listenUNIX, filename, f, wantPID=True)
def stoppedListening(ign):
l = reactor.listenUNIX(filename, f, wantPID=True)
return l.stopListening()
return l.stopListening().addCallback(stoppedListening)
def testCannotListen(self):
addr = self.mktemp()
p = ServerProto()
s = reactor.listenUNIXDatagram(addr, p)
self.failUnlessRaises(error.CannotListenError, reactor.listenUNIXDatagram, addr, p)
s.stopListening()
os.unlink(addr)
# test connecting to bound and connected (somewhere else) address
def setUpDNS(self):
self.auth = TestAuthority()
factory = server.DNSServerFactory([self.auth])
protocol = dns.DNSDatagramProtocol(factory)
while 1:
self.port = reactor.listenTCP(0, factory, interface='127.0.0.1')
portNumber = self.port.getHost().port
try:
self.udpPort = reactor.listenUDP(portNumber, protocol, interface='127.0.0.1')
except CannotListenError:
self.port.stopListening()
else:
break
self.resolver = client.Resolver(servers=[('127.0.0.1', portNumber)])
def search_device(self):
"""
Triggers a UPnP device discovery.
The returned deferred will be called with the L{UPnPDevice} that has
been found in the LAN.
@return: A deferred called with the detected L{UPnPDevice} instance.
@rtype: L{twisted.internet.defer.Deferred}
"""
if self._discovery is not None:
raise ValueError('already used')
self._discovery = defer.Deferred()
self._discovery_timeout = reactor.callLater(6, self._on_discovery_timeout)
attempt = 0
mcast = None
while True:
try:
self.mcast = reactor.listenMulticast(1900+attempt, self)
break
except CannotListenError:
attempt = random.randint(0, 500)
# joined multicast group, starting upnp search
self.mcast.joinGroup('239.255.255.250', socket.INADDR_ANY)
self.transport.write(_UPNP_SEARCH_REQUEST, (_UPNP_MCAST, _UPNP_PORT))
self.transport.write(_UPNP_SEARCH_REQUEST, (_UPNP_MCAST, _UPNP_PORT))
self.transport.write(_UPNP_SEARCH_REQUEST, (_UPNP_MCAST, _UPNP_PORT))
return self._discovery
#Private methods
def _discover_multicast():
"""
Local IP discovery protocol via multicast:
- Broadcast 3 ping multicast packet with "ping" in it
- Wait for an answer
- Retrieve the ip address from the returning packet, which is ours
"""
nonce = str(random.randrange(2**64))
p = _LocalNetworkMulticast(nonce)
for attempt in itertools.count():
port = 11000 + random.randint(0, 5000)
try:
mcast = reactor.listenMulticast(port, p)
except CannotListenError:
if attempt >= 10:
raise
continue
else:
break
try:
yield mcast.joinGroup('239.255.255.250', socket.INADDR_ANY)
logging.debug("Sending multicast ping")
for i in xrange(3):
p.transport.write(nonce, ('239.255.255.250', port))
address, = yield p.address_received.get_deferred(5)
finally:
mcast.stopListening()
defer.returnValue(address)
def listenOnFreePort(self, portBase, factory):
self.logger.debug("listenOnFreePort(%r, %r)", portBase, factory)
port = portBase
while True:
try:
listeningPort = reactor.listenTCP(port, factory)
self.logger.debug("Found free port %r to listen on", port)
return port, listeningPort
except error.CannotListenError, e:
port += 1
def run_service(soledad_sessions, port=IMAP_PORT, factory=None):
"""
Main entry point to run the service from the client.
:param soledad_sessions: a dict-like object, containing instances
of a Store (soledad instances), indexed by userid.
:returns: the port as returned by the reactor when starts listening, and
the factory for the protocol.
:rtype: tuple
"""
if not factory:
factory = LeapIMAPFactory(soledad_sessions)
try:
interface = "localhost"
# don't bind just to localhost if we are running on docker since we
# won't be able to access imap from the host
if os.environ.get("LEAP_DOCKERIZED"):
interface = ''
# TODO use Endpoints !!!
tport = reactor.listenTCP(port, factory,
interface=interface)
except CannotListenError:
log.error('IMAP Service failed to start: '
'cannot listen in port %s' % (port,))
except Exception as exc:
log.error("Error launching IMAP service: %r" % (exc,))
else:
# all good.
log.debug('IMAP4 Server is RUNNING in port %s' % (port,))
emit_async(catalog.IMAP_SERVICE_STARTED, str(port))
# FIXME -- change service signature
return tport, factory
# not ok, signal error.
emit_async(catalog.IMAP_SERVICE_FAILED_TO_START, str(port))
def run_service(soledad_sessions, keymanager_sessions, sendmail_opts,
port=SMTP_PORT, factory=None):
"""
Main entry point to run the service from the client.
:param soledad_sessions: a dict-like object, containing instances
of a Store (soledad instances), indexed by userid.
:param keymanager_sessions: a dict-like object, containing instances
of Keymanager, indexed by userid.
:param sendmail_opts: a dict-like object of sendmailOptions.
:param factory: a factory for the protocol that will listen in the given
port
:returns: the port as returned by the reactor when starts listening, and
the factory for the protocol.
:rtype: tuple
"""
if not factory:
factory = SMTPFactory(soledad_sessions, keymanager_sessions,
sendmail_opts)
try:
interface = "localhost"
# don't bind just to localhost if we are running on docker since we
# won't be able to access smtp from the host
if os.environ.get("LEAP_DOCKERIZED"):
interface = ''
# TODO Use Endpoints instead --------------------------------
tport = reactor.listenTCP(port, factory, interface=interface)
emit_async(catalog.SMTP_SERVICE_STARTED, str(port))
return tport, factory
except CannotListenError:
log.error('STMP Service failed to start: '
'cannot listen in port %s' % port)
emit_async(catalog.SMTP_SERVICE_FAILED_TO_START, str(port))
except Exception as exc:
log.error('Unhandled error while launching smtp gateway service')
log.error('%r' % exc)
def search_device(self):
"""
Triggers a UPnP device discovery.
The returned deferred will be called with the L{UPnPDevice} that has
been found in the LAN.
@return: A deferred called with the detected L{UPnPDevice} instance.
@rtype: L{twisted.internet.defer.Deferred}
"""
if self._discovery is not None:
raise ValueError('already used')
self._discovery = defer.Deferred()
self._discovery_timeout = reactor.callLater(6, self._on_discovery_timeout)
attempt = 0
mcast = None
while True:
try:
self.mcast = reactor.listenMulticast(1900+attempt, self)
break
except CannotListenError:
attempt = random.randint(0, 500)
# joined multicast group, starting upnp search
self.mcast.joinGroup('239.255.255.250', socket.INADDR_ANY)
self.transport.write(_UPNP_SEARCH_REQUEST, (_UPNP_MCAST, _UPNP_PORT))
self.transport.write(_UPNP_SEARCH_REQUEST, (_UPNP_MCAST, _UPNP_PORT))
self.transport.write(_UPNP_SEARCH_REQUEST, (_UPNP_MCAST, _UPNP_PORT))
return self._discovery
#Private methods
def _discover_multicast():
"""
Local IP discovery protocol via multicast:
- Broadcast 3 ping multicast packet with "ping" in it
- Wait for an answer
- Retrieve the ip address from the returning packet, which is ours
"""
nonce = str(random.randrange(2**64))
p = _LocalNetworkMulticast(nonce)
for attempt in itertools.count():
port = 11000 + random.randint(0, 5000)
try:
mcast = reactor.listenMulticast(port, p)
except CannotListenError:
if attempt >= 10:
raise
continue
else:
break
try:
yield mcast.joinGroup('239.255.255.250', socket.INADDR_ANY)
logging.debug("Sending multicast ping")
for i in xrange(3):
p.transport.write(nonce, ('239.255.255.250', port))
address, = yield p.address_received.get_deferred(5)
finally:
mcast.stopListening()
defer.returnValue(address)
def search_device(self):
"""
Triggers a UPnP device discovery.
The returned deferred will be called with the L{UPnPDevice} that has
been found in the LAN.
@return: A deferred called with the detected L{UPnPDevice} instance.
@rtype: L{twisted.internet.defer.Deferred}
"""
if self._discovery is not None:
raise ValueError('already used')
self._discovery = defer.Deferred()
self._discovery_timeout = reactor.callLater(6, self._on_discovery_timeout)
attempt = 0
mcast = None
while True:
try:
self.mcast = reactor.listenMulticast(1900+attempt, self)
break
except CannotListenError:
attempt = random.randint(0, 500)
# joined multicast group, starting upnp search
self.mcast.joinGroup('239.255.255.250', socket.INADDR_ANY)
self.transport.write(_UPNP_SEARCH_REQUEST, (_UPNP_MCAST, _UPNP_PORT))
self.transport.write(_UPNP_SEARCH_REQUEST, (_UPNP_MCAST, _UPNP_PORT))
self.transport.write(_UPNP_SEARCH_REQUEST, (_UPNP_MCAST, _UPNP_PORT))
return self._discovery
#Private methods