Example #1
0
    def testMsgWaitallProblems2(self):
        class ReceiveThread(threadutil.Thread):
            def __init__(self, sock, sizes):
                super(ReceiveThread, self).__init__()
                self.sock = sock
                self.sizes = sizes

            def run(self):
                cs, _ = self.sock.accept()
                for size in self.sizes:
                    data = SU.receiveData(cs, size)
                    SU.sendData(cs, data)
                cs.close()

        ss = SU.createSocket(bind=("localhost", 0))
        SIZES = [
            1000, 10000, 32000, 32768, 32780, 41950, 41952, 42000, 65000,
            65535, 65600, 80000, 999999
        ]
        serverthread = ReceiveThread(ss, SIZES)
        serverthread.setDaemon(True)
        serverthread.start()
        port = ss.getsockname()[1]
        cs = SU.createSocket(connect=("localhost", port), timeout=2)
        # test some sizes that might be problematic with MSG_WAITALL and check that they work fine
        for size in SIZES:
            SU.sendData(cs, tobytes("x") * size)
            data = SU.receiveData(cs, size)
            self.assertEqual(size, len(data))
        serverthread.join()
        ss.close()
        cs.close()
Example #2
0
 def testConnectCrash(self):
     serv_thread = TestServerDOS_multiplex.ServerThread(
         self.socket_server, ServerCallback_BrokenHandshake)
     serv_thread.start()
     time.sleep(0.2)
     self.assertTrue(serv_thread.is_alive(),
                     "server thread failed to start")
     try:
         host, port = serv_thread.locationStr.split(':')
         port = int(port)
         try:
             # first connection attempt (will fail because server daemon _handshake crashes)
             csock = SU.createSocket(connect=(host, port))
             conn = SU.SocketConnection(csock, "uri")
             Pyro4.message.Message.recv(conn, [Pyro4.message.MSG_CONNECTOK])
         except errors.ConnectionClosedError:
             pass
         conn.close()
         try:
             # second connection attempt, should still work (i.e. server should still be running)
             csock = SU.createSocket(connect=(host, port))
             conn = SU.SocketConnection(csock, "uri")
             Pyro4.message.Message.recv(conn, [Pyro4.message.MSG_CONNECTOK])
         except errors.ConnectionClosedError:
             pass
     finally:
         conn.close()
         serv_thread.stop_loop.set()
         serv_thread.join()
Example #3
0
 def testSend(self):
     ss = SU.createSocket(bind=("localhost", 0))
     port = ss.getsockname()[1]
     cs = SU.createSocket(connect=("localhost", port))
     SU.sendData(cs, tobytes("foobar!") * 10)
     cs.shutdown(socket.SHUT_WR)
     a = ss.accept()
     data = SU.receiveData(a[0], 5)
     self.assertEqual(tobytes("fooba"), data)
     data = SU.receiveData(a[0], 5)
     self.assertEqual(tobytes("r!foo"), data)
     a[0].close()
     ss.close()
     cs.close()
Example #4
0
 def testMsgWaitallProblems(self):
     ss = SU.createSocket(bind=("localhost", 0), timeout=2)
     port = ss.getsockname()[1]
     cs = SU.createSocket(connect=("localhost", port), timeout=2)
     a = ss.accept()
     # test some sizes that might be problematic with MSG_WAITALL and check that they work fine
     for size in [1000, 10000, 32000, 32768, 32780, 41950, 41952, 42000, 65000, 65535, 65600, 80000]:
         SU.sendData(cs, tobytes("x") * size)
         data = SU.receiveData(a[0], size)
         SU.sendData(a[0], data)
         data = SU.receiveData(cs, size)
         self.assertEqual(size, len(data))
     a[0].close()
     ss.close()
     cs.close()
Example #5
0
 def testSendUnix(self):
     SOCKNAME = "test_unixsocket"
     ss = SU.createSocket(bind=SOCKNAME)
     cs = SU.createSocket(connect=SOCKNAME)
     SU.sendData(cs, tobytes("foobar!") * 10)
     cs.shutdown(socket.SHUT_WR)
     a = ss.accept()
     data = SU.receiveData(a[0], 5)
     self.assertEqual(tobytes("fooba"), data)
     data = SU.receiveData(a[0], 5)
     self.assertEqual(tobytes("r!foo"), data)
     a[0].close()
     ss.close()
     cs.close()
     if os.path.exists(SOCKNAME): os.remove(SOCKNAME)
Example #6
0
 def connect(host, port):
     # connect to the server
     csock = SU.createSocket(connect=(host, port))
     conn = SU.SocketConnection(csock, "uri")
     # get the handshake/connect response
     Pyro4.message.Message.recv(conn, [Pyro4.message.MSG_CONNECTOK])
     return conn
