def __init__(self, peers_data, torrent): # initialize the peers class with peer data recieved self.torrent = deepcopy(torrent) self.interval = peers_data['interval'] self.seeders = peers_data['seeders'] self.leechers = peers_data['leechers'] # create a peer instance for all the peers recieved self.peers_list = [] # used for AWS Cloud test if self.torrent.client_request['AWS']: self.peers_list.append(peer('34.238.166.126', 6881, torrent)) for peer_IP, peer_port in peers_data['peers']: self.peers_list.append(peer(peer_IP, peer_port, torrent)) # bitfields from all peers self.bitfield_pieces_count = dict() # selecting the top N peers / pieces self.top_n = self.torrent.client_request['max peers'] # peers logger object self.swarm_logger = torrent_logger('swarm', SWARM_LOG_FILE, DEBUG) # torrent stats logger object self.torrent_stats_logger = torrent_logger('torrent_statistics', TORRENT_STATS_LOG_FILE, DEBUG) self.torrent_stats_logger.set_console_logging() # bitfield for pieces downloaded from peers self.bitfield_pieces_downloaded = set([]) # file handler for downloading / uploading file data self.file_handler = None # minimum pieces to recieve randomly self.minimum_pieces = 10 # check if the torrent file is for seeding if torrent.client_request['seeding'] != None: # client peer only need incase of seeding torrent self.client_peer = peer(self.torrent.client_IP, self.torrent.client_port, self.torrent) self.client_peer.initialize_seeding() # swarm lock for required for updating the global state self.swarm_lock = Lock()
def __init__(self, torrent): self.torrent = torrent; # the responding tracker instance for client self.client_tracker = None # connection status of the trackers self.connection_success = 1 self.connection_failure = 2 self.connection_not_attempted = 3 # trackers loggers object self.trackers_logger = torrent_logger('trackers', TRACKER_LOG_FILE, DEBUG) # get all the trackers list of the torrent data self.trackers_list = [] self.trackers_connection_status = [] for tracker_url in torrent.torrent_metadata.trackers_url_list: # classify HTTP and UDP torrent trackers if 'http' in tracker_url[:4]: tracker = http_torrent_tracker(torrent, tracker_url) if 'udp' in tracker_url[:4]: tracker = udp_torrent_tracker(torrent, tracker_url) # append the tracker class instance self.trackers_list.append(tracker) # append the connection status self.trackers_connection_status.append(self.connection_not_attempted) self.db_connection = sqlite3.connect('instance/bittorrent_data.sqlite') self.db = self.db_connection.cursor()
def __init__(self, peer_IP, peer_port, psocket=None): if psocket is None: # initializing a peer socket for TCP communiction self.peer_sock = socket(AF_INET, SOCK_STREAM) # peer connection self.peer_connection = False else: # peer connection self.peer_connection = True # initializing using the constructor argument socket self.peer_sock = psocket self.timeout = 3 self.peer_sock.settimeout(self.timeout) # IP and port of the peer self.IP = peer_IP self.port = peer_port self.unique_id = self.IP + ' ' + str(self.port) # the maximum peer request that seeder can handle self.max_peer_requests = 50 # socket locks for synchronization self.socket_lock = Lock() # logger for peer socket self.socket_logger = torrent_logger(self.unique_id, SOCKET_LOG_FILE, DEBUG)
def __init__(self, peer_IP, peer_port, torrent, init_peer_socket=None): # peer IP, port and torrent instance self.IP = peer_IP self.port = peer_port self.torrent = deepcopy(torrent) # initialize the peer_state self.state = peer_state() # string used for idenfiying the peer self.unique_id = '(' + self.IP + ' : ' + str(self.port) + ')' # unique peer ID recieved from peer self.peer_id = None # maximum download block message length self.max_block_length = torrent.block_length # handshake flag with peer self.handshake_flag = False # bitfield representing which data file pieces peer has self.bitfield_pieces = set([]) # peer socket for communication self.peer_sock = peer_socket(self.IP, self.port, init_peer_socket) # file handler used for reading/writing the file file self.file_handler = None # peer logger object with unique ID logger_name = 'peer' + self.unique_id self.peer_logger = torrent_logger(logger_name, PEER_LOG_FILE, DEBUG) if torrent.client_request['seeding'] != None: self.peer_logger.set_console_logging() # response message handler for recieved message self.response_handler = { KEEP_ALIVE: self.recieved_keep_alive, CHOKE: self.recieved_choke, UNCHOKE: self.recieved_unchoke, INTERESTED: self.recieved_interested, UNINTERESTED: self.recieved_uninterested, HAVE: self.recieved_have, BITFIELD: self.recieved_bitfield, REQUEST: self.recieved_request, PIECE: self.recieved_piece, CANCEL: self.recieved_cancel, PORT: self.recieved_port } # keep alive timeout : 10 second self.keep_alive_timeout = 10 # keep alive timer self.keep_alive_timer = None
def __init__(self, user_arguments): # the torrent_id for the file to be downloaded self.torrent_id = user_arguments[TORRENT_ID] # extract the torrent file path torrent_file_path = user_arguments[TORRENT_FILE_PATH] # bittorrent client logger self.bittorrent_logger = torrent_logger('bittorrent', BITTORRENT_LOG_FILE, DEBUG) self.bittorrent_logger.log('Reading ' + torrent_file_path + ' file ...') # read metadata from the torrent torrent file self.torrent_info = torrent_file_reader(torrent_file_path) # decide whether the user want to download or seed the torrent self.client_request = { 'seeding': None, 'downloading': None, 'uploading rate': sys.maxsize, 'downloading rate': sys.maxsize, 'max peers': 5, 'AWS': False, 'torrent_id': self.torrent_id } self.client_request['downloading'] = user_arguments[DOWNLOAD_DIR_PATH] # make torrent class instance from torrent data extracted from torrent file self.torrent = torrent(self.torrent_info.get_data(), self.client_request) self.bittorrent_logger.log(str(self.torrent)) db_connection = sqlite3.connect('instance/bittorrent_data.sqlite') db = db_connection.cursor() torrent_file_data = self.torrent.data() db.execute( """ insert into torrent_file_data (torrent_id, tracker_list, file_name, file_size, piece_length, info_hash, num_pieces, client_peer_id) values (?, ?, ?, ?, ?, ?, ?, ?) """, (self.torrent_id, torrent_file_data['tracker_list'], torrent_file_data['file_name'], torrent_file_data['file_size'], torrent_file_data['piece_length'], torrent_file_data['info_hash'], torrent_file_data['num_pieces'], torrent_file_data['client_peer_id'])) db_connection.commit() db_connection.close()
def __init__(self, torrent, tracker_url): super().__init__(torrent) # extract the tracker hostname and tracker port number self.tracker_url, self.tracker_port = self.parse_udp_tracker_url(tracker_url) # tracker logger self.tracker_logger = torrent_logger(self.tracker_url, TRACKER_LOG_FILE, DEBUG) # connection id : initially a magic number self.connection_id = 0x41727101980 # action : initially set to connection request action self.action = 0x0 # transaction id : random id to be set by the client self.transaction_id = int(rd.randrange(0, 255))
def __init__(self, torrent, tracker_url): super().__init__(torrent) self.tracker_url = tracker_url # tracker logger self.tracker_logger = torrent_logger(self.tracker_url, TRACKER_LOG_FILE, DEBUG)
def __init__(self, torrent_file_path): # the torrent_class logger self.torrent_file_logger = torrent_logger('torrent file', TORRENT_LOG_FILE, DEBUG) try: # raw extract of the torrent file self.torrent_file_raw_extract = bencodepy.decode_from_file( torrent_file_path) # used for EXCECUTION LOGGING torrent_read_log = 'Torrent file decoded successfully ' + SUCCESS self.torrent_file_logger.log(torrent_read_log) except Exception as err: # used for EXCECUTION LOGGING torrent_read_log = 'Torrent file decoding failure ! ' + FAILURE + str( err) self.torrent_file_logger.log(torrent_read_log) sys.exit() # check if encoding scheme is given in dictionary if b'encoding' in self.torrent_file_raw_extract.keys(): self.encoding = self.torrent_file_raw_extract[b'encoding'].decode() else: self.encoding = 'UTF-8' # formatted metadata from the torrent file self.torrent_file_extract = self.extract_torrent_metadata( self.torrent_file_raw_extract) # check if there is list of trackers if 'announce-list' in self.torrent_file_extract.keys(): trackers_url_list = self.torrent_file_extract['announce-list'] else: trackers_url_list = [self.torrent_file_extract['announce']] # file name file_name = self.torrent_file_extract['info']['name'] # piece length in bytes piece_length = self.torrent_file_extract['info']['piece length'] # sha1 hash concatenation of all pieces of files pieces = self.torrent_file_extract['info']['pieces'] # info hash generated for trackers info_hash = self.generate_info_hash() # files is list of tuple of size and path in case of multifile torrent files = None # check if torrent file contains multiple paths if 'files' in self.torrent_file_extract['info'].keys(): # file information - (length, path) files_dictionary = self.torrent_file_extract['info']['files'] files = [(file_data['length'], file_data['path']) for file_data in files_dictionary] file_size = 0 for file_length, file_path in files: file_size += file_length else: # file size in bytes file_size = self.torrent_file_extract['info']['length'] # base class constructor super().__init__(trackers_url_list, file_name, file_size, piece_length, pieces, info_hash, files) # used for EXCECUTION LOGGING self.torrent_file_logger.log(self.__str__())