A clone of btpd with my configuration changes.
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

348 lignes
6.5 KiB

  1. #include <sys/types.h>
  2. #include <sys/socket.h>
  3. #include <netinet/in.h>
  4. #include <math.h>
  5. #include <string.h>
  6. #include <unistd.h>
  7. #include "btpd.h"
  8. unsigned long
  9. peer_get_rate(unsigned long *rates)
  10. {
  11. unsigned long ret = 0;
  12. for (int i = 0; i < RATEHISTORY; i++)
  13. ret += rates[i];
  14. return ret;
  15. }
  16. void
  17. peer_kill(struct peer *p)
  18. {
  19. struct iob_link *iol;
  20. struct piece_req *req;
  21. btpd_log(BTPD_L_CONN, "killed peer.\n");
  22. if (p->flags & PF_ATTACHED)
  23. cm_on_lost_peer(p);
  24. else
  25. BTPDQ_REMOVE(&btpd.unattached, p, cm_entry);
  26. if (p->flags & PF_ON_READQ)
  27. BTPDQ_REMOVE(&btpd.readq, p, rq_entry);
  28. if (p->flags & PF_ON_WRITEQ)
  29. BTPDQ_REMOVE(&btpd.writeq, p, wq_entry);
  30. close(p->sd);
  31. event_del(&p->in_ev);
  32. event_del(&p->out_ev);
  33. iol = BTPDQ_FIRST(&p->outq);
  34. while (iol != NULL) {
  35. struct iob_link *next = BTPDQ_NEXT(iol, entry);
  36. iol->kill_buf(&iol->iob);
  37. free(iol);
  38. iol = next;
  39. }
  40. req = BTPDQ_FIRST(&p->p_reqs);
  41. while (req != NULL) {
  42. struct piece_req *next = BTPDQ_NEXT(req, entry);
  43. free(req);
  44. req = next;
  45. }
  46. req = BTPDQ_FIRST(&p->my_reqs);
  47. while (req != NULL) {
  48. struct piece_req *next = BTPDQ_NEXT(req, entry);
  49. free(req);
  50. req = next;
  51. }
  52. p->reader->kill(p->reader);
  53. if (p->piece_field != NULL)
  54. free(p->piece_field);
  55. free(p);
  56. btpd.npeers--;
  57. }
  58. void
  59. peer_request(struct peer *p, uint32_t index, uint32_t begin, uint32_t len)
  60. {
  61. p->nreqs_out++;
  62. struct piece_req *req = btpd_calloc(1, sizeof(*req));
  63. req->index = index;
  64. req->begin = begin;
  65. req->length = len;
  66. BTPDQ_INSERT_TAIL(&p->my_reqs, req, entry);
  67. net_send_request(p, req);
  68. }
  69. void
  70. peer_cancel(struct peer *p, uint32_t index, uint32_t begin, uint32_t len)
  71. {
  72. struct piece_req *req;
  73. again:
  74. req = BTPDQ_FIRST(&p->my_reqs);
  75. while (req != NULL &&
  76. !(index == req->index &&
  77. begin == req->begin &&
  78. len == req->length))
  79. req = BTPDQ_NEXT(req, entry);
  80. if (req != NULL) {
  81. net_send_cancel(p, req);
  82. BTPDQ_REMOVE(&p->my_reqs, req, entry);
  83. free(req);
  84. p->nreqs_out--;
  85. goto again;
  86. }
  87. }
  88. void
  89. peer_have(struct peer *p, uint32_t index)
  90. {
  91. net_send_have(p, index);
  92. }
  93. void
  94. peer_unchoke(struct peer *p)
  95. {
  96. p->flags &= ~PF_I_CHOKE;
  97. net_send_unchoke(p);
  98. }
  99. void
  100. peer_choke(struct peer *p)
  101. {
  102. struct piece_req *req;
  103. while ((req = BTPDQ_FIRST(&p->p_reqs)) != NULL)
  104. net_unsend_piece(p, req);
  105. p->flags |= PF_I_CHOKE;
  106. net_send_choke(p);
  107. }
  108. void
  109. peer_want(struct peer *p, uint32_t index)
  110. {
  111. assert(p->nwant < p->npieces);
  112. p->nwant++;
  113. if (p->nwant == 1) {
  114. p->flags |= PF_I_WANT;
  115. net_send_interest(p);
  116. }
  117. }
  118. void
  119. peer_unwant(struct peer *p, uint32_t index)
  120. {
  121. assert(p->nwant > 0);
  122. p->nwant--;
  123. if (p->nwant == 0) {
  124. p->flags &= ~PF_I_WANT;
  125. net_send_uninterest(p);
  126. }
  127. }
  128. static struct peer *
  129. peer_create_common(int sd)
  130. {
  131. struct peer *p = btpd_calloc(1, sizeof(*p));
  132. p->sd = sd;
  133. p->flags = PF_I_CHOKE | PF_P_CHOKE;
  134. BTPDQ_INIT(&p->p_reqs);
  135. BTPDQ_INIT(&p->my_reqs);
  136. BTPDQ_INIT(&p->outq);
  137. event_set(&p->out_ev, p->sd, EV_WRITE, net_write_cb, p);
  138. event_set(&p->in_ev, p->sd, EV_READ, net_read_cb, p);
  139. event_add(&p->in_ev, NULL);
  140. BTPDQ_INSERT_TAIL(&btpd.unattached, p, cm_entry);
  141. btpd.npeers++;
  142. return p;
  143. }
  144. void
  145. peer_create_in(int sd)
  146. {
  147. struct peer *p = peer_create_common(sd);
  148. net_handshake(p, 1);
  149. }
  150. void
  151. peer_create_out(struct torrent *tp, const uint8_t *id,
  152. const char *ip, int port)
  153. {
  154. int sd;
  155. struct peer *p;
  156. if (net_connect(ip, port, &sd) != 0)
  157. return;
  158. p = peer_create_common(sd);
  159. p->tp = tp;
  160. net_handshake(p, 0);
  161. }
  162. void
  163. peer_create_out_compact(struct torrent *tp, const char *compact)
  164. {
  165. int sd;
  166. struct peer *p;
  167. struct sockaddr_in addr;
  168. addr.sin_family = AF_INET;
  169. addr.sin_addr.s_addr = *(long *)compact;
  170. addr.sin_port = *(short *)(compact + 4);
  171. if (net_connect2((struct sockaddr *)&addr, sizeof(addr), &sd) != 0)
  172. return;
  173. p = peer_create_common(sd);
  174. p->tp = tp;
  175. net_handshake(p, 0);
  176. }
  177. void
  178. peer_on_choke(struct peer *p)
  179. {
  180. if ((p->flags & PF_P_CHOKE) != 0)
  181. return;
  182. else {
  183. p->flags |= PF_P_CHOKE;
  184. cm_on_choke(p);
  185. }
  186. }
  187. void
  188. peer_on_unchoke(struct peer *p)
  189. {
  190. if ((p->flags & PF_P_CHOKE) == 0)
  191. return;
  192. else {
  193. p->flags &= ~PF_P_CHOKE;
  194. cm_on_unchoke(p);
  195. }
  196. }
  197. void
  198. peer_on_interest(struct peer *p)
  199. {
  200. if ((p->flags & PF_P_WANT) != 0)
  201. return;
  202. else {
  203. p->flags |= PF_P_WANT;
  204. cm_on_interest(p);
  205. }
  206. }
  207. void
  208. peer_on_uninterest(struct peer *p)
  209. {
  210. if ((p->flags & PF_P_WANT) == 0)
  211. return;
  212. else {
  213. p->flags &= ~PF_P_WANT;
  214. cm_on_uninterest(p);
  215. }
  216. }
  217. void
  218. peer_on_have(struct peer *p, uint32_t index)
  219. {
  220. if (!has_bit(p->piece_field, index)) {
  221. set_bit(p->piece_field, index);
  222. p->npieces++;
  223. cm_on_piece_ann(p, index);
  224. }
  225. }
  226. void
  227. peer_on_bitfield(struct peer *p, uint8_t *field)
  228. {
  229. assert(p->npieces == 0);
  230. bcopy(field, p->piece_field, (size_t)ceil(p->tp->meta.npieces / 8.0));
  231. for (uint32_t i = 0; i < p->tp->meta.npieces; i++) {
  232. if (has_bit(p->piece_field, i)) {
  233. p->npieces++;
  234. cm_on_piece_ann(p, i);
  235. }
  236. }
  237. }
  238. void
  239. peer_on_piece(struct peer *p, uint32_t index, uint32_t begin,
  240. uint32_t length, const char *data)
  241. {
  242. struct piece_req *req = BTPDQ_FIRST(&p->my_reqs);
  243. if (req != NULL &&
  244. req->index == index &&
  245. req->begin == begin &&
  246. req->length == length) {
  247. assert(p->nreqs_out > 0);
  248. p->nreqs_out--;
  249. BTPDQ_REMOVE(&p->my_reqs, req, entry);
  250. free(req);
  251. cm_on_block(p, index, begin, length, data);
  252. }
  253. }
  254. void
  255. peer_on_request(struct peer *p, uint32_t index, uint32_t begin,
  256. uint32_t length)
  257. {
  258. off_t cbegin = index * p->tp->meta.piece_length + begin;
  259. char * content = torrent_get_bytes(p->tp, cbegin, length);
  260. net_send_piece(p, index, begin, content, length);
  261. }
  262. void
  263. peer_on_cancel(struct peer *p, uint32_t index, uint32_t begin,
  264. uint32_t length)
  265. {
  266. struct piece_req *req = BTPDQ_FIRST(&p->p_reqs);
  267. while (req != NULL) {
  268. if (req->index == index
  269. && req->begin == begin && req->length == length) {
  270. btpd_log(BTPD_L_MSG, "cancel matched.\n");
  271. net_unsend_piece(p, req);
  272. break;
  273. }
  274. req = BTPDQ_NEXT(req, entry);
  275. }
  276. }
  277. int
  278. peer_chokes(struct peer *p)
  279. {
  280. return p->flags & PF_P_CHOKE;
  281. }
  282. int
  283. peer_has(struct peer *p, uint32_t index)
  284. {
  285. return has_bit(p->piece_field, index);
  286. }
  287. int
  288. peer_laden(struct peer *p)
  289. {
  290. return p->nreqs_out >= MAXPIPEDREQUESTS;
  291. }
  292. int
  293. peer_wanted(struct peer *p)
  294. {
  295. return (p->flags & PF_I_WANT) == PF_I_WANT;
  296. }
  297. int
  298. peer_leech_ok(struct peer *p)
  299. {
  300. return (p->flags & (PF_I_WANT|PF_P_CHOKE)) == PF_I_WANT;
  301. }