Exemple #1
0
def main(argv):
        if len(argv) != 2:
                print "Usage: %s <torrent-file>" % argv[0]
                sys.exit(1)

        inputs = []
        outputs = []
        print "~~~ Starting BitTorrent Client ~~~"
        print "----------------------------------"

        # Read & parse torrent file
        tfile = Torrent(argv[1])
        tfile.print_info()

        #My ID has to be exactly 20 characters but each ID should be random
        my_id = "-SilviaLearnsBT%05d"%random.randint(0,99999)

        # Setup tracker connection
        tracker = Tracker(tfile.tracker_url)
        tracker.connect(tfile, my_id)

        # Setup Brain, the dispatcher
        brain = Brain({ "ip": "localhost", "port": 1050, "id": my_id}, tfile, tracker)

        if brain.is_complete():
                print "Aborting. I have the entire file!"

        else:
                print "Received list of peers from tracker: %r" % tracker.peers

                brain.add_peers()
                brain.connect_all(3)
                brain.run()

                print "~~~ GROOVY! You successfully downloaded a torrent ~~~"
Exemple #2
0
def main(argv):
    if len(argv) != 2:
        print "Usage: %s <torrent-file>" % argv[0]
        sys.exit(1)

    inputs = []
    outputs = []

    tfile = Torrent(argv[1])
    tfile.print_info()

    my_id = "xxxSpicyboiiixx%20d" % random.randint(0, 99999)

    tracker = Tracker(tfile.tracker_url)
    tracker.connect(tfile, my_id)

    brain = Brain({
        "ip": "localhost",
        "port": 1050,
        "id": my_id
    }, tfile, tracker)

    if brain.is_complete():
        print "Aborting"

    else:
        print "Received list of peers: %r" % tracker.peers
        brain.add_peers()
        brain.connect_all(3)
        brain.run()

        print "Downloaded a torrent"
Exemple #3
0
class TorrentClient:
    """
    The torrent client is the local peer that holds peer-to-peer
    connactions to download and upload pieces for a given torrent. 

    Once started, the client makes periodic announce calls to the tracker
    registered in the torrent meta file. These calls results in a list of peers 
    that should be tried in order to exchange pieces.
    """
    def __init__(self, torrent: Torrent):
        self.tracker = Tracker(torrent)
        self.available_peers = asyncio.Queue()
        self.peers: List[PeerConnection] = []
        self.piece_manager: PieceManager = None
        self.abort = False

    async def start(self) -> None:
        """
        Start downloading torrent held by this client.

        The method stops when downloading gull complete or aborted.
        """
        await self.tracker.connect()
        self.peers = [
            PeerConnection(self.available_peers, self.tracker.peer_id)
            for _ in range(MAX_PEERS)
        ]
        last_announce_call = None
        interval = self.tracker.interval

        while True:
            if self.piece_manager.compete:
                logging.info("Downloading complete")
                break

            if self.abort:
                logging.info("Downloading aborted!")
                break

            current = time.time()
            if not last_announce_call or (last_announce_call + interval >
                                          current):
                try:
                    self.tracker.connect()
                except TrackerError as e:
                    logging.error(e)
                    break
                last_announce_call = current
                interval = self.tracker.interval
        self.stop()

    def _empty_queue(self) -> None:
        raise NotImplementedError

    async def stop(self) -> None:
        await self.tracker.close()
        for peer in self.peers:
            peer.stop()
        self.piece_manager.close()
Exemple #4
0
from tracker import Tracker
from torrent import Torrent
import sys

