def _decode_introduction_request(self, placeholder, offset, data): offset, payload = BinaryConversion._decode_introduction_request( self, placeholder, offset, data) #if there's still bytes in this request, treat them as taste_bloom_filter has_taste = len(data) > offset if has_taste: if len(data) < offset + 8: raise DropPacket("Insufficient packet size") num_preferences, functions, size = unpack_from( '!IBH', data, offset) offset += 7 prefix = data[offset] offset += 1 if not 0 < num_preferences: raise DropPacket("Invalid num_preferences value") if not 0 < functions: raise DropPacket("Invalid functions value") if not 0 < size: raise DropPacket("Invalid size value") if not size % 8 == 0: raise DropPacket( "Invalid size value, must be a multiple of eight") length = int(ceil(size / 8)) if not length == len(data) - offset: raise DropPacket( "Invalid number of bytes available (irq) %d, %d, %d" % (length, len(data) - offset, size)) taste_bloom_filter = BloomFilter(data[offset:offset + length], functions, prefix=prefix) offset += length payload.set_num_preferences(num_preferences) payload.set_taste_bloom_filter(taste_bloom_filter) return offset, payload
def _decode_search_response(self, placeholder, offset, data): try: offset, payload = decode(data, offset) except (ValueError, KeyError): raise DropPacket("Unable to decode the search-reponse-payload") if len(payload) < 2: raise DropPacket("Invalid payload length") identifier, results = payload[:2] if len(identifier) != 2: raise DropPacket( "Unable to decode the search-response-payload, got %d bytes expected 2" % (len(identifier))) identifier, = unpack_from('!H', identifier) if not isinstance(results, list): raise DropPacket("Invalid 'results' type") for result in results: if not isinstance(result, tuple): raise DropPacket("Invalid result type") if len(result) < 9: raise DropPacket("Invalid result length") infohash, swarmname, length, nrfiles, category_list, creation_date, seeders, leechers, cid = result[: 9] if not isinstance(infohash, str): raise DropPacket("Invalid infohash type") if len(infohash) != 20: raise DropPacket("Invalid infohash length") if not isinstance(swarmname, unicode): raise DropPacket("Invalid swarmname type") if not isinstance(length, long): raise DropPacket("Invalid length type '%s'" % type(length)) if not isinstance(nrfiles, int): raise DropPacket("Invalid nrfiles type") if not isinstance(category_list, list) or not all( isinstance(key, unicode) for key in category_list): raise DropPacket("Invalid category_list type") if not isinstance(creation_date, long): raise DropPacket("Invalid creation_date type") if not isinstance(seeders, int): raise DropPacket("Invalid seeders type '%s'" % type(seeders)) if not isinstance(leechers, int): raise DropPacket("Invalid leechers type '%s'" % type(leechers)) if cid: if not isinstance(cid, str): raise DropPacket("Invalid cid type") if len(cid) != 20: raise DropPacket("Invalid cid length") return offset, placeholder.meta.payload.implement(identifier, results)
def _decode_search_request(self, placeholder, offset, data): try: offset, payload = decode(data, offset) except ValueError: raise DropPacket("Unable to decodr 21, 2012 e the search-payload") if len(payload) < 2: raise DropPacket("Invalid payload length") identifier, keywords = payload[:2] if len(identifier) != 2: raise DropPacket( "Unable to decode the search-payload, got %d bytes expected 2" % (len(identifier))) identifier, = unpack_from('!H', identifier) if not isinstance(keywords, list): raise DropPacket("Invalid 'keywords' type") for keyword in keywords: if not isinstance(keyword, unicode): raise DropPacket("Invalid 'keyword' type") if len(payload) > 5: functions, prefix, bytes_ = payload[2:6] if not isinstance(functions, int): raise DropPacket("Invalid functions type") if not 0 < functions: raise DropPacket("Invalid functions value") size = len(bytes_) if not 0 < size: raise DropPacket("Invalid size of bloomfilter") if not size % 8 == 0: raise DropPacket( "Invalid size of bloomfilter, must be a multiple of eight") if not isinstance(prefix, str): raise DropPacket("Invalid prefix type") if not 0 <= len(prefix) < 256: raise DropPacket("Invalid prefix length") bloom_filter = BloomFilter(bytes_, functions, prefix=prefix) else: bloom_filter = None return offset, placeholder.meta.payload.implement( identifier, keywords, bloom_filter)
def _decode_modification(self, placeholder, offset, data): try: offset, dic = decode(data, offset) except ValueError: raise DropPacket("Unable to decode the payload") if not "modification-type" in dic: raise DropPacket("Missing 'modification-type'") modification_type = dic["modification-type"] if not isinstance(modification_type, unicode): raise DropPacket("Invalid 'modification_type' type") if not "modification-value" in dic: raise DropPacket("Missing 'modification-value'") modification_value = dic["modification-value"] if not (isinstance(modification_value, unicode) and len(modification_value) < 1024): raise DropPacket("Invalid 'modification_value' type or value") if not "timestamp" in dic: raise DropPacket("Missing 'timestamp'") timestamp = dic["timestamp"] if not isinstance(timestamp, (int, long)): raise DropPacket("Invalid 'timestamp' type or value") if not "modification-on-mid" in dic: raise DropPacket("Missing 'modification-on-mid'") modification_on_mid = dic["modification-on-mid"] if not (isinstance(modification_on_mid, str) and len(modification_on_mid) == 20): raise DropPacket("Invalid 'modification-on-mid' type or value") if not "modification-on-global-time" in dic: raise DropPacket("Missing 'modification-on-global-time'") modification_on_global_time = dic["modification-on-global-time"] if not isinstance(modification_on_global_time, (int, long)): raise DropPacket("Invalid 'modification-on-global-time' type") try: packet_id, packet, message_name = self._get_message( modification_on_global_time, modification_on_mid) modification_on = Packet( self._community.get_meta_message(message_name), packet, packet_id) except DropPacket: member = self._community.get_member(mid=modification_on_mid) if not member: raise DelayPacketByMissingMember(self._community, modification_on_mid) raise DelayPacketByMissingMessage(self._community, member, modification_on_global_time) prev_modification_mid = dic.get("prev-modification-mid", None) if prev_modification_mid and not ( isinstance(prev_modification_mid, str) and len(prev_modification_mid) == 20): raise DropPacket("Invalid 'prev-modification-mid' type or value") prev_modification_global_time = dic.get( "prev-modification-global-time", None) if prev_modification_global_time and not isinstance( prev_modification_global_time, (int, long)): raise DropPacket("Invalid 'prev-modification-global-time' type") try: packet_id, packet, message_name = self._get_message( prev_modification_global_time, prev_modification_mid) prev_modification_packet = Packet( self._community.get_meta_message(message_name), packet, packet_id) except: prev_modification_packet = None return offset, placeholder.meta.payload.implement( modification_type, modification_value, timestamp, modification_on, prev_modification_packet, prev_modification_mid, prev_modification_global_time)
def _decode_comment(self, placeholder, offset, data): try: offset, dic = decode(data, offset) except ValueError: raise DropPacket("Unable to decode the payload") if not "text" in dic: raise DropPacket("Missing 'text'") text = dic["text"] if not (isinstance(text, unicode) and len(text) < 1024): raise DropPacket("Invalid 'text' type or value") if not "timestamp" in dic: raise DropPacket("Missing 'timestamp'") timestamp = dic["timestamp"] if not isinstance(timestamp, (int, long)): raise DropPacket("Invalid 'timestamp' type or value") reply_to_mid = dic.get("reply-to-mid", None) if reply_to_mid and not (isinstance(reply_to_mid, str) and len(reply_to_mid) == 20): raise DropPacket("Invalid 'reply-to-mid' type or value") reply_to_global_time = dic.get("reply-to-global-time", None) if reply_to_global_time and not isinstance(reply_to_global_time, (int, long)): raise DropPacket("Invalid 'reply-to-global-time' type") reply_after_mid = dic.get("reply-after-mid", None) if reply_after_mid and not (isinstance(reply_after_mid, str) and len(reply_after_mid) == 20): raise DropPacket("Invalid 'reply-after-mid' type or value") reply_after_global_time = dic.get("reply-after-global-time", None) if reply_after_global_time and not isinstance(reply_after_global_time, (int, long)): raise DropPacket("Invalid 'reply-after-global-time' type") playlist_mid = dic.get("playlist-mid", None) if playlist_mid and not (isinstance(playlist_mid, str) and len(playlist_mid) == 20): raise DropPacket("Invalid 'playlist-mid' type or value") playlist_global_time = dic.get("playlist-global-time", None) if playlist_global_time and not isinstance(playlist_global_time, (int, long)): raise DropPacket("Invalid 'playlist-global-time' type") if playlist_mid and playlist_global_time: try: packet_id, packet, message_name = self._get_message( playlist_global_time, playlist_mid) playlist = Packet( self._community.get_meta_message(message_name), packet, packet_id) except DropPacket: member = self._community.get_member(mid=playlist_mid) if not member: raise DelayPacketByMissingMember(self._community, playlist_mid) raise DelayPacketByMissingMessage(self._community, member, playlist_global_time) else: playlist = None infohash = dic.get("infohash", None) if infohash and not (isinstance(infohash, str) and len(infohash) == 20): raise DropPacket("Invalid 'infohash' type or value") return offset, placeholder.meta.payload.implement( text, timestamp, reply_to_mid, reply_to_global_time, reply_after_mid, reply_after_global_time, playlist, infohash)
def _decode_torrent(self, placeholder, offset, data): try: uncompressed_data = zlib.decompress(data[offset:]) except zlib.error: raise DropPacket("Invalid zlib data") offset = len(data) try: _, values = decode(uncompressed_data) except ValueError: raise DropPacket("Unable to decode the torrent-payload") infohash_time, name, files, trackers = values if len(infohash_time) != 28: raise DropPacket( "Unable to decode the torrent-payload, got %d bytes expected 28" % (len(infohash_time))) infohash, timestamp = unpack_from('!20sQ', infohash_time) if not isinstance(name, unicode): raise DropPacket("Invalid 'name' type") if not isinstance(files, tuple): raise DropPacket("Invalid 'files' type") if len(files) == 0: raise DropPacket("Should have at least one file") for file in files: if len(file) != 2: raise DropPacket("Invalid 'file_len' type") path, length = file if not isinstance(path, unicode): raise DropPacket("Invalid 'files_path' type is %s" % type(path)) if not isinstance(length, (int, long)): raise DropPacket("Invalid 'files_length' type is %s" % type(length)) if not isinstance(trackers, tuple): raise DropPacket("Invalid 'trackers' type") for tracker in trackers: if not isinstance(tracker, str): raise DropPacket("Invalid 'tracker' type") return offset, placeholder.meta.payload.implement( infohash, timestamp, name, files, trackers)