A clone of btpd with my configuration changes.
Du kannst nicht mehr als 25 Themen auswählen Themen müssen entweder mit einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.

348 Zeilen
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. }