#ifdef USE_EPOLL
#include <sys/epoll.h>
-#define EP_DELAY 100
+#define EP_DELAY 50
#endif
#include <time.h>
int WHOWAS_MAX = 100; // default 100 people maximum in the WHOWAS list
int DieDelay = 5;
time_t startup_time = time(NULL);
-int NetBufferSize = 10240; // NetBufferSize used as the buffer size for all read() ops
+int NetBufferSize = 10240; // NetBufferSize used as the buffer size for all read() ops
+int MaxConn = SOMAXCONN; // size of accept() backlog (128 by default on *BSD)
extern int MaxWhoResults;
time_t nb_start = 0;
int dns_timeout = 5;
void ReadConfig(bool bail, userrec* user)
{
- char dbg[MAXBUF],pauseval[MAXBUF],Value[MAXBUF],timeout[MAXBUF],NB[MAXBUF],flood[MAXBUF],MW[MAXBUF];
+ char dbg[MAXBUF],pauseval[MAXBUF],Value[MAXBUF],timeout[MAXBUF],NB[MAXBUF],flood[MAXBUF],MW[MAXBUF],MCON[MAXBUF];
char AH[MAXBUF],AP[MAXBUF],AF[MAXBUF],DNT[MAXBUF],pfreq[MAXBUF],thold[MAXBUF],sqmax[MAXBUF],rqmax[MAXBUF];
ConnectClass c;
std::stringstream errstr;
ConfValue("dns","timeout",0,DNT,&config_f);
ConfValue("options","moduledir",0,ModPath,&config_f);
ConfValue("disabled","commands",0,DisabledCommands,&config_f);
+ ConfValue("options","somaxconn",0,MCON,&config_f);
+ MaxConn = atoi(MCON);
+ if (MaxConn > SOMAXCONN)
+ log(DEFAULT,"WARNING: <options:somaxconn> value may be higher than the system-defined SOMAXCONN value!");
NetBufferSize = atoi(NB);
MaxWhoResults = atoi(MW);
dns_timeout = atoi(DNT);
if (!dns_timeout)
dns_timeout = 5;
+ if (!MaxConn)
+ MaxConn = SOMAXCONN;
if (!DNSServer[0])
strlcpy(DNSServer,"127.0.0.1",MAXBUF);
if (!ModPath[0])
{
struct kevent ke;
log(DEBUG,"kqueue: Add listening socket to events, kq=%d socket=%d",lkq,openSockfd[count]);
- EV_SET(&ke, openSockfd[count], EVFILT_READ, EV_ADD, 0, 32, NULL);
+ EV_SET(&ke, openSockfd[count], EVFILT_READ, EV_ADD, 0, MaxConn, NULL);
int i = kevent(lkq, &ke, 1, 0, 0, NULL);
if (i == -1)
{
if (me[t])
{
log(DEBUG,"kqueue: Add listening SERVER socket to events, kq=%d socket=%d",skq,me[t]->fd);
- EV_SET(&ke, me[t]->fd, EVFILT_READ, EV_ADD, 0, 32, NULL);
+ EV_SET(&ke, me[t]->fd, EVFILT_READ, EV_ADD, 0, MaxConn, NULL);
int i = kevent(skq, &ke, 1, 0, 0, NULL);
if (i == -1)
{
user_hash::iterator count2 = clientlist.begin();
#ifdef USE_EPOLL
- i = epoll_wait(sep, event, 1, EP_DELAY*2);
-#ifdef _POSIX_PRIORITY_SCHEDULING
- sched_yield();
-#endif
+ 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);
}
}
+ std::deque<std::string> msgs;
+ std::deque<std::string> sums;
for (int x = 0; x < SERVERportCount; x++)
{
- std::deque<std::string> msgs;
- std::deque<std::string> sums;
- msgs.clear();
sums.clear();
- if ((me[x]) && (me[x]->RecvPacket(msgs, tcp_host, sums)))
+ msgs.clear();
+ while ((me[x]) && (me[x]->RecvPacket(msgs, tcp_host, sums))) // returns 0 or more lines (can be multiple lines!)
{
for (int ctr = 0; ctr < msgs.size(); ctr++)
{
strlcpy(tcp_sum,msgs[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;
}
std::string msg = tcp_msg;
FOREACH_MOD OnPacketReceive(msg,tcp_host);
strlcpy(tcp_msg,msg.c_str(),MAXBUF);
- handle_link_packet(tcp_msg, tcp_host, me[x], tcp_sum);
+ if (me[x])
+ handle_link_packet(tcp_msg, tcp_host, me[x], tcp_sum);
}
- goto label;
+ sums.clear(); // we're done, clear the list for the next operation
+ msgs.clear();
}
}
if (count2->second)
curr = count2->second;
+ if ((long)curr == -1)
+ goto label;
+
if ((curr) && (curr->fd != 0))
{
#ifdef _POSIX_PRIORITY_SCHEDULING
if (count2 != clientlist.end())
{
curr = count2->second;
+ if ((long)curr == -1)
+ goto label;
+ int currfd = curr->fd;
// we don't check the state of remote users.
- if ((curr->fd != -1) && (curr->fd != FD_MAGIC_NUMBER))
+ if ((currfd != -1) && (currfd != FD_MAGIC_NUMBER))
{
curr->FlushWriteBuf();
if (curr->GetWriteError() != "")
curr->dns_done = true;
statsDnsBad++;
FullConnectUser(curr);
- goto label;
+ if (fd_ref_table[currfd] != curr) // something changed, bail pronto
+ goto label;
}
if ((curr->dns_done) && (curr->registered == 3) && (AllModulesReportReady(curr))) // both NICK and USER... and DNS
{
log(DEBUG,"dns done, registered=3, and modules ready, OK");
FullConnectUser(curr);
- goto label;
+ if (fd_ref_table[currfd] != curr) // something changed, bail pronto
+ goto label;
}
if ((TIME > curr->nping) && (isnick(curr->nick)) && (curr->registered == 7))
{
if (count2 != clientlist.end())
{
curr = count2->second;
+ if ((long)curr == -1)
+ goto label;
+ int currfd = curr->fd;
// we don't check the state of remote users.
- if ((curr->fd != -1) && (curr->fd != FD_MAGIC_NUMBER))
+ if ((currfd != -1) && (currfd != FD_MAGIC_NUMBER))
{
curr->FlushWriteBuf();
{
log(DEBUG,"InspIRCd: registration timeout: %s",curr->nick);
kill_link(curr,"Registration timeout");
- goto label;
+ goto label;
+
}
if ((TIME > curr->signon) && (curr->registered == 3) && (AllModulesReportReady(curr)))
{
curr->dns_done = true;
statsDnsBad++;
FullConnectUser(curr);
- goto label;
+ if (fd_ref_table[currfd] != curr) // something changed, bail pronto
+ goto label;
}
if ((curr->dns_done) && (curr->registered == 3) && (AllModulesReportReady(curr)))
{
log(DEBUG,"dns done, registered=3, and modules ready, OK");
FullConnectUser(curr);
- goto label;
+ if (fd_ref_table[currfd] != curr) // something changed, bail pronto
+ goto label;
}
if ((TIME > curr->nping) && (isnick(curr->nick)) && (curr->registered == 7))
{
}
}
- goto label;
+ if ((currfd < 0) || (!fd_ref_table[currfd]))
+ goto label;
}
if ((result == -1) && (errno != EAGAIN) && (errno != EINTR))
{
#endif
#ifdef USE_EPOLL
-#ifdef _POSIX_PRIORITY_SCHEDULING
- sched_yield();
-#endif
- i = epoll_wait(lep, event, 32, EP_DELAY*2);
-#ifdef _POSIX_PRIORITY_SCHEDULING
- sched_yield();
-#endif
+ i = epoll_wait(lep, event, 32, EP_DELAY);
if (i > 0) for (j = 0; j < i; j++)
{
log(DEBUG,"epoll: Listening socket event, i=%d,events[j].data.fd=%d",i,event[j].data.fd);
AddClient(incomingSockfd, resolved, ports[count], false, inet_ntoa (client.sin_addr));
log(DEBUG,"InspIRCd: adding client on port %lu fd=%lu",(unsigned long)ports[count],(unsigned long)incomingSockfd);
}
- //goto label;
}
}
}