def handle(self):
        '''
        Handle new incoming connection and keep it to receive messages.
        '''
        self.sockStream = ssl.wrap_socket(self.request, server_side=True,
                                          certfile=\
                                self.server.config.get('security', 'certfile'),
                                          keyfile=\
                                self.server.config.get('security', 'keyfile'),
                                          ssl_version=ssl.PROTOCOL_TLSv1)
        self.sockStream = FixedSockStream(self.sockStream)
        
        # whether client is slave or hypervisor
        (clientType, clientHostname) = self.sockStream.recv()
        # authenticate hypervisors
        if clientType == 'hypervisor':
            self.authClient(clientType)

        LOGGER.info(("%s [%s, %s] establishing connection...") % \
                                (clientType.capitalize(), \
                                 clientHostname, self.client_address))

        self.clientType = ThreadedTCPRequestHandler.C_SLAVE
        if clientType == ThreadedTCPRequestHandler.C_HYPERV:
            self.clientType = ThreadedTCPRequestHandler.C_HYPERV

        # prepare MasterEvent and add it to main program events queue
        # to handle logic of event
        evt = MasterEvent(MasterEvent.M_CLIENT_CONNECTED, (self.clientType,
                            self.client_address, self.sockStream, \
                            clientHostname))
        self.server.recvQueue.put((MasterEvent.PRIO_IMPORTANT, evt))

        # begin listening on the client's socket.
        # emit MasterEvent in case any message comes
        while not self.stopEvent.isSet():
            try:
                msg = self.sockStream.recv()
                evtType = MasterEvent.M_SLAVE_MSG
                if self.clientType == self.C_HYPERV:
                    evtType = MasterEvent.M_HYPERV_MSG

                LOGGER.debug("Server: Received message %s, enqueuing event: %s" % (msg, str(evtType)))
                msg.sender = self.client_address

                evt = MasterEvent(evtType, msg, self.client_address)
                self.server.recvQueue.put((MasterEvent.PRIO_NORMAL, evt))
            except SocketDisconnectedError, e:
                evt = MasterEvent(MasterEvent.M_CLIENT_DISCONNECTED, \
                                  (self.clientType, self.client_address))
                self.server.recvQueue.put((MasterEvent.PRIO_IMPORTANT, evt))
                break
class ThreadedTCPRequestHandler(SocketServer.BaseRequestHandler):
    """
    Client's TCP request handler.
    """
    C_SLAVE = "slave"
    C_HYPERV = "hypervisor"

    def setup(self):
        '''
        Initiate class properties
        '''
        self.stopEvent = threading.Event()
        self.stopEvent.clear()
        self.sockStream = None
        self.clientType = ThreadedTCPRequestHandler.C_SLAVE

    def authClient(self, clientType):
        '''
        Check if hypervisor is authentic. It will provide the connection password.
        '''
        msg = self.sockStream.recv()
        if msg == self.server.config.get('server', 'connection_passwd'):
            self.sockStream.send('PASSWD_OK')
        else:
            self.sockStream.send('PASSWD_WRONG')
            LOGGER.info("Incoming hypervisor connection rejected. " + \
                        "It didn't provide correct password")
            return
        return True

    def handle(self):
        '''
        Handle new incoming connection and keep it to receive messages.
        '''
        self.sockStream = ssl.wrap_socket(self.request, server_side=True,
                                          certfile=\
                                self.server.config.get('security', 'certfile'),
                                          keyfile=\
                                self.server.config.get('security', 'keyfile'),
                                          ssl_version=ssl.PROTOCOL_TLSv1)
        self.sockStream = FixedSockStream(self.sockStream)
        
        # whether client is slave or hypervisor
        (clientType, clientHostname) = self.sockStream.recv()
        # authenticate hypervisors
        if clientType == 'hypervisor':
            self.authClient(clientType)

        LOGGER.info(("%s [%s, %s] establishing connection...") % \
                                (clientType.capitalize(), \
                                 clientHostname, self.client_address))

        self.clientType = ThreadedTCPRequestHandler.C_SLAVE
        if clientType == ThreadedTCPRequestHandler.C_HYPERV:
            self.clientType = ThreadedTCPRequestHandler.C_HYPERV

        # prepare MasterEvent and add it to main program events queue
        # to handle logic of event
        evt = MasterEvent(MasterEvent.M_CLIENT_CONNECTED, (self.clientType,
                            self.client_address, self.sockStream, \
                            clientHostname))
        self.server.recvQueue.put((MasterEvent.PRIO_IMPORTANT, evt))

        # begin listening on the client's socket.
        # emit MasterEvent in case any message comes
        while not self.stopEvent.isSet():
            try:
                msg = self.sockStream.recv()
                evtType = MasterEvent.M_SLAVE_MSG
                if self.clientType == self.C_HYPERV:
                    evtType = MasterEvent.M_HYPERV_MSG

                LOGGER.debug("Server: Received message %s, enqueuing event: %s" % (msg, str(evtType)))
                msg.sender = self.client_address

                evt = MasterEvent(evtType, msg, self.client_address)
                self.server.recvQueue.put((MasterEvent.PRIO_NORMAL, evt))
            except SocketDisconnectedError, e:
                evt = MasterEvent(MasterEvent.M_CLIENT_DISCONNECTED, \
                                  (self.clientType, self.client_address))
                self.server.recvQueue.put((MasterEvent.PRIO_IMPORTANT, evt))
                break

        LOGGER.info("Server: Closing connection with %s [%s]" % \
                                    (clientHostname, self.client_address))
        self.sockStream.close()
        self.stopEvent.clear()
        return