Compare commits

...
This repository has been archived on 2025-02-12. You can view files and clone it, but cannot push or open issues or pull requests.

15 commits

38 changed files with 1223 additions and 722 deletions

View file

@ -4,6 +4,14 @@ Anything we add/remove/fix/change is in here (even our rants)
Fish (F), Mark (M)
===============================================================================
* NeoStats * Version 3.0.a2-dev
- Tidy up the new socket code (F)
- Fix bug with ordering of process_ip in AddUser. nick variable isn't
static, and usually is gone when we callback (F)
- DCC Partyline support added (F)
- replace socket/select code with a libevent based implementation (F)
- Provide a "buffered" socket implementation for network communications (F)
- Provide a "newline terminated protocol" socket implementation to handle
IRCd and DCC Chat communications (F)
- Remove fieldname from settings structure since option already provides a
unique string for storage. (M)
- Add validate and random channel key functions. (M)

2
configure vendored
View file

@ -28861,6 +28861,8 @@ echo "${ECHO_T}\"None\"" >&6
fi;
CFLAGS="$CFLAGS -fno-strict-aliasing"

View file

@ -344,6 +344,8 @@ AC_MSG_RESULT($withval),
AC_MSG_RESULT("None"))
CFLAGS="$CFLAGS -fno-strict-aliasing"
AC_SUBST(PROTOCOL)
AC_SUBST(SED)
AC_SUBST(LIBTOOL_DEPS)

View file

@ -25,7 +25,7 @@
#define _DNS_H_
int InitDns( void );
void do_dns( void );
void do_dns(int notused, short event, void *arg);
void FiniDns( void );
void canx_dns( Module* modptr );
void do_dns_stats_Z( Client * );

View file

@ -226,8 +226,8 @@ int irc_smo( const char *source, const char *umodetarget, const char *msg );
EXPORTFUNC void send_cmd (char *fmt, ...) __attribute__((format(printf,1,2))); /* 2=format 3=params */
MODULEFUNC void parse (char *line);
MODULEFUNC int parse (void *notused, void *rline, size_t len);
void (*irc_parse) ( char *line );
int (*irc_parse) (void *notused, void *rline, size_t len);
#endif

View file