Example #7
0
 def init(self, daemon, host, port, unixsocket=None):
     log.info("starting multiplexed socketserver")
     log.debug("selector implementation: " +
               self.selector.__class__.__name__)
     self.sock = None
     bind_location = unixsocket if unixsocket else (host, port)
     self.sock = socketutil.createSocket(bind=bind_location,
                                         reuseaddr=Pyro4.config.SOCK_REUSE,
                                         timeout=Pyro4.config.COMMTIMEOUT,
                                         noinherit=True,
                                         nodelay=Pyro4.config.SOCK_NODELAY)
     self.daemon = daemon
     self._socketaddr = sockaddr = self.sock.getsockname()
     if not unixsocket and sockaddr[0].startswith("127."):
         if host is None or host.lower(
         ) != "localhost" and not host.startswith("127."):
             log.warning(
                 "weird DNS setup: %s resolves to localhost (127.x.x.x)",
                 host)
     if unixsocket:
         self.locationStr = "./u:" + unixsocket
     else:
         host = host or sockaddr[0]
         port = port or sockaddr[1]
         if ":" in host:  # ipv6
             self.locationStr = "[%s]:%d" % (host, port)
         else:
             self.locationStr = "%s:%d" % (host, port)
     self.selector.register(self.sock, selectors.EVENT_READ, self)
Example #8
0
 def run(self):
     while not self.stop:
         time.sleep(self.loop_delay)
         time_since_last_autoclean = time.time() - self.last_cleaned
         if time_since_last_autoclean < config.NS_AUTOCLEAN:
             continue
         for name, uri in self.nameserver.list().items():
             if name in (constants.DAEMON_NAME, constants.NAMESERVER_NAME):
                 continue
             try:
                 uri_obj = core.URI(uri)
                 timeout = config.COMMTIMEOUT or 5
                 sock = socketutil.createSocket(connect=(uri_obj.host, uri_obj.port), timeout=timeout)
                 sock.close()
                 # if we get here, the listed server is still answering on its port
                 if name in self.unreachable:
                     del self.unreachable[name]
             except socket.error:
                 if name not in self.unreachable:
                     self.unreachable[name] = time.time()
                 if time.time() - self.unreachable[name] >= self.max_unreachable_time:
                     log.info("autoclean: unregistering %s; cannot connect uri %s for %d sec", name, uri, self.max_unreachable_time)
                     self.nameserver.remove(name)
                     del self.unreachable[name]
                     continue
         self.last_cleaned = time.time()
         if self.unreachable:
             log.debug("autoclean: %d/%d names currently unreachable", len(self.unreachable), self.nameserver.count())
Example #9
0
 def testContextAndSock(self):
     cert_dir = "../../certs"
     if not os.path.isdir(cert_dir):
         cert_dir = "../certs"
         if not os.path.isdir(cert_dir):
             cert_dir = "./certs"
             if not os.path.isdir(cert_dir):
                 self.fail("cannot locate test certs directory")
     try:
         config.SSL = True
         config.SSL_REQUIRECLIENTCERT = True
         server_ctx = SU.getSSLcontext(cert_dir + "/server_cert.pem",
                                       cert_dir + "/server_key.pem")
         client_ctx = SU.getSSLcontext(
             clientcert=cert_dir + "/client_cert.pem",
             clientkey=cert_dir + "/client_key.pem")
         self.assertEqual(ssl.CERT_REQUIRED, server_ctx.verify_mode)
         self.assertEqual(ssl.CERT_REQUIRED, client_ctx.verify_mode)
         self.assertTrue(client_ctx.check_hostname)
         sock = SU.createSocket(sslContext=server_ctx)
         try:
             self.assertTrue(hasattr(sock, "getpeercert"))
         finally:
             sock.close()
     finally:
         config.SSL = False
 def init(self, daemon, host, port, unixsocket=None):
     log.info("starting multiplexed socketserver")
     log.debug("selector implementation: %s.%s", self.selector.__class__.__module__, self.selector.__class__.__name__)
     self.sock = None
     bind_location = unixsocket if unixsocket else (host, port)
     if config.SSL:
         sslContext = socketutil.getSSLcontext(servercert=config.SSL_SERVERCERT,
                                               serverkey=config.SSL_SERVERKEY,
                                               keypassword=config.SSL_SERVERKEYPASSWD,
                                               cacerts=config.SSL_CACERTS)
         log.info("using SSL,  cert=%s  key=%s  cacerts=%s", config.SSL_SERVERCERT, config.SSL_SERVERKEY, config.SSL_CACERTS)
     else:
         sslContext = None
         log.info("not using SSL")
     self.sock = socketutil.createSocket(bind=bind_location,
                                         reuseaddr=config.SOCK_REUSE,
                                         timeout=config.COMMTIMEOUT,
                                         noinherit=True,
                                         nodelay=config.SOCK_NODELAY,
                                         sslContext=sslContext)
     self.daemon = daemon
     self._socketaddr = sockaddr = self.sock.getsockname()
     if not unixsocket and sockaddr[0].startswith("127."):
         if host is None or host.lower() != "localhost" and not host.startswith("127."):
             log.warning("weird DNS setup: %s resolves to localhost (127.x.x.x)", host)
     if unixsocket:
         self.locationStr = "./u:" + unixsocket
     else:
         host = host or sockaddr[0]
         port = port or sockaddr[1]
         if ":" in host:  # ipv6
             self.locationStr = "[%s]:%d" % (host, port)
         else:
             self.locationStr = "%s:%d" % (host, port)
     self.selector.register(self.sock, selectors.EVENT_READ, self)
