Reverting some changed related not to moving on libratbox3 but using ratbox3 source!

This commit is contained in:
Valery Yatsko 2008-04-02 19:37:50 +04:00
parent adbbdec52f
commit 54ac8b60a1
66 changed files with 3177 additions and 9512 deletions

View file

@ -46,7 +46,7 @@ CFLAGS = @CFLAGS@
# the system one.
#CFLAGS= -DNDEBUG -g -O2 -D"FD_SETSIZE=1024"
SHELL=/bin/sh
SUBDIRS=libratbox modules extensions src tools ssld doc help
SUBDIRS=libratbox modules extensions src tools servlink doc help
CLEANDIRS = ${SUBDIRS}
RSA_FILES=rsa_respond/README rsa_respond/respond.c rsa_respond/Makefile

View file

@ -1237,7 +1237,7 @@ fi
AC_CONFIG_FILES( \
Makefile \
ssld/Makefile \
servlink/Makefile \
extensions/Makefile \
unsupported/Makefile \
src/Makefile \

5823
dwr.patch

File diff suppressed because it is too large Load diff

View file

@ -126,10 +126,12 @@ mr_webirc(struct Client *client_p, struct Client *source_p, int parc, const char
else
strlcpy(source_p->host, source_p->sockhost, sizeof(source_p->host));
rb_inet_pton_sock(parv[4], (struct sockaddr *)&source_p->localClient->ip);
del_unknown_ip(source_p);
inetpton_sock(parv[4], (struct sockaddr *)&source_p->localClient->ip);
/* Check dlines now, k/glines will be checked on registration */
if((aconf = find_dline((struct sockaddr *)&source_p->localClient->ip)))
if((aconf = find_dline((struct sockaddr *)&source_p->localClient->ip,
source_p->localClient->ip.ss_family)))
{
if(!(aconf->status & CONF_EXEMPTDLINE))
{

View file

@ -43,7 +43,7 @@ struct Class
int con_freq;
int ping_freq;
int total;
rb_patricia_tree_t *ip_limits;
struct _patricia_tree_t *ip_limits;
int cidr_bitlen;
int cidr_amount;

View file

@ -233,7 +233,7 @@ struct LocalUser
conf_item_t *att_conf; /* attached conf */
struct server_conf *att_sconf;
struct rb_sockaddr_storage ip;
struct irc_sockaddr_storage ip;
time_t last_nick_change;
int number_of_nick_changes;
@ -296,10 +296,6 @@ struct LocalUser
char *mangledhost; /* non-NULL if host mangling module loaded and
applicable to this client */
struct rb_sockaddr_storage *lip; /* alloc before auth/freed after auth */
struct _ssl_ctl *ssl_ctl; /* which ssl daemon we're associate with */
rb_uint32_t localflags;
};
struct PreClient
@ -465,10 +461,6 @@ struct exit_client_hook
#define FLAGS2_EXEMPTSHIDE 0x40000000
#define FLAGS2_EXEMPTJUPE 0x80000000
/* flags for local clients, this needs stuff moved from above to here at some point */
#define LFLAGS_SSL 0x00000001
#define LFLAGS_FLUSH 0x00000002
#define DEFAULT_OPER_UMODES (UMODE_SERVNOTICE | UMODE_OPERWALL | \
UMODE_WALLOP | UMODE_LOCOPS)
#define DEFAULT_OPER_SNOMASK SNO_GENERAL
@ -511,16 +503,6 @@ struct exit_client_hook
#define ClearDynSpoof(x) ((x)->flags &= ~FLAGS_DYNSPOOF)
#define IsExUnknown(x) ((x)->flags & FLAGS_EXUNKNOWN)
#define SetExUnknown(x) ((x)->flags |= FLAGS_EXUNKNOWN)
/* local flags */
#define IsSSL(x) ((x)->localClient->localflags & LFLAGS_SSL)
#define SetSSL(x) ((x)->localClient->localflags |= LFLAGS_SSL)
#define ClearSSL(x) ((x)->localClient->localflags &= ~LFLAGS_SSL)
#define IsFlush(x) ((x)->localClient->localflags & LFLAGS_FLUSH)
#define SetFlush(x) ((x)->localClient->localflags |= LFLAGS_FLUSH)
#define ClearFlush(x) ((x)->localClient->localflags &= ~LFLAGS_FLUSH)
/* oper flags */
#define MyOper(x) (MyConnect(x) && IsOper(x))
@ -627,7 +609,6 @@ extern void close_connection(struct Client *);
extern void init_uid(void);
extern char *generate_uid(void);
void flood_endgrace(struct Client *);
void allocate_away(struct Client *);
void free_away(struct Client *);

View file

@ -65,7 +65,4 @@
/* Right out of the RFC */
#define IRCD_BUFSIZE 512
/* readbuf size */
#define READBUF_SIZE 16384
#endif /* INCLUDED_common_h */

View file

@ -45,9 +45,6 @@ extern struct Dictionary *nd_dict;
#define U_MAX_BITS 17
#define U_MAX 131072 /* 2^17 */
/* Client fd hash table size, used in hash.c */
#define CLI_FD_MAX 4096
/* Channel hash table size, hash.c/s_debug.c */
#define CH_MAX_BITS 16
#define CH_MAX 65536 /* 2^16 */
@ -101,10 +98,6 @@ extern void del_from_resv_hash(const char *name, struct ConfItem *aconf);
extern struct ConfItem *hash_find_resv(const char *name);
extern void clear_resv_hash(void);
void add_to_cli_fd_hash(struct Client *client_p);
void del_from_cli_fd_hash(struct Client *client_p);
struct Client *find_cli_fd_hash(int fd);
extern void hash_stats(struct Client *);
#endif /* INCLUDED_hash_h */

View file

@ -51,6 +51,8 @@ struct ConfItem *find_address_conf(const char *host, const char *sockhost,
const char *, const char *, struct sockaddr *,
int);
struct ConfItem *find_dline(struct sockaddr *, int);
#define find_kline(x) (find_conf_by_address((x)->host, (x)->sockhost, \
(x)->orighost, \
(struct sockaddr *)&(x)->localClient->ip, CONF_KILL,\
@ -83,7 +85,7 @@ struct AddressRec
struct
{
/* Pointer into ConfItem... -A1kmm */
struct rb_sockaddr_storage addr;
struct irc_sockaddr_storage addr;
int bits;
}
ipa;

View file

@ -99,6 +99,12 @@ size_t strlcpy(char *dst, const char *src, size_t siz);
size_t strlcat(char *dst, const char *src, size_t siz);
#endif
#ifdef HAVE_STRNDUP
#define DupNString(x, y, len) do { x = strndup(y, len); if(x == NULL) outofmemory(); } while (0)
#else
#define DupNString(x, y, len) do { x = malloc(len+1); if(x == NULL) outofmemory(); strlcpy(x, y, len+1); } while(0)
#endif
/*
* clean_string - cleanup control and high ascii characters
* -Dianora

View file

@ -109,7 +109,4 @@ extern int testing_conf;
extern struct ev_entry *check_splitmode_ev;
extern int maxconnections;
extern int ssl_ok;
#endif

View file

@ -152,6 +152,17 @@
#endif
#endif /* #ifdef IPV6 */
#ifdef IPV6
#define irc_sockaddr_storage sockaddr_storage
#else
#define irc_sockaddr_storage sockaddr
#define ss_family sa_family
#ifdef SOCKADDR_IN_HAS_LEN
#define ss_len sa_len
#endif
#endif
#ifdef IPV6
#define PATRICIA_BITS 128
#else

View file

@ -27,25 +27,28 @@
#ifndef INCLUDED_listener_h
#define INCLUDED_listener_h
struct Client;
struct Listener
{
rb_dlink_node node;
const char *name; /* listener name */
rb_fde_t *F; /* file descriptor */
int ref_count; /* number of connection references */
int active; /* current state of listener */
int ssl; /* ssl listener */
struct rb_sockaddr_storage addr;
char vhost[HOSTLEN + 1]; /* virtual name of listener */
};
void add_listener(int port, const char *vaddr_ip, int family, int ssl);
void close_listener(struct Listener *listener);
void close_listeners(void);
const char *get_listener_name(struct Listener *listener);
void show_ports(struct Client *client);
void free_listener(struct Listener *);
#include "ircd_defs.h"
struct Client;
struct Listener
{
struct Listener *next; /* list node pointer */
const char *name; /* listener name */
int fd; /* file descriptor */
int ref_count; /* number of connection references */
int active; /* current state of listener */
int index; /* index into poll array */
struct irc_sockaddr_storage addr;
struct DNSQuery *dns_query;
char vhost[HOSTLEN + 1]; /* virtual name of listener */
};
extern void add_listener(int port, const char *vaddr_ip, int family);
extern void close_listener(struct Listener *listener);
extern void close_listeners(void);
extern const char *get_listener_name(const struct Listener *listener);
extern void show_ports(struct Client *client);
extern void free_listener(struct Listener *);
#endif /* INCLUDED_listener_h */

View file

@ -46,8 +46,9 @@
#define MAX_FLOOD 5
#define MAX_FLOOD_BURST MAX_FLOOD * 8
extern PF read_ctrl_packet;
extern PF read_packet;
extern EVH flood_recalc;
extern PF read_ctrl_packet;
extern PF read_packet;
extern PF flood_recalc;
extern void flood_endgrace(struct Client *);
#endif /* INCLUDED_packet_h */

View file

@ -1,56 +1,45 @@
/*
* ircd-ratbox: A slightly useful ircd
* reject.h: header to a file which rejects users with prejudice
*
* Copyright (C) 2003 Aaron Sethman <androsyn@ratbox.org>
* Copyright (C) 2003-2005 ircd-ratbox development team
*
* 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 2 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, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
* USA
*
*
* $Id: reject.h 25056 2008-02-06 20:47:40Z androsyn $
*/
#ifndef INCLUDED_reject_h
#define INCLUDED_reject_h
/* amount of time to delay a rejected clients exit */
#define DELAYED_EXIT_TIME 10
void init_reject(void);
int check_reject(rb_fde_t *F, struct sockaddr *addr);
void add_reject(struct Client *);
void flush_reject(void);
int remove_reject(const char *ip);
struct ConfItem *find_dline(struct sockaddr *addr);
struct ConfItem *find_dline_exact(struct sockaddr *addr, unsigned int bitlen);
void remove_dline(struct ConfItem *aconf);
int add_dline(struct ConfItem *aconf);
int add_eline(struct ConfItem *aconf);
void report_dlines(struct Client *);
void report_tdlines(struct Client *);
void report_elines(struct Client *);
unsigned long delay_exit_length(void);
int throttle_add(struct sockaddr *addr);
int inc_global_cidr_count(struct Client *client_p);
void dec_global_cidr_count(struct Client *client_p);
int check_global_cidr_count(struct Client *client_p);
void rehash_global_cidr_tree(void);
#endif
/*
* ircd-ratbox: A slightly useful ircd
* reject.h: header to a file which rejects users with prejudice
*
* Copyright (C) 2003 Aaron Sethman <androsyn@ratbox.org>
* Copyright (C) 2003-2004 ircd-ratbox development team
*
* 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 2 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, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA
*
*
* $Id: reject.h 3446 2007-05-14 22:21:16Z jilles $
*/
#ifndef INCLUDED_reject_h
#define INCLUDED_reject_h
/* amount of time to delay a rejected clients exit */
#define DELAYED_EXIT_TIME 10
extern rb_dlink_list delay_exit;
void init_reject(void);
int check_reject(struct Client *);
void add_reject(struct Client *, const char *mask1, const char *mask2);
void flush_reject(void);
int remove_reject_ip(const char *ip);
int remove_reject_mask(const char *mask1, const char *mask2);
int add_unknown_ip(struct Client *client_p);
void del_unknown_ip(struct Client *client_p);
#endif

View file

@ -23,7 +23,7 @@
struct DNSReply
{
char *h_name;
struct rb_sockaddr_storage addr;
struct irc_sockaddr_storage addr;
};
struct DNSQuery
@ -32,14 +32,14 @@ struct DNSQuery
void (*callback)(void* vptr, struct DNSReply *reply); /* callback to call */
};
extern struct rb_sockaddr_storage irc_nsaddr_list[];
extern struct irc_sockaddr_storage irc_nsaddr_list[];
extern int irc_nscount;
extern void init_resolver(void);
extern void restart_resolver(void);
extern void delete_resolver_queries(const struct DNSQuery *);
extern void gethost_byname_type(const char *, struct DNSQuery *, int);
extern void gethost_byaddr(const struct rb_sockaddr_storage *, struct DNSQuery *);
extern void gethost_byaddr(const struct irc_sockaddr_storage *, struct DNSQuery *);
extern void add_local_domain(char *, size_t);
extern void report_dns_servers(struct Client *);

View file

@ -46,7 +46,7 @@ struct hostent;
struct ip_value
{
struct rb_sockaddr_storage ip;
struct irc_sockaddr_storage ip;
int ip_mask;
int type;
};
@ -54,26 +54,22 @@ struct ip_value
extern FILE *conf_fbfile_in;
extern char conf_line_in[256];
struct ConfItem
{
unsigned int status; /* If CONF_ILLEGAL, delete when no clients */
unsigned int flags;
int clients; /* Number of *LOCAL* clients using this */
union
{
char *name; /* IRC name, nick, server name, or original u@h */
const char *oper;
} info;
char *host; /* host part of user@host */
char *passwd; /* doubles as kline reason *ugh* */
char *spasswd; /* Password to send. */
char *user; /* user part of user@host */
int port;
time_t hold; /* Hold action until this time (calendar time) */
struct Class *c_class; /* Class of connection */
rb_patricia_node_t *pnode;
struct ConfItem
{
struct ConfItem *next; /* list node pointer */
unsigned int status; /* If CONF_ILLEGAL, delete when no clients */
unsigned int flags;
int clients; /* Number of *LOCAL* clients using this */
char *name; /* IRC name, nick, server name, or original u@h */
char *host; /* host part of user@host */
char *passwd; /* doubles as kline reason *ugh* */
char *spasswd; /* Password to send. */
char *user; /* user part of user@host */
int port;
time_t hold; /* Hold action until this time (calendar time) */
char *className; /* Name of class */
struct Class *c_class; /* Class of connection */
rb_patricia_node_t *pnode; /* Our patricia node */
};
#define CONF_ILLEGAL 0x80000000
@ -341,8 +337,8 @@ extern struct ConfItem *find_tkline(const char *, const char *, struct sockaddr
extern char *show_iline_prefix(struct Client *, struct ConfItem *, char *);
extern void get_printable_conf(struct ConfItem *,
char **, char **, char **, char **, int *, char **);
void get_printable_kline(struct Client *, struct ConfItem *,
const char **, const char **, const char **, const char **);
extern void get_printable_kline(struct Client *, struct ConfItem *,
char **, char **, char **, char **);
extern void yyerror(const char *);
extern int conf_yy_fatal_error(const char *);

View file

@ -203,7 +203,7 @@ struct server_conf
time_t hold;
int aftype;
struct rb_sockaddr_storage my_ipnum;
struct irc_sockaddr_storage my_ipnum;
char *class_name;
struct Class *class;

View file

@ -47,15 +47,15 @@ struct ServerStatistics
unsigned int is_cl; /* number of client connections */
unsigned int is_sv; /* number of server connections */
unsigned int is_ni; /* connection but no idea who it was */
unsigned long long int is_cbs; /* bytes sent to clients */
unsigned long long int is_cbr; /* bytes received to clients */
unsigned long long int is_sbs; /* bytes sent to servers */
unsigned long long int is_sbr; /* bytes received to servers */
unsigned short is_cbs; /* bytes sent to clients */
unsigned short is_cbr; /* bytes received to clients */
unsigned short is_sbs; /* bytes sent to servers */
unsigned short is_sbr; /* bytes received to servers */
unsigned long is_cks; /* k-bytes sent to clients */
unsigned long is_ckr; /* k-bytes received to clients */
unsigned long is_sks; /* k-bytes sent to servers */
unsigned long is_skr; /* k-bytes received to servers */
time_t is_cti; /* time spent connected by clients */
time_t is_cti; /* time spent connected by clients */
time_t is_sti; /* time spent connected by servers */
unsigned int is_ac; /* connections accepted */
unsigned int is_ref; /* accepts refused */
@ -74,7 +74,10 @@ struct ServerStatistics
unsigned int is_tgch; /* messages blocked due to target change */
};
extern struct ServerStatistics ServerStats;
extern struct ServerStatistics *ServerStats;
extern void init_stats(void);
extern void tstats(struct Client *client);
extern void count_memory(struct Client *);

View file

@ -1,40 +0,0 @@
/*
* sslproc.h: An interface to the ratbox ssld helper daemon
* Copyright (C) 2007 Aaron Sethman <androsyn@ratbox.org>
* Copyright (C) 2007 ircd-ratbox development team
*
* 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 2 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, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
* USA
*
* $Id: sslproc.h 25179 2008-03-30 16:34:57Z androsyn $
*/
#ifndef INCLUDED_sslproc_h
#define INCLUDED_sslproc_h
struct _ssl_ctl;
typedef struct _ssl_ctl ssl_ctl_t;
void init_ssld(void);
int start_ssldaemon(int count, const char *ssl_cert, const char *ssl_private_key, const char *ssl_dh_params);
ssl_ctl_t *start_ssld_accept(rb_fde_t *sslF, rb_fde_t *plainF, int id);
ssl_ctl_t *start_ssld_connect(rb_fde_t *sslF, rb_fde_t *plainF, int id);
void start_zlib_session(void *data);
void send_new_ssl_certs(const char *ssl_cert, const char *ssl_private_key, const char *ssl_dh_params);
void ssld_decrement_clicount(ssl_ctl_t *ctl);
int get_ssld_count(void);
#endif

View file

@ -612,6 +612,7 @@ add_target(struct Client *source_p, struct Client *target_p)
/* cant clear any, full target list */
else if(USED_TARGETS(source_p) == 10)
{
ServerStats->is_tgch++;
add_tgchange(source_p->sockhost);
return 0;
}

View file

@ -281,7 +281,7 @@ mc_nick(struct Client *client_p, struct Client *source_p, int parc, const char *
/* if nicks erroneous, or too long, kill */
if(!clean_nick(parv[1], 0))
{
ServerStats.is_kill++;
ServerStats->is_kill++;
sendto_realops_snomask(SNO_DEBUG, L_ALL,
"Bad Nick: %s From: %s(via %s)",
parv[1], source_p->servptr->name, client_p->name);
@ -343,7 +343,7 @@ ms_nick(struct Client *client_p, struct Client *source_p, int parc, const char *
/* if nicks empty, erroneous, or too long, kill */
if(!clean_nick(parv[1], 0))
{
ServerStats.is_kill++;
ServerStats->is_kill++;
sendto_realops_snomask(SNO_DEBUG, L_ALL,
"Bad Nick: %s From: %s(via %s)",
parv[1], parv[7], client_p->name);
@ -354,7 +354,7 @@ ms_nick(struct Client *client_p, struct Client *source_p, int parc, const char *
/* invalid username or host? */
if(!clean_username(parv[5]) || !clean_host(parv[6]))
{
ServerStats.is_kill++;
ServerStats->is_kill++;
sendto_realops_snomask(SNO_DEBUG, L_ALL,
"Bad user@host: %s@%s From: %s(via %s)",
parv[5], parv[6], parv[7], client_p->name);
@ -435,7 +435,7 @@ ms_uid(struct Client *client_p, struct Client *source_p, int parc, const char *p
/* if nicks erroneous, or too long, kill */
if(!clean_nick(parv[1], 0))
{
ServerStats.is_kill++;
ServerStats->is_kill++;
sendto_realops_snomask(SNO_DEBUG, L_ALL,
"Bad Nick: %s From: %s(via %s)",
parv[1], source_p->name, client_p->name);
@ -445,7 +445,7 @@ ms_uid(struct Client *client_p, struct Client *source_p, int parc, const char *p
if(!clean_username(parv[5]) || !clean_host(parv[6]))
{
ServerStats.is_kill++;
ServerStats->is_kill++;
sendto_realops_snomask(SNO_DEBUG, L_ALL,
"Bad user@host: %s@%s From: %s(via %s)",
parv[5], parv[6], source_p->name, client_p->name);
@ -455,7 +455,7 @@ ms_uid(struct Client *client_p, struct Client *source_p, int parc, const char *p
if(!clean_uid(parv[8]))
{
ServerStats.is_kill++;
ServerStats->is_kill++;
sendto_realops_snomask(SNO_DEBUG, L_ALL,
"Bad UID: %s From: %s(via %s)",
parv[8], source_p->name, client_p->name);
@ -527,7 +527,7 @@ ms_euid(struct Client *client_p, struct Client *source_p, int parc, const char *
/* if nicks erroneous, or too long, kill */
if(!clean_nick(parv[1], 0))
{
ServerStats.is_kill++;
ServerStats->is_kill++;
sendto_realops_snomask(SNO_DEBUG, L_ALL,
"Bad Nick: %s From: %s(via %s)",
parv[1], source_p->name, client_p->name);
@ -537,7 +537,7 @@ ms_euid(struct Client *client_p, struct Client *source_p, int parc, const char *
if(!clean_username(parv[5]) || !clean_host(parv[6]))
{
ServerStats.is_kill++;
ServerStats->is_kill++;
sendto_realops_snomask(SNO_DEBUG, L_ALL,
"Bad user@host: %s@%s From: %s(via %s)",
parv[5], parv[6], source_p->name, client_p->name);
@ -547,7 +547,7 @@ ms_euid(struct Client *client_p, struct Client *source_p, int parc, const char *
if(!clean_uid(parv[8]))
{
ServerStats.is_kill++;
ServerStats->is_kill++;
sendto_realops_snomask(SNO_DEBUG, L_ALL,
"Bad UID: %s From: %s(via %s)",
parv[8], source_p->name, client_p->name);
@ -557,7 +557,7 @@ ms_euid(struct Client *client_p, struct Client *source_p, int parc, const char *
if(strcmp(parv[9], "*") && !clean_host(parv[9]))
{
ServerStats.is_kill++;
ServerStats->is_kill++;
sendto_realops_snomask(SNO_DEBUG, L_ALL,
"Bad realhost: %s From: %s(via %s)",
parv[9], source_p->name, client_p->name);
@ -930,7 +930,7 @@ perform_nick_collides(struct Client *source_p, struct Client *client_p,
if (use_save)
{
save_user(&me, &me, target_p);
ServerStats.is_save++;
ServerStats->is_save++;
sendto_one(client_p, ":%s SAVE %s %ld", me.id,
uid, (long)newts);
register_client(client_p, source_p,
@ -950,7 +950,7 @@ perform_nick_collides(struct Client *source_p, struct Client *client_p,
/* we then need to KILL the old client everywhere */
kill_client_serv_butone(NULL, target_p, "%s (Nick collision (new))", me.name);
ServerStats.is_kill++;
ServerStats->is_kill++;
target_p->flags |= FLAGS_KILLED;
exit_client(client_p, target_p, &me, "Nick collision (new)");
@ -998,12 +998,12 @@ perform_nick_collides(struct Client *source_p, struct Client *client_p,
if (use_save)
{
ServerStats.is_save++;
ServerStats->is_save++;
save_user(&me, &me, target_p);
}
else
{
ServerStats.is_kill++;
ServerStats->is_kill++;
sendto_one_numeric(target_p, ERR_NICKCOLLISION,
form_str(ERR_NICKCOLLISION), target_p->name);
@ -1047,7 +1047,7 @@ perform_nickchange_collides(struct Client *source_p, struct Client *client_p,
if (use_save)
{
ServerStats.is_save += 2;
ServerStats->is_save += 2;
save_user(&me, &me, target_p);
sendto_one(client_p, ":%s SAVE %s %ld", me.id,
source_p->id, (long)newts);
@ -1057,13 +1057,13 @@ perform_nickchange_collides(struct Client *source_p, struct Client *client_p,
}
else
{
ServerStats.is_kill++;
ServerStats->is_kill++;
sendto_one_numeric(target_p, ERR_NICKCOLLISION,
form_str(ERR_NICKCOLLISION), target_p->name);
kill_client_serv_butone(NULL, source_p, "%s (Nick change collision)", me.name);
ServerStats.is_kill++;
ServerStats->is_kill++;
kill_client_serv_butone(NULL, target_p, "%s (Nick change collision)", me.name);
@ -1095,7 +1095,7 @@ perform_nickchange_collides(struct Client *source_p, struct Client *client_p,
if (use_save)
{
ServerStats.is_save++;
ServerStats->is_save++;
/* can't broadcast a SAVE because the
* nickchange has happened at client_p
* but not in other directions -- jilles */
@ -1107,7 +1107,7 @@ perform_nickchange_collides(struct Client *source_p, struct Client *client_p,
}
else
{
ServerStats.is_kill++;
ServerStats->is_kill++;
sendto_one_numeric(target_p, ERR_NICKCOLLISION,
form_str(ERR_NICKCOLLISION), target_p->name);
@ -1140,7 +1140,7 @@ perform_nickchange_collides(struct Client *source_p, struct Client *client_p,
if (use_save)
{
ServerStats.is_save++;
ServerStats->is_save++;
save_user(&me, &me, target_p);
}
else
@ -1151,7 +1151,7 @@ perform_nickchange_collides(struct Client *source_p, struct Client *client_p,
/* kill the client who existed before hand */
kill_client_serv_butone(client_p, target_p, "%s (Nick collision)", me.name);
ServerStats.is_kill++;
ServerStats->is_kill++;
target_p->flags |= FLAGS_KILLED;
(void) exit_client(client_p, target_p, &me, "Nick collision");
@ -1339,7 +1339,7 @@ save_user(struct Client *client_p, struct Client *source_p,
"Killed %s!%s@%s for nick collision detected by %s (%s does not support SAVE)",
target_p->name, target_p->username, target_p->host, source_p->name, target_p->from->name);
kill_client_serv_butone(NULL, target_p, "%s (Nick collision (no SAVE support))", me.name);
ServerStats.is_kill++;
ServerStats->is_kill++;
target_p->flags |= FLAGS_KILLED;
(void) exit_client(NULL, target_p, &me, "Nick collision (no SAVE support)");

View file

@ -43,7 +43,6 @@
#include "msg.h"
#include "parse.h"
#include "modules.h"
#include "reject.h"
static int mo_dline(struct Client *, struct Client *, int, const char **);
static int mo_undline(struct Client *, struct Client *, int, const char **);
@ -77,6 +76,7 @@ mo_dline(struct Client *client_p, struct Client *source_p,
const char *dlhost;
char *oper_reason;
char *reason = def;
struct irc_sockaddr_storage daddr;
char cidr_form_host[HOSTLEN + 1];
struct ConfItem *aconf;
int bits;
@ -149,37 +149,36 @@ mo_dline(struct Client *client_p, struct Client *source_p,
}
}
if(ConfigFileEntry.non_redundant_klines)
{
struct rb_sockaddr_storage daddr;
const char *creason;
int t = AF_INET, ty, b;
ty = parse_netmask(dlhost, (struct sockaddr *)&daddr, &b);
#ifdef IPV6
if(ty == HM_IPV6)
t = AF_INET6;
else
#endif
t = AF_INET;
if((aconf = find_dline((struct sockaddr *)&daddr)) != NULL)
{
int bx;
parse_netmask(aconf->host, NULL, &bx);
if(b >= bx)
{
creason = aconf->passwd ? aconf->passwd : "<No Reason>";
if(IsConfExemptKline(aconf))
sendto_one_notice(source_p,
":[%s] is (E)d-lined by [%s] - %s",
dlhost, aconf->host, creason);
else
sendto_one_notice(source_p,
":[%s] already D-lined by [%s] - %s",
dlhost, aconf->host, creason);
return 0;
}
}
if(ConfigFileEntry.non_redundant_klines)
{
const char *creason;
int t = AF_INET, ty, b;
ty = parse_netmask(dlhost, (struct sockaddr *)&daddr, &b);
#ifdef IPV6
if(ty == HM_IPV6)
t = AF_INET6;
else
#endif
t = AF_INET;
if((aconf = find_dline((struct sockaddr *)&daddr, t)) != NULL)
{
int bx;
parse_netmask(aconf->host, NULL, &bx);
if(b >= bx)
{
creason = aconf->passwd ? aconf->passwd : "<No Reason>";
if(IsConfExemptKline(aconf))
sendto_one(source_p,
":%s NOTICE %s :[%s] is (E)d-lined by [%s] - %s",
me.name, parv[0], dlhost, aconf->host, creason);
else
sendto_one(source_p,
":%s NOTICE %s :[%s] already D-lined by [%s] - %s",
me.name, parv[0], dlhost, aconf->host, creason);
return 0;
}
}
}
set_time();

View file

@ -684,46 +684,47 @@ majority_gline(struct Client *source_p, const char *user,
return NO;
}
/* remove_temp_gline()
*
* inputs - username, hostname to ungline
* outputs -
* side effects - tries to ungline anything that matches
*/
static int
remove_temp_gline(const char *user, const char *host)
{
struct ConfItem *aconf;
rb_dlink_node *ptr;
struct rb_sockaddr_storage addr, caddr;
int bits, cbits;
int mtype, gtype;
mtype = parse_netmask(host, (struct sockaddr *)&addr, &bits);
RB_DLINK_FOREACH(ptr, glines.head)
{
aconf = ptr->data;
gtype = parse_netmask(aconf->host, (struct sockaddr *)&caddr, &cbits);
if(gtype != mtype || (user && irccmp(user, aconf->user)))
continue;
if(gtype == HM_HOST)
{
if(irccmp(aconf->host, host))
continue;
}
else if(bits != cbits ||
!comp_with_mask_sock((struct sockaddr *)&addr,
(struct sockaddr *)&caddr, bits))
continue;
rb_dlinkDestroy(ptr, &glines);
delete_one_address_conf(aconf->host, aconf);
return YES;
}
return NO;
/* remove_temp_gline()
*
* inputs - username, hostname to ungline
* outputs -
* side effects - tries to ungline anything that matches
*/
static int
remove_temp_gline(const char *user, const char *host)
{
struct ConfItem *aconf;
rb_dlink_node *ptr;
struct irc_sockaddr_storage addr, caddr;
int bits, cbits;
int mtype, gtype;
mtype = parse_netmask(host, (struct sockaddr *)&addr, &bits);
RB_DLINK_FOREACH(ptr, glines.head)
{
aconf = ptr->data;
gtype = parse_netmask(aconf->host, (struct sockaddr *)&caddr, &cbits);
if(gtype != mtype || (user && irccmp(user, aconf->user)))
continue;
if(gtype == HM_HOST)
{
if(irccmp(aconf->host, host))
continue;
}
else if(bits != cbits ||
!comp_with_mask_sock((struct sockaddr *)&addr,
(struct sockaddr *)&caddr, bits))
continue;
rb_dlinkDestroy(ptr, &glines);
remove_reject_mask(aconf->user, aconf->host);
delete_one_address_conf(aconf->host, aconf);
return YES;
}
return NO;
}

View file

@ -691,7 +691,7 @@ static int
already_placed_kline(struct Client *source_p, const char *luser, const char *lhost, int tkline)
{
const char *reason, *p;
struct rb_sockaddr_storage iphost, *piphost;
struct irc_sockaddr_storage iphost, *piphost;
struct ConfItem *aconf;
int t, bits;
@ -859,7 +859,7 @@ remove_permkline_match(struct Client *source_p, struct ConfItem *aconf)
ilog(L_KLINE, "UK %s %s %s",
get_oper_name(source_p), user, host);
/* remove_reject_mask(aconf->user, aconf->host); XXX <- gonna go on bandb */
remove_reject_mask(aconf->user, aconf->host);
delete_one_address_conf(aconf->host, aconf);
return;
@ -929,7 +929,7 @@ remove_temp_kline(struct Client *source_p, struct ConfItem *aconf)
get_oper_name(source_p),
aconf->user, aconf->host);
rb_dlinkDestroy(ptr, &temp_klines[i]);
/* remove_reject_mask(aconf->user, aconf->host); XXX */
remove_reject_mask(aconf->user, aconf->host);
delete_one_address_conf(aconf->host, aconf);
return YES;
}

View file

@ -67,7 +67,7 @@ mr_pass(struct Client *client_p, struct Client *source_p, int parc, const char *
rb_free(client_p->localClient->passwd);
}
client_p->localClient->passwd = rb_strndup(parv[1], PASSWDLEN);
DupNString(client_p->localClient->passwd, parv[1], PASSWDLEN);
/* These are for servers only */
if(parc > 2 && client_p->user == NULL)

View file

@ -161,7 +161,7 @@ me_sasl(struct Client *client_p, struct Client *source_p,
else if(*parv[4] == 'S') {
sendto_one(target_p, form_str(RPL_SASLSUCCESS), me.name, EmptyString(target_p->name) ? "*" : target_p->name);
target_p->preClient->sasl_complete = 1;
ServerStats.is_ssuc++;
ServerStats->is_ssuc++;
}
*target_p->preClient->sasl_agent = '\0'; /* Blank the stored agent so someone else can answer */
}
@ -179,7 +179,7 @@ abort_sasl(struct Client *data)
return;
data->preClient->sasl_out = data->preClient->sasl_complete = 0;
ServerStats.is_sbad++;
ServerStats->is_sbad++;
if(!IsClosing(data))
sendto_one(data, form_str(ERR_SASLABORTED), me.name, EmptyString(data->name) ? "*" : data->name);

View file

@ -276,7 +276,7 @@ ms_signon(struct Client *client_p, struct Client *source_p,
if(!clean_nick(parv[1]))
{
ServerStats.is_kill++;
ServerStats->is_kill++;
sendto_realops_snomask(SNO_DEBUG, L_ALL,
"Bad Nick from SIGNON: %s From: %s(via %s)",
parv[1], source_p->servptr->name, client_p->name);
@ -294,7 +294,7 @@ ms_signon(struct Client *client_p, struct Client *source_p,
if(!clean_username(parv[2]) || !clean_host(parv[3]))
{
ServerStats.is_kill++;
ServerStats->is_kill++;
sendto_realops_snomask(SNO_DEBUG, L_ALL,
"Bad user@host from SIGNON: %s@%s From: %s(via %s)",
parv[2], parv[3], source_p->servptr->name, client_p->name);
@ -338,13 +338,13 @@ ms_signon(struct Client *client_p, struct Client *source_p,
source_p->name, target_p->name, target_p->from->name,
client_p->name);
ServerStats.is_kill++;
ServerStats->is_kill++;
sendto_one_numeric(target_p, ERR_NICKCOLLISION,
form_str(ERR_NICKCOLLISION), target_p->name);
kill_client_serv_butone(NULL, source_p, "%s (Nick change collision)", me.name);
ServerStats.is_kill++;
ServerStats->is_kill++;
kill_client_serv_butone(NULL, target_p, "%s (Nick change collision)", me.name);
@ -373,7 +373,7 @@ ms_signon(struct Client *client_p, struct Client *source_p,
source_p->name, target_p->name,
target_p->from->name, client_p->name);
ServerStats.is_kill++;
ServerStats->is_kill++;
sendto_one_numeric(target_p, ERR_NICKCOLLISION,
form_str(ERR_NICKCOLLISION), target_p->name);
@ -410,7 +410,7 @@ ms_signon(struct Client *client_p, struct Client *source_p,
kill_client_serv_butone(client_p, target_p,
"%s (Nick collision)", me.name);
ServerStats.is_kill++;
ServerStats->is_kill++;
target_p->flags |= FLAGS_KILLED;
(void) exit_client(client_p, target_p, &me, "Nick collision");

View file

@ -47,7 +47,6 @@
#include "hook.h"
#include "s_newconf.h"
#include "hash.h"
#include "reject.h"
static int m_stats (struct Client *, struct Client *, int, const char **);
@ -925,73 +924,10 @@ stats_usage (struct Client *source_p)
(int) rus.ru_nivcsw);
}
static void
stats_tstats(struct Client *source_p)
{
struct Client *target_p;
struct ServerStatistics sp;
rb_dlink_node *ptr;
memcpy(&sp, &ServerStats, sizeof(struct ServerStatistics));
RB_DLINK_FOREACH(ptr, serv_list.head)
{
target_p = ptr->data;
sp.is_sbs += target_p->localClient->sendB;
sp.is_sbr += target_p->localClient->receiveB;
sp.is_sti += rb_current_time() - target_p->localClient->firsttime;
sp.is_sv++;
}
RB_DLINK_FOREACH(ptr, lclient_list.head)
{
target_p = ptr->data;
sp.is_cbs += target_p->localClient->sendB;
sp.is_cbr += target_p->localClient->receiveB;
sp.is_cti += rb_current_time() - target_p->localClient->firsttime;
sp.is_cl++;
}
sendto_one_numeric(source_p, RPL_STATSDEBUG,
"T :accepts %u refused %u",
sp.is_ac, sp.is_ref);
sendto_one_numeric(source_p, RPL_STATSDEBUG,
"T :rejected %u delaying %lu",
sp.is_rej, delay_exit_length());
sendto_one_numeric(source_p, RPL_STATSDEBUG,
"T :nicks being delayed %lu", get_nd_count());
sendto_one_numeric(source_p, RPL_STATSDEBUG,
"T :unknown commands %u prefixes %u",
sp.is_unco, sp.is_unpf);
sendto_one_numeric(source_p, RPL_STATSDEBUG,
"T :nick collisions %u saves %u unknown closes %u",
sp.is_kill, sp.is_save, sp.is_ni);
sendto_one_numeric(source_p, RPL_STATSDEBUG,
"T :wrong direction %u empty %u",
sp.is_wrdi, sp.is_empt);
sendto_one_numeric(source_p, RPL_STATSDEBUG,
"T :numerics seen %u",
sp.is_num);
sendto_one_numeric(source_p, RPL_STATSDEBUG,
"T :auth successes %u fails %u",
sp.is_asuc, sp.is_abad);
sendto_one_numeric(source_p, RPL_STATSDEBUG, "T :Client Server");
sendto_one_numeric(source_p, RPL_STATSDEBUG,
"T :connected %u %u",
sp.is_cl, sp.is_sv);
sendto_one_numeric(source_p, RPL_STATSDEBUG,
"T :bytes sent %lluK %lluK",
sp.is_cbs / 1024,
sp.is_sbs / 1024);
sendto_one_numeric(source_p, RPL_STATSDEBUG,
"T :bytes recv %lluK %lluK",
sp.is_cbr / 1024,
sp.is_sbr / 1024);
sendto_one_numeric(source_p, RPL_STATSDEBUG,
"T :time connected %lu %lu",
(long) sp.is_cti, (long) sp.is_sti);
static void
stats_tstats (struct Client *source_p)
{
tstats (source_p);
}
static void

View file

@ -40,7 +40,6 @@
#include "s_conf.h"
#include "s_newconf.h"
#include "sprintf_irc.h"
#include "reject.h"
static int mo_testline(struct Client *, struct Client *, int, const char **);
static int mo_testgecos(struct Client *, struct Client *, int, const char **);
@ -62,7 +61,7 @@ mo_testline(struct Client *client_p, struct Client *source_p, int parc, const ch
{
struct ConfItem *aconf;
struct ConfItem *resv_p;
struct rb_sockaddr_storage ip;
struct irc_sockaddr_storage ip;
char user_trunc[USERLEN + 1], notildeuser_trunc[USERLEN + 1];
const char *name = NULL;
const char *username = NULL;
@ -120,12 +119,12 @@ mo_testline(struct Client *client_p, struct Client *source_p, int parc, const ch
/* parses as an IP, check for a dline */
if((type = parse_netmask(host, (struct sockaddr *)&ip, &host_mask)) != HM_HOST)
{
#ifdef IPV6
if(type == HM_IPV6)
aconf = find_dline((struct sockaddr *)&ip);
else
#endif
aconf = find_dline((struct sockaddr *)&ip);
#ifdef IPV6
if(type == HM_IPV6)
aconf = find_dline((struct sockaddr *)&ip, AF_INET6);
else
#endif
aconf = find_dline((struct sockaddr *)&ip, AF_INET);
if(aconf && aconf->status & CONF_DLINE)
{

View file

@ -42,28 +42,30 @@ struct Message unreject_msgtab = {
mapi_clist_av1 unreject_clist[] = { &unreject_msgtab, NULL };
DECLARE_MODULE_AV1(unreject, NULL, NULL, unreject_clist, NULL, NULL, "$Revision: 3161 $");
/*
* mo_unreject
*
*/
static int
mo_unreject(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
{
if(ConfigFileEntry.reject_after_count == 0 || ConfigFileEntry.reject_duration == 0)
{
sendto_one_notice(source_p, ":Reject cache is disabled");
return 0;
}
if(!parse_netmask(parv[1], NULL, NULL))
{
sendto_one_notice(source_p, ":Unable to parse netmask %s", parv[1]);
return 0;
}
if(remove_reject(parv[1]))
sendto_one_notice(source_p, ":Removed reject for %s", parv[1]);
else
sendto_one_notice(source_p, ":Unable to remove reject for %s", parv[1]);
return 0;
/*
* mo_unreject
*
*/
static int
mo_unreject(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
{
if(ConfigFileEntry.reject_after_count == 0 || ConfigFileEntry.reject_ban_time == 0 ||
ConfigFileEntry.reject_duration == 0)
{
sendto_one_notice(source_p, ":Reject cache is disabled");
return 0;
}
if(!parse_netmask(parv[1], NULL, NULL))
{
sendto_one_notice(source_p, ":Unable to parse netmask %s", parv[1]);
return 0;
}
if(remove_reject_ip(parv[1]))
sendto_one_notice(source_p, ":Removed reject for %s", parv[1]);
else
sendto_one_notice(source_p, ":Unable to remove reject for %s", parv[1]);
return 0;
}

3
servlink/.cvsignore Normal file
View file

@ -0,0 +1,3 @@
Makefile
setup.h
servlink

1
servlink/.indent.pro vendored Normal file
View file

@ -0,0 +1 @@
-i8 -bli0 -ut -nsai -l100 -npcs

82
servlink/Makefile.in Normal file
View file

@ -0,0 +1,82 @@
#
# Makefile.in for servlink/src
#
# $Id: Makefile.in 1285 2006-05-05 15:03:53Z nenolod $
#
CC = @CC@
INSTALL = @INSTALL@
INSTALL_BIN = @INSTALL_PROGRAM@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_SUID = @INSTALL_PROGRAM@ -o root -m 4755
RM = @RM@
LEX = @LEX@
LEXLIB = @LEXLIB@
CFLAGS = @IRC_CFLAGS@ -DIRCD_PREFIX=\"@prefix@\"
LDFLAGS = @LDFLAGS@
MKDEP = @MKDEP@ -DIRCD_PREFIX=\"@prefix@\"
MV = @MV@
RM = @RM@
prefix = @prefix@
exec_prefix = @exec_prefix@
bindir = @bindir@
libexecdir = @libexecdir@
confdir = @confdir@
localstatedir = @localstatedir@
ZIP_LIB = @ZLIB_LD@
IRCDLIBS = @LIBS@ $(ZIP_LIB)
INCLUDES = -I. -I../include $(SSL_INCLUDES)
CPPFLAGS = ${INCLUDES} @CPPFLAGS@
PROGS = servlink
SOURCES = \
servlink.c \
io.c \
control.c
OBJECTS = ${SOURCES:.c=.o}
all: servlink
build: all
servlink: ${OBJECTS}
${CC} ${CFLAGS} ${LDFLAGS} -o $@ ${OBJECTS} ${IRCDLIBS}
install: build
@echo "ircd: installing servlink ($(PROGS))"
@for i in $(PROGS); do \
if test -f $(DESTDIR)$(bindir)/$$i; then \
$(MV) $(DESTDIR)$(bindir)/$$i $(DESTDIR)$(bindir)/$$i.old; \
fi; \
$(INSTALL_BIN) $$i $(DESTDIR)$(bindir); \
done
.c.o:
${CC} ${CPPFLAGS} ${CFLAGS} -c $<
.PHONY: depend clean distclean
depend:
@${MKDEP} ${CPPFLAGS} ${SOURCES} > .depend.tmp
@sed -e '/^# DO NOT DELETE THIS LINE/,$$d' <Makefile >Makefile.depend
@echo '# DO NOT DELETE THIS LINE!!!' >>Makefile.depend
@echo '# make depend needs it.' >>Makefile.depend
@cat .depend.tmp >>Makefile.depend
@mv Makefile.depend Makefile
@rm -f .depend.tmp
clean:
${RM} -f *.o *~ *.core core servlink
lint:
lint -aacgprxhH $(CPPFLAGS) -DIRCD_PREFIX=\"@prefix@\" $(SOURCES) >>../lint.out
distclean: clean
${RM} -f Makefile
# End of Makefile

71
servlink/README Normal file
View file

@ -0,0 +1,71 @@
Servlink protocol documentation.
$Id: README 1285 2006-05-05 15:03:53Z nenolod $
--------------
After negotiating an incoming/outgoing server connection, the ircd will
fork, then execve servlink, with fd 0 as one end of a control pipe and
fd 1 as one end of a data pipe. fd 2 will be the socket connected to
the remote server.
The data pipe is used by the ircd to send/receive normal, decrypted,
uncompressed IRC commands to/from the remote server. The socket is used to
send the (processed) data to the remote server, and receive the data from
the remote server.
The control pipe is used to activate encryption/compression and to set the
encryption key/algorithm to be used.
Format of control messages:
<u8 command><optional data>
data format:
<u16 len><data>
Commands:
001 - SET_ZIP_OUT_LEVEL
data: yes
description:
set compression level (0 [use default, 6], or 1-9)
002 - START_ZIP_OUT
data: no
description:
all data written to the data pipe will be compressed
prior to being sent to the remote server.
003 - START_ZIP_IN
data: no
description:
all data not yet read from the slink program will be
decompressed before reading
004 - INJECT_RECVQ
data: recvq
Used before INIT to inject any data read from the server fd which
should be pre-processed by servlink before being sent back
to the LOCAL_FD through the data fd.
005 - INJECT_SENDQ
data: sendq
As above, but sent to remote server without processing.
006 - INIT
007 - ZIPSTATS
request to send ziplinks statistics reply.
replies
001 - ERROR
data: u32 len/char error[len]
fatal error message.
002 - ZIPSTATS
data: u32 in/u32 in_wire/u32 out/u32 out_wire
ziplinks commpression statistics

7
servlink/TODO Normal file
View file

@ -0,0 +1,7 @@
Servlink todo list
$Id: TODO 6 2005-09-10 01:02:21Z nenolod $
------------------
Fix any bugs that come up
Think of improvements :)

129
servlink/control.c Normal file
View file

@ -0,0 +1,129 @@
/************************************************************************
* IRC - Internet Relay Chat, servlink/servlink.c
*
* 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 1, 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, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* $Id: control.c 1285 2006-05-05 15:03:53Z nenolod $
*/
#include "setup.h"
#include <sys/types.h>
#include <assert.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#ifdef HAVE_LIBZ
#include <zlib.h>
#endif
#include "servlink.h"
#include "io.h"
#include "control.h"
static cmd_handler cmd_set_zip_out_level;
static cmd_handler cmd_start_zip_out;
static cmd_handler cmd_start_zip_in;
static cmd_handler cmd_init;
struct command_def command_table[] = {
{CMD_SET_ZIP_OUT_LEVEL, cmd_set_zip_out_level, COMMAND_FLAG_DATA},
{CMD_START_ZIP_OUT, cmd_start_zip_out, 0},
{CMD_START_ZIP_IN, cmd_start_zip_in, 0},
{CMD_INJECT_RECVQ, process_recvq, COMMAND_FLAG_DATA},
{CMD_INJECT_SENDQ, process_sendq, COMMAND_FLAG_DATA},
{CMD_INIT, cmd_init, 0},
{CMD_ZIPSTATS, send_zipstats, 0},
{0, 0, 0}
};
void
cmd_set_zip_out_level(struct ctrl_command *cmd)
{
#ifdef HAVE_LIBZ
out_state.zip_state.level = *cmd->data;
if((out_state.zip_state.level < -1) || (out_state.zip_state.level > 9))
send_error("invalid compression level %d", out_state.zip_state.level);
#else
send_error("can't set compression level - no libz support!");
#endif
}
void
cmd_start_zip_out(struct ctrl_command *cmd)
{
#ifdef HAVE_LIBZ
int ret;
if(out_state.zip)
send_error("can't start compression - already started!");
out_state.zip_state.z_stream.total_in = 0;
out_state.zip_state.z_stream.total_out = 0;
out_state.zip_state.z_stream.zalloc = (alloc_func) 0;
out_state.zip_state.z_stream.zfree = (free_func) 0;
out_state.zip_state.z_stream.data_type = Z_ASCII;
if(out_state.zip_state.level <= 0)
out_state.zip_state.level = Z_DEFAULT_COMPRESSION;
if((ret = deflateInit(&out_state.zip_state.z_stream, out_state.zip_state.level)) != Z_OK)
send_error("deflateInit failed: %s", zError(ret));
out_state.zip = 1;
#else
send_error("can't start compression - no libz support!");
#endif
}
void
cmd_start_zip_in(struct ctrl_command *cmd)
{
#ifdef HAVE_LIBZ
int ret;
if(in_state.zip)
send_error("can't start decompression - already started!");
in_state.zip_state.z_stream.total_in = 0;
in_state.zip_state.z_stream.total_out = 0;
in_state.zip_state.z_stream.zalloc = (alloc_func) 0;
in_state.zip_state.z_stream.zfree = (free_func) 0;
in_state.zip_state.z_stream.data_type = Z_ASCII;
if((ret = inflateInit(&in_state.zip_state.z_stream)) != Z_OK)
send_error("inflateInit failed: %s", zError(ret));
in_state.zip = 1;
#else
send_error("can't start decompression - no libz support!");
#endif
}
void
cmd_init(struct ctrl_command *cmd)
{
if(in_state.active || out_state.active)
send_error("CMD_INIT sent twice!");
in_state.active = 1;
out_state.active = 1;
CONTROL.read_cb = read_ctrl;
CONTROL.write_cb = NULL;
LOCAL.read_cb = read_data;
LOCAL.write_cb = NULL;
REMOTE.read_cb = read_net;
REMOTE.write_cb = NULL;
}

57
servlink/control.h Normal file
View file

@ -0,0 +1,57 @@
/************************************************************************
* IRC - Internet Relay Chat, servlink/control.h
*
* 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 1, 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, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* $Id: control.h 1285 2006-05-05 15:03:53Z nenolod $
*/
#ifndef INCLUDED_servlink_control_h
#define INCLUDED_servlink_control_h
#define CMD_SET_ZIP_OUT_LEVEL 1 /* data */
#define CMD_START_ZIP_OUT 2
#define CMD_START_ZIP_IN 3
#define CMD_INJECT_RECVQ 4 /* data */
#define CMD_INJECT_SENDQ 5 /* data */
#define CMD_INIT 6
#define CMD_ZIPSTATS 7
#define RPL_ERROR 1 /* data */
#define RPL_ZIPSTATS 2 /* data */
/* flags */
#define COMMAND_FLAG_DATA 0x0001 /* command has data
following */
struct ctrl_command
{
int command;
int datalen;
int gotdatalen;
int readdata;
unsigned char *data;
};
typedef void cmd_handler(struct ctrl_command *);
struct command_def
{
unsigned int commandid;
cmd_handler *handler;
unsigned int flags;
};
extern struct command_def command_table[];
#endif /* INCLUDED_servlink_control_h */

657
servlink/io.c Normal file
View file

@ -0,0 +1,657 @@
/************************************************************************
* IRC - Internet Relay Chat, servlink/io.c
*
* 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 1, 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, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* $Id: io.c 3319 2007-03-29 20:03:06Z jilles $
*/
#include "setup.h"
#include <sys/types.h>
#include <sys/socket.h>
#include <assert.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
#include <stdarg.h>
#include <stdio.h>
#include <unistd.h>
#ifdef HAVE_LIBZ
#include <zlib.h>
#endif
#include "servlink.h"
#include "io.h"
#include "control.h"
static int check_error(int, int, int);
static const char *
fd_name(int fd)
{
if(fd == CONTROL.fd)
return "control";
if(fd == LOCAL.fd)
return "data";
if(fd == REMOTE.fd)
return "network";
/* uh oh... */
return "unknown";
}
#if defined( HAVE_LIBZ )
static unsigned char tmp_buf[BUFLEN];
static unsigned char tmp2_buf[BUFLEN];
#endif
static unsigned char ctrl_buf[256] = "";
static unsigned int ctrl_len = 0;
static unsigned int ctrl_ofs = 0;
void
io_loop(int nfds)
{
fd_set rfds;
fd_set wfds;
int i, ret;
/* loop forever */
for (;;)
{
FD_ZERO(&rfds);
FD_ZERO(&wfds);
for (i = 0; i < 3; i++)
{
if(fds[i].read_cb)
FD_SET(fds[i].fd, &rfds);
if(fds[i].write_cb)
FD_SET(fds[i].fd, &wfds);
}
/* we have <3 fds ever, so I don't think select is too painful */
ret = select(nfds, &rfds, &wfds, NULL, NULL);
if(ret < 0)
{
check_error(ret, IO_SELECT, -1); /* exit on fatal errors */
}
else if(ret > 0)
{
/* call any callbacks */
for (i = 2; i >= 0; i--)
{
if(FD_ISSET(fds[i].fd, &rfds) && fds[i].read_cb)
(*fds[i].read_cb) ();
if(FD_ISSET(fds[i].fd, &wfds) && fds[i].write_cb)
(*fds[i].write_cb) ();
}
}
}
}
void
send_data_blocking(int fd, unsigned char *data, int datalen)
{
int ret;
fd_set wfds;
while (1)
{
ret = write(fd, data, datalen);
if(ret == datalen)
return;
else if(ret > 0)
{
data += ret;
datalen -= ret;
}
ret = check_error(ret, IO_WRITE, fd);
FD_ZERO(&wfds);
FD_SET(fd, &wfds);
/* sleep until we can write to the fd */
while (1)
{
ret = select(fd + 1, NULL, &wfds, NULL, NULL);
if(ret > 0) /* break out so we can write */
break;
if(ret < 0) /* error ? */
check_error(ret, IO_SELECT, fd); /* exit on fatal errors */
/* loop on non-fatal errors */
}
}
}
/*
* process_sendq:
*
* used before CMD_INIT to pass contents of SendQ from ircd
* to servlink. This data must _not_ be encrypted/compressed.
*/
void
process_sendq(struct ctrl_command *cmd)
{
send_data_blocking(REMOTE.fd, cmd->data, cmd->datalen);
}
/*
* process_recvq:
*
* used before CMD_INIT to pass contents of RecvQ from ircd
* to servlink. This data must be decrypted/decopmressed before
* sending back to the ircd.
*/
void
process_recvq(struct ctrl_command *cmd)
{
int ret;
unsigned char *buf;
int blen;
unsigned char *data = cmd->data;
unsigned int datalen = cmd->datalen;
buf = data;
blen = datalen;
ret = -1;
if(datalen > READLEN)
send_error("Error processing INJECT_RECVQ - buffer too long (%d > %d)",
datalen, READLEN);
#ifdef HAVE_LIBZ
if(in_state.zip)
{
/* decompress data */
in_state.zip_state.z_stream.next_in = buf;
in_state.zip_state.z_stream.avail_in = blen;
in_state.zip_state.z_stream.next_out = tmp2_buf;
in_state.zip_state.z_stream.avail_out = BUFLEN;
buf = tmp2_buf;
while (in_state.zip_state.z_stream.avail_in)
{
if((ret = inflate(&in_state.zip_state.z_stream, Z_NO_FLUSH)) != Z_OK)
{
if(!strncmp("ERROR ", (char *)in_state.zip_state.z_stream.next_in, 6))
send_error("Received uncompressed ERROR");
else
send_error("Inflate failed: %s", zError(ret));
}
blen = BUFLEN - in_state.zip_state.z_stream.avail_out;
if(in_state.zip_state.z_stream.avail_in)
{
send_data_blocking(LOCAL.fd, buf, blen);
blen = 0;
in_state.zip_state.z_stream.next_out = buf;
in_state.zip_state.z_stream.avail_out = BUFLEN;
}
}
if(!blen)
return;
}
#endif
send_data_blocking(LOCAL.fd, buf, blen);
}
void
send_zipstats(struct ctrl_command *unused)
{
#ifdef HAVE_LIBZ
int i = 0;
int ret;
u_int32_t len;
if(!in_state.active || !out_state.active)
send_error("Error processing CMD_ZIPSTATS - link is not active!");
if(!in_state.zip || !out_state.zip)
send_error("Error processing CMD_ZIPSTATS - link is not compressed!");
ctrl_buf[i++] = RPL_ZIPSTATS;
ctrl_buf[i++] = 0;
ctrl_buf[i++] = 16;
len = (u_int32_t) in_state.zip_state.z_stream.total_out;
ctrl_buf[i++] = ((len >> 24) & 0xFF);
ctrl_buf[i++] = ((len >> 16) & 0xFF);
ctrl_buf[i++] = ((len >> 8) & 0xFF);
ctrl_buf[i++] = ((len) & 0xFF);
len = (u_int32_t) in_state.zip_state.z_stream.total_in;
ctrl_buf[i++] = ((len >> 24) & 0xFF);
ctrl_buf[i++] = ((len >> 16) & 0xFF);
ctrl_buf[i++] = ((len >> 8) & 0xFF);
ctrl_buf[i++] = ((len) & 0xFF);
len = (u_int32_t) out_state.zip_state.z_stream.total_in;
ctrl_buf[i++] = ((len >> 24) & 0xFF);
ctrl_buf[i++] = ((len >> 16) & 0xFF);
ctrl_buf[i++] = ((len >> 8) & 0xFF);
ctrl_buf[i++] = ((len) & 0xFF);
len = (u_int32_t) out_state.zip_state.z_stream.total_out;
ctrl_buf[i++] = ((len >> 24) & 0xFF);
ctrl_buf[i++] = ((len >> 16) & 0xFF);
ctrl_buf[i++] = ((len >> 8) & 0xFF);
ctrl_buf[i++] = ((len) & 0xFF);
in_state.zip_state.z_stream.total_in = 0;
in_state.zip_state.z_stream.total_out = 0;
out_state.zip_state.z_stream.total_in = 0;
out_state.zip_state.z_stream.total_out = 0;
ret = check_error(write(CONTROL.fd, ctrl_buf, i), IO_WRITE, CONTROL.fd);
if(ret < i)
{
/* write incomplete, register write cb */
CONTROL.write_cb = write_ctrl;
/* deregister read_cb */
CONTROL.read_cb = NULL;
ctrl_ofs = ret;
ctrl_len = i - ret;
return;
}
#else
send_error("can't send_zipstats -- no zlib support!");
#endif
}
/* send_error
* - we ran into some problem, make a last ditch effort to
* flush the control fd sendq, then (blocking) send an
* error message over the control fd.
*/
void
send_error(const char *message, ...)
{
va_list args;
static int sending_error = 0;
struct linger linger_opt = { 1, 30 }; /* wait 30 seconds */
int len;
if(sending_error)
exit(1); /* we did _try_ */
sending_error = 1;
if(ctrl_len) /* attempt to flush any data we have... */
{
send_data_blocking(CONTROL.fd, (ctrl_buf + ctrl_ofs), ctrl_len);
}
/* prepare the message, in in_buf, since we won't be using it again.. */
in_state.buf[0] = RPL_ERROR;
in_state.buf[1] = 0;
in_state.buf[2] = 0;
va_start(args, message);
len = vsprintf((char *) in_state.buf + 3, message, args);
va_end(args);
in_state.buf[3 + len++] = '\0';
in_state.buf[1] = len >> 8;
in_state.buf[2] = len & 0xFF;
len += 3;
send_data_blocking(CONTROL.fd, in_state.buf, len);
/* XXX - is this portable?
* this obviously will fail on a non socket.. */
setsockopt(CONTROL.fd, SOL_SOCKET, SO_LINGER, &linger_opt, sizeof(struct linger));
/* well, we've tried... */
exit(1); /* now abort */
}
/* read_ctrl
* called when a command is waiting on the control pipe
*/
void
read_ctrl(void)
{
int ret;
unsigned char tmp[2];
unsigned char *len;
struct command_def *cdef;
static struct ctrl_command cmd = { 0, 0, 0, 0, NULL };
if(cmd.command == 0) /* we don't have a command yet */
{
cmd.gotdatalen = 0;
cmd.datalen = 0;
cmd.readdata = 0;
cmd.data = NULL;
/* read the command */
if(!(ret = check_error(read(CONTROL.fd, tmp, 1), IO_READ, CONTROL.fd)))
return;
cmd.command = tmp[0];
}
for (cdef = command_table; cdef->commandid; cdef++)
{
if((int)cdef->commandid == cmd.command)
break;
}
if(!cdef->commandid)
{
send_error("Unsupported command (servlink/ircd out of sync?): %d", cmd.command);
/* NOTREACHED */
}
/* read datalen for commands including data */
if(cdef->flags & COMMAND_FLAG_DATA)
{
if(cmd.gotdatalen < 2)
{
len = tmp;
if(!(ret = check_error(read(CONTROL.fd, len,
(2 - cmd.gotdatalen)), IO_READ, CONTROL.fd)))
return;
if(cmd.gotdatalen == 0)
{
cmd.datalen = len[0] << 8;
cmd.gotdatalen++;
ret--;
len++;
}
if(ret && (cmd.gotdatalen == 1))
{
cmd.datalen |= len[0];
cmd.gotdatalen++;
if(cmd.datalen > 0)
cmd.data = calloc(cmd.datalen, 1);
}
}
}
if(cmd.readdata < cmd.datalen) /* try to get any remaining data */
{
if(!(ret = check_error(read(CONTROL.fd,
(cmd.data + cmd.readdata),
cmd.datalen - cmd.readdata), IO_READ, CONTROL.fd)))
return;
cmd.readdata += ret;
if(cmd.readdata < cmd.datalen)
return;
}
/* we now have the command and any data */
(*cdef->handler) (&cmd);
if(cmd.datalen > 0)
free(cmd.data);
cmd.command = 0;
}
void
write_ctrl(void)
{
int ret;
assert(ctrl_len);
if(!(ret = check_error(write(CONTROL.fd, (ctrl_buf + ctrl_ofs),
ctrl_len), IO_WRITE, CONTROL.fd)))
return; /* no data waiting */
ctrl_len -= ret;
if(!ctrl_len)
{
/* write completed, de-register write cb */
CONTROL.write_cb = NULL;
/* reregister read_cb */
CONTROL.read_cb = read_ctrl;
ctrl_ofs = 0;
}
else
ctrl_ofs += ret;
}
void
read_data(void)
{
int ret, ret2;
unsigned char *buf = out_state.buf;
int blen;
ret2 = -1;
assert(!out_state.len);
#if defined(HAVE_LIBZ)
if(out_state.zip || out_state.crypt)
buf = tmp_buf;
#endif
while ((ret = check_error(read(LOCAL.fd, buf, READLEN), IO_READ, LOCAL.fd)))
{
blen = ret;
#ifdef HAVE_LIBZ
if(out_state.zip)
{
out_state.zip_state.z_stream.next_in = buf;
out_state.zip_state.z_stream.avail_in = ret;
buf = out_state.buf;
out_state.zip_state.z_stream.next_out = buf;
out_state.zip_state.z_stream.avail_out = BUFLEN;
if(!(ret2 = deflate(&out_state.zip_state.z_stream,
Z_PARTIAL_FLUSH)) == Z_OK)
send_error("error compressing outgoing data - deflate returned: %s",
zError(ret2));
if(!out_state.zip_state.z_stream.avail_out)
send_error("error compressing outgoing data - avail_out == 0");
if(out_state.zip_state.z_stream.avail_in)
send_error("error compressing outgoing data - avail_in != 0");
blen = BUFLEN - out_state.zip_state.z_stream.avail_out;
}
#endif
ret = check_error(write(REMOTE.fd, out_state.buf, blen), IO_WRITE, REMOTE.fd);
if(ret < blen)
{
/* write incomplete, register write cb */
REMOTE.write_cb = write_net;
/* deregister read_cb */
LOCAL.read_cb = NULL;
out_state.ofs = ret;
out_state.len = blen - ret;
return;
}
#if defined(HAVE_LIBZ)
if(out_state.zip)
buf = tmp_buf;
#endif
}
}
void
write_net(void)
{
int ret;
assert(out_state.len);
if(!(ret = check_error(write(REMOTE.fd,
(out_state.buf + out_state.ofs),
out_state.len), IO_WRITE, REMOTE.fd)))
return; /* no data waiting */
out_state.len -= ret;
if(!out_state.len)
{
/* write completed, de-register write cb */
REMOTE.write_cb = NULL;
/* reregister read_cb */
LOCAL.read_cb = read_data;
out_state.ofs = 0;
}
else
out_state.ofs += ret;
}
void
read_net(void)
{
int ret;
int ret2;
unsigned char *buf = in_state.buf;
int blen;
ret2 = -1;
assert(!in_state.len);
#if defined(HAVE_LIBZ)
if(in_state.zip)
buf = tmp_buf;
#endif
while ((ret = check_error(read(REMOTE.fd, buf, READLEN), IO_READ, REMOTE.fd)))
{
blen = ret;
#ifdef HAVE_LIBZ
if(in_state.zip)
{
/* decompress data */
in_state.zip_state.z_stream.next_in = buf;
in_state.zip_state.z_stream.avail_in = ret;
in_state.zip_state.z_stream.next_out = in_state.buf;
in_state.zip_state.z_stream.avail_out = BUFLEN;
while (in_state.zip_state.z_stream.avail_in)
{
if((ret2 = inflate(&in_state.zip_state.z_stream,
Z_NO_FLUSH)) != Z_OK)
{
if(!strncmp("ERROR ", (char *)buf, 6))
send_error("Received uncompressed ERROR");
send_error("Inflate failed: %s", zError(ret2));
}
blen = BUFLEN - in_state.zip_state.z_stream.avail_out;
if(in_state.zip_state.z_stream.avail_in)
{
if(blen)
{
send_data_blocking(LOCAL.fd, in_state.buf, blen);
blen = 0;
}
in_state.zip_state.z_stream.next_out = in_state.buf;
in_state.zip_state.z_stream.avail_out = BUFLEN;
}
}
if(!blen)
return; /* that didn't generate any decompressed input.. */
}
#endif
ret = check_error(write(LOCAL.fd, in_state.buf, blen), IO_WRITE, LOCAL.fd);
if(ret < blen)
{
in_state.ofs = ret;
in_state.len = blen - ret;
/* write incomplete, register write cb */
LOCAL.write_cb = write_data;
/* deregister read_cb */
REMOTE.read_cb = NULL;
return;
}
#if defined(HAVE_LIBZ)
if(in_state.zip)
buf = tmp_buf;
#endif
}
}
void
write_data(void)
{
int ret;
assert(in_state.len);
if(!(ret = check_error(write(LOCAL.fd,
(in_state.buf + in_state.ofs),
in_state.len), IO_WRITE, LOCAL.fd)))
return;
in_state.len -= ret;
if(!in_state.len)
{
/* write completed, de-register write cb */
LOCAL.write_cb = NULL;
/* reregister read_cb */
REMOTE.read_cb = read_net;
in_state.ofs = 0;
}
else
in_state.ofs += ret;
}
int
check_error(int ret, int io, int fd)
{
if(ret > 0) /* no error */
return ret;
if(ret == 0) /* EOF */
{
send_error("%s failed on %s: EOF", IO_TYPE(io), FD_NAME(fd));
exit(1); /* NOTREACHED */
}
/* ret == -1.. */
switch (errno)
{
case EINPROGRESS:
case EWOULDBLOCK:
#if EAGAIN != EWOULDBLOCK
case EAGAIN:
#endif
case EALREADY:
case EINTR:
#ifdef ERESTART
case ERESTART:
#endif
/* non-fatal error, 0 bytes read */
return 0;
}
/* fatal error */
send_error("%s failed on %s: %s", IO_TYPE(io), FD_NAME(fd), strerror(errno));
exit(1); /* NOTREACHED */
}

48
servlink/io.h Normal file
View file

@ -0,0 +1,48 @@
/************************************************************************
* IRC - Internet Relay Chat, servlink/io.h
*
* 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 1, 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, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* $Id: io.h 6 2005-09-10 01:02:21Z nenolod $
*/
#ifndef INCLUDED_servlink_io_h
#define INCLUDED_servlink_io_h
#include "control.h"
#define IO_READ 0
#define IO_WRITE 1
#define IO_SELECT 2
#define IO_TYPE(io) ((io==IO_SELECT)?"select": \
((io==IO_WRITE)?"write":"read"))
#define FD_NAME(fd) (fd_name(fd))
extern void io_loop(int nfds);
extern void write_data(void);
extern void read_data(void);
extern void write_ctrl(void);
extern void read_ctrl(void);
extern void write_net(void);
extern void read_net(void);
extern void send_error(const char *, ...);
extern void send_data_blocking(int fd, unsigned char *data, int datalen);
extern cmd_handler process_recvq;
extern cmd_handler process_sendq;
extern cmd_handler send_zipstats;
#endif /* INCLUDED_servlink_io_h */

121
servlink/servlink.c Normal file
View file

@ -0,0 +1,121 @@
/************************************************************************
* IRC - Internet Relay Chat, servlink/servlink.c
*
* 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 1, 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, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* $Id: servlink.c 6 2005-09-10 01:02:21Z nenolod $
*/
#include "setup.h"
#include <sys/types.h>
#include <sys/time.h>
#include <sys/socket.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#ifdef HAVE_LIBZ
#include <zlib.h>
#endif
#include "servlink.h"
#include "io.h"
#include "control.h"
static void usage(void);
struct slink_state in_state;
struct slink_state out_state;
struct fd_table fds[3] = {
{0, read_ctrl, NULL}, /* ctrl */
{0, NULL, NULL}, /* data */
{0, NULL, NULL}, /* net */
};
/* usage();
*
* Display usage message
*/
static void
usage(void)
{
fprintf(stderr, "ircd-ratbox server link v1.2\n");
fprintf(stderr, "2004-03-02\n");
fprintf(stderr, "\n");
fprintf(stderr, "This program is called by the ircd-ratbox ircd.\n");
fprintf(stderr, "It cannot be used on its own.\n");
exit(1);
}
int
main(int argc, char *argv[])
{
int max_fd = 0;
int i, x;
#ifdef SERVLINK_DEBUG
int GDBAttached = 0;
while (!GDBAttached)
sleep(1);
#endif
/* Make sure we are running under ircd.. */
if(argc != 4 || strcmp(argv[0], "-slink"))
usage(); /* exits */
for (i = 0; i < 3; i++)
{
fds[i].fd = atoi(argv[i + 1]);
if(fds[i].fd < 0)
exit(1);
}
for (i = 0; i < 3; i++)
{
/* XXX: Hack alert...we need to do dup2() here for some dumb
* platforms (Solaris) that don't like select using fds > 255
*/
if(fds[i].fd >= 255)
{
for(x = 0; x < 255; x++)
{
if(x != fds[0].fd && x != fds[1].fd && x != fds[2].fd)
{
if(dup2(fds[i].fd, x) < 0)
exit(1);
close(fds[i].fd);
fds[i].fd = x;
break;
}
}
}
fcntl(fds[i].fd, F_SETFL, O_NONBLOCK);
if(fds[i].fd > max_fd)
max_fd = fds[i].fd;
}
/* enter io loop */
io_loop(max_fd + 1);
/* NOTREACHED */
return (0);
} /* main() */

83
servlink/servlink.h Normal file
View file

@ -0,0 +1,83 @@
/************************************************************************
* IRC - Internet Relay Chat, servlink/servlink.h
*
* 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 1, 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, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* $Id: servlink.h 1285 2006-05-05 15:03:53Z nenolod $
*/
#ifndef INCLUDED_servlink_servlink_h
#define INCLUDED_servlink_servlink_h
#include "setup.h"
#ifdef HAVE_LIBZ
#include <zlib.h>
#endif
/* do not use stdin/out/err, as it seems to break on solaris */
#define CONTROL fds[0]
#define LOCAL fds[1]
#define REMOTE fds[2]
#undef SERVLINK_DEBUG
#define READLEN 16384
#ifdef HAVE_LIBZ
#define BUFLEN READLEN * 6 /* allow for decompression */
#else
#define BUFLEN READLEN
#endif
#ifdef HAVE_LIBZ
struct zip_state
{
z_stream z_stream;
int level; /* compression level */
};
#endif
struct slink_state
{
unsigned int crypt:1;
unsigned int zip:1;
unsigned int active:1;
unsigned char buf[BUFLEN * 2];
unsigned int ofs;
unsigned int len;
#ifdef HAVE_LIBZ
struct zip_state zip_state;
#endif
};
typedef void (io_callback) (void);
struct fd_table
{
int fd;
io_callback *read_cb;
io_callback *write_cb;
};
extern struct slink_state in_state;
extern struct slink_state out_state;
extern struct fd_table fds[3];
#endif /* INCLUDED_servlink_servlink_h */

View file

@ -44,31 +44,31 @@
rb_dlink_list class_list;
struct Class *default_class;
struct Class *
make_class(void)
{
struct Class *tmp;
tmp = rb_malloc(sizeof(struct Class));
ConFreq(tmp) = DEFAULT_CONNECTFREQUENCY;
PingFreq(tmp) = DEFAULT_PINGFREQUENCY;
MaxUsers(tmp) = 1;
MaxSendq(tmp) = DEFAULT_SENDQ;
tmp->ip_limits = rb_new_patricia(PATRICIA_BITS);
return tmp;
struct Class *
make_class(void)
{
struct Class *tmp;
tmp = (struct Class *) rb_malloc(sizeof(struct Class));
ConFreq(tmp) = DEFAULT_CONNECTFREQUENCY;
PingFreq(tmp) = DEFAULT_PINGFREQUENCY;
MaxUsers(tmp) = 1;
MaxSendq(tmp) = DEFAULT_SENDQ;
tmp->ip_limits = rb_new_patricia(PATRICIA_BITS);
return tmp;
}
void
free_class(struct Class *tmp)
{
if(tmp->ip_limits)
rb_destroy_patricia(tmp->ip_limits, NULL);
rb_free(tmp->class_name);
rb_free(tmp);
void
free_class(struct Class *tmp)
{
if(tmp->ip_limits)
rb_destroy_patricia(tmp->ip_limits, NULL);
rb_free(tmp->class_name);
rb_free(tmp);
}
/*

View file

@ -456,7 +456,7 @@ check_banned_lines(void)
continue;
/* if there is a returned struct ConfItem then kill it */
if((aconf = find_dline((struct sockaddr *)&client_p->localClient->ip)))
if((aconf = find_dline((struct sockaddr *)&client_p->localClient->ip, client_p->localClient->ip.ss_family)))
{
if(aconf->status & CONF_EXEMPTDLINE)
continue;
@ -540,7 +540,7 @@ check_banned_lines(void)
{
client_p = ptr->data;
if((aconf = find_dline((struct sockaddr *)&client_p->localClient->ip)))
if((aconf = find_dline((struct sockaddr *)&client_p->localClient->ip,client_p->localClient->ip.ss_family)))
{
if(aconf->status & CONF_EXEMPTDLINE)
continue;
@ -675,7 +675,7 @@ check_dlines(void)
if(IsMe(client_p))
continue;
if((aconf = find_dline((struct sockaddr *)&client_p->localClient->ip)) != NULL)
if((aconf = find_dline((struct sockaddr *)&client_p->localClient->ip,client_p->localClient->ip.ss_family)) != NULL)
{
if(aconf->status & CONF_EXEMPTDLINE)
continue;
@ -694,7 +694,7 @@ check_dlines(void)
{
client_p = ptr->data;
if((aconf = find_dline((struct sockaddr *)&client_p->localClient->ip)) != NULL)
if((aconf = find_dline((struct sockaddr *)&client_p->localClient->ip,client_p->localClient->ip.ss_family)) != NULL)
{
if(aconf->status & CONF_EXEMPTDLINE)
continue;
@ -1401,6 +1401,7 @@ exit_unknown_client(struct Client *client_p, struct Client *source_p, struct Cli
const char *comment)
{
delete_auth_queries(source_p);
del_unknown_ip(source_p);
rb_dlinkDelete(&source_p->localClient->tnode, &unknown_list);
if(!IsIOError(source_p))
@ -2025,21 +2026,21 @@ close_connection(struct Client *client_p)
{
struct server_conf *server_p;
ServerStats.is_sv++;
ServerStats.is_sbs += client_p->localClient->sendB;
ServerStats.is_sbr += client_p->localClient->receiveB;
ServerStats.is_sks += client_p->localClient->sendK;
ServerStats.is_skr += client_p->localClient->receiveK;
ServerStats.is_sti += rb_current_time() - client_p->localClient->firsttime;
if(ServerStats.is_sbs > 2047)
ServerStats->is_sv++;
ServerStats->is_sbs += client_p->localClient->sendB;
ServerStats->is_sbr += client_p->localClient->receiveB;
ServerStats->is_sks += client_p->localClient->sendK;
ServerStats->is_skr += client_p->localClient->receiveK;
ServerStats->is_sti += rb_current_time() - client_p->localClient->firsttime;
if(ServerStats->is_sbs > 2047)
{
ServerStats.is_sks += (ServerStats.is_sbs >> 10);
ServerStats.is_sbs &= 0x3ff;
ServerStats->is_sks += (ServerStats->is_sbs >> 10);
ServerStats->is_sbs &= 0x3ff;
}
if(ServerStats.is_sbr > 2047)
if(ServerStats->is_sbr > 2047)
{
ServerStats.is_skr += (ServerStats.is_sbr >> 10);
ServerStats.is_sbr &= 0x3ff;
ServerStats->is_skr += (ServerStats->is_sbr >> 10);
ServerStats->is_sbr &= 0x3ff;
}
/*
@ -2063,35 +2064,40 @@ close_connection(struct Client *client_p)
}
else if(IsClient(client_p))
{
ServerStats.is_cl++;
ServerStats.is_cbs += client_p->localClient->sendB;
ServerStats.is_cbr += client_p->localClient->receiveB;
ServerStats.is_cks += client_p->localClient->sendK;
ServerStats.is_ckr += client_p->localClient->receiveK;
ServerStats.is_cti += rb_current_time() - client_p->localClient->firsttime;
if(ServerStats.is_cbs > 2047)
ServerStats->is_cl++;
ServerStats->is_cbs += client_p->localClient->sendB;
ServerStats->is_cbr += client_p->localClient->receiveB;
ServerStats->is_cks += client_p->localClient->sendK;
ServerStats->is_ckr += client_p->localClient->receiveK;
ServerStats->is_cti += rb_current_time() - client_p->localClient->firsttime;
if(ServerStats->is_cbs > 2047)
{
ServerStats.is_cks += (ServerStats.is_cbs >> 10);
ServerStats.is_cbs &= 0x3ff;
ServerStats->is_cks += (ServerStats->is_cbs >> 10);
ServerStats->is_cbs &= 0x3ff;
}
if(ServerStats.is_cbr > 2047)
if(ServerStats->is_cbr > 2047)
{
ServerStats.is_ckr += (ServerStats.is_cbr >> 10);
ServerStats.is_cbr &= 0x3ff;
ServerStats->is_ckr += (ServerStats->is_cbr >> 10);
ServerStats->is_cbr &= 0x3ff;
}
}
else
ServerStats.is_ni++;
ServerStats->is_ni++;
/* XXX ctrlFd was here!!! */
if(client_p->localClient->F != NULL)
{
/* attempt to flush any pending linebufs. Evil, but .. -- adrian */
if(!IsIOError(client_p))
send_pop_queue(client_p);
del_from_cli_fd_hash(client_p);
rb_close(client_p->localClient->F);
client_p->localClient->F = NULL;
if(client_p->localClient->F)
{
/* attempt to flush any pending dbufs. Evil, but .. -- adrian */
if(!IsIOError(client_p))
send_queued(client_p);
rb_close(client_p->localClient->F);
client_p->localClient->F = NULL;
}
if(-1 < client_p->localClient->ctrlfd)
{
rb_close(client_p->localClient->ctrlfd);
client_p->localClient->ctrlfd = -1;
}
rb_linebuf_donebuf(&client_p->localClient->buf_sendq);

View file

@ -39,14 +39,11 @@
#include "cache.h"
#include "s_newconf.h"
#define hash_cli_fd(x) (x % CLI_FD_MAX)
rb_dlink_list *clientTable;
rb_dlink_list *channelTable;
rb_dlink_list *idTable;
rb_dlink_list *resvTable;
rb_dlink_list *hostTable;
static rb_dlink_list clientbyfdTable[U_MAX];
/*
* look in whowas.c for the missing ...[WW_MAX]; entry
@ -663,37 +660,6 @@ clear_resv_hash(void)
HASH_WALK_END
}
void
add_to_cli_fd_hash(struct Client *client_p)
{
rb_dlinkAddAlloc(client_p, &clientbyfdTable[hash_cli_fd(rb_get_fd(client_p->localClient->F))]);
}
void
del_from_cli_fd_hash(struct Client *client_p)
{
unsigned int hashv;
hashv = hash_cli_fd(rb_get_fd(client_p->localClient->F));
rb_dlinkFindDestroy(client_p, &clientbyfdTable[hashv]);
}
struct Client *
find_cli_fd_hash(int fd)
{
struct Client *target_p;
rb_dlink_node *ptr;
unsigned int hashv;
hashv = hash_cli_fd(fd);
RB_DLINK_FOREACH(ptr, clientbyfdTable[hashv].head)
{
target_p = ptr->data;
if(rb_get_fd(target_p->localClient->F) == fd)
return target_p;
}
return NULL;
}
static void
output_hash(struct Client *source_p, const char *name, int length, int *counts, int deepest)
{

View file

@ -39,7 +39,7 @@ static unsigned long hash_ipv6(struct sockaddr *, int);
static unsigned long hash_ipv4(struct sockaddr *, int);
/* int parse_netmask(const char *, struct rb_sockaddr_storage *, int *);
/* int parse_netmask(const char *, struct irc_sockaddr_storage *, int *);
* Input: A hostmask, or an IPV4/6 address.
* Output: An integer describing whether it is an IPV4, IPV6 address or a
* hostmask, an address(if it is an IP mask),
@ -51,7 +51,7 @@ parse_netmask(const char *text, struct sockaddr *naddr, int *nb)
{
char *ip = LOCAL_COPY(text);
char *ptr;
struct rb_sockaddr_storage *addr, xaddr;
struct irc_sockaddr_storage *addr, xaddr;
int *b, xb;
if(nb == NULL)
b = &xb;
@ -59,9 +59,9 @@ parse_netmask(const char *text, struct sockaddr *naddr, int *nb)
b = nb;
if(naddr == NULL)
addr = (struct rb_sockaddr_storage *)&xaddr;
addr = (struct irc_sockaddr_storage *)&xaddr;
else
addr = (struct rb_sockaddr_storage *)naddr;
addr = (struct irc_sockaddr_storage *)naddr;
#ifdef IPV6
if(strchr(ip, ':'))
@ -109,7 +109,7 @@ init_host_hash(void)
memset(&atable, 0, sizeof(atable));
}
/* unsigned long hash_ipv4(struct rb_sockaddr_storage*)
/* unsigned long hash_ipv4(struct irc_sockaddr_storage*)
* Input: An IP address.
* Output: A hash value of the IP address.
* Side effects: None
@ -128,7 +128,7 @@ hash_ipv4(struct sockaddr *saddr, int bits)
return 0;
}
/* unsigned long hash_ipv6(struct rb_sockaddr_storage*)
/* unsigned long hash_ipv6(struct irc_sockaddr_storage*)
* Input: An IP address.
* Output: A hash value of the IP address.
* Side effects: None
@ -196,7 +196,7 @@ get_mask_hash(const char *text)
return hash_text(text);
}
/* struct ConfItem* find_conf_by_address(const char*, struct rb_sockaddr_storage*,
/* struct ConfItem* find_conf_by_address(const char*, struct irc_sockaddr_storage*,
* int type, int fam, const char *username)
* Input: The hostname, the address, the type of mask to find, the address
* family, the username.
@ -343,7 +343,7 @@ find_conf_by_address(const char *name, const char *sockhost,
}
/* struct ConfItem* find_address_conf(const char*, const char*,
* struct rb_sockaddr_storage*, int);
* struct irc_sockaddr_storage*, int);
* Input: The hostname, username, address, address family.
* Output: The applicable ConfItem.
* Side-effects: None
@ -416,6 +416,21 @@ find_address_conf(const char *host, const char *sockhost, const char *user,
return iconf;
}
/* struct ConfItem* find_dline(struct irc_sockaddr_storage*, int)
* Input: An address, an address family.
* Output: The best matching D-line or exempt line.
* Side effects: None.
*/
struct ConfItem *
find_dline(struct sockaddr *addr, int aftype)
{
struct ConfItem *eline;
eline = find_conf_by_address(NULL, NULL, NULL, addr, CONF_EXEMPTDLINE | 1, aftype, NULL);
if(eline)
return eline;
return find_conf_by_address(NULL, NULL, NULL, addr, CONF_DLINE | 1, aftype, NULL);
}
/* void find_exact_conf_by_address(const char*, int, const char *)
* Input:
* Output: ConfItem if found
@ -427,7 +442,7 @@ find_exact_conf_by_address(const char *address, int type, const char *username)
int masktype, bits;
unsigned long hv;
struct AddressRec *arec;
struct rb_sockaddr_storage addr;
struct irc_sockaddr_storage addr;
if(address == NULL)
address = "/NOMATCH!/";
@ -533,7 +548,7 @@ delete_one_address_conf(const char *address, struct ConfItem *aconf)
int masktype, bits;
unsigned long hv;
struct AddressRec *arec, *arecl = NULL;
struct rb_sockaddr_storage addr;
struct irc_sockaddr_storage addr;
masktype = parse_netmask(address, (struct sockaddr *)&addr, &bits);
#ifdef IPV6
if(masktype == HM_IPV6)

View file

@ -539,7 +539,7 @@ inetpton_sock(const char *src, struct sockaddr *dst)
{
((struct sockaddr_in *) dst)->sin_port = 0;
((struct sockaddr_in *) dst)->sin_family = AF_INET;
SET_SS_LEN((struct rb_sockaddr_storage *) dst, sizeof(struct sockaddr_in));
SET_SS_LEN((struct irc_sockaddr_storage *) dst, sizeof(struct sockaddr_in));
return 1;
}
#ifdef IPV6
@ -547,7 +547,7 @@ inetpton_sock(const char *src, struct sockaddr *dst)
{
((struct sockaddr_in6 *) dst)->sin6_port = 0;
((struct sockaddr_in6 *) dst)->sin6_family = AF_INET6;
SET_SS_LEN((struct rb_sockaddr_storage *) dst, sizeof(struct sockaddr_in6));
SET_SS_LEN((struct irc_sockaddr_storage *) dst, sizeof(struct sockaddr_in6));
return 1;
}
#endif

View file

@ -78,10 +78,7 @@ extern int ServerRunning;
extern struct LocalUser meLocalUser;
extern char **myargv;
int maxconnections; /* XXX */
int ssl_ok = 0;
struct ServerStatistics ServerStats;
extern int maxconnections; /* XXX */
/*
* print_startup - print startup information
@ -502,7 +499,6 @@ main(int argc, char *argv[])
memset((void *) &Count, 0, sizeof(Count));
memset((void *) &ServerInfo, 0, sizeof(ServerInfo));
memset((void *) &AdminInfo, 0, sizeof(AdminInfo));
memset(&ServerStats, 0, sizeof(struct ServerStatistics));
/* Initialise the channel capability usage counts... */
init_chcap_usage_counts();
@ -578,6 +574,7 @@ main(int argc, char *argv[])
init_channels();
initclass();
initwhowas();
init_stats();
init_reject();
init_cache();
init_monitor();

File diff suppressed because it is too large Load diff

View file

@ -326,7 +326,7 @@ int comp_with_mask_sock(struct sockaddr *addr, struct sockaddr *dest, u_int mask
*/
int match_ips(const char *s1, const char *s2)
{
struct rb_sockaddr_storage ipaddr, maskaddr;
struct irc_sockaddr_storage ipaddr, maskaddr;
char mask[BUFSIZE];
char address[HOSTLEN + 1];
char *len;
@ -380,7 +380,7 @@ int match_ips(const char *s1, const char *s2)
int match_cidr(const char *s1, const char *s2)
{
struct rb_sockaddr_storage ipaddr, maskaddr;
struct irc_sockaddr_storage ipaddr, maskaddr;
char mask[BUFSIZE];
char address[NICKLEN + USERLEN + HOSTLEN + 6];
char *ipmask;

View file

@ -758,10 +758,9 @@ conf_set_listen_port(void *data)
}
if(listener_address == NULL)
{
/* XXX put ssl here -- dwr */
add_listener(args->v.number, listener_address, AF_INET, 0);
add_listener(args->v.number, listener_address, AF_INET);
#ifdef IPV6
add_listener(args->v.number, listener_address, AF_INET6, 0);
add_listener(args->v.number, listener_address, AF_INET6);
#endif
}
else
@ -774,7 +773,7 @@ conf_set_listen_port(void *data)
#endif
family = AF_INET;
add_listener(args->v.number, listener_address, family, 0);
add_listener(args->v.number, listener_address, family);
}

View file

@ -1,358 +1,474 @@
/*
* ircd-ratbox: A slightly useful ircd.
* packet.c: Packet handlers.
*
* Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
* Copyright (C) 1996-2002 Hybrid Development Team
* Copyright (C) 2002-2005 ircd-ratbox development team
*
* 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 2 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, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
* USA
*
* $Id: packet.c 25179 2008-03-30 16:34:57Z androsyn $
*/
#include "stdinc.h"
#include "s_conf.h"
#include "s_serv.h"
#include "client.h"
#include "ircd.h"
#include "parse.h"
#include "packet.h"
#include "hook.h"
#include "send.h"
#include "common.h"
static char readBuf[READBUF_SIZE];
static void client_dopacket(struct Client *client_p, char *buffer, size_t length);
/*
* parse_client_queued - parse client queued messages
*/
static void
parse_client_queued(struct Client *client_p)
{
int dolen = 0;
int checkflood = 1;
if(IsAnyDead(client_p))
return;
if(IsUnknown(client_p))
{
for (;;)
{
if(client_p->localClient->sent_parsed >= client_p->localClient->allow_read)
break;
dolen = rb_linebuf_get(&client_p->localClient->
buf_recvq, readBuf, READBUF_SIZE,
LINEBUF_COMPLETE, LINEBUF_PARSED);
if(dolen <= 0 || IsDead(client_p))
break;
client_dopacket(client_p, readBuf, dolen);
client_p->localClient->sent_parsed++;
/* He's dead cap'n */
if(IsAnyDead(client_p))
return;
/* if theyve dropped out of the unknown state, break and move
* to the parsing for their appropriate status. --fl
*/
if(!IsUnknown(client_p))
{
/* reset their flood limits, they're now
* graced to flood
*/
client_p->localClient->sent_parsed = 0;
break;
}
}
}
if(IsAnyServer(client_p) || IsExemptFlood(client_p))
{
while (!IsAnyDead(client_p) && (dolen = rb_linebuf_get(&client_p->localClient->buf_recvq,
readBuf, READBUF_SIZE, LINEBUF_COMPLETE,
LINEBUF_PARSED)) > 0)
{
client_dopacket(client_p, readBuf, dolen);
}
}
else if(IsClient(client_p))
{
if(IsOper(client_p) && ConfigFileEntry.no_oper_flood)
checkflood = 0;
/*
* Handle flood protection here - if we exceed our flood limit on
* messages in this loop, we simply drop out of the loop prematurely.
* -- adrian
*/
for (;;)
{
/* This flood protection works as follows:
*
* A client is given allow_read lines to send to the server. Every
* time a line is parsed, sent_parsed is increased. sent_parsed
* is decreased by 1 every time flood_recalc is called.
*
* Thus a client can 'burst' allow_read lines to the server, any
* excess lines will be parsed one per flood_recalc() call.
*
* Therefore a client will be penalised more if they keep flooding,
* as sent_parsed will always hover around the allow_read limit
* and no 'bursts' will be permitted.
*/
if(checkflood)
{
if(client_p->localClient->sent_parsed >= client_p->localClient->allow_read)
break;
}
/* allow opers 4 times the amount of messages as users. why 4?
* why not. :) --fl_
*/
else if(client_p->localClient->sent_parsed >= (4 * client_p->localClient->allow_read))
break;
dolen = rb_linebuf_get(&client_p->localClient->
buf_recvq, readBuf, READBUF_SIZE,
LINEBUF_COMPLETE, LINEBUF_PARSED);
if(!dolen)
break;
client_dopacket(client_p, readBuf, dolen);
if(IsAnyDead(client_p))
return;
client_p->localClient->sent_parsed++;
}
}
}
/*
* flood_recalc
*
* recalculate the number of allowed flood lines. this should be called
* once a second on any given client. We then attempt to flush some data.
*/
void
flood_recalc(void *unused)
{
rb_dlink_node *ptr, *next;
struct Client *client_p;
RB_DLINK_FOREACH_SAFE(ptr, next, lclient_list.head)
{
client_p = ptr->data;
if(unlikely(IsMe(client_p)))
continue;
if(unlikely(client_p->localClient == NULL))
continue;
if(IsFloodDone(client_p))
client_p->localClient->sent_parsed -= 2;
else
client_p->localClient->sent_parsed = 0;
if(client_p->localClient->sent_parsed < 0)
client_p->localClient->sent_parsed = 0;
if(--client_p->localClient->actually_read < 0)
client_p->localClient->actually_read = 0;
parse_client_queued(client_p);
if(unlikely(IsAnyDead(client_p)))
continue;
}
RB_DLINK_FOREACH_SAFE(ptr, next, unknown_list.head)
{
client_p = ptr->data;
if(client_p->localClient == NULL)
continue;
client_p->localClient->sent_parsed--;
if(client_p->localClient->sent_parsed < 0)
client_p->localClient->sent_parsed = 0;
if(--client_p->localClient->actually_read < 0)
client_p->localClient->actually_read = 0;
parse_client_queued(client_p);
}
}
/*
* read_packet - Read a 'packet' of data from a connection and process it.
*/
void
read_packet(rb_fde_t *F, void *data)
{
struct Client *client_p = data;
struct LocalUser *lclient_p = client_p->localClient;
int length = 0;
int lbuf_len;
int binary = 0;
#ifdef USE_IODEBUG_HOOKS
hook_data_int hdata;
#endif
while(1) /* note..for things like rt sigio to work you *must* loop on read until you get EAGAIN */
{
if(IsAnyDead(client_p))
return;
/*
* Read some data. We *used to* do anti-flood protection here, but
* I personally think it makes the code too hairy to make sane.
* -- adrian
*/
length = rb_read(client_p->localClient->F, readBuf, READBUF_SIZE);
if(length < 0)
{
if(rb_ignore_errno(errno))
{
rb_setselect(client_p->localClient->F,
RB_SELECT_READ, read_packet, client_p);
} else
error_exit_client(client_p, length);
return;
} else
if(length == 0)
{
error_exit_client(client_p, length);
return;
}
#ifdef USE_IODEBUG_HOOKS
hdata.client = client_p;
hdata.arg1 = readBuf;
hdata.arg2 = length;
call_hook(h_iorecv_id, &hdata);
#endif
if(client_p->localClient->lasttime < rb_current_time())
client_p->localClient->lasttime = rb_current_time();
client_p->flags &= ~FLAGS_PINGSENT;
/*
* Before we even think of parsing what we just read, stick
* it on the end of the receive queue and do it when its
* turn comes around.
*/
if(IsHandshake(client_p) || IsUnknown(client_p))
binary = 1;
lbuf_len = rb_linebuf_parse(&client_p->localClient->buf_recvq, readBuf, length, binary);
lclient_p->actually_read += lbuf_len;
if(IsAnyDead(client_p))
return;
/* Attempt to parse what we have */
parse_client_queued(client_p);
if(IsAnyDead(client_p))
return;
/* Check to make sure we're not flooding */
if(!IsAnyServer(client_p) &&
(rb_linebuf_alloclen(&client_p->localClient->buf_recvq) > ConfigFileEntry.client_flood))
{
if(!(ConfigFileEntry.no_oper_flood && IsOper(client_p)))
{
exit_client(client_p, client_p, client_p, "Excess Flood");
return;
}
}
/* bail if short read */
if(length < READBUF_SIZE)
{
rb_setselect(client_p->localClient->F, RB_SELECT_READ, read_packet, client_p);
return;
}
}
}
/*
* client_dopacket - copy packet to client buf and parse it
* client_p - pointer to client structure for which the buffer data
* applies.
* buffer - pointr to the buffer containing the newly read data
* length - number of valid bytes of data in the buffer
*
* Note:
* It is implicitly assumed that dopacket is called only
* with client_p of "local" variation, which contains all the
* necessary fields (buffer etc..)
*/
void
client_dopacket(struct Client *client_p, char *buffer, size_t length)
{
s_assert(client_p != NULL);
s_assert(buffer != NULL);
if(client_p == NULL || buffer == NULL)
return;
if(IsAnyDead(client_p))
return;
/*
* Update messages received
*/
++me.localClient->receiveM;
++client_p->localClient->receiveM;
/*
* Update bytes received
*/
client_p->localClient->receiveB += length;
me.localClient->receiveB += length;
parse(client_p, buffer, buffer + length);
}
/* flood_endgrace()
*
* marks the end of the clients grace period
*/
void
flood_endgrace(struct Client *client_p)
{
SetFloodDone(client_p);
/* Drop their flood limit back down */
client_p->localClient->allow_read = MAX_FLOOD;
/* sent_parsed could be way over MAX_FLOOD but under MAX_FLOOD_BURST,
* so reset it.
*/
client_p->localClient->sent_parsed = 0;
}
/*
* ircd-ratbox: A slightly useful ircd.
* packet.c: Packet handlers.
*
* Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
* Copyright (C) 1996-2002 Hybrid Development Team
* Copyright (C) 2002-2005 ircd-ratbox development team
*
* 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 2 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, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA
*
* $Id: packet.c 3446 2007-05-14 22:21:16Z jilles $
*/
#include "stdinc.h"
#include "s_conf.h"
#include "s_serv.h"
#include "client.h"
#include "common.h"
#include "ircd.h"
#include "parse.h"
#include "packet.h"
#include "irc_string.h"
#include "hook.h"
#include "send.h"
static char readBuf[READBUF_SIZE];
static void client_dopacket(struct Client *client_p, char *buffer, size_t length);
/*
* parse_client_queued - parse client queued messages
*/
static void
parse_client_queued(struct Client *client_p)
{
int dolen = 0;
int checkflood = 1;
if(IsAnyDead(client_p))
return;
if(IsUnknown(client_p))
{
for (;;)
{
if(client_p->localClient->sent_parsed >= client_p->localClient->allow_read)
break;
dolen = linebuf_get(&client_p->localClient->
buf_recvq, readBuf, READBUF_SIZE,
LINEBUF_COMPLETE, LINEBUF_PARSED);
if(dolen <= 0 || IsDead(client_p))
break;
client_dopacket(client_p, readBuf, dolen);
client_p->localClient->sent_parsed++;
/* He's dead cap'n */
if(IsAnyDead(client_p))
return;
/* if theyve dropped out of the unknown state, break and move
* to the parsing for their appropriate status. --fl
*/
if(!IsUnknown(client_p))
{
/* reset their flood limits, they're now
* graced to flood
*/
client_p->localClient->sent_parsed = 0;
break;
}
}
}
if(IsAnyServer(client_p) || IsExemptFlood(client_p))
{
while (!IsAnyDead(client_p) && (dolen = linebuf_get(&client_p->localClient->buf_recvq,
readBuf, READBUF_SIZE, LINEBUF_COMPLETE,
LINEBUF_PARSED)) > 0)
{
client_dopacket(client_p, readBuf, dolen);
}
}
else if(IsClient(client_p))
{
if(IsOper(client_p) && ConfigFileEntry.no_oper_flood)
checkflood = 0;
/*
* Handle flood protection here - if we exceed our flood limit on
* messages in this loop, we simply drop out of the loop prematurely.
* -- adrian
*/
for (;;)
{
/* This flood protection works as follows:
*
* A client is given allow_read lines to send to the server. Every
* time a line is parsed, sent_parsed is increased. sent_parsed
* is decreased by 1 every time flood_recalc is called.
*
* Thus a client can 'burst' allow_read lines to the server, any
* excess lines will be parsed one per flood_recalc() call.
*
* Therefore a client will be penalised more if they keep flooding,
* as sent_parsed will always hover around the allow_read limit
* and no 'bursts' will be permitted.
*/
if(checkflood)
{
if(client_p->localClient->sent_parsed >= client_p->localClient->allow_read)
break;
}
/* allow opers 4 times the amount of messages as users. why 4?
* why not. :) --fl_
*/
else if(client_p->localClient->sent_parsed >= (4 * client_p->localClient->allow_read))
break;
dolen = linebuf_get(&client_p->localClient->
buf_recvq, readBuf, READBUF_SIZE,
LINEBUF_COMPLETE, LINEBUF_PARSED);
if(!dolen)
break;
client_dopacket(client_p, readBuf, dolen);
if(IsAnyDead(client_p))
return;
client_p->localClient->sent_parsed++;
}
}
}
/* flood_endgrace()
*
* marks the end of the clients grace period
*/
void
flood_endgrace(struct Client *client_p)
{
SetFloodDone(client_p);
/* Drop their flood limit back down */
client_p->localClient->allow_read = MAX_FLOOD;
/* sent_parsed could be way over MAX_FLOOD but under MAX_FLOOD_BURST,
* so reset it.
*/
client_p->localClient->sent_parsed = 0;
}
/*
* flood_recalc
*
* recalculate the number of allowed flood lines. this should be called
* once a second on any given client. We then attempt to flush some data.
*/
void
flood_recalc(int fd, void *data)
{
struct Client *client_p = data;
struct LocalUser *lclient_p = client_p->localClient;
/* This can happen in the event that the client detached. */
if(!lclient_p)
return;
/* allow a bursting client their allocation per second, allow
* a client whos flooding an extra 2 per second
*/
if(IsFloodDone(client_p))
lclient_p->sent_parsed -= 2;
else
lclient_p->sent_parsed = 0;
if(lclient_p->sent_parsed < 0)
lclient_p->sent_parsed = 0;
if(--lclient_p->actually_read < 0)
lclient_p->actually_read = 0;
parse_client_queued(client_p);
if(IsAnyDead(client_p))
return;
/* and finally, reset the flood check */
rb_setflush(fd, 1000, flood_recalc, client_p);
}
/*
* read_ctrl_packet - Read a 'packet' of data from a servlink control
* link and process it.
*/
void
read_ctrl_packet(int fd, void *data)
{
struct Client *server = data;
struct LocalUser *lserver = server->localClient;
struct SlinkRpl *reply;
int length = 0;
unsigned char tmp[2];
unsigned char *len = tmp;
struct SlinkRplDef *replydef;
#ifdef USE_IODEBUG_HOOKS
hook_data_int hdata;
#endif
s_assert(lserver != NULL);
if(IsAnyDead(server))
return;
reply = &lserver->slinkrpl;
if(!reply->command)
{
reply->gotdatalen = 0;
reply->readdata = 0;
reply->data = NULL;
length = read(fd, tmp, 1);
if(length <= 0)
{
if((length == -1) && ignoreErrno(errno))
goto nodata;
error_exit_client(server, length);
return;
}
reply->command = tmp[0];
}
for (replydef = slinkrpltab; replydef->handler; replydef++)
{
if((int)replydef->replyid == reply->command)
break;
}
/* we should be able to trust a local slink process...
* and if it sends an invalid command, that's a bug.. */
s_assert(replydef->handler);
if((replydef->flags & SLINKRPL_FLAG_DATA) && (reply->gotdatalen < 2))
{
/* we need a datalen u16 which we don't have yet... */
length = read(fd, len, (2 - reply->gotdatalen));
if(length <= 0)
{
if((length == -1) && ignoreErrno(errno))
goto nodata;
error_exit_client(server, length);
return;
}
if(reply->gotdatalen == 0)
{
reply->datalen = *len << 8;
reply->gotdatalen++;
length--;
len++;
}
if(length && (reply->gotdatalen == 1))
{
reply->datalen |= *len;
reply->gotdatalen++;
if(reply->datalen > 0)
reply->data = rb_malloc(reply->datalen);
}
if(reply->gotdatalen < 2)
return; /* wait for more data */
}
if(reply->readdata < reply->datalen) /* try to get any remaining data */
{
length = read(fd, (reply->data + reply->readdata),
(reply->datalen - reply->readdata));
if(length <= 0)
{
if((length == -1) && ignoreErrno(errno))
goto nodata;
error_exit_client(server, length);
return;
}
reply->readdata += length;
if(reply->readdata < reply->datalen)
return; /* wait for more data */
}
#ifdef USE_IODEBUG_HOOKS
hdata.client = server;
hdata.arg1 = NULL;
hdata.arg2 = reply->command;
hdata.data = NULL;
call_hook(h_iorecvctrl_id, &hdata);
#endif
/* we now have the command and any data, pass it off to the handler */
(*replydef->handler) (reply->command, reply->datalen, reply->data, server);
/* reset SlinkRpl */
if(reply->datalen > 0)
rb_free(reply->data);
reply->command = 0;
if(IsAnyDead(server))
return;
nodata:
/* If we get here, we need to register for another COMM_SELECT_READ */
rb_setselect(fd, FDLIST_SERVER, COMM_SELECT_READ, read_ctrl_packet, server, 0);
}
/*
* read_packet - Read a 'packet' of data from a connection and process it.
*/
void
read_packet(int fd, void *data)
{
struct Client *client_p = data;
struct LocalUser *lclient_p = client_p->localClient;
int length = 0;
int lbuf_len;
int binary = 0;
#ifdef USE_IODEBUG_HOOKS
hook_data_int hdata;
#endif
if(IsAnyDead(client_p))
return;
/*
* Read some data. We *used to* do anti-flood protection here, but
* I personally think it makes the code too hairy to make sane.
* -- adrian
*/
length = client_p->localClient->F->read_impl(client_p->localClient->F, readBuf, READBUF_SIZE);
if(length <= 0)
{
if((length == -1) && ignoreErrno(errno))
{
rb_setselect(client_p->localClient->F->fd, FDLIST_IDLECLIENT,
COMM_SELECT_READ, read_packet, client_p, 0);
return;
}
error_exit_client(client_p, length);
return;
}
#ifdef USE_IODEBUG_HOOKS
hdata.client = client_p;
hdata.arg1 = readBuf;
hdata.arg2 = length;
call_hook(h_iorecv_id, &hdata);
#endif
if(client_p->localClient->lasttime < rb_current_time())
client_p->localClient->lasttime = rb_current_time();
client_p->flags &= ~FLAGS_PINGSENT;
/*
* Before we even think of parsing what we just read, stick
* it on the end of the receive queue and do it when its
* turn comes around.
*/
if(IsHandshake(client_p) || IsUnknown(client_p))
binary = 1;
lbuf_len = linebuf_parse(&client_p->localClient->buf_recvq, readBuf, length, binary);
lclient_p->actually_read += lbuf_len;
if(IsAnyDead(client_p))
return;
/* Attempt to parse what we have */
parse_client_queued(client_p);
if(IsAnyDead(client_p))
return;
/* Check to make sure we're not flooding */
if(!IsAnyServer(client_p) &&
(linebuf_alloclen(&client_p->localClient->buf_recvq) > ConfigFileEntry.client_flood))
{
if(!(ConfigFileEntry.no_oper_flood && IsOper(client_p)))
{
exit_client(client_p, client_p, client_p, "Excess Flood");
return;
}
}
/* If we get here, we need to register for another COMM_SELECT_READ */
if(PARSE_AS_SERVER(client_p))
{
rb_setselect(client_p->localClient->F->fd, FDLIST_SERVER, COMM_SELECT_READ,
read_packet, client_p, 0);
}
else
{
rb_setselect(client_p->localClient->F->fd, FDLIST_IDLECLIENT,
COMM_SELECT_READ, read_packet, client_p, 0);
}
}
/*
* client_dopacket - copy packet to client buf and parse it
* client_p - pointer to client structure for which the buffer data
* applies.
* buffer - pointr to the buffer containing the newly read data
* length - number of valid bytes of data in the buffer
*
* Note:
* It is implicitly assumed that dopacket is called only
* with client_p of "local" variation, which contains all the
* necessary fields (buffer etc..)
*/
void
client_dopacket(struct Client *client_p, char *buffer, size_t length)
{
s_assert(client_p != NULL);
s_assert(buffer != NULL);
if(client_p == NULL || buffer == NULL)
return;
if(IsAnyDead(client_p))
return;
/*
* Update messages received
*/
++me.localClient->receiveM;
++client_p->localClient->receiveM;
/*
* Update bytes received
*/
client_p->localClient->receiveB += length;
if(client_p->localClient->receiveB > 1023)
{
client_p->localClient->receiveK += (client_p->localClient->receiveB >> 10);
client_p->localClient->receiveB &= 0x03ff; /* 2^10 = 1024, 3ff = 1023 */
}
me.localClient->receiveB += length;
if(me.localClient->receiveB > 1023)
{
me.localClient->receiveK += (me.localClient->receiveB >> 10);
me.localClient->receiveB &= 0x03ff;
}
parse(client_p, buffer, buffer + length);
}

View file

@ -162,7 +162,7 @@ parse(struct Client *client_p, char *pbuffer, char *bufend)
/* didnt find any matching client, issue a kill */
if(from == NULL)
{
ServerStats.is_unpf++;
ServerStats->is_unpf++;
remove_unknown(client_p, sender, pbuffer);
return;
}
@ -172,7 +172,7 @@ parse(struct Client *client_p, char *pbuffer, char *bufend)
/* fake direction, hmm. */
if(from->from != client_p)
{
ServerStats.is_wrdi++;
ServerStats->is_wrdi++;
cancel_clients(client_p, from, pbuffer);
return;
}
@ -183,7 +183,7 @@ parse(struct Client *client_p, char *pbuffer, char *bufend)
if(*ch == '\0')
{
ServerStats.is_empt++;
ServerStats->is_empt++;
return;
}
@ -204,7 +204,7 @@ parse(struct Client *client_p, char *pbuffer, char *bufend)
{
mptr = NULL;
numeric = ch;
ServerStats.is_num++;
ServerStats->is_num++;
s = ch + 3; /* I know this is ' ' from above if */
*s++ = '\0'; /* blow away the ' ', and point s to next part */
}
@ -248,7 +248,7 @@ parse(struct Client *client_p, char *pbuffer, char *bufend)
me.name, from->name, ch);
}
}
ServerStats.is_unco++;
ServerStats->is_unco++;
return;
}

View file

@ -1,589 +1,303 @@
/*
* ircd-ratbox: A slightly useful ircd
* reject.c: reject users with prejudice
*
* Copyright (C) 2003 Aaron Sethman <androsyn@ratbox.org>
* Copyright (C) 2003-2005 ircd-ratbox development team
*
* 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 2 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, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
* USA
*
* $Id: reject.c 25119 2008-03-13 16:57:05Z androsyn $
*/
#include "stdinc.h"
#include "client.h"
#include "s_conf.h"
#include "reject.h"
#include "s_stats.h"
#include "ircd.h"
#include "send.h"
#include "numeric.h"
#include "parse.h"
#include "hostmask.h"
static rb_patricia_tree_t *global_tree;
static rb_patricia_tree_t *reject_tree;
static rb_patricia_tree_t *dline_tree;
static rb_patricia_tree_t *eline_tree;
static rb_dlink_list delay_exit;
static rb_dlink_list reject_list;
static rb_dlink_list throttle_list;
static rb_patricia_tree_t *throttle_tree;
static void throttle_expires(void *unused);
typedef struct _reject_data
{
rb_dlink_node rnode;
time_t time;
unsigned int count;
} reject_t;
typedef struct _delay_data
{
rb_dlink_node node;
rb_fde_t *F;
} delay_t;
typedef struct _throttle
{
rb_dlink_node node;
time_t last;
int count;
} throttle_t;
typedef struct _global_data
{
int count;
} global_t;
static rb_patricia_node_t *
add_ipline(struct ConfItem *aconf, rb_patricia_tree_t *tree, struct sockaddr *addr, int cidr)
{
rb_patricia_node_t *pnode;
pnode = make_and_lookup_ip(tree, addr, cidr);
if(pnode == NULL)
return NULL;
aconf->pnode = pnode;
pnode->data = aconf;
return (pnode);
}
int
add_dline(struct ConfItem *aconf)
{
struct rb_sockaddr_storage st;
int bitlen;
if(parse_netmask(aconf->host, (struct sockaddr *)&st, &bitlen) == HM_HOST)
return 0;
if(add_ipline(aconf, dline_tree, (struct sockaddr *)&st, bitlen) != NULL)
return 1;
return 0;
}
int
add_eline(struct ConfItem *aconf)
{
struct rb_sockaddr_storage st;
int bitlen;
if(parse_netmask(aconf->host, (struct sockaddr *)&st, &bitlen) == HM_HOST)
return 0;
if(add_ipline(aconf, eline_tree, (struct sockaddr *)&st, bitlen) != NULL)
return 1;
return 0;
}
unsigned long
delay_exit_length(void)
{
return rb_dlink_list_length(&delay_exit);
}
static void
reject_exit(void *unused)
{
rb_dlink_node *ptr, *ptr_next;
delay_t *ddata;
static const char *errbuf = "ERROR :Closing Link: (*** Banned (cache))\r\n";
RB_DLINK_FOREACH_SAFE(ptr, ptr_next, delay_exit.head)
{
ddata = ptr->data;
rb_write(ddata->F, errbuf, strlen(errbuf));
rb_close(ddata->F);
rb_free(ddata);
}
delay_exit.head = delay_exit.tail = NULL;
delay_exit.length = 0;
}
static void
reject_expires(void *unused)
{
rb_dlink_node *ptr, *next;
rb_patricia_node_t *pnode;
reject_t *rdata;
RB_DLINK_FOREACH_SAFE(ptr, next, reject_list.head)
{
pnode = ptr->data;
rdata = pnode->data;
if(rdata->time + ConfigFileEntry.reject_duration > rb_current_time())
continue;
rb_dlinkDelete(ptr, &reject_list);
rb_free(rdata);
rb_patricia_remove(reject_tree, pnode);
}
}
void
init_reject(void)
{
reject_tree = rb_new_patricia(PATRICIA_BITS);
dline_tree = rb_new_patricia(PATRICIA_BITS);
eline_tree = rb_new_patricia(PATRICIA_BITS);
throttle_tree = rb_new_patricia(PATRICIA_BITS);
global_tree = rb_new_patricia(PATRICIA_BITS);
rb_event_add("reject_exit", reject_exit, NULL, DELAYED_EXIT_TIME);
rb_event_add("reject_expires", reject_expires, NULL, 60);
rb_event_add("throttle_expires", throttle_expires, NULL, 10);
}
void
add_reject(struct Client *client_p)
{
rb_patricia_node_t *pnode;
reject_t *rdata;
/* Reject is disabled */
if(ConfigFileEntry.reject_after_count == 0 || ConfigFileEntry.reject_duration == 0)
return;
if((pnode = rb_match_ip(reject_tree, (struct sockaddr *)&client_p->localClient->ip)) != NULL)
{
rdata = pnode->data;
rdata->time = rb_current_time();
rdata->count++;
}
else
{
int bitlen = 32;
#ifdef RB_IPV6
if(GET_SS_FAMILY(&client_p->localClient->ip) == AF_INET6)
bitlen = 128;
#endif
pnode = make_and_lookup_ip(reject_tree, (struct sockaddr *)&client_p->localClient->ip, bitlen);
pnode->data = rdata = rb_malloc(sizeof(reject_t));
rb_dlinkAddTail(pnode, &rdata->rnode, &reject_list);
rdata->time = rb_current_time();
rdata->count = 1;
}
}
int
check_reject(rb_fde_t *F, struct sockaddr *addr)
{
rb_patricia_node_t *pnode;
reject_t *rdata;
delay_t *ddata;
/* Reject is disabled */
if(ConfigFileEntry.reject_after_count == 0 || ConfigFileEntry.reject_duration == 0)
return 0;
pnode = rb_match_ip(reject_tree, addr);
if(pnode != NULL)
{
rdata = pnode->data;
rdata->time = rb_current_time();
if(rdata->count > (unsigned long)ConfigFileEntry.reject_after_count)
{
ddata = rb_malloc(sizeof(delay_t));
ServerStats.is_rej++;
rb_setselect(F, RB_SELECT_WRITE | RB_SELECT_READ, NULL, NULL);
ddata->F = F;
rb_dlinkAdd(ddata, &ddata->node, &delay_exit);
return 1;
}
}
/* Caller does what it wants */
return 0;
}
void
flush_reject(void)
{
rb_dlink_node *ptr, *next;
rb_patricia_node_t *pnode;
reject_t *rdata;
RB_DLINK_FOREACH_SAFE(ptr, next, reject_list.head)
{
pnode = ptr->data;
rdata = pnode->data;
rb_dlinkDelete(ptr, &reject_list);
rb_free(rdata);
rb_patricia_remove(reject_tree, pnode);
}
}
int
remove_reject(const char *ip)
{
rb_patricia_node_t *pnode;
/* Reject is disabled */
if(ConfigFileEntry.reject_after_count == 0 || ConfigFileEntry.reject_duration == 0)
return -1;
if((pnode = rb_match_string(reject_tree, ip)) != NULL)
{
reject_t *rdata = pnode->data;
rb_dlinkDelete(&rdata->rnode, &reject_list);
rb_free(rdata);
rb_patricia_remove(reject_tree, pnode);
return 1;
}
return 0;
}
static void
delete_ipline(struct ConfItem *aconf, rb_patricia_tree_t *t)
{
rb_patricia_remove(t, aconf->pnode);
if(!aconf->clients)
{
free_conf(aconf);
}
}
static struct ConfItem *
find_ipline(rb_patricia_tree_t *t, struct sockaddr *addr)
{
rb_patricia_node_t *pnode;
pnode = rb_match_ip(t, addr);
if(pnode != NULL)
return (struct ConfItem *) pnode->data;
return NULL;
}
static struct ConfItem *
find_ipline_exact(rb_patricia_tree_t *t, struct sockaddr *addr, unsigned int bitlen)
{
rb_patricia_node_t *pnode;
pnode = rb_match_ip_exact(t, addr, bitlen);
if(pnode != NULL)
return (struct ConfItem *) pnode->data;
return NULL;
}
struct ConfItem *
find_dline(struct sockaddr *addr)
{
struct ConfItem *aconf;
aconf = find_ipline(eline_tree, addr);
if(aconf != NULL)
{
return aconf;
}
return (find_ipline(dline_tree, addr));
}
struct ConfItem *
find_dline_exact(struct sockaddr *addr, unsigned int bitlen)
{
return find_ipline_exact(dline_tree, addr, bitlen);
}
void
remove_dline(struct ConfItem *aconf)
{
delete_ipline(aconf, dline_tree);
}
void
report_dlines(struct Client *source_p)
{
rb_patricia_node_t *pnode;
struct ConfItem *aconf;
const char *host, *pass, *user, *oper_reason;
RB_PATRICIA_WALK(dline_tree->head, pnode)
{
aconf = pnode->data;
if(aconf->flags & CONF_FLAGS_TEMPORARY)
RB_PATRICIA_WALK_BREAK;
get_printable_kline(source_p, aconf, &host, &pass, &user, &oper_reason);
sendto_one_numeric(source_p, RPL_STATSDLINE,
form_str (RPL_STATSDLINE),
'D', host, pass,
oper_reason ? "|" : "",
oper_reason ? oper_reason : "");
}
RB_PATRICIA_WALK_END;
}
void
report_tdlines(struct Client *source_p)
{
rb_patricia_node_t *pnode;
struct ConfItem *aconf;
const char *host, *pass, *user, *oper_reason;
RB_PATRICIA_WALK(dline_tree->head, pnode)
{
aconf = pnode->data;
if(!(aconf->flags & CONF_FLAGS_TEMPORARY))
RB_PATRICIA_WALK_BREAK;
get_printable_kline(source_p, aconf, &host, &pass, &user, &oper_reason);
sendto_one_numeric(source_p, RPL_STATSDLINE,
form_str (RPL_STATSDLINE),
'd', host, pass,
oper_reason ? "|" : "",
oper_reason ? oper_reason : "");
}
RB_PATRICIA_WALK_END;
}
void
report_elines(struct Client *source_p)
{
rb_patricia_node_t *pnode;
struct ConfItem *aconf;
int port;
const char *name, *host, *pass, *user, *classname;
RB_PATRICIA_WALK(eline_tree->head, pnode)
{
aconf = pnode->data;
get_printable_conf(aconf, &name, &host, &pass, &user, &port, &classname);
sendto_one_numeric(source_p, RPL_STATSDLINE,
form_str (RPL_STATSDLINE),
'e', host, pass,
"", "");
}
RB_PATRICIA_WALK_END;
}
int
throttle_add(struct sockaddr *addr)
{
throttle_t *t;
rb_patricia_node_t *pnode;
if((pnode = rb_match_ip(throttle_tree, addr)) != NULL)
{
t = pnode->data;
if(t->count > ConfigFileEntry.throttle_count)
return 1;
/* Stop penalizing them after they've been throttled */
t->last = rb_current_time();
t->count++;
} else {
int bitlen = 32;
#ifdef RB_IPV6
if(GET_SS_FAMILY(addr) == AF_INET6)
bitlen = 128;
#endif
t = rb_malloc(sizeof(throttle_t));
t->last = rb_current_time();
t->count = 1;
pnode = make_and_lookup_ip(throttle_tree, addr, bitlen);
pnode->data = t;
rb_dlinkAdd(pnode, &t->node, &throttle_list);
}
return 0;
}
static void
throttle_expires(void *unused)
{
rb_dlink_node *ptr, *next;
rb_patricia_node_t *pnode;
throttle_t *t;
RB_DLINK_FOREACH_SAFE(ptr, next, throttle_list.head)
{
pnode = ptr->data;
t = pnode->data;
if(t->last + ConfigFileEntry.throttle_duration > rb_current_time())
continue;
rb_dlinkDelete(ptr, &throttle_list);
rb_free(t);
rb_patricia_remove(throttle_tree, pnode);
}
}
static int
get_global_count(struct sockaddr *addr)
{
rb_patricia_node_t *pnode;
global_t *glb;
if((pnode = rb_match_ip(global_tree, addr)))
{
glb = pnode->data;
return glb->count;
}
return 0;
}
static int
inc_global_ip(struct sockaddr *addr, int bitlen)
{
rb_patricia_node_t *pnode;
global_t *glb;
if((pnode = rb_match_ip(global_tree, addr)))
{
glb = pnode->data;
}
else
{
pnode = make_and_lookup_ip(global_tree, addr, bitlen);
glb = rb_malloc(sizeof(global_t));
pnode->data = glb;
}
glb->count++;
return glb->count;
}
static void
dec_global_ip(struct sockaddr *addr)
{
rb_patricia_node_t *pnode;
global_t *glb;
if((pnode = rb_match_ip(global_tree, addr)))
{
glb = pnode->data;
glb->count--;
if(glb->count == 0)
{
rb_free(glb);
rb_patricia_remove(global_tree, pnode);
return;
}
}
}
int
inc_global_cidr_count(struct Client *client_p)
{
struct rb_sockaddr_storage ip;
struct sockaddr *addr;
int bitlen;
if(!MyClient(client_p))
{
if(EmptyString(client_p->sockhost) || !strcmp(client_p->sockhost, "0"))
return -1;
if(!rb_inet_pton_sock(client_p->sockhost, (struct sockaddr *)&ip))
return -1;
addr = (struct sockaddr *)&ip;
} else
addr = (struct sockaddr *)&client_p->localClient->ip;
#ifdef RB_IPV6
if(GET_SS_FAMILY(addr) == AF_INET6)
{
bitlen = ConfigFileEntry.global_cidr_ipv6_bitlen;
} else
#endif
bitlen = ConfigFileEntry.global_cidr_ipv4_bitlen;
return inc_global_ip(addr, bitlen);
}
void
dec_global_cidr_count(struct Client *client_p)
{
struct rb_sockaddr_storage ip;
struct sockaddr *addr;
if(!MyClient(client_p))
{
if(EmptyString(client_p->sockhost) || !strcmp(client_p->sockhost, "0"))
return;
if(!rb_inet_pton_sock(client_p->sockhost, (struct sockaddr *)&ip))
return;
addr = (struct sockaddr *)&ip;
} else
addr = (struct sockaddr *)&client_p->localClient->ip;
dec_global_ip(addr);
}
int
check_global_cidr_count(struct Client *client_p)
{
struct rb_sockaddr_storage ip;
struct sockaddr *addr;
int count, max;
if(!MyClient(client_p))
{
if(EmptyString(client_p->sockhost) || !strcmp(client_p->sockhost, "0"))
return -1;
if(!rb_inet_pton_sock(client_p->sockhost, (struct sockaddr *)&ip))
return -1;
addr = (struct sockaddr *)&ip;
} else
addr = (struct sockaddr *)&client_p->localClient->ip;
count = get_global_count(addr);
#ifdef RB_IPV6
if(GET_SS_FAMILY(addr) == AF_INET6)
max = ConfigFileEntry.global_cidr_ipv6_count;
else
#endif
max = ConfigFileEntry.global_cidr_ipv4_count;
if(count >= max)
return 1;
return 0;
}
static void
clear_cidr_tree(void *data)
{
rb_free(data);
}
void
rehash_global_cidr_tree(void)
{
struct Client *client_p;
rb_dlink_node *ptr;
rb_clear_patricia(global_tree, clear_cidr_tree);
RB_DLINK_FOREACH(ptr, global_client_list.head)
{
client_p = ptr->data;
if(IsMe(client_p) && IsServer(client_p))
continue;
inc_global_cidr_count(client_p);
}
return;
}
/*
* ircd-ratbox: A slightly useful ircd
* reject.c: reject users with prejudice
*
* Copyright (C) 2003 Aaron Sethman <androsyn@ratbox.org>
* Copyright (C) 2003-2005 ircd-ratbox development team
*
* 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 2 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, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA
*
* $Id: reject.c 3456 2007-05-18 19:14:18Z jilles $
*/
#include "stdinc.h"
#include "config.h"
#include "patricia.h"
#include "client.h"
#include "s_conf.h"
#include "reject.h"
#include "s_stats.h"
#include "msg.h"
#include "hash.h"
static patricia_tree_t *reject_tree;
rb_dlink_list delay_exit;
static rb_dlink_list reject_list;
static patricia_tree_t *unknown_tree;
struct reject_data
{
rb_dlink_node rnode;
time_t time;
unsigned int count;
uint32_t mask_hashv;
};
static patricia_tree_t *unknown_tree;
static void
reject_exit(void *unused)
{
struct Client *client_p;
rb_dlink_node *ptr, *ptr_next;
RB_DLINK_FOREACH_SAFE(ptr, ptr_next, delay_exit.head)
{
client_p = ptr->data;
if(IsDead(client_p))
continue;
/* this MUST be here, to prevent the possibility
* sendto_one() generates a write error, and then a client
* ends up on the dead_list and the abort_list --fl
*
* new disconnect notice stolen from ircu --nenolod
* no, this only happens when someone's IP has some
* ban on it and rejects them rather longer than the
* ircu message suggests --jilles
*/
if(!IsIOError(client_p))
{
if(IsExUnknown(client_p))
sendto_one(client_p, "ERROR :Closing Link: %s (*** Too many unknown connections)", client_p->host);
else
sendto_one(client_p, "ERROR :Closing Link: %s (*** Banned (cache))", client_p->host);
}
close_connection(client_p);
SetDead(client_p);
rb_dlinkAddAlloc(client_p, &dead_list);
}
delay_exit.head = delay_exit.tail = NULL;
delay_exit.length = 0;
}
static void
reject_expires(void *unused)
{
rb_dlink_node *ptr, *next;
patricia_node_t *pnode;
struct reject_data *rdata;
RB_DLINK_FOREACH_SAFE(ptr, next, reject_list.head)
{
pnode = ptr->data;
rdata = pnode->data;
if(rdata->time + ConfigFileEntry.reject_duration > rb_current_time())
continue;
rb_dlinkDelete(ptr, &reject_list);
rb_free(rdata);
patricia_remove(reject_tree, pnode);
}
}
void
init_reject(void)
{
reject_tree = New_Patricia(PATRICIA_BITS);
unknown_tree = New_Patricia(PATRICIA_BITS);
rb_event_add("reject_exit", reject_exit, NULL, DELAYED_EXIT_TIME);
rb_event_add("reject_expires", reject_expires, NULL, 60);
}
void
add_reject(struct Client *client_p, const char *mask1, const char *mask2)
{
patricia_node_t *pnode;
struct reject_data *rdata;
uint32_t hashv;
/* Reject is disabled */
if(ConfigFileEntry.reject_after_count == 0 || ConfigFileEntry.reject_ban_time == 0)
return;
hashv = 0;
if (mask1 != NULL)
hashv ^= fnv_hash_upper(mask1, 32);
if (mask2 != NULL)
hashv ^= fnv_hash_upper(mask2, 32);
if((pnode = match_ip(reject_tree, (struct sockaddr *)&client_p->localClient->ip)) != NULL)
{
rdata = pnode->data;
rdata->time = rb_current_time();
rdata->count++;
}
else
{
int bitlen = 32;
#ifdef IPV6
if(client_p->localClient->ip.ss_family == AF_INET6)
bitlen = 128;
#endif
pnode = make_and_lookup_ip(reject_tree, (struct sockaddr *)&client_p->localClient->ip, bitlen);
pnode->data = rdata = rb_malloc(sizeof(struct reject_data));
rb_dlinkAddTail(pnode, &rdata->rnode, &reject_list);
rdata->time = rb_current_time();
rdata->count = 1;
}
rdata->mask_hashv = hashv;
}
int
check_reject(struct Client *client_p)
{
patricia_node_t *pnode;
struct reject_data *rdata;
/* Reject is disabled */
if(ConfigFileEntry.reject_after_count == 0 || ConfigFileEntry.reject_ban_time == 0 ||
ConfigFileEntry.reject_duration == 0)
return 0;
pnode = match_ip(reject_tree, (struct sockaddr *)&client_p->localClient->ip);
if(pnode != NULL)
{
rdata = pnode->data;
rdata->time = rb_current_time();
if(rdata->count > ConfigFileEntry.reject_after_count)
{
ServerStats->is_rej++;
SetReject(client_p);
rb_setselect(client_p->localClient->F->fd, FDLIST_NONE, COMM_SELECT_WRITE | COMM_SELECT_READ, NULL, NULL, 0);
SetClosing(client_p);
rb_dlinkMoveNode(&client_p->localClient->tnode, &unknown_list, &delay_exit);
return 1;
}
}
/* Caller does what it wants */
return 0;
}
void
flush_reject(void)
{
rb_dlink_node *ptr, *next;
patricia_node_t *pnode;
struct reject_data *rdata;
RB_DLINK_FOREACH_SAFE(ptr, next, reject_list.head)
{
pnode = ptr->data;
rdata = pnode->data;
rb_dlinkDelete(ptr, &reject_list);
rb_free(rdata);
patricia_remove(reject_tree, pnode);
}
}
int
remove_reject_ip(const char *ip)
{
patricia_node_t *pnode;
/* Reject is disabled */
if(ConfigFileEntry.reject_after_count == 0 || ConfigFileEntry.reject_ban_time == 0 ||
ConfigFileEntry.reject_duration == 0)
return -1;
if((pnode = match_string(reject_tree, ip)) != NULL)
{
struct reject_data *rdata = pnode->data;
rb_dlinkDelete(&rdata->rnode, &reject_list);
rb_free(rdata);
patricia_remove(reject_tree, pnode);
return 1;
}
return 0;
}
int
remove_reject_mask(const char *mask1, const char *mask2)
{
rb_dlink_node *ptr, *next;
patricia_node_t *pnode;
struct reject_data *rdata;
uint32_t hashv;
int n = 0;
hashv = 0;
if (mask1 != NULL)
hashv ^= fnv_hash_upper(mask1, 32);
if (mask2 != NULL)
hashv ^= fnv_hash_upper(mask2, 32);
RB_DLINK_FOREACH_SAFE(ptr, next, reject_list.head)
{
pnode = ptr->data;
rdata = pnode->data;
if (rdata->mask_hashv == hashv)
{
rb_dlinkDelete(ptr, &reject_list);
rb_free(rdata);
patricia_remove(reject_tree, pnode);
n++;
}
}
return n;
}
int
add_unknown_ip(struct Client *client_p)
{
patricia_node_t *pnode;
if((pnode = match_ip(unknown_tree, (struct sockaddr *)&client_p->localClient->ip)) == NULL)
{
int bitlen = 32;
#ifdef IPV6
if(client_p->localClient->ip.ss_family == AF_INET6)
bitlen = 128;
#endif
pnode = make_and_lookup_ip(unknown_tree, (struct sockaddr *)&client_p->localClient->ip, bitlen);
pnode->data = (void *)0;
}
if((unsigned long)pnode->data >= ConfigFileEntry.max_unknown_ip)
{
SetExUnknown(client_p);
SetReject(client_p);
rb_setselect(client_p->localClient->F->fd, FDLIST_NONE, COMM_SELECT_WRITE | COMM_SELECT_READ, NULL, NULL, 0);
SetClosing(client_p);
rb_dlinkMoveNode(&client_p->localClient->tnode, &unknown_list, &delay_exit);
return 1;
}
pnode->data = (void *)((unsigned long)pnode->data + 1);
return 0;
}
void
del_unknown_ip(struct Client *client_p)
{
patricia_node_t *pnode;
if((pnode = match_ip(unknown_tree, (struct sockaddr *)&client_p->localClient->ip)) != NULL)
{
pnode->data = (void *)((unsigned long)pnode->data - 1);
if((unsigned long)pnode->data <= 0)
{
patricia_remove(unknown_tree, pnode);
}
}
/* this can happen due to m_webirc.c's manipulations, for example */
}

View file

@ -79,7 +79,7 @@ struct reslist
char resend; /* send flag. 0 == dont resend */
time_t sentat;
time_t timeout;
struct rb_sockaddr_storage addr;
struct irc_sockaddr_storage addr;
char *name;
struct DNSQuery *query; /* query callback for this request */
};
@ -90,7 +90,7 @@ static rb_dlink_list request_list = { NULL, NULL, 0 };
static void rem_request(struct reslist *request);
static struct reslist *make_request(struct DNSQuery *query);
static void do_query_name(struct DNSQuery *query, const char *name, struct reslist *request, int);
static void do_query_number(struct DNSQuery *query, const struct rb_sockaddr_storage *,
static void do_query_number(struct DNSQuery *query, const struct irc_sockaddr_storage *,
struct reslist *request);
static void query_name(struct reslist *request);
static int send_res_msg(const char *buf, int len, int count);
@ -100,7 +100,7 @@ static int proc_answer(struct reslist *request, HEADER * header, char *, char *)
static struct reslist *find_id(int id);
static struct DNSReply *make_dnsreply(struct reslist *request);
extern struct rb_sockaddr_storage irc_nsaddr_list[IRCD_MAXNS];
extern struct irc_sockaddr_storage irc_nsaddr_list[IRCD_MAXNS];
extern int irc_nscount;
extern char irc_domain[HOSTLEN + 1];
@ -116,7 +116,7 @@ extern char irc_domain[HOSTLEN + 1];
* paul vixie, 29may94
* revised for ircd, cryogen(stu) may03
*/
static int res_ourserver(const struct rb_sockaddr_storage *inp)
static int res_ourserver(const struct irc_sockaddr_storage *inp)
{
#ifdef IPV6
struct sockaddr_in6 *v6;
@ -128,7 +128,7 @@ static int res_ourserver(const struct rb_sockaddr_storage *inp)
for (ns = 0; ns < irc_nscount; ns++)
{
const struct rb_sockaddr_storage *srv = &irc_nsaddr_list[ns];
const struct irc_sockaddr_storage *srv = &irc_nsaddr_list[ns];
#ifdef IPV6
v6 = (struct sockaddr_in6 *)srv;
#endif
@ -392,7 +392,7 @@ void gethost_byname_type(const char *name, struct DNSQuery *query, int type)
/*
* gethost_byaddr - get host name from address
*/
void gethost_byaddr(const struct rb_sockaddr_storage *addr, struct DNSQuery *query)
void gethost_byaddr(const struct irc_sockaddr_storage *addr, struct DNSQuery *query)
{
do_query_number(query, addr, NULL);
}
@ -424,7 +424,7 @@ static void do_query_name(struct DNSQuery *query, const char *name, struct resli
/*
* do_query_number - Use this to do reverse IP# lookups.
*/
static void do_query_number(struct DNSQuery *query, const struct rb_sockaddr_storage *addr,
static void do_query_number(struct DNSQuery *query, const struct irc_sockaddr_storage *addr,
struct reslist *request)
{
const unsigned char *cp;
@ -432,7 +432,7 @@ static void do_query_number(struct DNSQuery *query, const struct rb_sockaddr_sto
if (request == NULL)
{
request = make_request(query);
memcpy(&request->addr, addr, sizeof(struct rb_sockaddr_storage));
memcpy(&request->addr, addr, sizeof(struct irc_sockaddr_storage));
request->name = (char *)rb_malloc(HOSTLEN + 1);
}
@ -734,8 +734,8 @@ static void res_readreply(int fd, void *data)
struct DNSReply *reply = NULL;
int rc;
int answer_count;
socklen_t len = sizeof(struct rb_sockaddr_storage);
struct rb_sockaddr_storage lsin;
socklen_t len = sizeof(struct irc_sockaddr_storage);
struct irc_sockaddr_storage lsin;
rc = recvfrom(fd, buf, sizeof(buf), 0, (struct sockaddr *)&lsin, &len);

View file

@ -96,7 +96,7 @@
/* $Id: reslib.c 1695 2006-06-27 15:11:23Z jilles $ */
/* from Hybrid Id: reslib.c 177 2005-10-22 09:05:05Z michael $ */
struct rb_sockaddr_storage irc_nsaddr_list[IRCD_MAXNS];
struct irc_sockaddr_storage irc_nsaddr_list[IRCD_MAXNS];
int irc_nscount = 0;
char irc_domain[HOSTLEN + 1];

View file

@ -243,7 +243,7 @@ auth_dns_callback(void *vptr, struct DNSReply *reply)
static void
auth_error(struct AuthRequest *auth)
{
++ServerStats.is_abad;
++ServerStats->is_abad;
rb_close(auth->fd);
auth->fd = -1;
@ -265,8 +265,8 @@ auth_error(struct AuthRequest *auth)
static int
start_auth_query(struct AuthRequest *auth)
{
struct rb_sockaddr_storage localaddr;
socklen_t locallen = sizeof(struct rb_sockaddr_storage);
struct irc_sockaddr_storage localaddr;
socklen_t locallen = sizeof(struct irc_sockaddr_storage);
int fd;
int family;
@ -279,7 +279,7 @@ start_auth_query(struct AuthRequest *auth)
report_error("creating auth stream socket %s:%s",
get_client_name(auth->client, SHOW_IP),
log_client_name(auth->client, SHOW_IP), errno);
++ServerStats.is_abad;
++ServerStats->is_abad;
return 0;
}
@ -441,7 +441,7 @@ timeout_auth_queries_event(void *notused)
if(IsDoingAuth(auth))
{
ClearAuth(auth);
++ServerStats.is_abad;
++ServerStats->is_abad;
sendheader(auth->client, REPORT_FAIL_ID);
auth->client->localClient->auth_request = NULL;
}
@ -571,14 +571,14 @@ read_auth_reply(int fd, void *data)
if(s == NULL)
{
++ServerStats.is_abad;
++ServerStats->is_abad;
strcpy(auth->client->username, "unknown");
sendheader(auth->client, REPORT_FAIL_ID);
}
else
{
sendheader(auth->client, REPORT_FIN_ID);
++ServerStats.is_asuc;
++ServerStats->is_asuc;
SetGotId(auth->client);
}

View file

@ -195,7 +195,7 @@ check_client(struct Client *client_p, struct Client *source_p, const char *usern
source_p->name, IsGotId(source_p) ? "" : "~",
source_p->username, source_p->sockhost);
ServerStats.is_ref++;
ServerStats->is_ref++;
exit_client(client_p, source_p, &me, "Too many host connections (local)");
break;
@ -209,7 +209,7 @@ check_client(struct Client *client_p, struct Client *source_p, const char *usern
source_p->name, IsGotId(source_p) ? "" : "~",
source_p->username, source_p->sockhost);
ServerStats.is_ref++;
ServerStats->is_ref++;
exit_client(client_p, source_p, &me, "Too many host connections (global)");
break;
@ -223,7 +223,7 @@ check_client(struct Client *client_p, struct Client *source_p, const char *usern
source_p->name, IsGotId(source_p) ? "" : "~",
source_p->username, source_p->sockhost);
ServerStats.is_ref++;
ServerStats->is_ref++;
exit_client(client_p, source_p, &me, "Too many user connections (global)");
break;
@ -238,7 +238,7 @@ check_client(struct Client *client_p, struct Client *source_p, const char *usern
source_p->name, IsGotId(source_p) ? "" : "~",
source_p->username, source_p->sockhost);
ServerStats.is_ref++;
ServerStats->is_ref++;
exit_client(client_p, source_p, &me,
"No more connections allowed in your connection class");
break;
@ -253,7 +253,7 @@ check_client(struct Client *client_p, struct Client *source_p, const char *usern
#endif
port = ntohs(((struct sockaddr_in *)&source_p->localClient->listener->addr)->sin_port);
ServerStats.is_ref++;
ServerStats->is_ref++;
/* jdc - lists server name & port connections are on */
/* a purely cosmetical change */
/* why ipaddr, and not just source_p->sockhost? --fl */
@ -281,7 +281,7 @@ check_client(struct Client *client_p, struct Client *source_p, const char *usern
}
case BANNED_CLIENT:
exit_client(client_p, client_p, &me, "*** Banned ");
ServerStats.is_ref++;
ServerStats->is_ref++;
break;
case 0:
@ -1120,21 +1120,21 @@ get_printable_conf(struct ConfItem *aconf, char **name, char **host,
*port = (int) aconf->port;
}
void
get_printable_kline(struct Client *source_p, struct ConfItem *aconf,
const char **host, const char **reason,
const char **user, const char **oper_reason)
{
static const char *null = "<NULL>";
*host = EmptyString(aconf->host) ? null : aconf->host;
*reason = EmptyString(aconf->passwd) ? null : aconf->passwd;
*user = EmptyString(aconf->user) ? null : aconf->user;
if(EmptyString(aconf->spasswd) || !IsOper(source_p))
*oper_reason = NULL;
else
*oper_reason = aconf->spasswd;
void
get_printable_kline(struct Client *source_p, struct ConfItem *aconf,
char **host, char **reason,
char **user, char **oper_reason)
{
static char null[] = "<NULL>";
*host = EmptyString(aconf->host) ? null : aconf->host;
*reason = EmptyString(aconf->passwd) ? null : aconf->passwd;
*user = EmptyString(aconf->user) ? null : aconf->user;
if(EmptyString(aconf->spasswd) || !IsOper(source_p))
*oper_reason = NULL;
else
*oper_reason = aconf->spasswd;
}
/*

View file

@ -148,7 +148,7 @@ inotice(const char *format, ...)
va_list args;
va_start(args, format);
rb_vsnprintf(buf, sizeof(buf), format, args);
ircvsnprintf(buf, sizeof(buf), format, args);
va_end(args);
_iprint("notice", buf);
@ -163,7 +163,7 @@ iwarn(const char *format, ...)
va_list args;
va_start(args, format);
rb_vsnprintf(buf, sizeof(buf), format, args);
ircvsnprintf(buf, sizeof(buf), format, args);
va_end(args);
_iprint("warning", buf);
@ -178,7 +178,7 @@ ierror(const char *format, ...)
va_list args;
va_start(args, format);
rb_vsnprintf(buf, sizeof(buf), format, args);
ircvsnprintf(buf, sizeof(buf), format, args);
va_end(args);
_iprint("error", buf);

View file

@ -284,7 +284,7 @@ struct oper_conf *
find_oper_conf(const char *username, const char *host, const char *locip, const char *name)
{
struct oper_conf *oper_p;
struct rb_sockaddr_storage ip, cip;
struct irc_sockaddr_storage ip, cip;
char addr[HOSTLEN+1];
int bits, cbits;
rb_dlink_node *ptr;

View file

@ -1030,7 +1030,7 @@ server_estab(struct Client *client_p)
{
if(client_p != serv_list.head->data || serv_list.head->next)
{
ServerStats.is_ref++;
ServerStats->is_ref++;
sendto_one(client_p, "ERROR :I'm a leaf not a hub");
return exit_client(client_p, client_p, client_p, "I'm a leaf");
}
@ -1469,7 +1469,7 @@ int
serv_connect(struct server_conf *server_p, struct Client *by)
{
struct Client *client_p;
struct rb_sockaddr_storage myipnum;
struct irc_sockaddr_storage myipnum;
int fd;
char vhoststr[HOSTIPLEN];

View file

@ -41,7 +41,126 @@
/*
* stats stuff
*/
struct ServerStatistics ServerStats;
static struct ServerStatistics ircst;
struct ServerStatistics *ServerStats = &ircst;
void
init_stats()
{
memset(&ircst, 0, sizeof(ircst));
}
/*
* tstats
*
* inputs - client to report to
* output - NONE
* side effects -
*/
void
tstats(struct Client *source_p)
{
struct Client *target_p;
struct ServerStatistics *sp;
struct ServerStatistics tmp;
rb_dlink_node *ptr;
sp = &tmp;
memcpy(sp, ServerStats, sizeof(struct ServerStatistics));
RB_DLINK_FOREACH(ptr, serv_list.head)
{
target_p = ptr->data;
sp->is_sbs += target_p->localClient->sendB;
sp->is_sbr += target_p->localClient->receiveB;
sp->is_sks += target_p->localClient->sendK;
sp->is_skr += target_p->localClient->receiveK;
sp->is_sti += rb_current_time() - target_p->localClient->firsttime;
sp->is_sv++;
if(sp->is_sbs > 1023)
{
sp->is_sks += (sp->is_sbs >> 10);
sp->is_sbs &= 0x3ff;
}
if(sp->is_sbr > 1023)
{
sp->is_skr += (sp->is_sbr >> 10);
sp->is_sbr &= 0x3ff;
}
}
RB_DLINK_FOREACH(ptr, lclient_list.head)
{
target_p = ptr->data;
sp->is_cbs += target_p->localClient->sendB;
sp->is_cbr += target_p->localClient->receiveB;
sp->is_cks += target_p->localClient->sendK;
sp->is_ckr += target_p->localClient->receiveK;
sp->is_cti += rb_current_time() - target_p->localClient->firsttime;
sp->is_cl++;
if(sp->is_cbs > 1023)
{
sp->is_cks += (sp->is_cbs >> 10);
sp->is_cbs &= 0x3ff;
}
if(sp->is_cbr > 1023)
{
sp->is_ckr += (sp->is_cbr >> 10);
sp->is_cbr &= 0x3ff;
}
}
RB_DLINK_FOREACH(ptr, unknown_list.head)
{
sp->is_ni++;
}
sendto_one_numeric(source_p, RPL_STATSDEBUG,
"T :accepts %u refused %u", sp->is_ac, sp->is_ref);
sendto_one_numeric(source_p, RPL_STATSDEBUG,
"T :rejected %u delaying %lu",
sp->is_rej, rb_dlink_list_length(&delay_exit));
sendto_one_numeric(source_p, RPL_STATSDEBUG,
"T :nicks being delayed %lu",
get_nd_count());
sendto_one_numeric(source_p, RPL_STATSDEBUG,
"T :unknown commands %u prefixes %u",
sp->is_unco, sp->is_unpf);
sendto_one_numeric(source_p, RPL_STATSDEBUG,
"T :nick collisions %u saves %u unknown closes %u",
sp->is_kill, sp->is_save, sp->is_ni);
sendto_one_numeric(source_p, RPL_STATSDEBUG,
"T :wrong direction %u empty %u",
sp->is_wrdi, sp->is_empt);
sendto_one_numeric(source_p, RPL_STATSDEBUG,
"T :numerics seen %u", sp->is_num);
sendto_one_numeric(source_p, RPL_STATSDEBUG,
"T :tgchange blocked msgs %u restricted addrs %lu",
sp->is_tgch, rb_dlink_list_length(&tgchange_list));
sendto_one_numeric(source_p, RPL_STATSDEBUG,
"T :auth successes %u fails %u",
sp->is_asuc, sp->is_abad);
sendto_one_numeric(source_p, RPL_STATSDEBUG,
"T :sasl successes %u fails %u",
sp->is_ssuc, sp->is_sbad);
sendto_one_numeric(source_p, RPL_STATSDEBUG, "T :Client Server");
sendto_one_numeric(source_p, RPL_STATSDEBUG,
"T :connected %u %u", sp->is_cl, sp->is_sv);
sendto_one_numeric(source_p, RPL_STATSDEBUG,
"T :bytes sent %d.%uK %d.%uK",
(int) sp->is_cks, sp->is_cbs,
(int) sp->is_sks, sp->is_sbs);
sendto_one_numeric(source_p, RPL_STATSDEBUG,
"T :bytes recv %d.%uK %d.%uK",
(int) sp->is_ckr, sp->is_cbr,
(int) sp->is_skr, sp->is_sbr);
sendto_one_numeric(source_p, RPL_STATSDEBUG,
"T :time connected %d %d",
(int) sp->is_cti, (int) sp->is_sti);
}
void
count_memory(struct Client *source_p)

View file

@ -323,7 +323,7 @@ register_local_user(struct Client *client_p, struct Client *source_p, const char
if(IsNeedIdentd(aconf))
{
ServerStats.is_ref++;
ServerStats->is_ref++;
sendto_one_notice(source_p, ":*** Notice -- You need to install identd to use this server");
exit_client(client_p, source_p, &me, "Install identd");
return (CLIENT_EXITED);
@ -350,7 +350,7 @@ register_local_user(struct Client *client_p, struct Client *source_p, const char
if(IsNeedSasl(aconf) && !*user->suser)
{
ServerStats.is_ref++;
ServerStats->is_ref++;
sendto_one_notice(source_p, ":*** Notice -- You need to identify via SASL to use this server");
exit_client(client_p, source_p, &me, "SASL access only");
return (CLIENT_EXITED);
@ -370,7 +370,7 @@ register_local_user(struct Client *client_p, struct Client *source_p, const char
if(strcmp(encr, aconf->passwd))
{
ServerStats.is_ref++;
ServerStats->is_ref++;
sendto_one(source_p, form_str(ERR_PASSWDMISMATCH), me.name, source_p->name);
exit_client(client_p, source_p, &me, "Bad Password");
return (CLIENT_EXITED);
@ -404,7 +404,7 @@ register_local_user(struct Client *client_p, struct Client *source_p, const char
sendto_realops_snomask(SNO_FULL, L_ALL,
"Too many clients, rejecting %s[%s].", source_p->name, source_p->host);
ServerStats.is_ref++;
ServerStats->is_ref++;
exit_client(client_p, source_p, &me, "Sorry, server is full - try later");
return (CLIENT_EXITED);
}
@ -413,8 +413,8 @@ register_local_user(struct Client *client_p, struct Client *source_p, const char
if(!IsExemptKline(source_p) &&
(xconf = find_xline(source_p->info, 1)) != NULL)
{
ServerStats.is_ref++;
add_reject(source_p);
ServerStats->is_ref++;
add_reject(source_p, xconf->name, NULL);
exit_client(client_p, source_p, &me, "Bad user info");
return CLIENT_EXITED;
}
@ -435,7 +435,7 @@ register_local_user(struct Client *client_p, struct Client *source_p, const char
substitution_append_var(&varlist, "dnsbl-host", source_p->preClient->dnsbl_listed->host);
substitution_append_var(&varlist, "network-name", ServerInfo.network_name);
ServerStats.is_ref++;
ServerStats->is_ref++;
sendto_one(source_p, form_str(ERR_YOUREBANNEDCREEP),
me.name, source_p->name,
@ -446,7 +446,7 @@ register_local_user(struct Client *client_p, struct Client *source_p, const char
sendto_one_notice(source_p, ":*** Your IP address %s is listed in %s",
source_p->sockhost, source_p->preClient->dnsbl_listed->host);
source_p->preClient->dnsbl_listed->hits++;
add_reject(source_p);
add_reject(source_p, NULL, NULL);
exit_client(client_p, source_p, &me, "*** Banned (DNS blacklist)");
return CLIENT_EXITED;
}
@ -459,7 +459,7 @@ register_local_user(struct Client *client_p, struct Client *source_p, const char
sendto_realops_snomask(SNO_REJ, L_ALL,
"Invalid username: %s (%s@%s)",
source_p->name, source_p->username, source_p->host);
ServerStats.is_ref++;
ServerStats->is_ref++;
sendto_one_notice(source_p, ":*** Your username is invalid. Please make sure that your username contains "
"only alphanumeric characters.");
rb_sprintf(tmpstr2, "Invalid username [%s]", source_p->username);
@ -526,6 +526,7 @@ register_local_user(struct Client *client_p, struct Client *source_p, const char
Count.invisi++;
s_assert(!IsClient(source_p));
del_unknown_ip(source_p);
rb_dlinkMoveNode(&source_p->localClient->tnode, &unknown_list, &lclient_list);
SetClient(source_p);

View file

@ -1,14 +0,0 @@
#
# $Id: Makefile.am 24818 2008-01-02 18:38:26Z androsyn $
#
bin_PROGRAMS = ssld
AM_CFLAGS=$(WARNFLAGS)
INCLUDES = -I../include -I../libratbox/include
ssld_SOURCES = ssld.c
ssld_LDADD = ../libratbox/src/libratbox.la @ZLIB_LD@

View file

@ -1,499 +0,0 @@
# Makefile.in generated by automake 1.10.1 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
# 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
@SET_MAKE@
VPATH = @srcdir@
pkgdatadir = $(datadir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
install_sh_SCRIPT = $(install_sh) -c
INSTALL_HEADER = $(INSTALL_DATA)
transform = $(program_transform_name)
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
bin_PROGRAMS = ssld$(EXEEXT)
subdir = ssld
DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \
$(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
CONFIG_HEADER = $(top_builddir)/include/setup.h
CONFIG_CLEAN_FILES =
am__installdirs = "$(DESTDIR)$(bindir)"
binPROGRAMS_INSTALL = $(INSTALL_PROGRAM)
PROGRAMS = $(bin_PROGRAMS)
am_ssld_OBJECTS = ssld.$(OBJEXT)
ssld_OBJECTS = $(am_ssld_OBJECTS)
ssld_DEPENDENCIES = ../libratbox/src/libratbox.la
DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/include
depcomp = $(SHELL) $(top_srcdir)/depcomp
am__depfiles_maybe = depfiles
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
--mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
CCLD = $(CC)
LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
--mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
$(LDFLAGS) -o $@
SOURCES = $(ssld_SOURCES)
DIST_SOURCES = $(ssld_SOURCES)
ETAGS = etags
CTAGS = ctags
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = @ACLOCAL@
ALLOCA = @ALLOCA@
AMTAR = @AMTAR@
AR = @AR@
AS = @AS@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
CP = @CP@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CXX = @CXX@
CXXCPP = @CXXCPP@
CXXDEPMODE = @CXXDEPMODE@
CXXFLAGS = @CXXFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
DSYMUTIL = @DSYMUTIL@
ECHO = @ECHO@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
ETC_DIR = @ETC_DIR@
EXEEXT = @EXEEXT@
F77 = @F77@
FFLAGS = @FFLAGS@
GREP = @GREP@
HELP_DIR = @HELP_DIR@
INCLTDL = @INCLTDL@
INSTALL = @INSTALL@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
IRCD_PREFIX = @IRCD_PREFIX@
LD = @LD@
LDFLAGS = @LDFLAGS@
LEX = @LEX@
LEXLIB = @LEXLIB@
LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
LIBLTDL = @LIBLTDL@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
LN = @LN@
LN_S = @LN_S@
LOG_DIR = @LOG_DIR@
LTLIBOBJS = @LTLIBOBJS@
LT_OBJDIR = @LT_OBJDIR@
MAINT = @MAINT@
MAKEINFO = @MAKEINFO@
MKDIR_P = @MKDIR_P@
MODULE_DIR = @MODULE_DIR@
MV = @MV@
NMEDIT = @NMEDIT@
OBJEXT = @OBJEXT@
PACKAGE = @PACKAGE@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
PACKAGE_NAME = @PACKAGE_NAME@
PACKAGE_STRING = @PACKAGE_STRING@
PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
PICFLAGS = @PICFLAGS@
RANLIB = @RANLIB@
RM = @RM@
SED = @SED@
SEDOBJ = @SEDOBJ@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
SHLIBEXT = @SHLIBEXT@
SQLITE_INCLUDES = @SQLITE_INCLUDES@
SQLITE_LD = @SQLITE_LD@
SQLITE_SUBDIR = @SQLITE_SUBDIR@
SSL_INCLUDES = @SSL_INCLUDES@
SSL_LIBS = @SSL_LIBS@
SSL_SRCS_ENABLE = @SSL_SRCS_ENABLE@
STRIP = @STRIP@
TOUCH = @TOUCH@
VERSION = @VERSION@
WARNFLAGS = @WARNFLAGS@
YACC = @YACC@
YFLAGS = @YFLAGS@
ZLIB_LD = @ZLIB_LD@
abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
abs_top_builddir = @abs_top_builddir@
abs_top_srcdir = @abs_top_srcdir@
ac_ct_CC = @ac_ct_CC@
ac_ct_CXX = @ac_ct_CXX@
ac_ct_F77 = @ac_ct_F77@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
confdir = @confdir@
datadir = @datadir@
datarootdir = @datarootdir@
docdir = @docdir@
dvidir = @dvidir@
exec_prefix = @exec_prefix@
helpdir = @helpdir@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
libdir = @libdir@
libexecdir = @libexecdir@
localedir = @localedir@
localstatedir = @localstatedir@
logdir = @logdir@
mandir = @mandir@
mkdir_p = @mkdir_p@
moduledir = @moduledir@
oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
subdirs = @subdirs@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
AM_CFLAGS = $(WARNFLAGS)
INCLUDES = -I../include -I../libratbox/include
ssld_SOURCES = ssld.c
ssld_LDADD = ../libratbox/src/libratbox.la @ZLIB_LD@
all: all-am
.SUFFIXES:
.SUFFIXES: .c .lo .o .obj
$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
&& exit 0; \
exit 1;; \
esac; \
done; \
echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu ssld/Makefile'; \
cd $(top_srcdir) && \
$(AUTOMAKE) --gnu ssld/Makefile
.PRECIOUS: Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
*config.status*) \
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
*) \
echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
esac;
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
install-binPROGRAMS: $(bin_PROGRAMS)
@$(NORMAL_INSTALL)
test -z "$(bindir)" || $(MKDIR_P) "$(DESTDIR)$(bindir)"
@list='$(bin_PROGRAMS)'; for p in $$list; do \
p1=`echo $$p|sed 's/$(EXEEXT)$$//'`; \
if test -f $$p \
|| test -f $$p1 \
; then \
f=`echo "$$p1" | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'`; \
echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(binPROGRAMS_INSTALL) '$$p' '$(DESTDIR)$(bindir)/$$f'"; \
$(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(binPROGRAMS_INSTALL) "$$p" "$(DESTDIR)$(bindir)/$$f" || exit 1; \
else :; fi; \
done
uninstall-binPROGRAMS:
@$(NORMAL_UNINSTALL)
@list='$(bin_PROGRAMS)'; for p in $$list; do \
f=`echo "$$p" | sed 's,^.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/'`; \
echo " rm -f '$(DESTDIR)$(bindir)/$$f'"; \
rm -f "$(DESTDIR)$(bindir)/$$f"; \
done
clean-binPROGRAMS:
@list='$(bin_PROGRAMS)'; for p in $$list; do \
f=`echo $$p|sed 's/$(EXEEXT)$$//'`; \
echo " rm -f $$p $$f"; \
rm -f $$p $$f ; \
done
ssld$(EXEEXT): $(ssld_OBJECTS) $(ssld_DEPENDENCIES)
@rm -f ssld$(EXEEXT)
$(LINK) $(ssld_OBJECTS) $(ssld_LDADD) $(LIBS)
mostlyclean-compile:
-rm -f *.$(OBJEXT)
distclean-compile:
-rm -f *.tab.c
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ssld.Po@am__quote@
.c.o:
@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(COMPILE) -c $<
.c.obj:
@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'`
.c.lo:
@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $<
mostlyclean-libtool:
-rm -f *.lo
clean-libtool:
-rm -rf .libs _libs
ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \
END { if (nonempty) { for (i in files) print i; }; }'`; \
mkid -fID $$unique
tags: TAGS
TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
tags=; \
here=`pwd`; \
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) '{ files[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in files) print i; }; }'`; \
if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
test -n "$$unique" || unique=$$empty_fix; \
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
$$tags $$unique; \
fi
ctags: CTAGS
CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
tags=; \
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) '{ files[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in files) print i; }; }'`; \
test -z "$(CTAGS_ARGS)$$tags$$unique" \
|| $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
$$tags $$unique
GTAGS:
here=`$(am__cd) $(top_builddir) && pwd` \
&& cd $(top_srcdir) \
&& gtags -i $(GTAGS_ARGS) $$here
distclean-tags:
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
distdir: $(DISTFILES)
@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
list='$(DISTFILES)'; \
dist_files=`for file in $$list; do echo $$file; done | \
sed -e "s|^$$srcdirstrip/||;t" \
-e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
case $$dist_files in \
*/*) $(MKDIR_P) `echo "$$dist_files" | \
sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
sort -u` ;; \
esac; \
for file in $$dist_files; do \
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
if test -d $$d/$$file; then \
dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
fi; \
cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
else \
test -f $(distdir)/$$file \
|| cp -p $$d/$$file $(distdir)/$$file \
|| exit 1; \
fi; \
done
check-am: all-am
check: check-am
all-am: Makefile $(PROGRAMS)
installdirs:
for dir in "$(DESTDIR)$(bindir)"; do \
test -z "$$dir" || $(MKDIR_P) "$$dir"; \
done
install: install-am
install-exec: install-exec-am
install-data: install-data-am
uninstall: uninstall-am
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
installcheck: installcheck-am
install-strip:
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
`test -z '$(STRIP)' || \
echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
mostlyclean-generic:
clean-generic:
distclean-generic:
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@echo "it deletes files that may require special tools to rebuild."
clean: clean-am
clean-am: clean-binPROGRAMS clean-generic clean-libtool mostlyclean-am
distclean: distclean-am
-rm -rf ./$(DEPDIR)
-rm -f Makefile
distclean-am: clean-am distclean-compile distclean-generic \
distclean-tags
dvi: dvi-am
dvi-am:
html: html-am
info: info-am
info-am:
install-data-am:
install-dvi: install-dvi-am
install-exec-am: install-binPROGRAMS
install-html: install-html-am
install-info: install-info-am
install-man:
install-pdf: install-pdf-am
install-ps: install-ps-am
installcheck-am:
maintainer-clean: maintainer-clean-am
-rm -rf ./$(DEPDIR)
-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic
mostlyclean: mostlyclean-am
mostlyclean-am: mostlyclean-compile mostlyclean-generic \
mostlyclean-libtool
pdf: pdf-am
pdf-am:
ps: ps-am
ps-am:
uninstall-am: uninstall-binPROGRAMS
.MAKE: install-am install-strip
.PHONY: CTAGS GTAGS all all-am check check-am clean clean-binPROGRAMS \
clean-generic clean-libtool ctags distclean distclean-compile \
distclean-generic distclean-libtool distclean-tags distdir dvi \
dvi-am html html-am info info-am install install-am \
install-binPROGRAMS install-data install-data-am install-dvi \
install-dvi-am install-exec install-exec-am install-html \
install-html-am install-info install-info-am install-man \
install-pdf install-pdf-am install-ps install-ps-am \
install-strip installcheck installcheck-am installdirs \
maintainer-clean maintainer-clean-generic mostlyclean \
mostlyclean-compile mostlyclean-generic mostlyclean-libtool \
pdf pdf-am ps ps-am tags uninstall uninstall-am \
uninstall-binPROGRAMS
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:

File diff suppressed because it is too large Load diff