Remove servlink, it's functionality is now provided by ssld.

This commit is contained in:
William Pitcock 2008-04-06 13:38:55 -05:00
parent 5da17c500b
commit 7f55df0596
13 changed files with 1 additions and 1261 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 servlink ssld doc help
SUBDIRS=libratbox modules extensions src tools ssld doc help
CLEANDIRS = ${SUBDIRS}
RSA_FILES=rsa_respond/README rsa_respond/respond.c rsa_respond/Makefile

View File

@ -1193,7 +1193,6 @@ fi
AC_CONFIG_FILES( \
Makefile \
servlink/Makefile \
ssld/Makefile \
extensions/Makefile \
unsupported/Makefile \

View File

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

View File

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

View File

@ -1,82 +0,0 @@
#
# 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

View File

@ -1,71 +0,0 @@
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

View File

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

View File

@ -1,129 +0,0 @@
/************************************************************************
* 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;
}

View File

@ -1,57 +0,0 @@
/************************************************************************
* 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 */

View File

@ -1,657 +0,0 @@
/************************************************************************
* 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 */
}

View File

@ -1,48 +0,0 @@
/************************************************************************
* 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 */

View File

@ -1,121 +0,0 @@
/************************************************************************
* 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() */

View File

@ -1,83 +0,0 @@
/************************************************************************
* 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 */