Пример #1
0
 def is_stun_message(self, data):
     try:
         channel, len = struct.unpack('!HH', data[:4])
         if 0x4000 <= channel <= 0x7FFF:
             return True
         else:
             method, length, magic, tx_id = STUNMessage.parse_header(data[:20])
             return magic == STUN_MAGIC_COOKIE
     except:
         return False
Пример #2
0
 def is_stun_message(self, data):
     try:
         channel, len = struct.unpack('!HH', data[:4])
         if 0x4000 <= channel <= 0x7FFF:
             return True
         else:
             method, length, magic, tx_id = STUNMessage.parse_header(
                 data[:20])
             return magic == STUN_MAGIC_COOKIE
     except:
         return False
Пример #3
0
 def send_to(self, data, addr):
     if isinstance(addr, int):
         msg = struct.pack('!HH', addr, len(data))
         self._write(msg + data)
     elif addr in self.bindings:
         header = TURNSession._channeldata_format.pack(
             self.bindings[addr], len(data))
         self._write(header + data)
     else:
         self._write(
             STUNMessage('Send', [('XOR-PEER-ADDRESS', addr),
                                  ('DATA', data)]).to_bytes())
Пример #4
0
 def bind(self, addr):
     if addr in self.bindings or addr in [
             addr for (_, addr, _) in self._pending_bindings
     ]:
         return
     self.permit(addr)
     self.logger.info("Requesting channel bind for {}:{}".format(
         self._next_channel, addr))
     msg = STUNMessage('ChannelBind',
                       [('CHANNEL-NUMBER', self._next_channel),
                        ('XOR-PEER-ADDRESS', addr)])
     self._send(msg)
     self._pending_bindings.append(
         (msg.transaction_id, addr, self._next_channel))
     self._next_channel += 1
Пример #5
0
 def permit(self, addr):
     self.logger.info("Permitting sends from {}".format(addr))
     msg = STUNMessage('CreatePermission', [('XOR-PEER-ADDRESS', addr)])
     self._send(msg)
Пример #6
0
        """
        Write directly to the TURN relay
        :param data:
        :return:
        """
        self.writeDatagram(data, self.turn_address, self.turn_port)

    def sendto(self, data, address):
        if address in self.bindings.values():
            self._logger.debug("Sending to {} through relay".format(address))
            self._session.send_to(data, address)
        else:
            host, port = address
            self._logger.debug("Sending to {} directly".format(address))
            self.writeDatagram(data, QHostAddress(host), port)

    def handle_data(self, (host, port), data):
        self._logger.debug("{}:{}/UDP<<".format(host, port))
        if self._session and self._session.is_stun_message(data):
            self._logger.debug("Handling using turn session")
            response = STUNMessage.from_bytes(data)
            self._session.handle_response(response)
        else:
            self._logger.debug("Emitting data, len: {}".format(len(data)))
            self._data_cb((host, port), data)

    def _readyRead(self):
        while self.hasPendingDatagrams():
            data, host, port = self.readDatagram(self.pendingDatagramSize())
            self.handle_data((host.toString(), int(port)), data)
Пример #7
0
        """
        Write directly to the TURN relay
        :param data:
        :return:
        """
        self.writeDatagram(data, self.turn_address, self.turn_port)

    def sendto(self, data, address):
        if address in self.bindings.values():
            self._logger.debug("Sending to {} through relay".format(address))
            self._session.send_to(data, address)
        else:
            host, port = address
            self._logger.debug("Sending to {} directly".format(address))
            self.writeDatagram(data, QHostAddress(host), port)

    def handle_data(self, (host, port), data):
        self._logger.debug("{}:{}/UDP<<".format(host, port))
        if self._session and self._session.is_stun_message(data):
            self._logger.debug("Handling using turn session")
            response = STUNMessage.from_bytes(data)
            self._session.handle_response(response)
        else:
            self._logger.debug("Emitting data, len: {}".format(len(data)))
            self._data_cb((host, port), data)

    def _readyRead(self):
        while self.hasPendingDatagrams():
            data, host, port = self.readDatagram(self.pendingDatagramSize())
            self.handle_data((host.toString(), int(port)), data)