torrent = Torrent(sys.argv[1])
tracker = Tracker(torrent)
print(tracker.connect())
Exemple #5
0
def write_peerlist(tfile, filename, fake_announce):
    '''
    Zapis peerlistu.
    @param tfile Cesta k torrentu
    @param filename Cesta k suboru pre zapis peerlistu
    @param fake_announce Falosna announce URL
    @return True ak je spracovanie uspesne, inak False
    '''

    torrent = Torrent(tfile)
    if not torrent.valid:
        Log.error("AntiPirat: Nevalidny torrent subor {}".format(tfile))
        return False

    if fake_announce != None:
        Log.info(
            "AntiPirat: Kontaktujem tracker cez fake announce url (parameter -a): {}"
            .format(fake_announce))
        tracker = Tracker(fake_announce, torrent)
        if tracker.connect():
            peers = tracker.get_peerlist()
            if peers is not None:
                try:
                    Log.info("AntiPirat: Otvaram subor k zapisu peerlistu {}".
                             format(filename))
                    f = open(filename, "w")
                    for p in peers:
                        f.write("{}\n".format(p))
                    Log.info(
                        "AntiPirat: Uspesne ukonceny zapis peerlistu z trackeru {}"
                        .format(fake_announce))
                    f.close()
                except:
                    Log.error(
                        "AntiPirat: Nepodarilo sa zapisat peerlist do suboru {}"
                        .format(filename))
                    return False
            else:
                Log.error("AntiPirat: Ziskavanie peerlistu zlyhalo")
                return False
        else:
            Log.error("AntiPirat: Spojenie s trackerom zlyhalo")
            return False
        Log.info("AntiPirat: Uspesne dokonceny zapis peerlistov do suboru {}".
                 format(filename))
        return True
    else:
        trackers = torrent.http_trackers
        Log.info("AntiPirat: Pocet najdenych HTTP trackerov: {}".format(
            len(trackers)))

        try:
            Log.info("AntiPirat: Otvaram subor k zapisu peerlistu {}".format(
                filename))
            f = open(filename, "w")
        except:
            Log.error(
                "AntiPirat: Nepodarilo sa otvorit subor {}".format(filename))
            return False

        for t in trackers:
            Log.info("AntiPirat: Kontaktujem tracker {}".format(t))
            tracker = Tracker(t, torrent)
            if tracker.connect():
                peers = tracker.get_peerlist()
                if peers is not None:
                    for p in peers:
                        f.write("{}\n".format(p))
                    Log.info(
                        "AntiPirat: Uspesne ukonceny zapis peerlistu z trackeru {}"
                        .format(t))
            else:
                Log.info(
                    "AntiPirat: Preskakujem tracker, u ktoreho doslo k chybe: {}"
                    .format(t))

        f.close()
        Log.info("AntiPirat: Uspesne dokonceny zapis peerlistov do suboru {}".
                 format(filename))
        return True
Exemple #6
0
class TorrentClient:
    """
    The torrent client is the local peer that holds peer-to-peer
    connections to download and upload pieces for a given torrent.

    Once started, the client makes periodic announce calls to the tracker
    registered in the torrent meta-data. These calls result in a list of 
    peers that should be tried in order to exchange pieces.

    Each received peer is kept in a queue that a pool of PeerConnection
    objects consume. There is a fixed number of PeerConnections that can
    have a connection open to a peer. Since we are not creating expensive 
    threads (or worse yet processes) we can create them all at once and 
    they will be waiting until there is a peer to consume in the queue.
    """
    def __init__(self, torrent):
        self.tracker = Tracker(torrent)
        #The list of potential peers is the work queue, consumed by the
        #PeerConnections
        self.available_peers = Queue()
        #The list of peers is the list of workers that *might* be connected
        #to a peer. Else they are waiting to consume new remote peers from
        #the `available_peers`.
        self.peers = []
        #The piece manager implements on which pieces to request
        #as well as the logic to persist received pieces to disk
        self.piece_manager = PieceManager(torrent)
        self.abort = False

    async def start(self):
        """
        Start downloading the torrent held by this client.

        This results in connecting to the tracker to retrieve the list
        of peers to communicate with. Once the torrent is fully downloaded or
        if the downloaded is aborted this method will complete. 
        """
        self.peers = [
            PeerConnection(self.available_peers,
                           self.tracker.torrent.info_hash,
                           self.tracker.peer_id, self.piece_manager,
                           self._on_block_retrieved)
            for _ in range(MAX_PEER_CONNECTIONS)
        ]

        #The time we last made an announce call (timestamp)
        previous = None
        #Default interval between announce calls (in seconds)
        interval = 30 * 60

        while True:
            if self.piece_manager.complete:
                print('Torrent fully downloaded!')
                break
            if self.abort:
                print('Aborting download...')
                break

            current = time.time()
            #if first request
            #or default interval has not passed after prev request
            if (not previous) or (previous + interval < current):
                response = self.tracker.connect(
                    first=False if previous else True,
                    uploaded=self.piece_manager.bytes_uploaded,
                    downloaded=self.piece_manager.bytes_downloaded)
                print(response)
                if response:
                    previous = current
                    interval = response.interval
                    self._empty_queue()

                    for peer in response.peers:
                        self.available_peers.put_nowait(peer)
            else:
                await asyncio.sleep(5)
        self.stop()

    def _empty_queue(self):
        while not self.available_peers.empty():
            self.available_peers.get_nowait()

    def stop(self):
        """
        Stop the download or seeding process.
        """
        self.abort = True
        for peer in self.peers:
            peer.stop()
        self.piece_manager.close()

    def _on_block_retrieved(self, peer_id, piece_index, block_offset, data):
        """
        Callback function called by the `PeerConnection` when a block is
        retrieved from a peer.

        :param peer_id: The id of the peer the block was retrieved from
        :param piece_index: The piece index this block is a part of
        :param block_offset: The block offset within its piece
        :param data: The binary data retrieved
        """
        self.piece_manager.block_received(peer_id=peer_id,
                                          piece_index=piece_index,
                                          block_offset=block_offset,
                                          data=data)