Example #11
0
 def init(self, daemon, host, port, unixsocket=None):
     log.info("starting thread pool socketserver")
     self.daemon = daemon
     self.sock = None
     bind_location = unixsocket if unixsocket else (host, port)
     self.sock = socketutil.createSocket(bind=bind_location,
                                         reuseaddr=Pyro4.config.SOCK_REUSE,
                                         timeout=Pyro4.config.COMMTIMEOUT,
                                         noinherit=True)
     self._socketaddr = self.sock.getsockname()
     if not unixsocket and self._socketaddr[0].startswith("127."):
         if host is None or host.lower(
         ) != "localhost" and not host.startswith("127."):
             log.warning(
                 "weird DNS setup: %s resolves to localhost (127.x.x.x)",
                 host)
     if unixsocket:
         self.locationStr = "./u:" + unixsocket
     else:
         host = host or self._socketaddr[0]
         port = port or self._socketaddr[1]
         if ":" in host:  # ipv6
             self.locationStr = "[%s]:%d" % (host, port)
         else:
             self.locationStr = "%s:%d" % (host, port)
     self.pool = Pool()
Example #12
0
 def testCreateBoundSockets6(self):
     s = SU.createSocket(bind=('::1', 0))
     self.assertEqual(socket.AF_INET6, s.family)
     bs = SU.createBroadcastSocket(bind=('::1', 0))
     self.assertIn(':', s.getsockname()[0])
     self.assertIn(':', bs.getsockname()[0])
     s.close()
     bs.close()
     self.assertRaises(ValueError, SU.createSocket, bind=('::1', 12345), connect=('::1', 1234))
Example #13
0
 def __pyroCreateConnection(self, replaceUri=False):
     """
     Connects this proxy to the remote Pyro daemon. Does connection handshake.
     Returns true if a new connection was made, false if an existing one was already present.
     """
     with self.__pyroConnLock:
         if self._pyroConnection is not None:
             return False     # already connected
         from Pyro4.naming import resolve  # don't import this globally because of cyclic dependancy
         uri=resolve(self._pyroUri)
         # socket connection (normal or Unix domain socket)
         conn=None
         log.debug("connecting to %s", uri)
         connect_location=uri.sockname if uri.sockname else (uri.host, uri.port)
         with self.__pyroLock:
             try:
                 if self._pyroConnection is not None:
                     return False    # already connected
                 sock=socketutil.createSocket(connect=connect_location, reuseaddr=Pyro4.config.SOCK_REUSE, timeout=self.__pyroTimeout)
                 conn=socketutil.SocketConnection(sock, uri.object)
                 # Do handshake. For now, no need to send anything. (message type CONNECT is not yet used)
                 msg = Message.recv(conn, None)
                 # any trailing data (dataLen>0) is an error message, if any
             except Exception:
                 x=sys.exc_info()[1]
                 if conn:
                     conn.close()
                 err="cannot connect: %s" % x
                 log.error(err)
                 if isinstance(x, errors.CommunicationError):
                     raise
                 else:
                     ce = errors.CommunicationError(err)
                     ce.__cause__ = x
                     raise ce
             else:
                 if msg.type==Pyro4.message.MSG_CONNECTFAIL:
                     error="connection rejected"
                     if msg.data:
                         serializer = util.get_serializer_by_id(msg.serializer_id)
                         data = serializer.deserializeData(msg.data, compressed=msg.flags & Pyro4.message.FLAGS_COMPRESSED)
                         error += ", reason: " + data
                     conn.close()
                     log.error(error)
                     raise errors.CommunicationError(error)
                 elif msg.type==Pyro4.message.MSG_CONNECTOK:
                     self._pyroConnection=conn
                     if replaceUri:
                         self._pyroUri=uri
                     log.debug("connected to %s", self._pyroUri)
                     return True
                 else:
                     conn.close()
                     err="connect: invalid msg type %d received" % msg.type
                     log.error(err)
                     raise errors.ProtocolError(err)
