Furrent
downloader.hpp
Go to the documentation of this file.
1 #pragma once
2 
3 #include <cstdint>
4 #include <memory>
5 #include <optional>
6 
7 #include "download/bitfield.hpp"
8 #include "download/message.hpp"
9 #include "download/socket.hpp"
10 #include "peer.hpp"
11 #include "tfriend_fw.hpp"
12 #include "torrent.hpp"
13 #include "util/result.hpp"
14 
15 using namespace fur::util;
16 using namespace fur::peer;
17 using namespace fur::download::socket;
18 using namespace fur::download::message;
19 
20 namespace fur::download {
21 
23 struct Downloaded {
24  int64_t index;
25  std::vector<uint8_t> content;
26 };
27 
28 } // namespace fur::download
29 
30 namespace fur::download::downloader {
31 
32 enum class DownloaderError {
38  NoBitfield,
47 };
48 
50 
54 class Downloader {
55  public:
57  explicit Downloader(const TorrentFile& torrent, const Peer& peer);
58 
66  [[nodiscard]] Result<Downloaded, DownloaderError> try_download(const Piece&);
67 
68  private:
69  const TorrentFile& torrent;
70  const Peer& peer;
71 
75  std::optional<Socket> socket;
76 
82  bool choked = true;
85  std::optional<Bitfield> bitfield;
86 
87  public:
91  Outcome<DownloaderError> ensure_connected();
92 
93  private:
95  Outcome<DownloaderError> handshake();
96 
97  Outcome<DownloaderError> send_message(const Message& msg, timeout timeout);
100 
103  void destroy_socket();
104 
105  // Befriend this class so the unit tests are able to access private members.
106  friend TestingFriend;
107 };
108 } // namespace fur::download::downloader
message.hpp
fur::download::socket
Definition: socket.cpp:8
torrent.hpp
fur::download::downloader::DownloaderError
DownloaderError
Definition: downloader.hpp:32
fur::download::downloader::DownloaderError::DifferentInfoHash
@ DifferentInfoHash
The peer sent back a different info hash when handshaking.
fur::download::downloader
Definition: downloader.cpp:13
fur::download::downloader::DownloaderError::CorruptPiece
@ CorruptPiece
The piece was correctly downloaded but doesn't match the expected hash.
fur::download::Downloaded::index
int64_t index
Definition: downloader.hpp:24
fur::download::socket::SocketError
SocketError
Definition: socket.hpp:15
fur::util::Result
Used to handle errors without using exceptions.
Definition: result.hpp:18
fur::download::downloader::DownloaderError::NoBitfield
@ NoBitfield
The peer didn't send the bitfield as its first message.
fur::download::socket::timeout
std::chrono::steady_clock::duration timeout
Definition: socket.hpp:13
peer.hpp
fur::download::Downloaded
A downloaded piece for a torrent file.
Definition: downloader.hpp:23
fur::download::downloader::DownloaderError::MissingPiece
@ MissingPiece
The peer doesn't have the requested piece.
fur::download::downloader::Downloader
Definition: downloader.hpp:54
fur::peer::Peer
Represents a single peer as given by the tracker.
Definition: peer.hpp:19
bitfield.hpp
fur::download
Definition: bitfield.cpp:24
socket.hpp
fur::TorrentFile
Represents a parsed .torrent file.
Definition: torrent.hpp:32
fur::download::downloader::from_socket_error
DownloaderError from_socket_error(const socket::SocketError &err)
Definition: downloader.cpp:18
fur::download::downloader::DownloaderError::InvalidMessage
@ InvalidMessage
Error decoding a BitTorrent TCP protocol message.
fur::download::downloader::DownloaderError::SocketOther
@ SocketOther
The socket experienced some other, generic, error.
fur::peer
Definition: peer.cpp:15
fur::download::downloader::DownloaderError::SocketTimeout
@ SocketTimeout
The socket timed out.
fur::download::Downloaded::content
std::vector< uint8_t > content
Definition: downloader.hpp:25
fur::download::message::Message
Definition: message.hpp:46
fur::download::message
Definition: message.cpp:9
fur::Piece
Definition: torrent.hpp:75
fur::util
Definition: result.hpp:12
result.hpp