@ -91,6 +91,12 @@
#ifdef HAVE_ASSERT_H
#include <assert.h>
#endif /* HAVE_ASSERT_H */
#ifdef HAVE_ARPA_INET_H
#include <arpa/inet.h>
#endif
#ifdef HAVE_SYS_IOCTL_H
#include <sys/ioctl.h>
#endif
/* These macros handle DLL imports and exports for win32 module support */
#ifdef WIN32
@ -348,6 +354,12 @@ EXPORTFUNC char CmodeCharToPrefix( const char mode );
#define BUFSIZE 512
/* this is like a recvq setting. Going over this, we are getting flooded */
#define LINEBUFSIZE 2048
/* this is the max data we read from a sock at once */
#define READBUFSIZE 4096
#define MAXHOST (128 + 1)
#define MAXPASS (32 + 1)
#define MAXNICK (32 + 1)
@ -492,6 +504,9 @@ EXPORTVAR extern const char version_time[];
typedef struct _Module Module;
typedef struct _Bot Bot;
/* to avoid warnings for Sock */
struct Sock;
/** @brief Server structure
* Client extension structure for server specifics
*/
@ -549,8 +564,10 @@ typedef struct Client {
void *modvalue[NUM_MODULES];
int fd;
int port;
struct Sock *sock;
} Client;
/** @brief me structure
* structure containing information about the neostats core
*/
@ -581,6 +598,7 @@ typedef struct tme {
char serviceschan[MAXCHANLEN];
unsigned int synched:1;
Client *s;
struct Sock *servsock;
int requests;
long SendM;
long SendBytes;
@ -783,17 +801,6 @@ typedef struct bot_setting {
*/
typedef int (*timer_handler) ( void );
/** @brief Socket function types
*
*/
typedef int (*sock_func) ( int sock_no, char *name );
typedef int (*before_poll_func) ( void *data, struct pollfd * );
typedef void (*after_poll_func) ( void *data, struct pollfd *, unsigned int );
/* socket interface type */
#define SOCK_POLL 1
#define SOCK_STANDARD 2
/* Event system flags */
#define EVENT_FLAG_DISABLED 0x00000001 /* Event is disabled */
#define EVENT_FLAG_IGNORE_SYNCH 0x00000002 /* Event triggers even if not synched */
@ -910,6 +917,29 @@ EXPORTVAR extern int RunLevel;
#define GET_CUR_MODNAME() RunModule[RunLevel]->info->name
#define GET_CUR_MODVERSION() RunModule[RunLevel]->info->version
/** @brief Socket function types
*
*/
#if 0
typedef int (*sock_func) ( int sock_no, char *name );
#endif
/* socket interface type */
#define SOCK_STANDARD 1
#define SOCK_BUFFERED 2
#define SOCK_LINEMODE 3
#define SOCK_LISTEN 4
#define SOCK_NATIVE 5
#if 0
typedef void (*linemodecb)(char *);
#endif
typedef int (*sockcb)(int, void *data);
typedef int (*sockfunccb)(void *, void *, size_t);
/** @brief Module socket list structure
*
*/
@ -922,24 +952,46 @@ typedef struct Sock {
char name[MAX_MOD_NAME];
/** socket interface (poll or standard) type */
int socktype;
/** if socktype = SOCK_POLL, before poll function */
/** Socket before poll function */
before_poll_func beforepoll;
/** Socket after poll function */
after_poll_func afterpoll;
/** data */
void *data;
/* if socktype = SOCK_STANDARD, function calls */
/** Socket read function */
#if 0
sock_func readfnc;
/** Socket write function */
sock_func writefnc;
/** Socket error function */
sock_func errfnc;
#endif
/** rmsgs */
long rmsgs;
/** rbytes */
long rbytes;
/** smsgs */
long smsgs;
/** sbytes */
long sbytes;
union {
struct bufferevent *buffered;
struct event *event;
} event;
union {
struct linemode {
char *readbuf;
size_t readbufsize;
sockfunccb funccb;
sockcb errcb;
size_t recvq;
} linemode;
struct listenmode {
int port;
sockcb funccb;
} listenmode;
struct standmode {
sockfunccb readfunc;
sockcb writefunc;
} standmode;
} sfunc;
} Sock;
typedef enum TIMER_TYPE {
@ -1032,12 +1084,15 @@ EXPORTFUNC int SetTimerInterval( const char *timer_name, int interval );
/* Find timer from name */
EXPORTFUNC Timer *FindTimer( const char *timer_name );
EXPORTFUNC int add_sock( const char *sock_name, int socknum, sock_func readfunc, sock_func writefunc, sock_func errfunc );
EXPORTFUNC int add_sockpoll( const char *sock_name, void *data, before_poll_func beforepoll, after_poll_func afterpoll );
EXPORTFUNC int del_sock( const char *sock_name );
EXPORTFUNC Sock *add_sock (const char *sock_name, int socknum, sockfunccb readfunc, sockcb writefunc, short what, void *data, struct timeval *tv, int type);
EXPORTFUNC int update_sock(Sock *sock, short what, short reset, struct timeval *tv);
EXPORTFUNC int del_sock(Sock *sock);
EXPORTFUNC Sock *find_sock( const char *sock_name );
EXPORTFUNC int sock_connect( int socktype, unsigned long ipaddr, int port, const char *name, sock_func func_read, sock_func func_write, sock_func func_error );
EXPORTFUNC int sock_connect (int socktype, struct in_addr ip, int port);
EXPORTFUNC int sock_disconnect( const char *name );
EXPORTFUNC Sock *add_listen_sock(const char *sock_name, const int port, int type, sockcb acceptcb, void *data);
EXPORTFUNC Sock *add_linemode_socket(const char *sock_name, int socknum, sockfunccb readcb, sockcb errcb, void *arg);
EXPORTFUNC int send_to_sock(Sock *sock, const char *buf, const int buflen);
/* Add a new bot to NeoStats */
EXPORTFUNC Bot *AddBot( BotInfo *botinfo );
@ -1176,7 +1231,7 @@ EXPORTVAR unsigned char UmodeChRegNick;
EXPORTFUNC int IsBotMode( const char mode );
/* dns.c */
EXPORTFUNC int dns_lookup( char *str, adns_rrtype type, void (*callback) ( char *data, adns_answer * a), char *data );
EXPORTFUNC int dns_lookup( char *str, adns_rrtype type, void (*callback) ( void *data, adns_answer * a), void *data );
/* services.c */
EXPORTFUNC int add_services_cmd_list( bot_cmd *bot_cmd_list );

View file

@ -86,6 +86,7 @@ extern const char *ns_help_set_debuglevel[];
extern const char *ns_help_set_debugchan[];
extern const char *ns_help_set_debugtochan[];
extern const char *ns_help_set_debugmodule[];
extern const char *ns_help_set_recvq[];
extern const char cmd_help_oneline[];
extern const char cmd_help_about_oneline[];

View file

@ -65,6 +65,7 @@ typedef struct config {
unsigned int cmdreport;
unsigned int unauthreport;
unsigned char cmdchar[2];
size_t recvq;
} config;
extern config nsconfig;

View file

@ -26,14 +26,18 @@
#ifndef SOCK_H
#define SOCK_H
#include "event.h"
int InitSocks( void );
void FiniSocks( void );
int ns_cmd_socklist( CmdParams* cmdparams );
int del_sockets( Module *mod_ptr );
void Connect( void );
void send_to_socket( const char *buf, const int buflen );
int check_sql_sock( void );
void send_to_ircd_socket (const char *buf, const int buflen);
Sock *add_buffered_socket(const char *sock_name, int socknum, evbuffercb readcb, evbuffercb writecb, everrorcb errcb, void *arg);
extern char recbuf[BUFSIZE];
#endif

View file

@ -27,7 +27,7 @@
int InitTimers( void );
void FiniTimers( void );
int ns_cmd_timerlist( CmdParams* cmdparams );
void CheckTimers( void );
void CheckTimers_cb (int notused, short event, void *arg);
int del_timers( Module *mod_ptr );
#endif /* _TIMER_H_ */

View file

@ -1,18 +1,6 @@
if BUILD_PCRE
PCREDIR = pcre
else
PCREDIR =
endif
if BUILD_CURL
CURLDIR = curl
else
CURLDIR =
endif
SUBDIRS = adns rta $(CURLDIR) $(PCREDIR) event
SUBDIRS = adns rta pcre curl event
EXTRA_DIST = gdbm/autoconf.h.in gdbm/gdbmdefs.h gdbm/gdbmerrno.h gdbm/extern.h \
gdbm/systems.h gdbm/gdbmconst.h gdbm/proto.h
include $(top_srcdir)/autotools/rules.mk
include $(top_srcdir)/autotools/rules.mk

View file

@ -60,7 +60,7 @@ RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \
uninstall-recursive
ETAGS = etags
CTAGS = ctags
DIST_SUBDIRS = adns rta curl pcre event
DIST_SUBDIRS = $(SUBDIRS)
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
pkglibdir = $(prefix)/modules
ACLOCAL = @ACLOCAL@
@ -185,11 +185,7 @@ sharedstatedir = @sharedstatedir@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
wi_PWD = @wi_PWD@
@BUILD_PCRE_FALSE@PCREDIR =
@BUILD_PCRE_TRUE@PCREDIR = pcre
@BUILD_CURL_FALSE@CURLDIR =
@BUILD_CURL_TRUE@CURLDIR = curl
SUBDIRS = adns rta $(CURLDIR) $(PCREDIR) event
SUBDIRS = adns rta pcre curl event
EXTRA_DIST = gdbm/autoconf.h.in gdbm/gdbmdefs.h gdbm/gdbmerrno.h gdbm/extern.h \
gdbm/systems.h gdbm/gdbmconst.h gdbm/proto.h

View file

@ -290,6 +290,11 @@ extern "C" { /* I really dislike this - iwj. */
} rrs;
} adns_answer;
/* this is called when there is a update for a socket */
typedef void (*fd_update) (int fd, short what);
void set_fdupdate(adns_state ads, fd_update func);
/* Memory management:
* adns_state and adns_query are actually pointers to malloc'd state;
* On submission questions are copied, including the owner domain;
@ -324,7 +329,7 @@ extern "C" { /* I really dislike this - iwj. */
*/
int adns_init(adns_state * newstate_r, adns_initflags flags,
FILE * diagfile /*0=>stderr */ );
FILE * diagfile /*0=>stderr */, fd_update func );
int adns_init_strcfg(adns_state * newstate_r, adns_initflags flags,
FILE * diagfile /*0=>discard */ ,

View file

@ -36,6 +36,13 @@
#include "tvarith.h"
/* socket monitoring managemnet */
void set_fdupdate(adns_state ads, fd_update myfdfunc) {
ads->fdfunc = myfdfunc;
}
/* TCP connection management. */
static void tcp_close(adns_state ads)
@ -43,6 +50,11 @@ static void tcp_close(adns_state ads)
int serv;
serv = ads->tcpserver;
/* EVNT: Delsock */
if (ads->fdfunc)
ads->fdfunc(ads->tcpsocket, -1);
close(ads->tcpsocket);
ads->tcpsocket = -1;
ads->tcprecv.used = ads->tcprecv_skip = ads->tcpsend.used = 0;
@ -77,6 +89,9 @@ static void tcp_connected(adns_state ads, struct timeval now)
adns__debug(ads, ads->tcpserver, 0, "TCP connected");
ads->tcpstate = server_ok;
/* EVNT Read */
if (ads->fdfunc)
ads->fdfunc(ads->tcpsocket, POLLIN);
for (qu = ads->tcpw.head; qu && ads->tcpstate == server_ok;
qu = nqu) {
nqu = qu->next;
@ -142,6 +157,9 @@ void adns__tcp_tryconnect(adns_state ads, struct timeval now)
}
if (errno == EWOULDBLOCK || errno == EINPROGRESS) {
ads->tcptimeout = now;
/* EVNT addsock write */
if (ads->fdfunc)
ads->fdfunc(ads->tcpsocket, POLLOUT);
timevaladd(&ads->tcptimeout, TCPCONNMS);
return;
}

View file

@ -368,6 +368,7 @@ struct query_queue {
struct adns__state {
adns_initflags iflags;
FILE *diagfile;
fd_update fdfunc;
int configerrno;
struct query_queue udpw, tcpw, childw, output;
adns_query forallnext;

View file

@ -639,7 +639,9 @@ static int init_finish(adns_state ads)
r = errno;
goto x_closeudp;
}
if (ads->fdfunc)
ads->fdfunc(ads->udpsocket, POLLIN);
/* EVNT read */
return 0;
x_closeudp:
@ -658,7 +660,7 @@ static void init_abort(adns_state ads)
free(ads);
}
int adns_init(adns_state * ads_r, adns_initflags flags, FILE * diagfile)
int adns_init(adns_state * ads_r, adns_initflags flags, FILE * diagfile, fd_update func)
{
adns_state ads;
const char *res_options, *adns_res_options;
@ -694,7 +696,7 @@ int adns_init(adns_state * ads_r, adns_initflags flags, FILE * diagfile)
init_abort(ads);
return r;
}
ads->fdfunc = func;
r = init_finish(ads);
if (r)
return r;
@ -745,9 +747,15 @@ void adns_finish(adns_state ads)
else
break;
}
/* EVNT delsocket */
if (ads->fdfunc)
ads->fdfunc(ads->udpsocket, -1);
close(ads->udpsocket);
if (ads->tcpsocket >= 0)
if (ads->tcpsocket >= 0) {
if (ads->fdfunc)
ads->fdfunc(ads->tcpsocket, -1);
close(ads->tcpsocket);
}
adns__vbuf_free(&ads->tcpsend);
adns__vbuf_free(&ads->tcprecv);
freesearchlist(ads);

View file

@ -363,9 +363,15 @@ typedef struct {
* 0, otherwise it will be >0. type will always be the type
* requested.
*/
/* this is called when there is a update for a socket */
typedef void (*fd_update) (int fd, short what);
ADNS_API void set_fdupdate(adns_state ads, fd_update func);
ADNS_API int adns_init(adns_state *newstate_r, adns_initflags flags,
FILE *diagfile /*0=>stderr*/);
FILE *diagfile /*0=>stderr*/, fd_update func);
ADNS_API int adns_init_strcfg(adns_state *newstate_r, adns_initflags flags,
FILE *diagfile /*0=>discard*/, const char *configtext);
@ -853,6 +859,9 @@ ADNS_API const char *adns_errtypeabbrev(adns_status st);
* not returned by the same adns library.
*/
#ifdef __cplusplus
} /* end of extern "C" */
#endif

View file

