You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

accept.c 6.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297
  1. /* This file is part of Netsukuku
  2. * (c) Copyright 2005 Andrea Lo Pumo aka AlpT <alpt@freaknet.org>
  3. *
  4. * This source code is free software; you can redistribute it and/or
  5. * modify it under the terms of the GNU General Public License as published
  6. * by the Free Software Foundation; either version 2 of the License,
  7. * or (at your option) any later version.
  8. *
  9. * This source code is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  12. * Please refer to the GNU Public License for more details.
  13. *
  14. * You should have received a copy of the GNU Public License along with
  15. * this source code; if not, write to:
  16. * Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  17. *
  18. * --
  19. * accept.c: This is how it works:
  20. *
  21. * When a new accept is made add_accept is called. It first updates the accept
  22. * table and then, if the accept_tbl isn't full add the new accept in the tbl.
  23. * If the accept_tbl is full the connection is dropped.
  24. * Each accept in the table last for free_accept_time after the close of that
  25. * connection, so if an host has fulled the accept_tbl has to wait
  26. * free_accept_time of seconds to be able to reconnect again.
  27. */
  28. #include "includes.h"
  29. #include "request.h"
  30. #include "inet.h"
  31. #include "accept.h"
  32. #include "xmalloc.h"
  33. #include "log.h"
  34. void
  35. init_accept_tbl(int startups, int accepts, int time)
  36. {
  37. /* TODO: activate and test it !! */
  38. #if 0
  39. int i;
  40. max_connections = startups;
  41. max_accepts_per_host = accepts;
  42. free_accept_time = time;
  43. accept_idx = accept_sidx = 0;
  44. pthread_mutex_init(&mtx_acpt_idx, NULL);
  45. pthread_mutex_init(&mtx_acpt_sidx, NULL);
  46. accept_tbl =
  47. (struct accept_table *) xmalloc(sizeof(struct accept_table) *
  48. max_connections);
  49. memset(accept_tbl, '\0',
  50. sizeof(struct accept_table) * max_connections);
  51. for (i = 0; i < max_connections; i++) {
  52. accept_tbl[i].pid =
  53. (pid_t *) xmalloc(sizeof(pid_t) * max_accepts_per_host);
  54. memset(accept_tbl[i].pid, '\0',
  55. sizeof(pid_t) * max_accepts_per_host);
  56. accept_tbl[i].closed =
  57. (unsigned char *) xmalloc(sizeof(unsigned char) *
  58. max_accepts_per_host);
  59. memset(accept_tbl[i].closed, '\0',
  60. sizeof(unsigned char) * max_accepts_per_host);
  61. accept_tbl[i].acp_t =
  62. (time_t *) xmalloc(sizeof(time_t) * max_accepts_per_host);
  63. memset(accept_tbl[i].acp_t, '\0',
  64. sizeof(time_t) * max_accepts_per_host);
  65. }
  66. #endif
  67. }
  68. void
  69. destroy_accept_tbl(void)
  70. {
  71. /* TODO: activate and test it !! */
  72. #if 0
  73. int i;
  74. if (!accept_tbl)
  75. return;
  76. for (i = 0; i < max_connections; i++) {
  77. xfree(accept_tbl[i].pid);
  78. xfree(accept_tbl[i].closed);
  79. xfree(accept_tbl[i].acp_t);
  80. }
  81. xfree(accept_tbl);
  82. accept_tbl = 0;
  83. #endif
  84. }
  85. void
  86. update_accept_tbl(void)
  87. {
  88. time_t cur_t, passed_time;
  89. int i, e, k, ee, pid_exists;
  90. if (update_accept_tbl_mutex)
  91. return;
  92. else
  93. update_accept_tbl_mutex = 1;
  94. time(&cur_t);
  95. for (i = 0; i < max_connections; i++) {
  96. if (!accept_tbl[i].ip.len)
  97. continue;
  98. if (accept_tbl[i].accepts) {
  99. for (e = 0; e < max_accepts_per_host; e++) {
  100. if (!accept_tbl[i].acp_t[e])
  101. continue;
  102. if (accept_tbl[i].pid[e]) {
  103. k = kill(accept_tbl[i].pid[e], 0);
  104. pid_exists = !(k == -1 && errno == ESRCH);
  105. } else
  106. pid_exists = 0;
  107. #if 0
  108. debug(DBG_NOISE, "ACPT: Updating tbl: cur_t: %d, "
  109. "accept_tbl[%d].acp_t[%d]:%d+%d, "
  110. "accept_tbl[i].pid[e]: %d, "
  111. "kill=%d (ESRCH=%d)",
  112. cur_t, i, e, accept_tbl[i].acp_t[e],
  113. free_accept_time, accept_tbl[i].pid[e], k, ESRCH);
  114. #endif
  115. passed_time = accept_tbl[i].acp_t[e] + free_accept_time;
  116. if ((accept_tbl[i].closed[e] || !pid_exists) &&
  117. passed_time <= cur_t) {
  118. ee = e;
  119. del_accept(i, &ee);
  120. }
  121. }
  122. }
  123. }
  124. update_accept_tbl_mutex = 0;
  125. }
  126. int
  127. find_ip_acpt(inet_prefix ip)
  128. {
  129. int i;
  130. for (i = 0; i < max_accepts_per_host; i++) {
  131. if (!memcmp(accept_tbl[i].ip.data, &ip.data, MAX_IP_SZ))
  132. return i;
  133. }
  134. return -1;
  135. }
  136. int
  137. find_first_free(void)
  138. {
  139. int i;
  140. for (i = 0; i < max_connections; i++)
  141. if (!accept_tbl[i].accepts)
  142. return i;
  143. return -1;
  144. }
  145. int
  146. is_ip_acpt_free(inet_prefix ip, int *index)
  147. {
  148. int idx;
  149. update_accept_tbl();
  150. if ((idx = find_ip_acpt(ip)) == -1)
  151. if ((idx = find_first_free()) == -1)
  152. return E_TOO_MANY_CONN;
  153. /*debug(DBG_NOISE, "ACPT: accept_tbl[%d].accepts: %d, max_acp: %d", idx,
  154. accept_tbl[idx].accepts, max_accepts_per_host); */
  155. if (accept_tbl[idx].accepts >= max_accepts_per_host)
  156. return E_ACCEPT_TBL_FULL;
  157. *index = idx;
  158. return 0;
  159. }
  160. int
  161. find_free_acp_t(int idx)
  162. {
  163. int e;
  164. for (e = 0; e < max_accepts_per_host; e++) {
  165. if (!accept_tbl[idx].acp_t[e])
  166. return e;
  167. }
  168. return -1; /*This happens if the rq_tbl is full for the "rq" request */
  169. }
  170. int
  171. new_accept(int idx, inet_prefix ip)
  172. {
  173. int cl = 0;
  174. /* TODO: activate and test it !! */
  175. #if 0
  176. time_t cur_t;
  177. time(&cur_t);
  178. if ((cl = find_free_acp_t(idx)) == -1)
  179. return -1;
  180. accept_tbl[idx].accepts++;
  181. accept_tbl[idx].acp_t[cl] = cur_t;
  182. accept_tbl[idx].closed[cl] = 0;
  183. inet_copy(&accept_tbl[idx].ip, &ip);
  184. #endif
  185. return cl;
  186. }
  187. /*
  188. * add_accept: It adds a new accept of `ip'. If `replace' is not 0 the `ip's
  189. * accepts are not incremented and accept_sidx is set to 0.
  190. */
  191. int
  192. add_accept(inet_prefix ip, int replace)
  193. {
  194. /* TODO: activate and test it !! */
  195. #if 0
  196. int err, idx, cl;
  197. if ((err = is_ip_acpt_free(ip, &idx)))
  198. return err;
  199. if (!replace || !accept_tbl[idx].accepts) {
  200. cl = new_accept(idx, ip);
  201. if (cl < 0)
  202. return -1;
  203. } else
  204. cl = 0;
  205. /*This global var will be given to the thread */
  206. pthread_mutex_lock(&mtx_acpt_idx);
  207. accept_idx = idx;
  208. pthread_mutex_unlock(&mtx_acpt_idx);
  209. pthread_mutex_lock(&mtx_acpt_sidx);
  210. accept_sidx = cl;
  211. pthread_mutex_unlock(&mtx_acpt_sidx);
  212. #endif
  213. return 0;
  214. }
  215. void
  216. del_accept(int idx, int *sidx)
  217. {
  218. #if 0
  219. if (!accept_tbl[idx].accepts)
  220. return;
  221. if (accept_tbl[idx].acp_t[*sidx]) {
  222. accept_tbl[idx].accepts--;
  223. accept_tbl[idx].acp_t[*sidx] = 0;
  224. accept_tbl[idx].closed[*sidx] = 0;
  225. if (!accept_tbl[idx].accepts)
  226. memset(&accept_tbl[idx].ip, '\0', sizeof(inet_prefix));
  227. (*sidx)--;
  228. }
  229. #endif
  230. }
  231. int
  232. close_accept(int idx, int sidx)
  233. {
  234. #if 0
  235. if (!accept_tbl[idx].accepts)
  236. return -1;
  237. accept_tbl[idx].closed[sidx] = 1;
  238. #endif
  239. return 0;
  240. }
  241. void
  242. add_accept_pid(pid_t pid, int idx, int sidx)
  243. {
  244. /* TODO: activate and test it !! */
  245. #if 0
  246. accept_tbl[idx].pid[sidx] = pid;
  247. /* debug(DBG_NOISE, "ACPT: Added pig %d in accept_tbl[%d].pid[%d]",
  248. accept_tbl[idx].pid[sidx], idx, sidx);
  249. */
  250. #endif
  251. }