Example #14
0
 def testCreateBoundUnixSockets(self):
     SOCKNAME = "test_unixsocket"
     if os.path.exists(SOCKNAME):
         os.remove(SOCKNAME)
     s = SU.createSocket(bind=SOCKNAME)
     self.assertEqual(socket.AF_UNIX, s.family)
     self.assertEqual(SOCKNAME, s.getsockname())
     s.close()
     if os.path.exists(SOCKNAME):
         os.remove(SOCKNAME)
     # unicode arg
     SOCKNAME = unicode(SOCKNAME)
     s = SU.createSocket(bind=SOCKNAME)
     self.assertEqual(socket.AF_UNIX, s.family)
     self.assertEqual(SOCKNAME, s.getsockname())
     s.close()
     if os.path.exists(SOCKNAME):
         os.remove(SOCKNAME)
     self.assertRaises(ValueError, SU.createSocket, bind=SOCKNAME, connect=SOCKNAME)
Example #15
0
 def __pyroCreateConnection(self, replaceUri=False):
     """
     Connects this proxy to the remote Pyro daemon. Does connection handshake.
     Returns true if a new connection was made, false if an existing one was already present.
     """
     with self.__pyroConnLock:
         if self._pyroConnection is not None:
             return False     # already connected
         from Pyro4.naming import resolve  # don't import this globally because of cyclic dependancy
         uri=resolve(self._pyroUri)
         # socket connection (normal or Unix domain socket)
         conn=None
         log.debug("connecting to %s", uri)
         connect_location=uri.sockname if uri.sockname else (uri.host, uri.port)
         with self.__pyroLock:
             try:
                 if self._pyroConnection is not None:
                     return False    # already connected
                 sock=socketutil.createSocket(connect=connect_location, reuseaddr=Pyro4.config.SOCK_REUSE, timeout=self.__pyroTimeout)
                 conn=socketutil.SocketConnection(sock, uri.object)
                 # Do handshake. For now, no need to send anything.
                 msgType, flags, seq, data = MessageFactory.getMessage(conn, None)
                 # any trailing data (dataLen>0) is an error message, if any
             except Exception:
                 x=sys.exc_info()[1]
                 if conn:
                     conn.close()
                 err="cannot connect: %s" % x
                 log.error(err)
                 if isinstance(x, errors.CommunicationError):
                     raise
                 else:
                     raise errors.CommunicationError(err)
             else:
                 if msgType==MessageFactory.MSG_CONNECTFAIL:
                     error="connection rejected"
                     if data:
                         if sys.version_info>=(3,0):
                             data=str(data,"utf-8")
                         error+=", reason: "+data
                     conn.close()
                     log.error(error)
                     raise errors.CommunicationError(error)
                 elif msgType==MessageFactory.MSG_CONNECTOK:
                     self._pyroConnection=conn
                     if replaceUri:
                         log.debug("replacing uri with bound one")
                         self._pyroUri=uri
                     log.debug("connected to %s", self._pyroUri)
                     return True
                 else:
                     conn.close()
                     err="connect: invalid msg type %d received" % msgType
                     log.error(err)
                     raise errors.ProtocolError(err)
Example #16
0
 def testServerPoolFull(self):
     port = socketutil.findProbablyUnusedPort()
     serv = SocketServer_Threadpool()
     daemon = ServerCallback()
     serv.init(daemon, "localhost", port)
     serversock = serv.sock.getsockname()
     csock1 = socketutil.createSocket(connect=serversock)
     csock2 = socketutil.createSocket(connect=serversock)
     try:
         serv.events([serv.sock])
         time.sleep(0.2)
         self.assertEqual([None], daemon.received_denied_reasons)
         serv.events([serv.sock])
         time.sleep(0.2)
         self.assertEqual(2, len(daemon.received_denied_reasons))
         self.assertIn("no free workers, increase server threadpool size", daemon.received_denied_reasons)
     finally:
         csock1.close()
         csock2.close()
         serv.shutdown()
