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.

198 lignes
4.9 KiB

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