netsukuku/src/accept.c

298 lines
6.4 KiB
C
Raw Normal View History

2013-09-16 09:53:25 +00:00
/* 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)
2013-09-16 09:53:25 +00:00
{
/* 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;
2013-09-16 09:53:25 +00:00
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);
2013-09-16 09:53:25 +00:00
}
#endif
}
void
destroy_accept_tbl(void)
2013-09-16 09:53:25 +00:00
{
/* TODO: activate and test it !! */
#if 0
int i;
if (!accept_tbl)
2013-09-16 09:53:25 +00:00
return;
for (i = 0; i < max_connections; i++) {
2013-09-16 09:53:25 +00:00
xfree(accept_tbl[i].pid);
xfree(accept_tbl[i].closed);
xfree(accept_tbl[i].acp_t);
}
xfree(accept_tbl);
accept_tbl = 0;
2013-09-16 09:53:25 +00:00
#endif
}
void
update_accept_tbl(void)
2013-09-16 09:53:25 +00:00
{
time_t cur_t, passed_time;
int i, e, k, ee, pid_exists;
if (update_accept_tbl_mutex)
2013-09-16 09:53:25 +00:00
return;
else
update_accept_tbl_mutex = 1;
2013-09-16 09:53:25 +00:00
time(&cur_t);
for (i = 0; i < max_connections; i++) {
if (!accept_tbl[i].ip.len)
2013-09-16 09:53:25 +00:00
continue;
if (accept_tbl[i].accepts) {
for (e = 0; e < max_accepts_per_host; e++) {
if (!accept_tbl[i].acp_t[e])
2013-09-16 09:53:25 +00:00
continue;
if (accept_tbl[i].pid[e]) {
k = kill(accept_tbl[i].pid[e], 0);
pid_exists = !(k == -1 && errno == ESRCH);
2013-09-16 09:53:25 +00:00
} else
pid_exists = 0;
2013-09-16 09:53:25 +00:00
#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);
2013-09-16 09:53:25 +00:00
#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;
2013-09-16 09:53:25 +00:00
del_accept(i, &ee);
}
}
}
}
update_accept_tbl_mutex = 0;
2013-09-16 09:53:25 +00:00
}
int
find_ip_acpt(inet_prefix ip)
2013-09-16 09:53:25 +00:00
{
int i;
for (i = 0; i < max_accepts_per_host; i++) {
if (!memcmp(accept_tbl[i].ip.data, &ip.data, MAX_IP_SZ))
2013-09-16 09:53:25 +00:00
return i;
}
return -1;
}
int
find_first_free(void)
2013-09-16 09:53:25 +00:00
{
int i;
for (i = 0; i < max_connections; i++)
if (!accept_tbl[i].accepts)
2013-09-16 09:53:25 +00:00
return i;
return -1;
}
int
is_ip_acpt_free(inet_prefix ip, int *index)
2013-09-16 09:53:25 +00:00
{
int idx;
2013-09-16 09:53:25 +00:00
update_accept_tbl();
if ((idx = find_ip_acpt(ip)) == -1)
if ((idx = find_first_free()) == -1)
2013-09-16 09:53:25 +00:00
return E_TOO_MANY_CONN;
2013-09-16 09:53:25 +00:00
/*debug(DBG_NOISE, "ACPT: accept_tbl[%d].accepts: %d, max_acp: %d", idx,
accept_tbl[idx].accepts, max_accepts_per_host); */
2013-09-16 09:53:25 +00:00
if (accept_tbl[idx].accepts >= max_accepts_per_host)
2013-09-16 09:53:25 +00:00
return E_ACCEPT_TBL_FULL;
*index = idx;
2013-09-16 09:53:25 +00:00
return 0;
}
int
find_free_acp_t(int idx)
2013-09-16 09:53:25 +00:00
{
int e;
for (e = 0; e < max_accepts_per_host; e++) {
if (!accept_tbl[idx].acp_t[e])
2013-09-16 09:53:25 +00:00
return e;
}
return -1; /*This happens if the rq_tbl is full for the "rq" request */
2013-09-16 09:53:25 +00:00
}
int
new_accept(int idx, inet_prefix ip)
2013-09-16 09:53:25 +00:00
{
int cl = 0;
2013-09-16 09:53:25 +00:00
/* TODO: activate and test it !! */
#if 0
time_t cur_t;
2013-09-16 09:53:25 +00:00
time(&cur_t);
if ((cl = find_free_acp_t(idx)) == -1)
2013-09-16 09:53:25 +00:00
return -1;
accept_tbl[idx].accepts++;
accept_tbl[idx].acp_t[cl] = cur_t;
accept_tbl[idx].closed[cl] = 0;
2013-09-16 09:53:25 +00:00
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)
2013-09-16 09:53:25 +00:00
{
/* TODO: activate and test it !! */
#if 0
int err, idx, cl;
if ((err = is_ip_acpt_free(ip, &idx)))
2013-09-16 09:53:25 +00:00
return err;
if (!replace || !accept_tbl[idx].accepts) {
cl = new_accept(idx, ip);
if (cl < 0)
2013-09-16 09:53:25 +00:00
return -1;
} else
cl = 0;
2013-09-16 09:53:25 +00:00
/*This global var will be given to the thread */
2013-09-16 09:53:25 +00:00
pthread_mutex_lock(&mtx_acpt_idx);
accept_idx = idx;
2013-09-16 09:53:25 +00:00
pthread_mutex_unlock(&mtx_acpt_idx);
pthread_mutex_lock(&mtx_acpt_sidx);
accept_sidx = cl;
2013-09-16 09:53:25 +00:00
pthread_mutex_unlock(&mtx_acpt_sidx);
#endif
return 0;
}
void
del_accept(int idx, int *sidx)
2013-09-16 09:53:25 +00:00
{
#if 0
if (!accept_tbl[idx].accepts)
2013-09-16 09:53:25 +00:00
return;
if (accept_tbl[idx].acp_t[*sidx]) {
2013-09-16 09:53:25 +00:00
accept_tbl[idx].accepts--;
accept_tbl[idx].acp_t[*sidx] = 0;
accept_tbl[idx].closed[*sidx] = 0;
if (!accept_tbl[idx].accepts)
2013-09-16 09:53:25 +00:00
memset(&accept_tbl[idx].ip, '\0', sizeof(inet_prefix));
(*sidx)--;
}
#endif
}
int
close_accept(int idx, int sidx)
2013-09-16 09:53:25 +00:00
{
#if 0
if (!accept_tbl[idx].accepts)
2013-09-16 09:53:25 +00:00
return -1;
accept_tbl[idx].closed[sidx] = 1;
2013-09-16 09:53:25 +00:00
#endif
return 0;
}
void
add_accept_pid(pid_t pid, int idx, int sidx)
2013-09-16 09:53:25 +00:00
{
/* TODO: activate and test it !! */
#if 0
accept_tbl[idx].pid[sidx] = pid;
2013-09-16 09:53:25 +00:00
/* debug(DBG_NOISE, "ACPT: Added pig %d in accept_tbl[%d].pid[%d]",
accept_tbl[idx].pid[sidx], idx, sidx);
*/
#endif
}