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