A clone of btpd with my configuration changes.
25'ten fazla konu seçemezsiniz Konular bir harf veya rakamla başlamalı, kısa çizgiler ('-') içerebilir ve en fazla 35 karakter uzunluğunda olabilir.

196 satır
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. }