示例#1
0
    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()
示例#2
0
    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)
示例#4
0
    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()
示例#6
0
 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))          
示例#7
0
 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)
示例#8
0
    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__())