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.

196 lignes
4.8 KiB

  1. #include "btpd.h"
  2. #define CHOKE_INTERVAL (& (struct timeval) { 10, 0 })
  3. static struct event m_choke_timer;
  4. static unsigned m_npeers;
  5. static struct peer_tq m_peerq = BTPDQ_HEAD_INITIALIZER(m_peerq);
  6. static int m_max_uploads;
  7. struct peer_sort {
  8. struct peer *p;
  9. unsigned i;
  10. };
  11. static int
  12. rate_cmp(const void *arg1, const void *arg2)
  13. {
  14. struct peer *p1 = ((struct peer_sort *)arg1)->p;
  15. struct peer *p2 = ((struct peer_sort *)arg2)->p;
  16. unsigned long rate1 = cm_full(p1->n->tp) ? p1->rate_up / 2: p1->rate_dwn;
  17. unsigned long rate2 = cm_full(p2->n->tp) ? p2->rate_up / 2: p2->rate_dwn;
  18. if (rate1 < rate2)
  19. return -1;
  20. else if (rate1 == rate2)
  21. return 0;
  22. else
  23. return 1;
  24. }
  25. static void
  26. choke_do(void)
  27. {
  28. if (m_max_uploads < 0) {
  29. struct peer *p;
  30. BTPDQ_FOREACH(p, &m_peerq, ul_entry)
  31. if (p->flags & PF_I_CHOKE)
  32. peer_unchoke(p);
  33. } else if (m_max_uploads == 0) {
  34. struct peer *p;
  35. BTPDQ_FOREACH(p, &m_peerq, ul_entry)
  36. if ((p->flags & PF_I_CHOKE) == 0)
  37. peer_choke(p);
  38. } else {
  39. struct peer_sort worthy[m_npeers];
  40. int nworthy = 0;
  41. int i = 0;
  42. int found = 0;
  43. struct peer *p;
  44. int unchoked[m_npeers];
  45. BTPDQ_FOREACH(p, &m_peerq, ul_entry) {
  46. int ok = 0;
  47. if (!peer_full(p)) {
  48. if (cm_full(p->n->tp)) {
  49. if (p->rate_up > 0)
  50. ok = 1;
  51. } else if (peer_active_down(p) && p->rate_dwn > 0)
  52. ok = 1;
  53. }
  54. if (ok) {
  55. worthy[nworthy].p = p;
  56. worthy[nworthy].i = i;
  57. nworthy++;
  58. }
  59. i++;
  60. }
  61. qsort(worthy, nworthy, sizeof(worthy[0]), rate_cmp);
  62. bzero(unchoked, sizeof(unchoked));
  63. for (i = nworthy - 1; i >= 0 && found < m_max_uploads - 1; i--) {
  64. if ((worthy[i].p->flags & PF_P_WANT) != 0)
  65. found++;
  66. if ((worthy[i].p->flags & PF_I_CHOKE) != 0)
  67. peer_unchoke(worthy[i].p);
  68. unchoked[worthy[i].i] = 1;
  69. }
  70. i = 0;
  71. BTPDQ_FOREACH(p, &m_peerq, ul_entry) {
  72. if (!unchoked[i]) {
  73. if (found < m_max_uploads && !peer_full(p)) {
  74. if (p->flags & PF_P_WANT)
  75. found++;
  76. if (p->flags & PF_I_CHOKE)
  77. peer_unchoke(p);
  78. } else {
  79. if ((p->flags & PF_I_CHOKE) == 0)
  80. peer_choke(p);
  81. }
  82. }
  83. i++;
  84. }
  85. }
  86. }
  87. static void
  88. shuffle_optimists(void)
  89. {
  90. for (int i = 0; i < m_npeers; i++) {
  91. struct peer *p = BTPDQ_FIRST(&m_peerq);
  92. if ((p->flags & (PF_P_WANT|PF_I_CHOKE)) == (PF_P_WANT|PF_I_CHOKE)) {
  93. break;
  94. } else {
  95. BTPDQ_REMOVE(&m_peerq, p, ul_entry);
  96. BTPDQ_INSERT_TAIL(&m_peerq, p, ul_entry);
  97. }
  98. }
  99. }
  100. static void
  101. choke_cb(int sd, short type, void *arg)
  102. {
  103. btpd_ev_add(&m_choke_timer, CHOKE_INTERVAL);
  104. static int cb_count = 0;
  105. cb_count++;
  106. if (cb_count % 3 == 0)
  107. shuffle_optimists();
  108. choke_do();
  109. }
  110. void
  111. ul_on_new_peer(struct peer *p)
  112. {
  113. long where = rand_between(-2, m_npeers);
  114. if (where < 1)
  115. BTPDQ_INSERT_HEAD(&m_peerq, p, ul_entry);
  116. else {
  117. struct peer *it = BTPDQ_FIRST(&m_peerq);
  118. where--;
  119. while (where > 0) {
  120. it = BTPDQ_NEXT(it, ul_entry);
  121. where--;
  122. }
  123. BTPDQ_INSERT_AFTER(&m_peerq, it, p, ul_entry);
  124. }
  125. m_npeers++;
  126. choke_do();
  127. }
  128. void
  129. ul_on_lost_peer(struct peer *p)
  130. {
  131. assert(m_npeers > 0);
  132. BTPDQ_REMOVE(&m_peerq, p, ul_entry);
  133. m_npeers--;
  134. if ((p->flags & (PF_P_WANT|PF_I_CHOKE)) == PF_P_WANT)
  135. choke_do();
  136. }
  137. void
  138. ul_on_lost_torrent(struct net *n)
  139. {
  140. struct peer *p;
  141. BTPDQ_FOREACH(p, &n->peers, p_entry) {
  142. BTPDQ_REMOVE(&m_peerq, p, ul_entry);
  143. m_npeers--;
  144. }
  145. choke_do();
  146. }
  147. void
  148. ul_on_interest(struct peer *p)
  149. {
  150. if ((p->flags & PF_I_CHOKE) == 0)
  151. choke_do();
  152. }
  153. void
  154. ul_on_uninterest(struct peer *p)
  155. {
  156. if ((p->flags & PF_I_CHOKE) == 0)
  157. choke_do();
  158. }
  159. void
  160. ul_init(void)
  161. {
  162. if (net_max_uploads >= -1)
  163. m_max_uploads = net_max_uploads;
  164. else {
  165. if (net_bw_limit_out == 0)
  166. m_max_uploads = 8;
  167. else if (net_bw_limit_out < (10 << 10))
  168. m_max_uploads = 2;
  169. else if (net_bw_limit_out < (20 << 10))
  170. m_max_uploads = 3;
  171. else if (net_bw_limit_out < (40 << 10))
  172. m_max_uploads = 4;
  173. else
  174. m_max_uploads = 5 + (net_bw_limit_out / (100 << 10));
  175. }
  176. evtimer_set(&m_choke_timer, choke_cb, NULL);
  177. btpd_ev_add(&m_choke_timer, CHOKE_INTERVAL);
  178. }