Exemple #7
0
        data = self.meta_info[b"info"][b"pieces"]
        pieces, offset, length = [], 0, len(data)
        pieces = [data[offset:offset + 20] for offset in range(0, length, 20)]
        return pieces

    @property
    def output_file(self):
        """
        Returns the output filename that we will use to save the torrent data in
        """
        logging.info("Torrent output file: {0}".format(
            self.meta_info[b"info"][b"name"].decode("utf-8")))
        return self.meta_info[b"info"][b"name"].decode("utf-8")


if __name__ == "__main__":
    parser = argparse.ArgumentParser()
    parser.add_argument("-f",
                        "--file",
                        help="Torrent's absolute file path",
                        type=str,
                        required=True)
    args = parser.parse_args()

    t = Torrent(torrent_path=args.file)
    tr = Tracker(t)

    loop = asyncio.get_event_loop()
    r1 = loop.run_until_complete(tr.connect())
    print(r1)
Exemple #8
0
from torrent_file import TorrentFile
import argparse

if __name__ == '__main__':
    parser = argparse.ArgumentParser(description='Bittorrent client')
    parser.add_argument('--tests', action='store_true', help='Run doctests')
    parser.add_argument('--url',
                        default='http://173.230.132.32',
                        help='URL of tracker')
    parser.add_argument('--gen',
                        action='store_true',
                        help='Generate new torrent file with random data.')
    parser.add_argument('--fname',
                        metavar='filename',
                        default='myfile.torrent',
                        help='File to use for generation or reading.')
    args = parser.parse_args()
    if args.gen:
        # Generate new torrent file
        # torrent_file = torrent_file.TorrentFile(info_dict, args.fname, True)
        pass
    else:
        torrent_file = TorrentFile(args.fname)

    if args.tests:
        import doctest
        doctest.testmod()

    tracker = Tracker(torrent_file)
    tracker.connect()
Exemple #9
0
    parser.add_argument(
        '--url',
        default='http://173.230.132.32',
        help='URL of tracker'
    )
    parser.add_argument(
        '--gen',
        action='store_true',
        help='Generate new torrent file with random data.'
    )
    parser.add_argument(
        '--fname',
        metavar='filename',
        default='myfile.torrent',
        help='File to use for generation or reading.'
    )
    args = parser.parse_args()
    if args.gen:
        # Generate new torrent file
        # torrent_file = torrent_file.TorrentFile(info_dict, args.fname, True)
        pass
    else:
        torrent_file = TorrentFile(args.fname)

    if args.tests:
        import doctest
        doctest.testmod()

    tracker = Tracker(torrent_file)
    tracker.connect()
import asyncio, bencode
from torrentFile import TorrentFile
from tracker import Tracker
from client import Client
import socket

client = Client()
seedsTorrent = TorrentFile('torrents/file2.torrent')
seedsTorrent.describe()

seedsTracker = Tracker(seedsTorrent.announce)
seedsTracker.connect(seedsTorrent, client)
print()

seedsTracker.describe()

infoHash = seedsTorrent.infoHash
#byte = "BitTorrent protocol\0\0\0\0\0\0\0\0".encode()
#print(byte)
handshakeMessage = str(19).encode() + "BitTorrent protocol\x00\x00\x00\x00\x00\x00\x00\x00".encode() + infoHash + client.peerId.encode()
print(handshakeMessage)
print(len(handshakeMessage))
peers = seedsTracker.peers

for peer in peers:
	print("nmap -p {} {}".format( peer['port'], peer['ip']))

"""
tf2 = TorrentFile('torrents/file2.torrent')
tf2.describe()