1 /*
2  * This file Copyright (C) 2008-2014 Mnemosyne LLC
3  *
4  * It may be used under the GNU GPL versions 2 or 3
5  * or any future license endorsed by Mnemosyne LLC.
6  *
7  */
8 
9 #pragma once
10 
11 #ifndef __TRANSMISSION__
12 #error only libtransmission should #include this header.
13 #endif
14 
15 #include "transmission.h"
16 #include "bitfield.h"
17 #include "history.h"
18 #include "quark.h"
19 
20 /**
21  * @addtogroup peers Peers
22  * @{
23  */
24 
25 struct tr_peer;
26 struct tr_swarm;
27 
28 enum
29 {
30     /* this is the maximum size of a block request.
31        most bittorrent clients will reject requests
32        larger than this size. */
33     MAX_BLOCK_SIZE = (1024 * 16)
34 };
35 
36 /**
37 ***  Peer Publish / Subscribe
38 **/
39 
40 typedef enum
41 {
42     TR_PEER_CLIENT_GOT_BLOCK,
43     TR_PEER_CLIENT_GOT_CHOKE,
44     TR_PEER_CLIENT_GOT_PIECE_DATA,
45     TR_PEER_CLIENT_GOT_ALLOWED_FAST,
46     TR_PEER_CLIENT_GOT_SUGGEST,
47     TR_PEER_CLIENT_GOT_PORT,
48     TR_PEER_CLIENT_GOT_REJ,
49     TR_PEER_CLIENT_GOT_BITFIELD,
50     TR_PEER_CLIENT_GOT_HAVE,
51     TR_PEER_CLIENT_GOT_HAVE_ALL,
52     TR_PEER_CLIENT_GOT_HAVE_NONE,
53     TR_PEER_PEER_GOT_PIECE_DATA,
54     TR_PEER_ERROR
55 }
56 PeerEventType;
57 
58 typedef struct
59 {
60     PeerEventType eventType;
61 
62     uint32_t pieceIndex; /* for GOT_BLOCK, GOT_HAVE, CANCEL, ALLOWED, SUGGEST */
63     struct tr_bitfield* bitfield; /* for GOT_BITFIELD */
64     uint32_t offset; /* for GOT_BLOCK */
65     uint32_t length; /* for GOT_BLOCK + GOT_PIECE_DATA */
66     int err; /* errno for GOT_ERROR */
67     tr_port port; /* for GOT_PORT */
68 }
69 tr_peer_event;
70 
71 extern tr_peer_event const TR_PEER_EVENT_INIT;
72 
73 typedef void (* tr_peer_callback)(struct tr_peer* peer, tr_peer_event const* event, void* client_data);
74 
75 /***
76 ****
77 ***/
78 
79 typedef void (* tr_peer_destruct_func)(struct tr_peer* peer);
80 typedef bool (* tr_peer_is_transferring_pieces_func)(struct tr_peer const* peer, uint64_t now, tr_direction direction,
81     unsigned int* Bps);
82 
83 struct tr_peer_virtual_funcs
84 {
85     tr_peer_destruct_func destruct;
86     tr_peer_is_transferring_pieces_func is_transferring_pieces;
87 };
88 
89 /**
90  * State information about a connected peer.
91  *
92  * @see struct peer_atom
93  * @see tr_peerMsgs
94  */
95 typedef struct tr_peer
96 {
97     /* whether or not we should free this peer soon.
98        NOTE: private to peer-mgr.c */
99     bool doPurge;
100 
101     /* number of bad pieces they've contributed to */
102     uint8_t strikes;
103 
104     /* how many requests the peer has made that we haven't responded to yet */
105     int pendingReqsToClient;
106 
107     /* how many requests we've made and are currently awaiting a response for */
108     int pendingReqsToPeer;
109 
110     /* Hook to private peer-mgr information */
111     struct peer_atom* atom;
112 
113     struct tr_swarm* swarm;
114 
115     /** how complete the peer's copy of the torrent is. [0.0...1.0] */
116     float progress;
117 
118     struct tr_bitfield blame;
119     struct tr_bitfield have;
120 
121     /* the client name.
122        For BitTorrent peers, this is the app name derived from the `v' string in LTEP's handshake dictionary */
123     tr_quark client;
124 
125     tr_recentHistory blocksSentToClient;
126     tr_recentHistory blocksSentToPeer;
127 
128     tr_recentHistory cancelsSentToClient;
129     tr_recentHistory cancelsSentToPeer;
130 
131     struct tr_peer_virtual_funcs const* funcs;
132 }
133 tr_peer;
134 
135 void tr_peerConstruct(struct tr_peer* peer, tr_torrent const* tor);
136 
137 void tr_peerDestruct(struct tr_peer* peer);
138 
139 /** Update the tr_peer.progress field based on the 'have' bitset. */
140 void tr_peerUpdateProgress(tr_torrent* tor, struct tr_peer*);
141 
142 bool tr_peerIsSeed(struct tr_peer const* peer);
143 
144 /***
145 ****
146 ***/
147 
148 typedef struct tr_swarm_stats
149 {
150     int activePeerCount[2];
151     int activeWebseedCount;
152     int peerCount;
153     int peerFromCount[TR_PEER_FROM__MAX];
154 }
155 tr_swarm_stats;
156 
157 extern tr_swarm_stats const TR_SWARM_STATS_INIT;
158 
159 void tr_swarmGetStats(struct tr_swarm const* swarm, tr_swarm_stats* setme);
160 
161 void tr_swarmIncrementActivePeers(struct tr_swarm* swarm, tr_direction direction, bool is_active);
162 
163 /***
164 ****
165 ***/
166 
167 #ifdef _WIN32
168 #undef EMSGSIZE
169 #define EMSGSIZE WSAEMSGSIZE
170 #endif
171 
172 /** @} */
173