Commits

Anonymous committed 07d46f2

[svn] - use a hashtable for fdlist storage. first step to making the amount of allowed clients dynamic and removing MAXCONNECTIONS.

  • Participants
  • Parent commits cf68e65

Comments (0)

Files changed (10)

+jilles      2007/03/05 01:14:46 UTC	(20070305-3227)
+  Log:
+  Fix some cases where the size argument to strlcpy()
+  for usernames and hostnames is 1 too small.
+  
+
+  Changes:	Modified:
+  +1 -1		trunk/modules/m_chghost.c (File Modified) 
+  +2 -2		trunk/src/res.c (File Modified) 
+  +2 -2		trunk/src/s_user.c (File Modified) 
+
+
 jilles      2007/03/04 23:42:55 UTC	(20070304-3225)
   Log:
   Cut down quit/part/kick reasons to avoid quit reasons
-#define SERNO "20070304-3225"
+#define SERNO "20070305-3227"

libcharybdis/commio.c

  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
  *  USA
  *
- *  $Id: commio.c 1779 2006-07-30 16:36:39Z jilles $
+ *  $Id: commio.c 3229 2007-03-05 17:23:07Z nenolod $
  */
 
 #include "libcharybdis.h"
 	"Comm Error"
 };
 
-fde_t *fd_table = NULL;
+#define FD_HASH_SIZE 128
+static dlink_list fd_table[FD_HASH_SIZE];
 
 static void fdlist_update_biggest(int fd, int opening);
 
 static void comm_connect_dns_callback(void *vptr, struct DNSReply *reply);
 static PF comm_connect_tryconnect;
 
