Esempio n. 1
0
 def __notify_box_close(self):
     with self.__notify_box_close_lock:
         log.v('Notify box %d close.' % self.box.uuid)
         try:
             self.box.send(Message.create_close_data())
         except Exception as e:
             log.e('Send close message failed.')
Esempio n. 2
0
 def run(self):
     log.v('[RM] Update network speed.')
     d, u = speedtest.get_speeds()
     if d and u:
         self.conn.download_speed = int(d) * 8
         self.conn.upload_speed = int(u) * 8
     self.conn.is_updating_network_speed = False
Esempio n. 3
0
 def __handle_box_server_data(self, c, msg):
     for cc in self.clients:
         if cc.uuid == msg.uuid:
             log.v('Send data to client %d from box %d.' %
                   (cc.uuid, c.uuid))
             cc.append_data_to_buffer(msg.content)
             return
     log.v('Can not find client %d when box sending data.' % msg.uuid)
     self.__notify_box_client_broken(msg.uuid)
Esempio n. 4
0
    def __start_main(self):
        self.__is_quit_thread = False
        while not self.__is_quit_thread:
            read_list = [self.__qs]
            write_list = []
            err_list = []

            # Box or box-cache connections.

            read_list.append(self.s)

            if self.box_cache:  # connected without authorized
                read_list.extend(self.box_cache)
                # INFO: If cached-box need read, then it is self.box.
                err_list.extend(self.box_cache)

            if self.box:  # The only authorized box.
                read_list.append(self.box)
                if self.box.has_buffered_datas(): write_list.append(self.box)
                err_list.append(self.box)

            # Client connections.

            read_list.append(self.cs)

            if self.clients:
                read_list.extend(self.clients)
                write_list.extend(
                    filter(lambda c: c.has_buffered_datas(), self.clients))
                err_list.extend(self.clients)

            # log.v('READLIST: %s' % str(len(read_list)))
            # log.v('WRITELIST: %s' % str(len(write_list)))
            # log.v('ERRORLIST: %s' % str(len(err_list)))
            # self.dump()

            # Wait.

            read_result, write_result, err_result = select.select(
                read_list, write_list, err_list, 5)

            # Handle read, write and error connections.

            log.v('Before handle connection or socket')

            for e in err_result:
                self.__handle_connection_error(e)

            for r in read_result:
                self.__handle_connection_read(r)

            for w in write_result:
                self.__handle_connection_write(w)

            self.__handle_connection_timeout()

            log.v('After handle connection or socket')
Esempio n. 5
0
 def __handle_client_connection(self, c):
     data = c.recv(config.SOCKET_RECV_LEN)
     if not data:
         raise socket.error('Client send EOF.')
     log.v('Send data to box %d from client %d' % (self.box.uuid, c.uuid))
     # MUST check here.
     self.box.timeout_tracer.reset()
     self.box.ping_tracer.reset()
     self.box.append_data_to_buffer(
         Message.create_client_data_data(c.uuid, data))
Esempio n. 6
0
 def __send_a_data(self, data):
     """ Send a data to client.
     """
     send_data = data
     try:
         while send_data:
             length = self.s.send(send_data)
             send_data = send_data[length:] if length < len(send_data) else None
         self.blocked = False
     except (socket.error, socket.timeout) as e:
         err = e.args[0]
         self.blocked = True
         if err == errno.EAGAIN or err == errno.EWOULDBLOCK:
             log.v('Client %d block error %d, need send later.' % (self.uuid, err))
             self.data_queue.appendleft(send_data)
             return
         raise socket.error(e)
Esempio n. 7
0
    def __handle_cached_box_connection(self, c):
        msg = Message(c.recv(config.SOCKET_RECV_LEN), c)
        if not msg.is_valid:
            raise socket.error('Invalid register message from box')

        if msg.type == Type.CONNECT:
            if not self.__handle_box_register(c, msg):
                raise socket.error('Box failed to register')

            self.box = c
            self.box.ping_tracer.reset()
            self.box.timeout_tracer.reset()
            self.box_cache.remove(c)
            self.__clean_cached_boxes()
        else:
            log.v('Unknown message type %d from cached-box %d' %
                  (msg.type, c.uuid))
Esempio n. 8
0
    def run(self):
        self.is_quit = False

        while not self.is_quit:
            log.v('[RM] Try connect to relay manager.')

            self.conn = RelayManagerConnection(socket.socket(socket.AF_INET, socket.SOCK_STREAM))

            try:
                self.__connect()
            except (socket.error, socket.timeout) as e:
                log.e('[RM] Send connect request to relay manager failed: %s' % str(e))
                self.conn.close()
                time.sleep(30)
                continue

            log.v('[RM] Relay manager connected.')

            self.__update_network_speed()
            self.__send_heartbeat()
            self.__send_status()

            while not self.is_quit:
                try:
                    reads, _, errors = select.select([self.conn], [], [self.conn], 1)
                    self.__update_messages()
                    self.__update_messages_udp()
                    self.__update_tracers()
                    if self.conn in reads:
                        self.__handle_conn()
                    if self.conn in errors:
                        raise socket.error('connection error in select()')
                except (socket.error, socket.timeout) as e:
                    log.e('[RM] Send HEARTBEAT or STATUS failed: %s' % str(e))
                    self.conn.close()
                    time.sleep(1)
                    break

        # Quit the connection.
        try:
            self.__send_disconnect()
            self.conn.close()
        except (socket.error, socket.timeout) as e:
            pass