@ -47,6 +47,12 @@
/* TCP connection management. */
/* socket monitoring managemnet */
void set_fdupdate(adns_state ads, fd_update myfdfunc) {
ads->fdfunc = myfdfunc;
}
static void tcp_close(adns_state ads) {
int serv;
@ -69,6 +75,11 @@ void adns__tcp_broken(adns_state ads, const char *what, const char *why) {
for (qu= ads->tcpw.head; qu; qu= qu->next)
qu->retries++;
}
/* EVNT: Delsock */
if (ads->fdfunc)
ads->fdfunc(ads->tcpsocket, -1);
tcp_close(ads);
ads->tcpstate= server_broken;
@ -80,6 +91,9 @@ static void tcp_connected(adns_state ads, struct timeval now) {
adns__debug(ads,ads->tcpserver,0,"TCP connected");
ads->tcpstate= server_ok;
/* EVNT Read */
if (ads->fdfunc)
ads->fdfunc(ads->tcpsocket, POLLIN);
for (qu= ads->tcpw.head; qu && ads->tcpstate == server_ok; qu= nqu) {
nqu= qu->next;
assert(qu->state == query_tcpw);
@ -136,6 +150,10 @@ void adns__tcp_tryconnect(adns_state ads, struct timeval now) {
if (r==0) { tcp_connected(ads,now); return; }
if (errno == EWOULDBLOCK || errno == EINPROGRESS) {
ads->tcptimeout= now;
/* EVNT addsock write */
if (ads->fdfunc)
ads->fdfunc(ads->tcpsocket, POLLOUT);
timevaladd(&ads->tcptimeout,TCPCONNMS);
return;
}

View file

@ -287,6 +287,7 @@ struct query_queue { adns_query head, tail; };
struct adns__state {
adns_initflags iflags;
FILE *diagfile;
fd_update fdfunc;
int configerrno;
struct query_queue udpw, tcpw, childw, output;
adns_query forallnext;

View file

@ -540,6 +540,11 @@ static int init_finish(adns_state ads) {
r= adns__setnonblock(ads,ads->udpsocket);
if (r) { r= errno; goto x_closeudp; }
if (ads->fdfunc)
ads->fdfunc(ads->udpsocket, POLLIN);
/* EVNT read */
return 0;
x_closeudp:
@ -564,7 +569,7 @@ static void init_abort(adns_state ads) {
}
int adns_init(adns_state *ads_r, adns_initflags flags, FILE *diagfile) {
int adns_init(adns_state *ads_r, adns_initflags flags, FILE *diagfile, fd_update func) {
adns_state ads;
const char *res_options, *adns_res_options;
int r;
@ -640,7 +645,7 @@ int adns_init(adns_state *ads_r, adns_initflags flags, FILE *diagfile) {
init_abort(ads);
return r;
}
ads->fdfunc = func;
r= init_finish(ads);
if (r) return r;
@ -679,8 +684,16 @@ void adns_finish(adns_state ads) {
else if (ads->output.head) adns_cancel(ads->output.head);
else break;
}
/* EVNT delsocket */
if (ads->fdfunc)
ads->fdfunc(ads->udpsocket, -1);
adns_socket_close(ads->udpsocket);
if (ads->tcpsocket >= 0) adns_socket_close(ads->tcpsocket);
if (ads->tcpsocket >= 0) {
adns_socket_close(ads->tcpsocket);
if (ads->fdfunc)
ads->fdfunc(ads->tcpsocket, -1);
}
adns__vbuf_free(&ads->tcpsend);
adns__vbuf_free(&ads->tcprecv);
freesearchlist(ads);

View file

@ -135,6 +135,13 @@ bufferevent_readcb(int fd, short event, void *arg)
(*bufev->errorcb)(bufev, what, bufev->cbarg);
}
#ifdef WIN32
#ifndef EINPROGRESS
#define EINPROGRESS WSAEWOULDBLOCK
#endif
#endif
static void
bufferevent_writecb(int fd, short event, void *arg)
{

View file

@ -55,7 +55,7 @@
#ifdef USE_LOG
#include "log.h"
#else
#define LOG_DBG(x)
#define LOG_DBG(x)
#define log_error(x) perror(x)
#endif

View file

@ -241,6 +241,7 @@ int bufferevent_enable(struct bufferevent *bufev, short event);
int bufferevent_disable(struct bufferevent *bufev, short event);
void bufferevent_settimeout(struct bufferevent *bufev,
int timeout_read, int timeout_write);
void bufferevent_setwatermark(struct bufferevent *bufev, short events, size_t lowmark, size_t highmark);
#define EVBUFFER_LENGTH(x) (x)->off
#define EVBUFFER_DATA(x) (x)->buffer
@ -259,7 +260,6 @@ int evbuffer_write(struct evbuffer *, int);
int evbuffer_read(struct evbuffer *, int, int);
u_char *evbuffer_find(struct evbuffer *, u_char *, size_t);
void evbuffer_setcb(struct evbuffer *, void (*)(struct evbuffer *, size_t, size_t, void *), void *);
#ifdef __cplusplus
}
#endif

View file

@ -394,9 +394,10 @@ dbcommand(char *buf, int *nin, char *out, int *nout, int connid)
snprintf((char *) conn->password, 32, "%s", &buf[4]);
nreply = MX_LN_SZ;
snprintf(line, MX_LN_SZ,
"select * from pg_user where usename=\"%s\" and passwd = \"%s\"",
"select * from pg_user where username=\"%s\" and passwd = \"%s\"",
conn->username, conn->password);
SQL_string(line, reply, &nreply);
#if 0
if (nreply != 1279)
{
/* SQL command failed! Report error */
@ -423,7 +424,7 @@ dbcommand(char *buf, int *nin, char *out, int *nout, int connid)
return (RTA_CLOSE);
}
#endif
/* XXX validate it */
*nin -= length;
out[0] = 'R';

241
src/dcc.c
View file

@ -27,6 +27,7 @@
#endif
#include "modules.h"
#include "commands.h"
#include "services.h"
typedef int (*dcc_cmd_handler) (CmdParams* cmdparams);
@ -40,7 +41,11 @@ static int dccoutput = 0;
static int dcc_req_send (CmdParams* cmdparams);
static int dcc_req_chat (CmdParams* cmdparams);
static int DCCChatConnect(Client *dcc, int port);
static int dcc_parse(void *arg, void *line, size_t);
static int dcc_error(int what, void *arg);
static void DelDCCClient(Client *dcc);
static int dcc_write(Client *dcc, char *buf);
static dcc_cmd dcc_cmds[]= {
{"SEND", dcc_req_send},
{"CHAT", dcc_req_chat},
@ -49,90 +54,87 @@ static dcc_cmd dcc_cmds[]= {
static void DCCChatDisconnect(Client *dcc)
{
os_sock_close (dcc->fd);
del_sock(dcc->sock);
}
static int DCCChatConnect(Client *dcc, int port)
{
struct sockaddr_in dccaddr;
struct hostent *target_host;
OS_SOCKET socketfd;
int flags = 1;
struct in_addr ip;
static void DCCGotAddr(void *data, adns_answer *a) {
Client *u = (Client *)data;
if (a && a->nrrs > 0 && u && a->status == adns_s_ok) {
u->ip.s_addr = a->rrs.addr->addr.inet.sin_addr.s_addr;
if (u->ip.s_addr > 0) {
DCCChatConnect(u, u->port);
return;
}
}
/* if we get here, there was something wrong */
nlog (LOG_WARNING, "DCC: Unable to connect to %s.%d: Unknown hostname", u->user->hostname, u->port);
DelDCCClient(u);
return;
}
os_memset((void *) &dccaddr, 0, sizeof(struct sockaddr_in));
ip.s_addr = inet_addr(dcc->user->hostname);
if (ip.s_addr != INADDR_NONE)
{
target_host = NULL;
static int DCCChatStart(Client *dcc, int port)
{
dcc->port = port;
if (dcc->ip.s_addr > 0) {
/* we have a valid IP address for this user, so just go and kick off the connection straight away */
return DCCChatConnect(dcc, port);
} else {
/* we don't have a valid IP address, kick off a DNS lookup */
dns_lookup(dcc->user->hostname, adns_r_addr, DCCGotAddr, (void *)dcc);
}
else
{
target_host = gethostbyname(dcc->user->hostname);
if (target_host)
memcpy(&ip.s_addr, target_host->h_addr_list[0], (size_t) target_host->h_length);
}
if (target_host)
{
dccaddr.sin_family = target_host->h_addrtype;
dccaddr.sin_addr.s_addr = ip.s_addr;
}
else
{
if (ip.s_addr == INADDR_NONE)
{
nlog (LOG_WARNING, "DCC: Unable to connect to %s.%d: Unknown hostname", dcc->user->hostname, port);
return NS_FAILURE;
}
dccaddr.sin_family = AF_INET;
dccaddr.sin_addr.s_addr = ip.s_addr;
}
dccaddr.sin_port = (unsigned short) htons((unsigned short) port);
dlog(DEBUG1, "DCC: Connecting to %s.%d", inet_ntoa(dccaddr.sin_addr), port);
if ((socketfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
{
nlog (LOG_WARNING, "DCC: Unable to open stream socket: %s", strerror(errno));
return NS_FAILURE;
}
setsockopt(socketfd, SOL_SOCKET, SO_REUSEADDR, (char *)&flags, sizeof(flags));
me.lsa.sin_family = AF_INET;
me.lsa.sin_addr.s_addr = INADDR_ANY;
if (bind (socketfd, (struct sockaddr *) &me.lsa, sizeof(me.lsa)) < 0)
{
nlog (LOG_WARNING, "bind(): Warning, Couldn't bind to IP address %s", strerror (errno));
os_sock_close (socketfd);
return NS_FAILURE;
}
#if 0
if ((err = os_sock_set_nonblocking (socketfd)) < 0) {
nlog (LOG_CRITICAL, "can't set socket non-blocking: %s", strerror (err));
return NS_FAILURE;
}
#endif
if (connect(socketfd, (struct sockaddr *) &dccaddr, sizeof(dccaddr))==-1)
{
switch (errno) {
case EINPROGRESS:
break;
default:
nlog (LOG_WARNING, "Error connecting to dcc host %s.%d: %s", inet_ntoa(dccaddr.sin_addr), port, strerror(errno));
os_sock_close (socketfd);
return NS_FAILURE;
}
}
if (socketfd == -1)
{
return NS_SUCCESS;
}
static int DCCChatConnect(Client *dcc, int port) {
OS_SOCKET socketfd;
char tmpname[BUFSIZE];
if ((socketfd = sock_connect(SOCK_STREAM, dcc->ip, port)) == NS_FAILURE) {
nlog(LOG_WARNING, "Error Connecting to DCC Host %s(%s:%d): %s", dcc->user->hostname, inet_ntoa(dcc->ip), port, strerror(errno));
DelDCCClient(dcc);
return NS_FAILURE;
}
/* ok, now add it as a linebuffered protocol */
ircsnprintf(tmpname, BUFSIZE, "DCC-%s", dcc->name);
if ((dcc->sock = add_linemode_socket(tmpname, socketfd, dcc_parse, dcc_error, (void*)dcc)) == NULL) {
nlog(LOG_WARNING, "Can't add a Linemode Socket for DCC %s", dcc->user->hostname);
os_sock_close(socketfd);
DelDCCClient(dcc);
return NS_FAILURE;
}
dcc->fd = socketfd;
dcc->port = port;
return NS_SUCCESS;
}
void dcc_parse(Client *dcc, char *line)
static int
dcc_partyline (Client *dcc, char *line) {
Client *todcc;
lnode_t *dccnode;
char tmpbuf[BUFSIZE];
ircsnprintf(tmpbuf, BUFSIZE, "\2%s\2: %s", dcc->name, line);
dccnode = list_first (dcclist);
while (dccnode) {
todcc = (Client *)lnode_get(dccnode);
dcc_write(todcc, tmpbuf);
dccnode = list_next(dcclist, dccnode);
}
irc_chanalert(ns_botptr, tmpbuf);
return NS_SUCCESS;
}
static int
dcc_parse(void *arg, void *rline, size_t len)
{
char buf[BUFSIZE];
char *cmd;
char *line = (char *)rline;
Client *dcc = (Client *)arg;
CmdParams *cmdparams;
strcpy(buf, line);
@ -140,7 +142,7 @@ void dcc_parse(Client *dcc, char *line)
{
cmd = strchr(buf, ' ');
if(!cmd)
return;
return NS_FAILURE;
*cmd = 0;
cmd++;
cmdparams = (CmdParams*) ns_calloc (sizeof(CmdParams));
@ -150,106 +152,58 @@ void dcc_parse(Client *dcc, char *line)
if (cmdparams->target) {
cmdparams->bot = cmdparams->target->user->bot;
if (!cmdparams->bot) {
return;
dcc_write(dcc, "Use .<botname> to send a command to a NeoStats Bot");
dcc_write(dcc, "Otherwise, jsut type test without a leading . to send to the DCC");
dcc_write(dcc, "partyline");
return NS_FAILURE;
}
}
if (cmdparams->bot->flags & BOT_FLAG_SERVICEBOT)
{
cmdparams->param = cmd;
run_bot_cmd (cmdparams, 0);
return NS_SUCCESS;
}
}
ns_free (cmdparams);
}
}
int dcc_read(Client *dcc)
{
register int i, j;
char c;
char buf[BUFSIZE];
for (j = 0; j < BUFSIZE; j++) {
i = os_sock_read (dcc->fd, &c, 1);
if (i >= 0) {
buf[j] = c;
if ((c == '\n') || (c == '\r')) {
strip (buf);
dlog(DEBUG1, "DCCRX: %s", buf);
dcc_parse(dcc, buf);
break;
}
} else {
nlog (LOG_WARNING, "read returned an Error");
return -1;
}
}
dcc_partyline(dcc, line);
return NS_SUCCESS;
}
int dcc_write(const Client *dcc, char *buf)
int dcc_write(Client *dcc, char *buf)
{
static char dcc_buf[BUFSIZE];
int ret; /* write() return value */
dccoutput = 0;
dlog(DEBUG1, "DCCTX: %s", buf);
strlcpy(dcc_buf, buf, BUFSIZE);
strlcat(dcc_buf, "\n", BUFSIZE);
ret = os_sock_write (dcc->fd, dcc_buf, strlen(dcc_buf));
if (ret < 0)
{
if (send_to_sock(dcc->sock, dcc_buf, strlen(dcc_buf)) == NS_FAILURE) {
nlog(LOG_WARNING, "Got a write error when attempting to write %d", errno);
os_sock_close (dcc->fd);
return -1;
DelDCCClient(dcc);
return NS_FAILURE;
}
return NS_SUCCESS;
}
void dcc_send_msg(const Client* dcc, char * buf)
{
dcc_write(dcc, buf);
dcc_write((Client *)dcc, buf);
}
int dcc_error(int sock_no, char *name)
int dcc_error(int sock_no, void *name)
{
Sock *sock = (Sock *)name;
if (sock->data) {
DelDCCClient(sock->data);
} else {
nlog(LOG_WARNING, "Problem, Sock->data is NULL, therefore we can't delete DCCClient!");
}
del_sock(sock);
return NS_SUCCESS;
}
void dcc_hook_1 (fd_set *read_fd_set, fd_set *write_fd_set)
{
Client *dcc;
lnode_t *dccnode;
dccnode = list_first (dcclist);
while (dccnode) {
dcc = (Client *)lnode_get(dccnode);
if (dccoutput) {
FD_SET(dcc->fd, write_fd_set);
} else {
FD_SET(dcc->fd, read_fd_set);
}
dccnode = list_next(dcclist, dccnode);
}
}
void dcc_hook_2 (fd_set *read_fd_set, fd_set *write_fd_set)
{
Client *dcc;
lnode_t *dccnode;
dccnode = list_first (dcclist);
while (dccnode) {
dcc = (Client *)lnode_get(dccnode);
if (FD_ISSET(dcc->fd, read_fd_set)) {
dcc_read(dcc);
} else if (FD_ISSET(dcc->fd, write_fd_set)) {
dcc_write(dcc, "TEST");
}
dccnode = list_next(dcclist, dccnode);
}
}
int InitDCC(void)
{
dcclist = list_create(-1);
@ -264,12 +218,11 @@ void FiniDCC(void)
dccnode = list_first (dcclist);
while (dccnode) {
dcc = (Client *)lnode_get(dccnode);
lnode_destroy (dccnode);
DCCChatDisconnect(dcc);
ns_free (dcc);
dccnode = list_next(dcclist, dccnode);
}
list_destroy (dcclist);
list_destroy_nodes (dcclist);
}
Client *AddDCCClient(CmdParams *cmdparams)
@ -281,13 +234,13 @@ Client *AddDCCClient(CmdParams *cmdparams)
{
os_memcpy(dcc, cmdparams->source, sizeof(Client));
lnode_create_append (dcclist, dcc);
dcc->flags |= CLIENT_FLAG_DCC;
dcc->flags = CLIENT_FLAG_DCC;
return dcc;
}
return NULL;
}
void DelDCCClient(Client *dcc)
static void DelDCCClient(Client *dcc)
{
lnode_t *dccnode;
@ -344,7 +297,7 @@ static int dcc_req_chat (CmdParams* cmdparams)
if (ac == 3)
{
dcc = AddDCCClient(cmdparams);
if (DCCChatConnect(dcc, atoi (av[2])) != NS_SUCCESS)
if (DCCChatStart(dcc, atoi (av[2])) != NS_SUCCESS)
{
DelDCCClient(dcc);
}

100
src/dns.c
View file

@ -31,6 +31,13 @@
#endif
#include "dns.h"
#include "services.h"
#include "event.h"
#ifdef HAVE_POLL_H
#include <poll.h>
#endif
#ifdef HAVE_SYS_TIME_H
#include <sys/time.h>
#endif
#define DNS_QUEUE_SIZE 300 /* number on concurrent DNS lookups */
#define DNS_DATA_SIZE 255
@ -39,14 +46,15 @@ typedef struct DnsLookup {
adns_query q; /**< the ADNS query */
adns_answer *a; /**< the ADNS result if we have completed */
adns_rrtype type; /**< the type we are looking for, only populated if we add to a queue */
char data[DNS_DATA_SIZE]; /**< the User data based to the callback */
void *data;
char lookupdata[255]; /**< the look up data, only populated if we add to a queue */
void (*callback) (char *data, adns_answer * a);
void (*callback) (void *data, adns_answer * a);
/**< a function pointer to call when we have a result */
Module* modptr;
} DnsLookup;
adns_state ads;
struct event *dnstimeout;
struct DNSStats {
int totalq;
@ -80,7 +88,7 @@ void dns_check_queue();
*
* @return returns 1 on success, 0 on failure (to add the lookup, not a successful lookup
*/
int dns_lookup (char *str, adns_rrtype type, void (*callback) (char *data, adns_answer * a), char *data)
int dns_lookup (char *str, adns_rrtype type, void (*callback) (void *data, adns_answer * a), void *data)
{
DnsLookup *dnsdata;
int status;
@ -96,7 +104,7 @@ int dns_lookup (char *str, adns_rrtype type, void (*callback) (char *data, adns_
}
/* set the module name */
dnsdata->modptr = GET_CUR_MODULE();
strlcpy (dnsdata->data, data, DNS_DATA_SIZE);
dnsdata->data = data;
dnsdata->callback = callback;
dnsdata->type = type;
if (list_isfull (dnslist)) {
@ -122,12 +130,62 @@ int dns_lookup (char *str, adns_rrtype type, void (*callback) (char *data, adns_
DNSStats.failure++;
return 0;
}
dlog(DEBUG1, "DNS: Added dns query %s to list", data);
dlog(DEBUG1, "DNS: Added dns query %s to list", str);
/* if we get here, then the submit was successful. Add it to the list of queryies */
lnode_create_append (dnslist, dnsdata);
return 1;
}
int
adns_read(void *data, void *notused, size_t len) {
Sock *sock = (Sock *)data;
struct timeval tv;
gettimeofday(&tv, NULL);
if (len > 0) {
adns_processreadable(ads, sock->sock_no, &tv);
} else {
adns_processexceptional(ads, sock->sock_no, &tv);
}
do_dns(0,0,NULL);
return NS_SUCCESS;
}
int
adns_write(int fd, void *data) {
struct timeval tv;
gettimeofday(&tv, NULL);
adns_processwriteable(ads, fd, &tv);
do_dns(0,0,NULL);
return NS_SUCCESS;
}
void
sock_update (int fd, short what) {
Sock *sock;
char tmpname[BUFSIZE];
int what2;
ircsnprintf(tmpname, BUFSIZE, "ADNS-%d", fd);
sock = find_sock(tmpname);
what2 = EV_PERSIST;
if (what & POLLIN) {
what2 |= EV_READ;
} else if (what & POLLOUT) {
what2 |= EV_WRITE;
} else if (what == -1) {
del_sock(sock);
return;
}
if (sock) {
update_sock(sock, what2, 1, NULL);
/* just update */
} else {
/* its new */
sock = add_sock(tmpname, fd, adns_read, adns_write, what2, sock, NULL, SOCK_NATIVE);
sock->data = sock;
}
}
/** @brief sets up DNS subsystem
*
* configures ADNS for use with NeoStats.
@ -137,7 +195,7 @@ int dns_lookup (char *str, adns_rrtype type, void (*callback) (char *data, adns_
int InitDns (void)
{
int adnsstart;
struct timeval tv;
SET_SEGV_LOCATION();
dnslist = list_create (DNS_QUEUE_SIZE);
if (!dnslist) {
@ -149,14 +207,21 @@ int InitDns (void)
if (!dnsqueue)
return NS_FAILURE;
#ifndef DEBUG
adnsstart = adns_init (&ads, adns_if_noerrprint | adns_if_noautosys, 0);
adnsstart = adns_init (&ads, adns_if_noerrprint | adns_if_noautosys, 0, sock_update);
#else
adnsstart = adns_init (&ads, adns_if_debug | adns_if_noautosys, 0);
adnsstart = adns_init (&ads, adns_if_debug | adns_if_noautosys, 0, sock_update);
#endif
if (adnsstart) {
nlog (LOG_CRITICAL, "ADNS init failed: %s", strerror (adnsstart));
return NS_FAILURE;
}
dnstimeout = os_malloc(sizeof(struct event));
timerclear(&tv);
tv.tv_sec = 1;
event_set(dnstimeout, 0, EV_TIMEOUT|EV_PERSIST, do_dns, NULL);
event_add(dnstimeout, &tv);
return NS_SUCCESS;
}
@ -185,6 +250,9 @@ void FiniDns (void)
}
list_destroy_nodes (dnsqueue);
list_destroy (dnsqueue);
event_del(dnstimeout);
free(dnstimeout);
free(ads);
}
/** @brief Canx any DNS queries for modules we might be unloading
@ -233,13 +301,19 @@ void canx_dns(Module* modptr)
*
* @return Nothing
*/
void do_dns (void)
void do_dns (int notused, short event, void *arg)
{
lnode_t *dnsnode, *dnsnode1;
int status;
DnsLookup *dnsdata;
struct timeval tv;
SET_SEGV_LOCATION();
/* process timeouts for ADNS */
gettimeofday(&tv,NULL);
adns_processtimeouts(ads, &tv);
/* if the list is empty, no use doing anything */
if (list_isempty (dnslist)) {
dns_check_queue();
@ -273,7 +347,7 @@ void do_dns (void)
lnode_destroy (dnsnode1);
break;
}
dlog(DEBUG1, "DNS: Calling callback function with data %s for module %s", dnsdata->data, dnsdata->modptr->info->name);
dlog(DEBUG1, "DNS: Calling callback function with for module %s", dnsdata->modptr->info->name);
DNSStats.success++;
/* call the callback function */
SET_RUN_LEVEL(dnsdata->modptr);
@ -309,7 +383,7 @@ void dns_check_queue()
dnsnode = list_first(dnsqueue);
while ((dnsnode) && (!list_isfull(dnslist))) {
dnsdata = lnode_get(dnsnode);
dlog(DEBUG2, "Moving DNS query %s from queue to active", dnsdata->data);
dlog(DEBUG2, "Moving DNS query from queue to active");
if (dnsdata->type == adns_r_ptr) {
sa.sin_family = AF_INET;
sa.sin_addr.s_addr = inet_addr (dnsdata->lookupdata);
@ -332,7 +406,7 @@ void dns_check_queue()
dnsnode = list_next(dnsqueue, dnsnode);
list_delete(dnsqueue, dnsnode2);
list_append(dnslist, dnsnode2);
dlog(DEBUG1, "DNS: Added dns query %s to list", dnsdata->data);
dlog(DEBUG1, "DNS: Added dns query to list");
/* while loop */
}
/* isempty */

View file

@ -792,22 +792,23 @@ EXPORTFUNC void process_ircd_cmd( int cmdptr, char *cmd, char* origin, char **av
* @return none
*/
void parse( char *line )
int parse(void *arg, void *rline, size_t len )
{
char origin[64], cmd[64], *coreLine;
char *line = (char *)rline;
int cmdptr = 0;
int ac = 0;
char **av = NULL;
SET_SEGV_LOCATION();
if( !( *line ) )
return;
return NS_FAILURE;
dlog( DEBUG1, "------------------------BEGIN PARSE-------------------------" );
dlog( DEBUGRX, "RX: %s", line );
if( *line == ':' ) {
coreLine = strpbrk( line, " " );
if( !coreLine )
return;
return NS_FAILURE;
*coreLine = 0;
while( isspace( *++coreLine ) );
strlcpy( origin, line + 1, sizeof( origin ) );
@ -818,7 +819,7 @@ void parse( char *line )
*origin = 0;
}
if( !*line )
return;
return NS_FAILURE;
coreLine = strpbrk( line, " " );
if( coreLine ) {
*coreLine = 0;
@ -834,6 +835,7 @@ void parse( char *line )
process_ircd_cmd( cmdptr, cmd, origin, av, ac );
ns_free( av );
dlog( DEBUG1, "-------------------------END PARSE--------------------------" );
return NS_SUCCESS;
}
/** @brief unsupported_cmd
@ -2493,7 +2495,7 @@ void send_cmd( char *fmt, ... )
buf[BUFSIZE - 2] = '\n';
}
buflen = strnlen( buf, BUFSIZE );
send_to_socket( buf, buflen );
send_to_ircd_socket( buf, buflen );
}
/** @brief HaveFeature

View file

@ -181,13 +181,11 @@ static int InitMe( void )
/* Default reconnect time */
nsconfig.r_time = 10;
/* Debug mode overrides */
#ifndef NDEBUG
#ifdef DEBUG
nsconfig.debug = 1;
nsconfig.loglevel = LOG_INFO;
nsconfig.debuglevel = DEBUG10;
nsconfig.foreground = 1;
#endif /* DEBUG */
#endif /* DEBUG */
/* default debugmodule to all */
strlcpy( nsconfig.debugmodule, "all", MAX_MOD_NAME );

View file

@ -356,6 +356,12 @@ const char *ns_help_set_serviceumode[] = {
NULL
};
const char *ns_help_set_recvq[] = {
"\2RECVQ <size>\2",
"Set the Default RecieveQ size for socket based actions",
NULL
};
const char *cmd_help_help[] = {
"Syntax: \2HELP [command]\2",
"",

View file

@ -260,7 +260,6 @@ int os_write( int fd, const void *buffer, unsigned int count )
int retval;
retval = write( fd, buffer, count );
printf( strerror( errno ) );
os_errno = errno;
return retval;
}

View file

@ -818,17 +818,18 @@ m_end_of_burst (char *origin, char **argv, int argc, int srv)
/* :<source> <command> <param1> <paramN> :<last parameter> */
/* <source> <command> <param1> <paramN> :<last parameter> */
void
parse (char *line)
int
parse (void *notused, void *rline, size_t len)
{
char origin[64], cmd[64], *coreLine;
char *line = (char *)rline;
int cmdptr = 0;
int ac = 0;
char **av = NULL;
SET_SEGV_LOCATION();
if (!(*line))
return;
return NS_FAILURE;
dlog (DEBUG1, "------------------------BEGIN PARSE-------------------------");
dlog (DEBUGRX, "%s", line);
coreLine = strpbrk (line, " ");
@ -872,6 +873,7 @@ parse (char *line)
process_ircd_cmd (cmdptr, cmd, origin, av, ac);
ns_free (av);
dlog (DEBUG1, "-------------------------END PARSE--------------------------");
return NS_SUCCESS;
}
static void

View file

@ -24,8 +24,11 @@
#include "neostats.h"
#include "rta.h"
#include "rtaserv.h"
#include "event.h"
#include <fcntl.h>
#ifdef HAVE_SYS_IOCTL_H
#include <sys/ioctl.h>
#endif
void rta_exit(void);
static int rta_active = 0;
@ -41,6 +44,8 @@ typedef struct Sql_Conn {
int responsefree;
int cmdpos;
int cmd[1000];
Sock *sock;
lnode_t *node;
} Sql_Conn;
OS_SOCKET sqlListenSock = -1;
@ -50,11 +55,12 @@ char rtauser[MAXUSER];
char rtapass[MAXPASS];
char rtahost[MAXHOST];
int rtaport;
struct timeval rtatimeout;
Sock *listensock;
static void sql_accept_conn(OS_SOCKET srvfd);
static OS_SOCKET sqllisten_on_port(int port);
static int sql_handle_ui_request(lnode_t *sqlnode);
static int sql_handle_ui_output(lnode_t *sqlnode);
static int sql_accept_conn(int, void *);
static int sql_handle_ui_request(void *arg, void *data , size_t len);
static int sql_handle_ui_output(int fd, void *arg);
int check_sql_sock();
/* this is for sqlserver logging callback */
@ -65,7 +71,7 @@ void rtaservlog(char *logline)
int InitRTAServ (void)
{
rtaport = 8888;
rtaport = 8889;
rta_init(rtaservlog);
/* add the server hash to the sql library */
neo_bans.address = GetBanHash();
@ -85,8 +91,8 @@ int InitRTAServ (void)
/* init the sql Listen Socket now as well */
sqlconnections = list_create(MAXSQLCON);
sqlListenSock = sqllisten_on_port(rtaport);
if (sqlListenSock == -1) {
if ((listensock = add_listen_sock("RTAServ", rtaport, SOCK_STREAM, sql_accept_conn, NULL)) == NULL) {
nlog(LOG_CRITICAL, "Failed to Setup Sql Port. SQL not available");
return NS_FAILURE;
}
@ -123,6 +129,11 @@ const char *rta_help_set_rtaport[] = {
NULL
};
const char *rta_help_set_rtatimeout[] = {
"RTATIMEOUT ",
NULL
};
static int rta_set_rtauser_cb (CmdParams* cmdparams, SET_REASON reason)
{
rta_change_auth(rtauser, rtapass);
@ -145,12 +156,17 @@ static int rta_set_rtaport_cb (CmdParams* cmdparams, SET_REASON reason)
return NS_SUCCESS;
}
static int rta_set_rtatimeout_cb (CmdParams *cmdparams, SET_REASON reason)
{
return NS_SUCCESS;
}
static bot_setting rta_settings[]=
{
{"RTAUSER", rtauser, SET_TYPE_STRING, 0, MAXUSER, NS_ULEVEL_ADMIN, NULL, rta_help_set_rtauser, rta_set_rtauser_cb, (void*)"user" },
{"RTAPASS", rtapass, SET_TYPE_STRING, 0, MAXPASS, NS_ULEVEL_ADMIN, NULL, rta_help_set_rtapass, rta_set_rtapass_cb, (void*)"pass" },
{"RTAHOST", rtahost, SET_TYPE_HOST, 0, MAXHOST, NS_ULEVEL_ADMIN, NULL, rta_help_set_rtahost, rta_set_rtahost_cb, (void*)"127.0.0.1" },
{"RTAPORT", &rtaport, SET_TYPE_INT, 0, 0, NS_ULEVEL_ADMIN, NULL, rta_help_set_rtaport, rta_set_rtaport_cb, (void*)8888 },
{"RTATIMEOUT", &rtatimeout.tv_sec, SET_TYPE_INT, 1, 1000, NS_ULEVEL_ADMIN, NULL, rta_help_set_rtatimeout, rta_set_rtatimeout_cb, (void*)300},
{NULL, NULL, 0, 0, 0, 0, NULL, NULL },
};
@ -164,6 +180,7 @@ static bot_setting rta_settings[]=
/* rehash handler */
int check_sql_sock()
{
#if 0
if (sqlListenSock < 1) {
dlog(DEBUG1, "Rehashing SQL sock");
sqlListenSock = sqllisten_on_port(rtaport);
@ -172,55 +189,9 @@ int check_sql_sock()
return NS_FAILURE;
}
}
#endif
return NS_SUCCESS;
}
/***************************************************************
* listen_on_port(int port): - Open a socket to listen for
* incoming TCP connections on the port given. Return the file
* descriptor if OK, and -1 on any error. The calling routine
* can handle any error condition.
*
* Input: The interger value of the port number to bind to
* Output: The file descriptor of the socket
* Effects: none
***************************************************************/
OS_SOCKET
sqllisten_on_port(int port)
{
OS_SOCKET srvfd; /* FD for our listen server socket */
struct sockaddr_in srvskt;
int adrlen;
adrlen = sizeof(struct sockaddr_in);
(void) memset((void *) &srvskt, 0, (size_t) adrlen);
srvskt.sin_family = AF_INET;
/* bind to the local IP */
if (me.dobind) {
srvskt.sin_addr = me.lsa.sin_addr;
} else {
srvskt.sin_addr.s_addr = INADDR_ANY;
}
srvskt.sin_port = htons(rtaport);
if ((srvfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
{
nlog(LOG_CRITICAL, "rtaserv: Unable to get socket for port %d.", port);
return -1;
}
os_sock_set_nonblocking (srvfd);
if (bind(srvfd, (struct sockaddr *) &srvskt, adrlen) < 0)
{
nlog(LOG_CRITICAL, "Unable to bind to port %d", port);
return -1;
}
if (listen(srvfd, 1) < 0)
{
nlog(LOG_CRITICAL, "Unable to listen on port %d", port);
return -1;
}
return (srvfd);
}
/***************************************************************
* accept_ui_session(): - Accept a new UI/DB/manager session.
* This routine is called when a user interface program such
@ -234,18 +205,24 @@ sqllisten_on_port(int port)
* Output: none
* Effects: manager connection table (ui)
***************************************************************/
void
sql_accept_conn(OS_SOCKET srvfd)
#if 0
int
sql_accept_conn(OS_SOCKET srvfd, void *data)
#endif
int
sql_accept_conn(int srvfd, void *data)
{
int adrlen; /* length of an inet socket address */
Sql_Conn *newui;
char tmp[16];
char tmpname[BUFSIZE];
/* if we reached our max connection, just exit */
if (list_count(sqlconnections) > 5) {
nlog(LOG_NOTICE, "Can not accept new SQL connection. Full");
os_sock_close (srvfd);
return;
/* we return ns_success as we want to keep looking for new connections */
return NS_SUCCESS;
}
/* We have a new UI/DB/manager connection request. So make a free
@ -260,28 +237,33 @@ sql_accept_conn(OS_SOCKET srvfd)
{
nlog(LOG_WARNING, "rtaserv: Manager accept() error (%s).", strerror(errno));
ns_free(newui);
os_sock_close (srvfd);
return;
return NS_SUCCESS;
}
else
{
inet_ntop(AF_INET, &newui->cliskt.sin_addr.s_addr, tmp, 16);
if (!match(rtahost, tmp)) {
/* we didnt get a match, bye bye */
/* we didnt get a match, bye bye */
nlog(LOG_NOTICE, "rtaserv: Rejecting SQL Connection from %s", tmp);
os_sock_close (newui->fd);
ns_free(newui);
return;
return NS_SUCCESS;
}
/* inc number ui, then init new ui */
os_sock_set_nonblocking (srvfd);
os_sock_set_nonblocking (newui->fd);
newui->cmdpos = 0;
newui->responsefree = 50000; /* max response packetsize if 50000 */
newui->nbytein = 0;
newui->nbyteout = 0;
lnode_create_append (sqlconnections, newui);
inet_ntop(AF_INET, &newui->cliskt.sin_addr.s_addr, tmp, 16);
newui->node = lnode_create(newui);
list_append(sqlconnections, newui->node);
inet_ntop(AF_INET, &newui->cliskt.sin_addr.s_addr, tmp, 16);
dlog(DEBUG1, "New SqlConnection from %s", tmp);
ircsnprintf(tmpname, BUFSIZE, "RTAConn%d", newui->fd);
newui->sock = add_sock(tmpname, newui->fd, sql_handle_ui_request, sql_handle_ui_output, EV_READ|EV_PERSIST|EV_TIMEOUT, newui, &rtatimeout, SOCK_STANDARD);
return NS_SUCCESS;
}
}
@ -300,40 +282,31 @@ sql_accept_conn(OS_SOCKET srvfd)
* Effects: many, many side effects via table callbacks
***************************************************************/
int
sql_handle_ui_request(lnode_t *sqlnode)
sql_handle_ui_request(void *arg, void *data , size_t len)
{
int ret; /* a return value */
int dbstat; /* a return value */
int t; /* a temp int */
Sql_Conn *sqlconn;
dlog (DEBUG1, "sql_handle_ui_request");
if ((sqlconn = lnode_get(sqlnode)) == NULL) {
nlog(LOG_WARNING, "Got a Sql Handle without a valid node");
return NS_SUCCESS;
}
/* We read data from the connection into the buffer in the ui struct.
Once we've read all of the data we can, we call the DB routine to
parse out the SQL command and to execute it. */
ret = os_sock_read (sqlconn->fd,
(char *)&(sqlconn->cmd[sqlconn->cmdpos]), (1000 - sqlconn->cmdpos));
/* shutdown manager conn on error or on zero bytes read */
if (ret <= 0)
{
/* log this since a normal close is with an 'X' command from the
client program? */
dlog(DEBUG1, "Disconnecting SqlClient for failed read");
Sql_Conn *sqlconn = (Sql_Conn *)arg;
if (len == -1) {
/* a error occured */
deldbconnection(sqlconn->fd);
os_sock_close (sqlconn->fd);
list_delete(sqlconnections, sqlnode);
lnode_destroy(sqlnode);
list_delete(sqlconnections, sqlconn->node);
lnode_destroy(sqlconn->node);
ns_free(sqlconn);
return NS_FAILURE;
}
sqlconn->cmdpos += ret;
sqlconn->nbytein += ret;
if (len == -2) {
dlog(DEBUG1, "SQL Timeout");
list_delete(sqlconnections, sqlconn->node);
lnode_destroy(sqlconn->node);
deldbconnection(sqlconn->fd);
ns_free(sqlconn);
return NS_FAILURE;
}
memmove((sqlconn->cmd + sqlconn->cmdpos), data, len);
sqlconn->cmdpos += len;
sqlconn->nbytein += len;
/* The commands are in the buffer. Call the DB to parse and execute
them */
@ -347,13 +320,16 @@ sql_handle_ui_request(lnode_t *sqlnode)
/* move any trailing SQL cmd text up in the buffer */
(void) memmove(sqlconn->cmd, &sqlconn->cmd[t], t);
} while (dbstat == RTA_SUCCESS);
if (dbstat == RTA_ERROR) {
deldbconnection(sqlconn->fd);
}
/* the command is done (including side effects). Send any reply back
to the UI */
if (sql_handle_ui_output(sqlnode) == NS_FAILURE)
if (sql_handle_ui_output(sqlconn->fd, sqlconn) == NS_FAILURE) {
list_delete(sqlconnections, sqlconn->node);
lnode_destroy(sqlconn->node);
deldbconnection(sqlconn->fd);
ns_free(sqlconn);
return NS_FAILURE;
}
return NS_SUCCESS;
}
@ -367,27 +343,20 @@ sql_handle_ui_request(lnode_t *sqlnode)
* Effects: none
***************************************************************/
int
sql_handle_ui_output(lnode_t *sqlnode)
sql_handle_ui_output(int fd, void *arg)
{
int ret; /* write() return value */
Sql_Conn *sqlconn;
Sql_Conn *sqlconn = (Sql_Conn *)arg;
dlog (DEBUG1, "sql_handle_ui_output");
if ((sqlconn = lnode_get(sqlnode)) == NULL) {
nlog(LOG_WARNING, "Got a Sql write Handle without a valid node");
return NS_SUCCESS;
}
if (sqlconn->responsefree < 50000)
{
ret = os_sock_write (sqlconn->fd, sqlconn->response, (50000 - sqlconn->responsefree));
if (ret < 0)
ret = send_to_sock(sqlconn->sock, sqlconn->response, (50000 - sqlconn->responsefree));
if (ret == NS_FAILURE)
{
nlog(LOG_WARNING, "Got a write error when attempting to return data to the SQL Server");
deldbconnection(sqlconn->fd);
os_sock_close (sqlconn->fd);
list_delete(sqlconnections, sqlnode);
lnode_destroy(sqlnode);
list_delete(sqlconnections, sqlconn->node);
lnode_destroy(sqlconn->node);
ns_free(sqlconn);
return NS_FAILURE;
}
@ -403,69 +372,13 @@ sql_handle_ui_output(lnode_t *sqlnode)
(50000 - sqlconn->responsefree - ret));
sqlconn->responsefree += ret;
sqlconn->nbyteout += ret; /* # bytes sent on conn */
/* schedule a new write callback - Onshot, not persistant */
update_sock(sqlconn->sock, EV_WRITE|EV_TIMEOUT, 0, &rtatimeout);
}
}
return NS_SUCCESS;
}
//from read_loop
void rta_hook_1 (fd_set *read_fd_set, fd_set *write_fd_set)
{
lnode_t *sqlnode;
Sql_Conn *sqldata;
if (!rta_active) {
return ;
}
/* if we have sql support, add the Listen Socket to the fds */
if (sqlListenSock > 0)
FD_SET(sqlListenSock, read_fd_set);
/* if we have any existing connections, add them of course */
if (list_count(sqlconnections) > 0) {
sqlnode = list_first(sqlconnections);
while (sqlnode != NULL) {
sqldata = lnode_get(sqlnode);
if (sqldata->responsefree < 50000) {
FD_SET(sqldata->fd, write_fd_set);
} else {
FD_SET(sqldata->fd, read_fd_set);
}
sqlnode = list_next(sqlconnections, sqlnode);
}
}
}
void rta_hook_2 (fd_set *read_fd_set, fd_set *write_fd_set)
{
lnode_t *sqlnode;
Sql_Conn *sqldata;
if (!rta_active) {
return ;
}
/* did we get a connection to the SQL listen sock */
if ((sqlListenSock > 0) && (FD_ISSET(sqlListenSock, read_fd_set)))
sql_accept_conn(sqlListenSock);
/* don't bother checking the sql connections if we dont have any active connections! */
restart:
if (list_count(sqlconnections) > 0) {
sqlnode = list_first(sqlconnections);
while (sqlnode != NULL) {
sqldata = lnode_get(sqlnode);
if (FD_ISSET(sqldata->fd, read_fd_set)) {
if (sql_handle_ui_request(sqlnode) == NS_FAILURE) {
goto restart;
}
} else if (FD_ISSET(sqldata->fd, write_fd_set)) {
if (sql_handle_ui_output(sqlnode) == NS_FAILURE) {
goto restart;
}
}
sqlnode = list_next(sqlconnections, sqlnode);
}
}
}
#if 0
/** Copyright info */
static const char *rta_copyright[] = {
@ -553,6 +466,9 @@ void rtaserv_fini (void)
list_destroy_auto (sqlconnections);
rta_active = 1;
del_services_set_list (rta_settings);
if (listensock) {
del_sock(listensock);
}
rta_exit();
}

View file

@ -133,7 +133,10 @@ static bot_setting ns_settings[]=
{"CMDCHAR", nsconfig.cmdchar, SET_TYPE_STRING, 0, 2, NS_ULEVEL_ADMIN, NULL, ns_help_set_cmdchar, NULL,( void* )"!" },
{"CMDREPORT", &nsconfig.cmdreport, SET_TYPE_BOOLEAN, 0, 0, NS_ULEVEL_ADMIN, NULL, ns_help_set_cmdreport, NULL,( void* )1 },
{"LOGLEVEL", &nsconfig.loglevel, SET_TYPE_INT, 1, 6, NS_ULEVEL_ADMIN, NULL, ns_help_set_loglevel, NULL,( void* )5 },
#if 0
{"DEBUGLEVEL", &nsconfig.debuglevel, SET_TYPE_INT, 1, 10, NS_ULEVEL_ADMIN, NULL, ns_help_set_debuglevel, NULL,( void* )0 },
#endif
{"RECVQ", &nsconfig.debuglevel, SET_TYPE_INT, 1024,10240000, NS_ULEVEL_ADMIN, NULL, ns_help_set_recvq, NULL, ( void*)2048},
{"DEBUGCHAN", nsconfig.debugchan, SET_TYPE_STRING, 0, MAXCHANLEN, NS_ULEVEL_ADMIN, NULL, ns_help_set_debugchan, NULL,( void* )"#debug" },
{"DEBUGTOCHAN", &nsconfig.debugtochan, SET_TYPE_BOOLEAN, 0, 0, NS_ULEVEL_ADMIN, NULL, ns_help_set_debugtochan, NULL,( void* )0 },
{NULL, NULL, 0, 0, 0, 0, NULL, NULL },

View file

@ -51,6 +51,7 @@ RETSIGTYPE sigterm_handler( int signum )
exit( NS_SUCCESS );
#else /* VALGRIND */
nlog( LOG_CRITICAL, msg_sigterm );
/* XXX-Mark something is wrong with irc_globops */
irc_globops( NULL, msg_sigterm );
do_exit( NS_EXIT_NORMAL, msg_sigterm );
#endif /* VALGRIND */

1013
src/sock.c

File diff suppressed because it is too large Load diff

View file

@ -28,6 +28,8 @@
#include "services.h"
#include "modules.h"
#include "log.h"
#include "timer.h"
#include "event.h"
#define TIMER_TABLE_SIZE 300 /* Number of Timers */
@ -40,25 +42,45 @@ static time_t lastservertimesync = 0;
static int is_midnight (void);
static void run_mod_timers (int ismidnight);
static struct event *timers;
int InitTimers (void)
{
struct timeval tv;
timerhash = hash_create (TIMER_TABLE_SIZE, 0, 0);
if(!timerhash) {
nlog (LOG_CRITICAL, "Unable to create timer hash");
return NS_FAILURE;
}
timers = os_malloc(sizeof(struct event));
timerclear(&tv);
tv.tv_sec = 1;
event_set(timers, 0, EV_TIMEOUT|EV_PERSIST, CheckTimers_cb, NULL);
event_add(timers, &tv);
return NS_SUCCESS;
}
void FiniTimers (void)
{
event_del(timers);
os_free(timers);
hash_destroy (timerhash);
}
void
CheckTimers (void)
CheckTimers_cb (int notused, short event, void *arg)
{
struct timeval tv;
SET_SEGV_LOCATION();
timerclear(&tv);
tv.tv_sec = 1;
if (me.now - me.tslastping > nsconfig.pingtime) {
PingServers ();
me.tslastping = me.now;
@ -84,6 +106,9 @@ CheckTimers (void)
if (midnight == 1 && is_midnight () == 0)
midnight = 0;
}
/* re-add this timeout */
event_add(timers, &tv);
}
static int

View file

@ -221,7 +221,10 @@ int new_transfer(char *url, char *params, NS_TRANSFER savetofileormemory, char *
}
/* setup any params we must post to the server */
#if 0
if (params[0] != 0) {
#endif
if (params) {
strlcpy(newtrans->params, params, MAXURL);
if ((ret = curl_easy_setopt(newtrans->curleasyhandle, CURLOPT_POSTFIELDS, newtrans->params)) != 0) {
nlog(LOG_WARNING, "Curl Set nosignal failed. Returned %d for url %s", ret, url);

View file

@ -64,7 +64,7 @@ static Client *new_user (const char *nick)
return u;
}
static void lookupnickip (char *data, adns_answer *a)
static void lookupnickip (void *data, adns_answer *a)
{
CmdParams *cmdparams;
Client *u;
@ -72,13 +72,14 @@ static void lookupnickip (char *data, adns_answer *a)
u = FindUser ((char *)data);
if (a && a->nrrs > 0 && u && a->status == adns_s_ok) {
u->ip.s_addr = a->rrs.addr->addr.inet.sin_addr.s_addr;
strlcpy (u->hostip, inet_ntoa (u->ip), HOSTIPLEN);
if (u->ip.s_addr > 0) {
cmdparams = (CmdParams*) ns_calloc (sizeof(CmdParams));
cmdparams->source = u;
SendAllModuleEvent (EVENT_NICKIP, cmdparams);
ns_free (cmdparams);
}
}
}
}
static int process_ip (const char *nick, const char *host)
@ -116,16 +117,21 @@ Client *AddUser (const char *nick, const char *user, const char *host,
nlog (LOG_WARNING, "AddUser: trying to add a user that already exists %s", nick);
return NULL;
}
if (ip) {
ipaddress = strtoul (ip, NULL, 10);
} else if (!(ircd_srv.protocol&PROTOCOL_NICKIP) && me.want_nickip == 1) {
ipaddress = process_ip (nick, host);
}
dlog (DEBUG2, "AddUser: %s (%s@%s) %s (%d) -> %s at %s", nick, user, host, realname, (int)htonl (ipaddress), server, TS);
u = new_user (nick);
if (!u) {
return NULL;
}
/* XXX for testing */
#warning this is for testing
#if 0
if (ip) {
ipaddress = strtoul (ip, NULL, 10);
} else if (!(ircd_srv.protocol&PROTOCOL_NICKIP) && me.want_nickip == 1) {
ipaddress = process_ip (u->name, host);
}
#endif
ipaddress = process_ip(u->name, host);
u->tsconnect = TS ? strtoul (TS, NULL, 10) : me.now;
if (time(NULL) - u->tsconnect > nsconfig.splittime) {
u->flags |= NS_FLAGS_NETJOIN;