+inline fde_t *
+comm_locate_fd(int fd)
+{
+	int bucket = fd % FD_HASH_SIZE;
+	dlink_list *list = &fd_table[bucket];
+	dlink_node *n;
+
+	DLINK_FOREACH(n, list->head)
+	{
+		fde_t *F = (fde_t *) n->data;
+
+		if (F->fd == fd)
+			return F;
+	}
+
+	return NULL;
+}
+
+inline fde_t *
+comm_add_fd(int fd)
+{
+	fde_t *F = comm_locate_fd(fd);
+	dlink_list *list;
+
+	if (F != NULL)
+		return F;
+
+	F = calloc(sizeof(fde_t), 1);
+	F->fd = fd;
+	list = &fd_table[fd % FD_HASH_SIZE];
+	dlinkAdd(F, &F->node, list);
+
+	return F;
+}
+
+inline void
+comm_remove_fd(int fd)
+{
+	int bucket = fd % FD_HASH_SIZE;
+	fde_t *F;
+	dlink_list *list = &fd_table[bucket];
+
+	F = comm_locate_fd(fd);
+	if (F == NULL)
+		return;
+
+	dlinkDelete(&F->node, list);
+	MyFree(F);
+}
+
 /* 32bit solaris is kinda slow and stdio only supports fds < 256
  * so we got to do this crap below.
  * (BTW Fuck you Sun, I hate your guts and I hope you go bankrupt soon)
+ * XXX: this is no longer needed in Solaris 10. --nenolod
  */
 #if defined (__SVR4) && defined (__sun) 
 static void comm_fd_hack(int *fd)
 
 	for (i = 4; i < MAXCONNECTIONS; ++i)
 	{
-		if(fd_table[i].flags.open)
+		fde_t *F = comm_locate_fd(i);
+
+		if(F != NULL && F->flags.open)
 			comm_close(i);
 		else
 			close(i);
 {
 	int nonb = 0;
 	int res;
+	fde_t *F = comm_locate_fd(fd);
 
 	nonb |= O_NONBLOCK;
 	res = fcntl(fd, F_GETFL, 0);
 	if(-1 == res || fcntl(fd, F_SETFL, res | nonb) == -1)
 		return 0;
 
-	fd_table[fd].flags.nonblocking = 1;
+	if (F != NULL)
+		F->flags.nonblocking = 1;
+
 	return 1;
 }
 
 {
 	fde_t *F;
 	s_assert(fd >= 0);
-	F = &fd_table[fd];
+	F = comm_locate_fd(fd);
 	s_assert(F->flags.open);
 
 	F->timeout = CurrentTime + (timeout / 1000);
 {
 	fde_t *F;
 	s_assert(fd >= 0);
-	F = &fd_table[fd];
+	F = comm_locate_fd(fd);
 	s_assert(F->flags.open);
 
 	F->flush_timeout = CurrentTime + (timeout / 1000);
 	fde_t *F;
 	for (fd = 0; fd <= highest_fd; fd++)
 	{
-		F = &fd_table[fd];
+		F = comm_locate_fd(fd);
+		if(F == NULL)
+			continue;
 		if(!F->flags.open)
 			continue;
 		if(F->flags.closing)
 	void *ipptr = NULL;
 	fde_t *F;
 	s_assert(fd >= 0);
-	F = &fd_table[fd];
+	F = comm_locate_fd(fd);
 	F->flags.called_connect = 1;
 	s_assert(callback);
 	F->connect.callback = callback;
 comm_connect_callback(int fd, int status)
 {
 	CNCB *hdl;
-	fde_t *F = &fd_table[fd];
+	fde_t *F = comm_locate_fd(fd);
+
 	/* This check is gross..but probably necessary */
-	if(F->connect.callback == NULL)
+	if(F == NULL || F->connect.callback == NULL)
 		return;
+
 	/* Clear the connect flag + handler */
 	hdl = F->connect.callback;
 	F->connect.callback = NULL;
 comm_connect_tryconnect(int fd, void *notused)
 {
 	int retval;
-	fde_t *F = &fd_table[fd];
+	fde_t *F = comm_locate_fd(fd);
 
 	if(F->connect.callback == NULL)
 		return;
 	/* Try the connect() */
-	retval = connect(fd, (struct sockaddr *) &fd_table[fd].connect.hostaddr, 
-			       GET_SS_LEN(fd_table[fd].connect.hostaddr));
+	retval = connect(fd, (struct sockaddr *) &F->connect.hostaddr, 
+			       GET_SS_LEN(F->connect.hostaddr));
 	/* Error? */
 	if(retval < 0)
 	{
 	 * re-opening it
 	 */
 	s_assert(!opening);
-	while (highest_fd >= 0 && !fd_table[highest_fd].flags.open)
+	while (highest_fd >= 0 && comm_locate_fd(fd)->flags.open) /* XXX */
 		highest_fd--;
 }
 
 
 	if(!initialized)
 	{
-		/* Since we're doing this once .. */
-		fd_table = MyMalloc((MAXCONNECTIONS + 1) * sizeof(fde_t));
+		memset(&fd_table, '\0', sizeof(dlink_list) * FD_HASH_SIZE);
 		initialized = 1;
 	}
 }
 void
 comm_open(int fd, unsigned int type, const char *desc)
 {
-	fde_t *F = &fd_table[fd];
+	fde_t *F = comm_add_fd(fd);
 	s_assert(fd >= 0);
 
 	if(F->flags.open)
 void
 comm_close(int fd)
 {
-	fde_t *F = &fd_table[fd];
+	fde_t *F = comm_locate_fd(fd);
 	s_assert(F->flags.open);
 	/* All disk fd's MUST go through file_close() ! */
 	s_assert(F->type != FD_FILE);
 	F->flags.open = 0;
 	fdlist_update_biggest(fd, 0);
 	number_fd--;
-	memset(F, '\0', sizeof(fde_t));
+	comm_remove_fd(fd);
+
 	F->timeout = 0;
 	/* Unlike squid, we're actually closing the FD here! -- adrian */
 	close(fd);
 }
 
-
 /*
  * comm_dump() - dump the list of active filedescriptors
  */
 {
 	int i;
 
-	for (i = 0; i <= highest_fd; i++)
+	for (i = 0; i <= FD_HASH_SIZE; i++)
 	{
-		if(!fd_table[i].flags.open)
+		dlink_node *n;
+
+		if (dlink_list_length(&fd_table[i]) <= 0)
 			continue;
 
-		sendto_one_numeric(source_p, RPL_STATSDEBUG, 
-				   "F :fd %-3d desc '%s'",
-				   i, fd_table[i].desc);
+		DLINK_FOREACH(n, fd_table[i].head)
+		{
+			fde_t *F = (fde_t *) n->data;
+
+			if(F == NULL || !F->flags.open)
+				continue;
+
+			sendto_one_numeric(source_p, RPL_STATSDEBUG, 
+					   "F :fd %-3d bucket %-3d desc '%s'",
+					   F->fd, i, F->desc);
+		}
 	}
 }
 
 comm_note(int fd, const char *format, ...)
 {
 	va_list args;
+	fde_t *F = comm_add_fd(fd);	/* XXX: epoll, kqueue. */
 
 	if(format)
 	{
 		va_start(args, format);
-		ircvsnprintf(fd_table[fd].desc, FD_DESC_SZ, format, args);
+		ircvsnprintf(F->desc, FD_DESC_SZ, format, args);
 		va_end(args);
 	}
 	else
-		fd_table[fd].desc[0] = '\0';
+		F->desc[0] = '\0';
 }
 
 

libcharybdis/commio.h

  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
  *  USA
  *
- *  $Id: commio.h 1757 2006-07-25 23:34:45Z jilles $
+ *  $Id: commio.h 3229 2007-03-05 17:23:07Z nenolod $
  */
 
 #ifndef INCLUDED_commio_h
 #include "setup.h"
 #include "config.h"
 #include "ircd_defs.h"
+#include "tools.h"
 
 /* Callback for completed IO events */
 typedef void PF(int fd, void *);
 	}
 	connect;
 	int pflags;
+	dlink_node node;
 };
 
 
-extern fde_t *fd_table;
-
 void fdlist_init(void);
 
 extern void comm_open(int, unsigned int, const char *);
 #define mangle_mapped_sockaddr(x) 
 #endif
 
+extern fde_t *comm_locate_fd(int fd);
 
 #endif /* INCLUDED_commio_h */

libcharybdis/devpoll.c

  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
  *  USA
  *
- *  $Id: devpoll.c 390 2005-12-07 18:46:56Z nenolod $
+ *  $Id: devpoll.c 3229 2007-03-05 17:23:07Z nenolod $
  */
 
 #include "config.h"
 	int cur_mask = fdmask[fd];
 	PF *cur_handler;
 	fdmask[fd] = 0;
+	fde_t *F = comm_locate_fd(fd);
+
 	switch (filter)
 	{
 	case COMM_SELECT_READ:
-		cur_handler = fd_table[fd].read_handler;
+		cur_handler = F->read_handler;
 		if(handler)
 			fdmask[fd] |= POLLRDNORM;
 		else
 			fdmask[fd] &= ~POLLRDNORM;
-		if(fd_table[fd].write_handler)
+		if(F->write_handler)
 			fdmask[fd] |= POLLWRNORM;
 		break;
 	case COMM_SELECT_WRITE:
-		cur_handler = fd_table[fd].write_handler;
+		cur_handler = F->write_handler;
 		if(handler)
 			fdmask[fd] |= POLLWRNORM;
 		else
 			fdmask[fd] &= ~POLLWRNORM;
-		if(fd_table[fd].read_handler)
+		if(F->read_handler)
 			fdmask[fd] |= POLLRDNORM;
 		break;
 	default:
 comm_setselect(int fd, fdlist_t list, unsigned int type, PF * handler,
 	       void *client_data, time_t timeout)
 {
-	fde_t *F = &fd_table[fd];
+	fde_t *F = comm_locate_fd(fd);
 	s_assert(fd >= 0);
 	s_assert(F->flags.open);
 
 		{
 			int fd = dopoll.dp_fds[i].fd;
 			PF *hdl = NULL;
-			fde_t *F = &fd_table[fd];
+			fde_t *F = comm_locate_fd(fd);
 			if((dopoll.dp_fds[i].
 			    revents & (POLLRDNORM | POLLIN | POLLHUP |
 				       POLLERR))

libcharybdis/epoll.c

  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
  *  USA
  *
- *  $Id: epoll.c 390 2005-12-07 18:46:56Z nenolod $
+ *  $Id: epoll.c 3229 2007-03-05 17:23:07Z nenolod $
  */
 
 #include "config.h"
 	       void *client_data, time_t timeout)
 {
 	struct epoll_event ep_event;
-	fde_t *F = &fd_table[fd];
+	fde_t *F = comm_locate_fd(fd);
 	int old_flags = F->pflags;
 	int op = -1;
 	

libcharybdis/kqueue.c

  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
  *  USA
  *
- *  $Id: kqueue.c 3205 2007-02-09 22:18:23Z nenolod $
+ *  $Id: kqueue.c 3229 2007-03-05 17:23:07Z nenolod $
  */
 
 #include "stdinc.h"
 comm_setselect(int fd, fdlist_t list, unsigned int type, PF * handler,
 	       void *client_data, time_t timeout)
 {
-	fde_t *F = &fd_table[fd];
+	fde_t *F = comm_locate_fd(fd);
 	s_assert(fd >= 0);
 	s_assert(F->flags.open);
 
 	{
 		int fd = (int) ke[i].ident;
 		PF *hdl = NULL;
-		fde_t *F = &fd_table[fd];
+		fde_t *F = comm_locate_fd(fd);
 
 		if(ke[i].flags & EV_ERROR)
 		{

libcharybdis/poll.c

  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
  *  USA
  *
- *  $Id: poll.c 390 2005-12-07 18:46:56Z nenolod $
+ *  $Id: poll.c 3229 2007-03-05 17:23:07Z nenolod $
  */
 
 #include "config.h"
 static void
 poll_update_pollfds(int fd, short event, PF * handler)
 {
-	fde_t *F = &fd_table[fd];
+	fde_t *F = comm_locate_table(fd);
 	int comm_index;
 
 	if(F->comm_index < 0)
 comm_setselect(int fd, fdlist_t list, unsigned int type, PF * handler,
 	       void *client_data, time_t timeout)
 {
-	fde_t *F = &fd_table[fd];
+	fde_t *F = comm_locate_fd(fd);
 	s_assert(fd >= 0);
 	s_assert(F->flags.open);
 
 		   (pollfd_list.pollfds[ci].fd) == -1)
 			continue;
 		fd = pollfd_list.pollfds[ci].fd;
-		F = &fd_table[fd];
+		F = comm_locate_fd(fd);
 		if(revents & (POLLRDNORM | POLLIN | POLLHUP | POLLERR))
 		{
 			hdl = F->read_handler;

libcharybdis/ports.c

 ircd_setselect(int fd, fdlist_t list, unsigned int type, PF * handler,
 	       void *client_data)
 {
-	fde_t *F = &fd_table[fd];
+	fde_t *F = comm_locate_fd(fd);
 	s_assert(fd >= 0);
 	s_assert(F->flags.open);
 
 		case PORT_SOURCE_FD:
 			fd = pelst[i].portev_object;
 			PF *hdl = NULL;
-			fde_t *F = &fd_table[fd];
+			fde_t *F = comm_locate_fd(fd);
 
 			if ((pelst[i].portev_events & POLLRDNORM) && (hdl = F->read_handler)) {
 				F->read_handler = NULL;

libcharybdis/select.c

  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
  *  USA
  *
- *  $Id: select.c 390 2005-12-07 18:46:56Z nenolod $
+ *  $Id: select.c 3229 2007-03-05 17:23:07Z nenolod $
  */
 
 #include "config.h"
 comm_setselect(int fd, fdlist_t list, unsigned int type, PF * handler,
 	       void *client_data, time_t timeout)
 {
-	fde_t *F = &fd_table[fd];
+	fde_t *F = comm_locate_fd(fd);
 	s_assert(fd >= 0);
 	s_assert(F->flags.open);
 
 	/* XXX we *could* optimise by falling out after doing num fds ... */
 	for (fd = 0; fd < highest_fd + 1; fd++)
 	{
-		F = &fd_table[fd];
+		F = comm_locate_fd(fd);
 
 		if(FD_ISSET(fd, &tmpreadfds))
 		{