- // fix by brain - this must be below any manipulation of the hashmap by modules
- user_hash::iterator count2 = clientlist.begin();
-
-#ifdef USE_EPOLL
- i = epoll_wait(sep, event, 1, EP_DELAY);
- if (i > 0)
- {
- log(DEBUG,"epoll: Listening server socket event, i=%d, event.data.fd=%d",i,event[0].data.fd);
- for (int x = 0; x != SERVERportCount; x++)
- {
- if ((me[x]) && (event[0].data.fd == me[x]->fd))
- {
-#endif
-#ifdef USE_KQUEUE
- ts.tv_sec = 0;
- ts.tv_nsec = 30000L;
- i = kevent(skq, NULL, 0, &ke, 1, &ts);
- if (i > 0)
- {
- log(DEBUG,"kqueue: Listening server socket event, i=%d, ke.ident=%d",i,ke.ident);
- for (int x = 0; x != SERVERportCount; x++)
- {
- if ((me[x]) && (ke.ident == me[x]->fd))
- {
-
-#endif
-#ifdef USE_SELECT
- FD_ZERO(&serverfds);
- for (int x = 0; x != SERVERportCount; x++)
- {
- if (me[x])
- FD_SET(me[x]->fd, &serverfds);
- }
- tvs.tv_usec = 30000L;
- tvs.tv_sec = 0;
- int servresult = select(FD_SETSIZE, &serverfds, NULL, NULL, &tvs);
- if (servresult > 0)
- {
- for (int x = 0; x != SERVERportCount; x++)
- {
- if ((me[x]) && (FD_ISSET (me[x]->fd, &serverfds)))
- {
-#endif
- char remotehost[MAXBUF],resolved[MAXBUF];
- length = sizeof (client);
- incomingSockfd = accept (me[x]->fd, (sockaddr *) &client, &length);
- if (incomingSockfd != -1)
- {
- strlcpy(remotehost,(char *)inet_ntoa(client.sin_addr),MAXBUF);
- if(CleanAndResolve(resolved, remotehost) != TRUE)
- {
- strlcpy(resolved,remotehost,MAXBUF);
- }
- // add to this connections ircd_connector vector
- // *FIX* - we need the LOCAL port not the remote port in &client!
- me[x]->AddIncoming(incomingSockfd,resolved,me[x]->port);
- }
- }
- }
- }
-
- std::deque<std::string> msgs;
- std::deque<std::string> sums;
- for (int x = 0; x < SERVERportCount; x++)
- {
- if (me[x])
- me[x]->FlushWriteBuffers();
- sums.clear();
- msgs.clear();
- while ((me[x]) && (me[x]->RecvPacket(msgs, tcp_host, sums))) // returns 0 or more lines (can be multiple lines!)
- {
- has_been_netsplit = false;
- for (int ctr = 0; ctr < msgs.size(); ctr++)
- {
- strlcpy(tcp_msg,msgs[ctr].c_str(),MAXBUF);
- strlcpy(tcp_sum,sums[ctr].c_str(),MAXBUF);
- log(DEBUG,"Processing: %s",tcp_msg);
- if (!tcp_msg[0])
- {
- log(DEBUG,"Invalid string from %s [route%lu]",tcp_host,(unsigned long)x);
- break;
- }
- // during a netburst, send all data to all other linked servers
- if ((((nb_start>0) && (tcp_msg[0] != 'Y') && (tcp_msg[0] != 'X') && (tcp_msg[0] != 'F'))) || (is_uline(tcp_host)))
- {
- if (is_uline(tcp_host))
- {
- if ((tcp_msg[0] != 'Y') && (tcp_msg[0] != 'X') && (tcp_msg[0] != 'F'))
- {
- NetSendToAllExcept_WithSum(tcp_host,tcp_msg,tcp_sum);
- }
- }
- else
- NetSendToAllExcept_WithSum(tcp_host,tcp_msg,tcp_sum);
- }
- std::string msg = tcp_msg;
- FOREACH_MOD OnPacketReceive(msg,tcp_host);
- strlcpy(tcp_msg,msg.c_str(),MAXBUF);
- if (me[x])
- handle_link_packet(tcp_msg, tcp_host, me[x], tcp_sum);
- if (!me[x]->FindHost(tcp_host))
- {
- log(DEBUG,"Connector gone, bailing!");
- goto label;
- }
- }
- goto label;
- }
- }
-
- while (count2 != clientlist.end())
- {
-#ifdef USE_SELECT
- FD_ZERO(&sfd);
-#endif
-
- total_in_this_set = 0;
+ /* Once a second, do the background processing */
+ if (TIME != OLDTIME)
+ while (DoBackgroundUserStuff(TIME));
+
+ /* Call the socket engine to wait on the active
+ * file descriptors. The socket engine has everything's
+ * descriptors in its list... dns, modules, users,
+ * servers... so its nice and easy, just one call.
+ */
+ SE->Wait(activefds);
+
+ /**
+ * Now process each of the fd's. For users, we have a fast
+ * lookup table which can find a user by file descriptor, so
+ * processing them by fd isnt expensive. If we have a lot of
+ * listening ports or module sockets though, things could get
+ * ugly.
+ */
+ numberactive = activefds.size();
+ for (unsigned int activefd = 0; activefd < numberactive; activefd++)
+ {
+ int socket_type = SE->GetType(activefds[activefd]);
+ switch (socket_type)
+ {
+ case X_ESTAB_CLIENT:
+
+ cu = fd_ref_table[activefds[activefd]];
+ if (cu)
+ ProcessUser(cu);