Example #17
0
 def connect(host, port):
     # connect to the server
     csock = SU.createSocket(connect=(host, port))
     conn = SU.SocketConnection(csock, "uri")
     # send the handshake/connect data
     ser = Pyro4.util.get_serializer_by_id(Pyro4.util.MarshalSerializer.serializer_id)
     data, _ = ser.serializeData({"handshake": "hello", "object": Pyro4.constants.DAEMON_NAME}, False)
     msg = Pyro4.message.Message(Pyro4.message.MSG_CONNECT, data, Pyro4.util.MarshalSerializer.serializer_id, 0, 0)
     conn.send(msg.to_bytes())
     # get the handshake/connect response
     Pyro4.message.Message.recv(conn, [Pyro4.message.MSG_CONNECTOK])
     return conn
Example #18
0
def interruptSocket(address):
    """bit of a hack to trigger a blocking server to get out of the loop, useful at clean shutdowns"""
    try:
        sock=socketutil.createSocket(connect=address, keepalive=False, timeout=None)
        socketutil.triggerSocket(sock)
        try:
            sock.shutdown(socket.SHUT_RDWR)
        except (OSError, socket.error):
            pass
        sock.close()
    except socket.error:
        pass
Example #19
0
def interruptSocket(address):
    """bit of a hack to trigger a blocking server to get out of the loop, useful at clean shutdowns"""
    try:
        sock = socketutil.createSocket(connect=address,
                                       keepalive=False,
                                       timeout=None)
        if sys.version_info < (3, 0):
            sock.send("!" * 16)
        else:
            sock.send(bytes([1] * 16))
        sock.close()
    except socket.error:
        pass
Example #20
0
 def testCreateUnboundSockets6(self):
     s = SU.createSocket(ipv6=True)
     self.assertEqual(socket.AF_INET6, s.family)
     bs = SU.createBroadcastSocket(ipv6=True)
     self.assertEqual(socket.AF_INET6, bs.family)
     try:
         host, port, _, _ = s.getsockname()
         # can either fail with socket.error or return (host,0)
         self.assertEqual(0, port)
     except socket.error:
         pass
     try:
         host, port, _, _ = bs.getsockname()
         # can either fail with socket.error or return (host,0)
         self.assertEqual(0, port)
     except socket.error:
         pass
     s.close()
     bs.close()
 def init(self, daemon, host, port, unixsocket=None):
     log.info("starting thread pool socketserver")
     self.daemon = daemon
     self.sock = None
     bind_location = unixsocket if unixsocket else (host, port)
     if config.SSL:
         sslContext = socketutil.getSSLcontext(
             servercert=config.SSL_SERVERCERT,
             serverkey=config.SSL_SERVERKEY,
             keypassword=config.SSL_SERVERKEYPASSWD,
             cacerts=config.SSL_CACERTS)
         log.info("using SSL,  cert=%s  key=%s  cacerts=%s",
                  config.SSL_SERVERCERT, config.SSL_SERVERKEY,
                  config.SSL_CACERTS)
     else:
         sslContext = None
         log.info("not using SSL")
     self.sock = socketutil.createSocket(bind=bind_location,
                                         reuseaddr=config.SOCK_REUSE,
                                         timeout=config.COMMTIMEOUT,
                                         noinherit=True,
                                         nodelay=config.SOCK_NODELAY,
                                         sslContext=sslContext)
     self._socketaddr = self.sock.getsockname()
     if not unixsocket and self._socketaddr[0].startswith("127."):
         if host is None or host.lower(
         ) != "localhost" and not host.startswith("127."):
             log.warning(
                 "weird DNS setup: %s resolves to localhost (127.x.x.x)",
                 host)
     if unixsocket:
         self.locationStr = "./u:" + unixsocket
     else:
         host = host or self._socketaddr[0]
         port = port or self._socketaddr[1]
         if ":" in host:  # ipv6
             self.locationStr = "[%s]:%d" % (host, port)
         else:
             self.locationStr = "%s:%d" % (host, port)
     self.pool = Pool()
     self.housekeeper = Housekeeper(daemon)
     self.housekeeper.start()
Example #22
0
 def create_ssl_socket(*args, **kwargs):
     """Override the Pyro createSocket method and wrap with SSL"""
     socket = socketutil.createSocket(*args, **kwargs)
     ssl_socket = SSLSocket.wrap_socket(socket, *args, **kwargs)
     return ssl_socket
Example #23
0
 def testAbstractNamespace(self):
     SOCKNAME = "\0test_unixsocket_abstract_ns"  # mind the \0 at the start
     s = SU.createSocket(bind=SOCKNAME)
     sn_bytes = tobytes(SOCKNAME)
     self.assertEqual(sn_bytes, s.getsockname())
     s.close()