Added flood control support.
This closes bug #79: Flood control, and rate limits
This commit is contained in:
parent
5454ae279a
commit
8815118fde
|
@ -128,6 +128,7 @@ libuhub_SOURCES := \
|
|||
src/core/commands.c \
|
||||
src/core/config.c \
|
||||
src/core/eventqueue.c \
|
||||
src/core/floodctl.c \
|
||||
src/core/hub.c \
|
||||
src/core/hubevent.c \
|
||||
src/core/hubio.c \
|
||||
|
|
|
@ -142,6 +142,12 @@
|
|||
#define DEF_LIMIT_MAX_SHARE 0
|
||||
#define DEF_LIMIT_MIN_SLOTS 0
|
||||
#define DEF_LIMIT_MAX_SLOTS 0
|
||||
#define DEF_FLOOD_INTERVAL 0
|
||||
#define DEF_FLOOD_CHAT 0
|
||||
#define DEF_FLOOD_CONNECT 0
|
||||
#define DEF_FLOOD_SEARCH 0
|
||||
#define DEF_FLOOD_UPDATE 0
|
||||
#define DEF_FLOOD_EXTRAS 0
|
||||
#define DEF_TLS_ENABLE 0
|
||||
#define DEF_TLS_REQUIRE 1
|
||||
#define DEF_TLS_PRIVATE_KEY ""
|
||||
|
@ -175,6 +181,11 @@
|
|||
#define DEF_MSG_USER_SLOTS_HIGH "User have too many upload slots."
|
||||
#define DEF_MSG_USER_HUB_LIMIT_LOW "User is on too few hubs."
|
||||
#define DEF_MSG_USER_HUB_LIMIT_HIGH "User is on too many hubs."
|
||||
#define DEF_MSG_FLOOD_CHAT "Chat flood detected, messages are dropped."
|
||||
#define DEF_MSG_FLOOD_CONNECT "Connect flood detected, connection refused."
|
||||
#define DEF_MSG_FLOOD_SEARCH "Search flood detected, search is stopped."
|
||||
#define DEF_MSG_FLOOD_UPDATE "Update flood detected."
|
||||
#define DEF_MSG_FLOOD_EXTRAS "Flood detected."
|
||||
#define DEF_MSG_PROTO_NO_COMMON_HASH "No common hash algorithm."
|
||||
#define DEF_MSG_PROTO_OBSOLETE_ADC0 "Your client does not support ADC/1.0."
|
||||
|
||||
|
@ -217,6 +228,14 @@ void config_defaults(struct hub_config* config)
|
|||
DEFAULT_INTEGER(limit_min_slots, DEF_LIMIT_MIN_SLOTS);
|
||||
DEFAULT_INTEGER(limit_max_slots, DEF_LIMIT_MAX_SLOTS);
|
||||
|
||||
/* Flood control */
|
||||
DEFAULT_INTEGER(flood_ctl_interval, DEF_FLOOD_INTERVAL);
|
||||
DEFAULT_INTEGER(flood_ctl_chat, DEF_FLOOD_CHAT);
|
||||
DEFAULT_INTEGER(flood_ctl_connect, DEF_FLOOD_CONNECT);
|
||||
DEFAULT_INTEGER(flood_ctl_search, DEF_FLOOD_SEARCH);
|
||||
DEFAULT_INTEGER(flood_ctl_update, DEF_FLOOD_UPDATE);
|
||||
DEFAULT_INTEGER(flood_ctl_extras, DEF_FLOOD_EXTRAS);
|
||||
|
||||
/* Status/error strings */
|
||||
DEFAULT_STRING (msg_hub_full, DEF_MSG_HUB_FULL);
|
||||
DEFAULT_STRING (msg_hub_disabled, DEF_MSG_HUB_DISABLED)
|
||||
|
@ -247,6 +266,11 @@ void config_defaults(struct hub_config* config)
|
|||
DEFAULT_STRING (msg_user_slots_high, DEF_MSG_USER_SLOTS_HIGH);
|
||||
DEFAULT_STRING (msg_user_hub_limit_low, DEF_MSG_USER_HUB_LIMIT_LOW);
|
||||
DEFAULT_STRING (msg_user_hub_limit_high, DEF_MSG_USER_HUB_LIMIT_HIGH);
|
||||
DEFAULT_STRING (msg_user_flood_chat, DEF_MSG_FLOOD_CHAT);
|
||||
DEFAULT_STRING (msg_user_flood_connect, DEF_MSG_FLOOD_CONNECT);
|
||||
DEFAULT_STRING (msg_user_flood_search, DEF_MSG_FLOOD_SEARCH);
|
||||
DEFAULT_STRING (msg_user_flood_update, DEF_MSG_FLOOD_UPDATE);
|
||||
DEFAULT_STRING (msg_user_flood_extras, DEF_MSG_FLOOD_EXTRAS);
|
||||
DEFAULT_STRING (msg_proto_no_common_hash, DEF_MSG_PROTO_NO_COMMON_HASH);
|
||||
DEFAULT_STRING (msg_proto_obsolete_adc0, DEF_MSG_PROTO_OBSOLETE_ADC0);
|
||||
|
||||
|
@ -296,6 +320,13 @@ static int apply_config(struct hub_config* config, char* key, char* data, int li
|
|||
GET_INT(limit_min_slots);
|
||||
GET_INT(limit_max_slots);
|
||||
|
||||
GET_INT(flood_ctl_interval);
|
||||
GET_INT(flood_ctl_chat);
|
||||
GET_INT(flood_ctl_connect);
|
||||
GET_INT(flood_ctl_search);
|
||||
GET_INT(flood_ctl_update);
|
||||
GET_INT(flood_ctl_extras);
|
||||
|
||||
/* Status/error strings */
|
||||
GET_STR (msg_hub_full);
|
||||
GET_STR (msg_hub_disabled);
|
||||
|
@ -326,6 +357,11 @@ static int apply_config(struct hub_config* config, char* key, char* data, int li
|
|||
GET_STR (msg_user_slots_high);
|
||||
GET_STR (msg_user_hub_limit_low);
|
||||
GET_STR (msg_user_hub_limit_high);
|
||||
GET_STR (msg_user_flood_chat);
|
||||
GET_STR (msg_user_flood_connect);
|
||||
GET_STR (msg_user_flood_search);
|
||||
GET_STR (msg_user_flood_update);
|
||||
GET_STR (msg_user_flood_extras);
|
||||
GET_STR (msg_proto_no_common_hash);
|
||||
GET_STR (msg_proto_obsolete_adc0);
|
||||
|
||||
|
@ -380,6 +416,11 @@ void free_config(struct hub_config* config)
|
|||
hub_free(config->msg_user_slots_high);
|
||||
hub_free(config->msg_user_hub_limit_low);
|
||||
hub_free(config->msg_user_hub_limit_high);
|
||||
hub_free(config->msg_user_flood_chat);
|
||||
hub_free(config->msg_user_flood_connect);
|
||||
hub_free(config->msg_user_flood_search);
|
||||
hub_free(config->msg_user_flood_update);
|
||||
hub_free(config->msg_user_flood_extras);
|
||||
hub_free(config->msg_proto_no_common_hash);
|
||||
hub_free(config->msg_proto_obsolete_adc0);
|
||||
|
||||
|
@ -462,7 +503,14 @@ void dump_config(struct hub_config* config, int ignore_defaults)
|
|||
DUMP_INT(limit_max_share, DEF_LIMIT_MAX_SHARE);
|
||||
DUMP_INT(limit_min_slots, DEF_LIMIT_MIN_SLOTS);
|
||||
DUMP_INT(limit_max_slots, DEF_LIMIT_MAX_SLOTS);
|
||||
|
||||
|
||||
DUMP_INT(flood_ctl_interval, DEF_FLOOD_INTERVAL);
|
||||
DUMP_INT(flood_ctl_chat, DEF_FLOOD_CHAT);
|
||||
DUMP_INT(flood_ctl_connect, DEF_FLOOD_CONNECT);
|
||||
DUMP_INT(flood_ctl_search, DEF_FLOOD_SEARCH);
|
||||
DUMP_INT(flood_ctl_update, DEF_FLOOD_UPDATE);
|
||||
DUMP_INT(flood_ctl_extras, DEF_FLOOD_EXTRAS);
|
||||
|
||||
/* Status/error strings */
|
||||
DUMP_STR (msg_hub_full, DEF_MSG_HUB_FULL);
|
||||
DUMP_STR (msg_hub_disabled, DEF_MSG_HUB_DISABLED);
|
||||
|
@ -493,6 +541,11 @@ void dump_config(struct hub_config* config, int ignore_defaults)
|
|||
DUMP_STR (msg_user_slots_high, DEF_MSG_USER_SLOTS_HIGH);
|
||||
DUMP_STR (msg_user_hub_limit_low, DEF_MSG_USER_HUB_LIMIT_LOW);
|
||||
DUMP_STR (msg_user_hub_limit_high, DEF_MSG_USER_HUB_LIMIT_HIGH);
|
||||
DUMP_STR (msg_user_flood_chat, DEF_MSG_FLOOD_CHAT);
|
||||
DUMP_STR (msg_user_flood_connect, DEF_MSG_FLOOD_CONNECT);
|
||||
DUMP_STR (msg_user_flood_search, DEF_MSG_FLOOD_SEARCH);
|
||||
DUMP_STR (msg_user_flood_update, DEF_MSG_FLOOD_UPDATE);
|
||||
DUMP_STR (msg_user_flood_extras, DEF_MSG_FLOOD_EXTRAS);
|
||||
DUMP_STR (msg_proto_no_common_hash, DEF_MSG_PROTO_NO_COMMON_HASH);
|
||||
DUMP_STR (msg_proto_obsolete_adc0, DEF_MSG_PROTO_OBSOLETE_ADC0);
|
||||
}
|
||||
|
|
|
@ -60,6 +60,13 @@ struct hub_config
|
|||
int limit_min_slots; /**<<< "Limit minimum number of slots open per user (0=off, default: 0)" */
|
||||
int limit_max_slots; /**<<< "Limit maximum number of slots open per user (0=off, default: 0)" */
|
||||
|
||||
int flood_ctl_interval; /**<<< "Time interval in seconds for flood control check. If 0 then all flood control is disabled. (0=off, default: 0)" */
|
||||
int flood_ctl_chat; /**<<< "Max chat messages allowed inside the time interval (0=off, default: 0)" */
|
||||
int flood_ctl_connect; /**<<< "Max connect requests allowed inside the time interval (0=off, default: 0)" */
|
||||
int flood_ctl_search; /**<<< "Max search requests allowed inside the time interval (0=off, default: 0)" */
|
||||
int flood_ctl_update; /**<<< "Max updates allowed inside the time interval (0=off, default: 0)" */
|
||||
int flood_ctl_extras; /**<<< "Max extra protocol messages allowed inside the time interval (0=off, default: 0)" */
|
||||
|
||||
/* Messages that can be sent to a user */
|
||||
char* msg_hub_full; /**<<< "hub is full" */
|
||||
char* msg_hub_disabled; /**<<< "hub is disabled" */
|
||||
|
@ -90,6 +97,11 @@ struct hub_config
|
|||
char* msg_user_slots_high; /**<<< "User have too many upload slots." */
|
||||
char* msg_user_hub_limit_low; /**<<< "User is on too few hubs." */
|
||||
char* msg_user_hub_limit_high; /**<<< "User is on too many hubs." */
|
||||
char* msg_user_flood_chat; /**<<< "Chat flood detected, messages are dropped." */
|
||||
char* msg_user_flood_connect; /**<<< "Connect flood detected, connection refused." */
|
||||
char* msg_user_flood_search; /**<<< "Search flood detected, search is stopped." */
|
||||
char* msg_user_flood_update; /**<<< "Update flood detected." */
|
||||
char* msg_user_flood_extras; /**<<< "Flood detected." */
|
||||
char* msg_proto_no_common_hash; /**<<< "No common hash algorithm." */
|
||||
char* msg_proto_obsolete_adc0; /**<<< "Client is using an obsolete ADC protocol version." */
|
||||
|
||||
|
|
|
@ -0,0 +1,55 @@
|
|||
/*
|
||||
* uhub - A tiny ADC p2p connection hub
|
||||
* Copyright (C) 2007-2010, Jan Vidar Krey
|
||||
*
|
||||
* This program 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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program 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. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "uhub.h"
|
||||
|
||||
void flood_control_reset(struct flood_control* data)
|
||||
{
|
||||
memset(data, 0, sizeof(struct flood_control));
|
||||
}
|
||||
|
||||
int flood_control_check(struct flood_control* data, size_t max_count, size_t time_delay, time_t now)
|
||||
{
|
||||
// Is flood control disabled?
|
||||
if (!time_delay || !max_count)
|
||||
return 0;
|
||||
|
||||
if (!data->time)
|
||||
{
|
||||
data->time = now;
|
||||
data->count = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((now - data->time) > time_delay)
|
||||
{
|
||||
data->time = now;
|
||||
data->count = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (data->count <= max_count)
|
||||
{
|
||||
data->count++;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* uhub - A tiny ADC p2p connection hub
|
||||
* Copyright (C) 2007-2010, Jan Vidar Krey
|
||||
*
|
||||
* This program 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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program 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. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef HAVE_UHUB_FLOOD_CTL_H
|
||||
#define HAVE_UHUB_FLOOD_CTL_H
|
||||
|
||||
struct flood_control
|
||||
{
|
||||
time_t time;
|
||||
size_t count;
|
||||
};
|
||||
|
||||
/**
|
||||
* Reset flood control statistics
|
||||
*/
|
||||
void flood_control_reset(struct flood_control*);
|
||||
|
||||
/**
|
||||
* @param ctl Flood control data structure
|
||||
* @param max_count Max count for flood control
|
||||
* @param window Time window for max_count to appear.
|
||||
* @param now The current time.
|
||||
*
|
||||
* @return 0 if flood no flood detected.
|
||||
* 1 if flood detected.
|
||||
*/
|
||||
int flood_control_check(struct flood_control* ctl, size_t max_count, size_t window, time_t now);
|
||||
|
||||
|
||||
#endif /* HAVE_UHUB_FLOOD_CTL_H */
|
||||
|
|
@ -21,6 +21,31 @@
|
|||
|
||||
struct hub_info* g_hub = 0;
|
||||
|
||||
#define CHECK_CHAT_ONLY \
|
||||
if (hub->config->chat_only && u->credentials < cred_operator) \
|
||||
break
|
||||
|
||||
#define CHECK_FLOOD(TYPE, WARN) \
|
||||
if (flood_control_check(&u->flood_ ## TYPE , hub->config->flood_ctl_ ## TYPE, hub->config->flood_ctl_interval, net_get_time())) \
|
||||
{ \
|
||||
if (WARN) \
|
||||
{ \
|
||||
hub_send_flood_warning(hub, u, hub->config->msg_user_flood_ ## TYPE); \
|
||||
} \
|
||||
break; \
|
||||
}
|
||||
|
||||
#define ROUTE_MSG \
|
||||
if (user_is_logged_in(u)) \
|
||||
{ \
|
||||
ret = route_message(hub, u, cmd); \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
ret = -1; \
|
||||
} \
|
||||
break;
|
||||
|
||||
int hub_handle_message(struct hub_info* hub, struct hub_user* u, const char* line, size_t length)
|
||||
{
|
||||
int ret = 0;
|
||||
|
@ -36,20 +61,32 @@ int hub_handle_message(struct hub_info* hub, struct hub_user* u, const char* lin
|
|||
{
|
||||
switch (cmd->cmd)
|
||||
{
|
||||
case ADC_CMD_HSUP: ret = hub_handle_support(hub, u, cmd); break;
|
||||
case ADC_CMD_HPAS: ret = hub_handle_password(hub, u, cmd); break;
|
||||
case ADC_CMD_BINF: ret = hub_handle_info(hub, u, cmd); break;
|
||||
case ADC_CMD_HSUP:
|
||||
CHECK_FLOOD(extras, 0);
|
||||
ret = hub_handle_support(hub, u, cmd);
|
||||
break;
|
||||
|
||||
case ADC_CMD_HPAS:
|
||||
CHECK_FLOOD(extras, 0);
|
||||
ret = hub_handle_password(hub, u, cmd);
|
||||
break;
|
||||
|
||||
case ADC_CMD_BINF:
|
||||
CHECK_FLOOD(update, 1);
|
||||
ret = hub_handle_info(hub, u, cmd);
|
||||
break;
|
||||
|
||||
case ADC_CMD_DINF:
|
||||
case ADC_CMD_EINF:
|
||||
case ADC_CMD_FINF:
|
||||
/* these must never be allowed for security reasons,
|
||||
so we ignore them. */
|
||||
/* these must never be allowed for security reasons, so we ignore them. */
|
||||
break;
|
||||
|
||||
case ADC_CMD_EMSG:
|
||||
case ADC_CMD_DMSG:
|
||||
case ADC_CMD_BMSG:
|
||||
case ADC_CMD_FMSG:
|
||||
CHECK_FLOOD(chat, 1);
|
||||
ret = hub_handle_chat_message(hub, u, cmd);
|
||||
break;
|
||||
|
||||
|
@ -57,26 +94,27 @@ int hub_handle_message(struct hub_info* hub, struct hub_user* u, const char* lin
|
|||
case ADC_CMD_DSCH:
|
||||
case ADC_CMD_ESCH:
|
||||
case ADC_CMD_FSCH:
|
||||
cmd->priority = -1;
|
||||
CHECK_CHAT_ONLY;
|
||||
CHECK_FLOOD(search, 1);
|
||||
ROUTE_MSG;
|
||||
|
||||
case ADC_CMD_DRES:
|
||||
cmd->priority = -1;
|
||||
CHECK_CHAT_ONLY;
|
||||
/* CHECK_FLOOD(search, 0); */
|
||||
ROUTE_MSG;
|
||||
|
||||
case ADC_CMD_DRCM:
|
||||
case ADC_CMD_DCTM:
|
||||
cmd->priority = -1;
|
||||
if (hub->config->chat_only && u->credentials < cred_operator)
|
||||
{
|
||||
/* These below aren't allowed in chat only hubs */
|
||||
break;
|
||||
}
|
||||
CHECK_CHAT_ONLY;
|
||||
CHECK_FLOOD(connect, 1);
|
||||
ROUTE_MSG;
|
||||
|
||||
default:
|
||||
if (user_is_logged_in(u))
|
||||
{
|
||||
ret = route_message(hub, u, cmd);
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = -1;
|
||||
}
|
||||
break;
|
||||
CHECK_FLOOD(extras, 1);
|
||||
ROUTE_MSG;
|
||||
}
|
||||
adc_msg_free(cmd);
|
||||
}
|
||||
|
@ -422,6 +460,28 @@ void hub_send_password_challenge(struct hub_info* hub, struct hub_user* u)
|
|||
adc_msg_free(igpa);
|
||||
}
|
||||
|
||||
void hub_send_flood_warning(struct hub_info* hub, struct hub_user* u, const char* message)
|
||||
{
|
||||
struct adc_message* msg;
|
||||
char* tmp;
|
||||
|
||||
if (user_flag_get(u, flag_flood))
|
||||
return;
|
||||
|
||||
msg = adc_msg_construct(ADC_CMD_ISTA, 128);
|
||||
if (msg)
|
||||
{
|
||||
tmp = adc_msg_escape(message);
|
||||
adc_msg_add_argument(msg, "110");
|
||||
adc_msg_add_argument(msg, tmp);
|
||||
hub_free(tmp);
|
||||
}
|
||||
|
||||
route_to_user(hub, u, msg);
|
||||
user_flag_set(u, flag_flood);
|
||||
adc_msg_free(msg);
|
||||
}
|
||||
|
||||
static void hub_event_dispatcher(void* callback_data, struct event_data* message)
|
||||
{
|
||||
struct hub_info* hub = (struct hub_info*) callback_data;
|
||||
|
|
|
@ -227,6 +227,11 @@ extern void hub_send_password_challenge(struct hub_info* hub, struct hub_user* u
|
|||
*/
|
||||
extern void hub_send_status(struct hub_info*, struct hub_user* user, enum status_message msg, enum msg_status_level level);
|
||||
|
||||
/**
|
||||
* Warn user about flooding.
|
||||
*/
|
||||
extern void hub_send_flood_warning(struct hub_info*, struct hub_user* user, const char* message);
|
||||
|
||||
/**
|
||||
* Allocates memory, initializes the hub based on the configuration,
|
||||
* and returns a hub handle.
|
||||
|
|
|
@ -54,6 +54,12 @@ struct hub_user* user_create(struct hub_info* hub, struct net_connection* con, s
|
|||
|
||||
memcpy(&user->id.addr, addr, sizeof(struct ip_addr_encap));
|
||||
user_set_state(user, state_protocol);
|
||||
|
||||
flood_control_reset(&user->flood_chat);
|
||||
flood_control_reset(&user->flood_connect);
|
||||
flood_control_reset(&user->flood_search);
|
||||
flood_control_reset(&user->flood_update);
|
||||
flood_control_reset(&user->flood_extras);
|
||||
return user;
|
||||
}
|
||||
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
|
||||
struct hub_info;
|
||||
struct hub_iobuf;
|
||||
struct flood_control;
|
||||
|
||||
enum user_state
|
||||
{
|
||||
|
@ -46,6 +47,7 @@ enum user_flags
|
|||
feature_link = 0x00000100, /** LINK: Hub link (not supported) */
|
||||
feature_adcs = 0x00000200, /** ADCS: ADC over TLS/SSL */
|
||||
feature_bas0 = 0x00000400, /** BAS0: Obsolete pre-ADC/1.0 protocol version */
|
||||
flag_flood = 0x00400000, /** User has been notified about flooding. */
|
||||
flag_muted = 0x00800000, /** User is muted (cannot chat) */
|
||||
flag_ignore = 0x01000000, /** Ignore further reads */
|
||||
flag_maxbuf = 0x02000000, /** Hit max buf read, ignore msg */
|
||||
|
@ -117,6 +119,11 @@ struct hub_user
|
|||
struct hub_user_limits limits; /** Data used for limitation */
|
||||
enum user_quit_reason quit_reason; /** Quit reason (see user_quit_reason) */
|
||||
|
||||
struct flood_control flood_chat;
|
||||
struct flood_control flood_connect;
|
||||
struct flood_control flood_search;
|
||||
struct flood_control flood_update;
|
||||
struct flood_control flood_extras;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -155,6 +155,12 @@ int net_backend_process()
|
|||
return 1;
|
||||
}
|
||||
|
||||
time_t net_get_time()
|
||||
{
|
||||
return g_backend->now;
|
||||
}
|
||||
|
||||
|
||||
void net_con_initialize(struct net_connection* con, int sd, net_connection_cb callback, const void* ptr, int events)
|
||||
{
|
||||
g_backend->handler.con_init(g_backend->data, con, sd, callback, ptr);
|
||||
|
|
|
@ -75,6 +75,11 @@ extern void net_backend_shutdown();
|
|||
*/
|
||||
extern int net_backend_process();
|
||||
|
||||
/**
|
||||
* Get the current time.
|
||||
*/
|
||||
time_t net_get_time();
|
||||
|
||||
extern struct timeout_queue* net_backend_get_timeout_queue();
|
||||
|
||||
struct net_cleanup_handler* net_cleanup_initialize(size_t max);
|
||||
|
|
|
@ -72,6 +72,7 @@ extern "C" {
|
|||
|
||||
#include "core/auth.h"
|
||||
#include "core/config.h"
|
||||
#include "core/floodctl.h"
|
||||
#include "core/eventid.h"
|
||||
#include "core/eventqueue.h"
|
||||
#include "core/netevent.h"
|
||||
|
|
Loading…
Reference in New Issue