123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297 |
- /* This file is part of Netsukuku
- * (c) Copyright 2005 Andrea Lo Pumo aka AlpT <alpt@freaknet.org>
- *
- * This source code is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as published
- * by the Free Software Foundation; either version 2 of the License,
- * or (at your option) any later version.
- *
- * This source code is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- * Please refer to the GNU Public License for more details.
- *
- * You should have received a copy of the GNU Public License along with
- * this source code; if not, write to:
- * Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * --
- * accept.c: This is how it works:
- *
- * When a new accept is made add_accept is called. It first updates the accept
- * table and then, if the accept_tbl isn't full add the new accept in the tbl.
- * If the accept_tbl is full the connection is dropped.
- * Each accept in the table last for free_accept_time after the close of that
- * connection, so if an host has fulled the accept_tbl has to wait
- * free_accept_time of seconds to be able to reconnect again.
- */
-
- #include "includes.h"
-
- #include "request.h"
- #include "inet.h"
- #include "accept.h"
- #include "xmalloc.h"
- #include "log.h"
-
-
- void
- init_accept_tbl(int startups, int accepts, int time)
- {
- /* TODO: activate and test it !! */
- #if 0
- int i;
-
- max_connections = startups;
- max_accepts_per_host = accepts;
- free_accept_time = time;
- accept_idx = accept_sidx = 0;
- pthread_mutex_init(&mtx_acpt_idx, NULL);
- pthread_mutex_init(&mtx_acpt_sidx, NULL);
-
- accept_tbl =
- (struct accept_table *) xmalloc(sizeof(struct accept_table) *
- max_connections);
- memset(accept_tbl, '\0',
- sizeof(struct accept_table) * max_connections);
-
- for (i = 0; i < max_connections; i++) {
- accept_tbl[i].pid =
- (pid_t *) xmalloc(sizeof(pid_t) * max_accepts_per_host);
- memset(accept_tbl[i].pid, '\0',
- sizeof(pid_t) * max_accepts_per_host);
-
- accept_tbl[i].closed =
- (unsigned char *) xmalloc(sizeof(unsigned char) *
- max_accepts_per_host);
- memset(accept_tbl[i].closed, '\0',
- sizeof(unsigned char) * max_accepts_per_host);
-
- accept_tbl[i].acp_t =
- (time_t *) xmalloc(sizeof(time_t) * max_accepts_per_host);
- memset(accept_tbl[i].acp_t, '\0',
- sizeof(time_t) * max_accepts_per_host);
- }
- #endif
- }
-
- void
- destroy_accept_tbl(void)
- {
- /* TODO: activate and test it !! */
- #if 0
- int i;
-
- if (!accept_tbl)
- return;
- for (i = 0; i < max_connections; i++) {
- xfree(accept_tbl[i].pid);
- xfree(accept_tbl[i].closed);
- xfree(accept_tbl[i].acp_t);
- }
- xfree(accept_tbl);
- accept_tbl = 0;
- #endif
- }
-
-
- void
- update_accept_tbl(void)
- {
- time_t cur_t, passed_time;
- int i, e, k, ee, pid_exists;
-
- if (update_accept_tbl_mutex)
- return;
- else
- update_accept_tbl_mutex = 1;
-
- time(&cur_t);
-
- for (i = 0; i < max_connections; i++) {
- if (!accept_tbl[i].ip.len)
- continue;
- if (accept_tbl[i].accepts) {
- for (e = 0; e < max_accepts_per_host; e++) {
- if (!accept_tbl[i].acp_t[e])
- continue;
-
- if (accept_tbl[i].pid[e]) {
- k = kill(accept_tbl[i].pid[e], 0);
- pid_exists = !(k == -1 && errno == ESRCH);
- } else
- pid_exists = 0;
-
- #if 0
- debug(DBG_NOISE, "ACPT: Updating tbl: cur_t: %d, "
- "accept_tbl[%d].acp_t[%d]:%d+%d, "
- "accept_tbl[i].pid[e]: %d, "
- "kill=%d (ESRCH=%d)",
- cur_t, i, e, accept_tbl[i].acp_t[e],
- free_accept_time, accept_tbl[i].pid[e], k, ESRCH);
- #endif
-
- passed_time = accept_tbl[i].acp_t[e] + free_accept_time;
- if ((accept_tbl[i].closed[e] || !pid_exists) &&
- passed_time <= cur_t) {
- ee = e;
- del_accept(i, &ee);
- }
- }
- }
- }
- update_accept_tbl_mutex = 0;
- }
-
- int
- find_ip_acpt(inet_prefix ip)
- {
- int i;
-
- for (i = 0; i < max_accepts_per_host; i++) {
- if (!memcmp(accept_tbl[i].ip.data, &ip.data, MAX_IP_SZ))
- return i;
- }
-
- return -1;
- }
-
- int
- find_first_free(void)
- {
- int i;
-
- for (i = 0; i < max_connections; i++)
- if (!accept_tbl[i].accepts)
- return i;
- return -1;
- }
-
- int
- is_ip_acpt_free(inet_prefix ip, int *index)
- {
- int idx;
-
- update_accept_tbl();
-
- if ((idx = find_ip_acpt(ip)) == -1)
- if ((idx = find_first_free()) == -1)
- return E_TOO_MANY_CONN;
-
- /*debug(DBG_NOISE, "ACPT: accept_tbl[%d].accepts: %d, max_acp: %d", idx,
- accept_tbl[idx].accepts, max_accepts_per_host); */
-
- if (accept_tbl[idx].accepts >= max_accepts_per_host)
- return E_ACCEPT_TBL_FULL;
-
- *index = idx;
- return 0;
- }
-
- int
- find_free_acp_t(int idx)
- {
- int e;
-
- for (e = 0; e < max_accepts_per_host; e++) {
- if (!accept_tbl[idx].acp_t[e])
- return e;
- }
-
- return -1; /*This happens if the rq_tbl is full for the "rq" request */
- }
-
- int
- new_accept(int idx, inet_prefix ip)
- {
- int cl = 0;
- /* TODO: activate and test it !! */
- #if 0
- time_t cur_t;
-
- time(&cur_t);
-
- if ((cl = find_free_acp_t(idx)) == -1)
- return -1;
- accept_tbl[idx].accepts++;
- accept_tbl[idx].acp_t[cl] = cur_t;
- accept_tbl[idx].closed[cl] = 0;
- inet_copy(&accept_tbl[idx].ip, &ip);
- #endif
- return cl;
- }
-
- /*
- * add_accept: It adds a new accept of `ip'. If `replace' is not 0 the `ip's
- * accepts are not incremented and accept_sidx is set to 0.
- */
- int
- add_accept(inet_prefix ip, int replace)
- {
- /* TODO: activate and test it !! */
- #if 0
- int err, idx, cl;
-
- if ((err = is_ip_acpt_free(ip, &idx)))
- return err;
-
- if (!replace || !accept_tbl[idx].accepts) {
- cl = new_accept(idx, ip);
- if (cl < 0)
- return -1;
- } else
- cl = 0;
-
- /*This global var will be given to the thread */
- pthread_mutex_lock(&mtx_acpt_idx);
- accept_idx = idx;
- pthread_mutex_unlock(&mtx_acpt_idx);
-
- pthread_mutex_lock(&mtx_acpt_sidx);
- accept_sidx = cl;
- pthread_mutex_unlock(&mtx_acpt_sidx);
- #endif
- return 0;
- }
-
- void
- del_accept(int idx, int *sidx)
- {
- #if 0
- if (!accept_tbl[idx].accepts)
- return;
-
- if (accept_tbl[idx].acp_t[*sidx]) {
- accept_tbl[idx].accepts--;
- accept_tbl[idx].acp_t[*sidx] = 0;
- accept_tbl[idx].closed[*sidx] = 0;
- if (!accept_tbl[idx].accepts)
- memset(&accept_tbl[idx].ip, '\0', sizeof(inet_prefix));
- (*sidx)--;
- }
- #endif
- }
-
- int
- close_accept(int idx, int sidx)
- {
- #if 0
- if (!accept_tbl[idx].accepts)
- return -1;
-
- accept_tbl[idx].closed[sidx] = 1;
- #endif
- return 0;
- }
-
- void
- add_accept_pid(pid_t pid, int idx, int sidx)
- {
- /* TODO: activate and test it !! */
- #if 0
- accept_tbl[idx].pid[sidx] = pid;
- /* debug(DBG_NOISE, "ACPT: Added pig %d in accept_tbl[%d].pid[%d]",
- accept_tbl[idx].pid[sidx], idx, sidx);
- */
- #endif
- }
|