Esempio n. 9
0
    def __handle_box_connection(self, c):
        msg = Message(c.recv(config.SOCKET_RECV_LEN), c)
        if not msg.is_valid:
            raise socket.error('Invalid message from box')

        if msg.type == Type.SERVER_DATA:
            c.timeout_tracer.reset()
            c.ping_tracer.reset()
            self.__handle_box_server_data(c, msg)
        elif msg.type == Type.DISCONNECT:
            socket.error('Box %d notify disconnect' % c.uuid)
        elif msg.type == Type.SERVER_ERROR:
            self.__handle_box_server_error(c, msg)
        elif msg.type == Type.PING:
            log.v('Get box %d PING message.' % c.uuid)
            c.ping_tracer.reset()
            c.append_data_to_buffer(Message.create_ping_ack_data())
        else:
            log.v('Unknown message type %d from box %d' % (msg.type, c.uuid))
Esempio n. 10
0
 def __connect(self):
     info = {
         'serverId': self.upnp.get_box_serial(),
         'serverType': 'contributed',
     }
     log.v('[RM] CONNECT TO: %s; INFO: %s' % (str(self.address), str(info)))
     # self.conn = RelayManagerConnection(socket.socket(socket.AF_INET, socket.SOCK_STREAM))
     self.conn.connect(self.address)
     self.conn.send(RelayManagerMessage.create_connect_data(info))
     log.v('[RM] After send when connecting.')
     data = self.conn.recv(config.SOCKET_RECV_LEN, magic=RelayManagerMessage.MAGIC)
     log.v('[RM] After recv when connecting.')
     if not data:
         raise socket.error('EOF')
     msg = RelayManagerMessage(data)
     if not msg.is_valid:
         raise socket.error('Invalid message')
     if msg.msg_type != RelayManagerMessage.Type.ACCEPT:
         raise socket.error('Not accepted')
Esempio n. 11
0
 def dump(self):
     log.v('>>>>>>>>>>>>>> dump tcp relay begin <<<<<<<<<<<<<<')
     log.v('Cached Box: %d' % len(self.box_cache))
     log.v('Box: %s' % str(bool(self.box)))
     if self.box:
         log.v('Box Messages to Send: %d' % len(self.box.data_queue))
     log.v('Clients: %d' % len(self.clients))
     for c in self.clients:
         log.v('Client Messages to Send: %d' % len(c.data_queue))
     log.v('>>>>>>>>>>>>>> dump tcp relay end <<<<<<<<<<<<<<')
Esempio n. 12
0
 def __notify_box_client_broken(self, uuid):
     log.v('Notify box %d that client %d has broken.' %
           (self.box.uuid, uuid))
     self.box.append_data_to_buffer(
         Message.create_client_error_data(uuid,
                                          ECode.RELAY_CLIENT_DISCONNECTED))
Esempio n. 13
0
    def __handle_connection_write(self, c):
        log.v('Handle connection writing.')

        if c is self.box:
            log.v('Handle box writing.')

            try:
                # Check box timeout without PING from relay.
                # c.timeout_tracer.reset()
                c.send()
                if c.blocked:
                    self.__close_box()
            except (socket.error, socket.timeout) as e:
                log.e('Send buffered datas to box %d failed: %s' %
                      (c.uuid, str(e)))
                self.__close_box()
        elif c in self.clients:
            log.v('Handle client writing.')

            try:
                log.v(
                    'Send data to client %d in __handle_connection_write().' %
                    c.uuid)
                c.timeout_tracer.reset()
                changed = c.send()
                if changed:
                    if c.blocked:
                        log.v('Client %d has blocked' % c.uuid)
                        self.box.append_data_to_buffer(
                            Message.create_pause_data(c.uuid))
                    else:
                        log.v('Client %d has not blocked' % c.uuid)
                        self.box.append_data_to_buffer(
                            Message.create_resume_data(c.uuid))
                else:
                    # log.v('Client %d blocked state has not changed.' % c.uuid)
                    pass
            except (socket.error, socket.timeout) as e:
                log.e('Send buffered datas to client failed: %s' % str(e))
                self.__notify_box_client_broken(c.uuid)
                self.__close_client(c)
Esempio n. 14
0
    def __handle_connection_read(self, r):
        # log.v('Handle connection reading.')

        if r is self.s:
            log.v('Handle box listener reading.')

            c, addr = r.accept()
            conn = BoxConnection(c)
            log.d('Connected by box %d, address, %s' % (conn.uuid, repr(addr)))
            if self.box:
                conn.close()
            else:
                self.box_cache.append(conn)
        elif r in self.box_cache:
            log.v('Handle cached box reading.')

            try:
                self.__handle_cached_box_connection(r)
            except (socket.error, socket.timeout) as e:
                log.e('Cached box %d connection encounter an error: %s' %
                      (r.uuid, str(e)))
                self.__close_cached_box(r)
        elif r is self.box:
            log.v('Handle box reading.')

            try:
                self.__handle_box_connection(r)
            except (socket.error, socket.timeout) as e:
                log.e('Box %d connection encounter an error: %s' %
                      (r.uuid, str(e)))
                self.__close_box()
        elif r is self.cs:
            log.v('Handle client listener reading.')

            c, addr = r.accept()
            conn = ClientConnection(c)
            log.d('Connected by client %d, address, %s' %
                  (conn.uuid, repr(addr)))
            if not self.box:
                log.d('Skip this client because no box connected !!!')
                conn.close()
                return
            self.clients.append(conn)
        elif r in self.clients:
            log.v('Handle client reading.')

            try:
                r.timeout_tracer.reset()
                self.__handle_client_connection(r)
            except (socket.error, socket.timeout) as e:
                log.e('Client %d connection enconter an error: %s.' %
                      (r.uuid, str(e)))
                self.__notify_box_client_broken(r.uuid)
                self.__close_client(r)
        elif r is self.__qs:
            log.v('Handle quit-socket reading.')

            self.__handle_quit_request(r)
        else:
            log.d('The connection does not need handle.')