+2000-03-30 Perry Lorier <isomer@coders.net>
+ * ircd/ircd.c: rewrote check_pings() for maintainability
+ and speed. Also changed quit msg's so they don't have
+ redundant nick[host] info in them.
+
+ * ircd/send.c: Changed write errors to report what error
+ occured (if possible).
+
+ * ircd/gline.c: added gline comment to the quit.
+
+ * ircd/m_server.c: Added suggestions to server quits mentioning
+ what went wrong so the admin can fix it earlier instead of asking
+ questions...
+
+ * ircd/map.c: Changed m_map() to hide numerics, show a * beside
+ servers that aren't fully burst yet. And show '(--s)' for servers
+ where its not sure.
+
+ * doc/example.conf: Fixed wrapped U:
+
2000-03-30 Kevin L. Mitchell <klmitch@mit.edu>
* ircd/m_mode.c (ms_mode): implemented a new m_mode in terms of
#
# ChangeLog for ircu2.10.11
#
-# $Id: ChangeLog,v 1.45 2000-03-30 22:03:36 kev Exp $
+# $Id: ChangeLog,v 1.46 2000-03-30 22:09:51 isomer Exp $
#
# Insert new changes at beginning of the change list.
#
# it is not allowed to jupe others as well.
U:Uworld.EU.undernet.org:EuWorld,E,protocol,StatServ,NoteServ,Undernet:*
-U:Uworld2.undernet.org:UWorld2,W,ChanSvr,ChanSaver,ChanServ,COM1,COM2,COM3,COM4:
-*
-U:Uworld.undernet.org:Uworld,X,NickSvr,NickSaver,NickServ,LPT1,LPT2,AUX:*
+U:Uworld2.undernet.org:UWorld2,ChanSvr,ChanSaver,ChanServ,COM1,COM2,COM3,COM4:*
+U:Uworld.undernet.org:Uworld,X,W,NickSvr,NickSaver,NickServ,LPT1,LPT2,AUX:*
#
# While running your server, you will most probably encounter individuals
/* and get rid of him */
if (sptr != acptr)
- exit_client(sptr->from, acptr, &me, "G-lined");
+ exit_client_msg(sptr->from, acptr, &me, "G-lined (%s)", agline->reason);
}
}
}
return (next);
}
+static time_t check_pings(void)
+{
+ int expire=0;
+ /* Temp to figure out what time this connection will next need
+ * to be checked.
+ */
+ int next_check = CurrentTime + PINGFREQUENCY;
+ /*
+ * The current lowest expire time - ie: the time that check_pings
+ * needs to be called next.
+ */
+ int max_ping = 0;
+ /*
+ * The time you've got before a ping is sent/your connection is
+ * terminated.
+ */
+
+ int i=0; /* loop counter */
+
+ /* Scan through the client table */
+ for (i=0; i <= HighestFd; i++) {
+ struct Client *cptr;
+
+ cptr = LocalClientArray[i];
+
+ /* Skip empty entries */
+ if (!cptr)
+ continue;
+
+ assert(&me != cptr); /* I should never be in the local client array,
+ * so if I am, dying is a good thing(tm).
+ */
+
+ /* Remove dead clients.
+ * We will have sent opers a message when we set the dead flag,
+ * so don't bother to send one now.
+ */
+ if (IsDead(cptr)) {
+ exit_client(cptr, cptr, &me, cptr->info);
+ continue;
+ }
+
+ /* Should we concider adding a class 0 for 'unregistered clients',
+ * where we can specify their 'ping timeout' etc?
+ */
+ max_ping = IsRegistered(cptr) ? get_client_ping(cptr) : CONNECTTIMEOUT;
+
+ /* Ok, the thing that will happen most frequently, is that someone will
+ * have sent something recently. Cover this first for speed.
+ */
+ if (CurrentTime-cptr->lasttime <= max_ping) {
+ expire=cptr->lasttime + max_ping;
+ if (next_check<expire)
+ next_check=expire;
+ continue;
+ }
+
+ /* Quit the client after max_ping*2 - they should have answered by now */
+ if (CurrentTime-cptr->lasttime <= (max_ping*2) ) {
+
+ /* If it was a server, then tell ops about it. */
+ if (IsServer(cptr) || IsConnecting(cptr) || IsHandshake(cptr))
+ sendto_ops("No response from %s, closing link", cptr->name);
+
+ exit_client_msg(cptr, cptr, &me, "Ping timeout");
+ continue;
+ } /* of testing to see if ping has been sent */
+
+ /* Unregistered clients pingout after max_ping seconds, they don't
+ * get given a second chance.
+ */
+ if (!IsRegistered(cptr)) {
+ /* Display message if they have sent a NICK and a USER but no
+ * nospoof PONG.
+ */
+ if (*cptr->name && *cptr->user->username) {
+ sendto_one(cptr,
+ ":%s %d %s :Your client may not be compatible with this server.",
+ me.name, ERR_BADPING, cptr->name);
+ sendto_one(cptr,
+ ":%s %d %s :Compatible clients are available at "
+ "ftp://ftp.undernet.org/pub/irc/clients",
+ me.name, ERR_BADPING, cptr->name);
+ }
+ exit_client_msg(cptr,cptr,&me, "Ping Timeout");
+ continue;
+ } /* of not registered */
+
+ if (0 == (cptr->flags & FLAGS_PINGSENT)) {
+ /*
+ * If we havent PINGed the connection and we havent heard from it in a
+ * while, PING it to make sure it is still alive.
+ */
+ cptr->flags |= FLAGS_PINGSENT;
+
+ /*
+ * If we're late in noticing don't hold it against them :)
+ */
+ cptr->lasttime = CurrentTime - max_ping;
+
+ if (IsUser(cptr))
+ sendto_one(cptr, "PING :%s", me.name);
+ else
+ sendto_one(cptr, "%s " TOK_PING " :%s", NumServ(&me), me.name);
+ } /* of if not ping sent... */
+
+ expire=cptr->lasttime+max_ping*2;
+
+ if (expire<next_check)
+ next_check=expire;
+
+ } /* end of loop over clients */
+
+ assert(next_check>=CurrentTime);
+
+ return next_check;
+}
+
+#if 0
static time_t check_pings(void)
{
struct Client *cptr;
- int ping = 0;
+ int max_ping = 0;
int i;
time_t oldest = CurrentTime + PINGFREQUENCY;
time_t timeout;
+ /* For each client... */
for (i = 0; i <= HighestFd; i++) {
- if (!(cptr = LocalClientArray[i]))
+ if (!(cptr = LocalClientArray[i])) /* oops! not a client... */
continue;
/*
* me is never in the local client array
continue;
}
- ping = IsRegistered(cptr) ? get_client_ping(cptr) : CONNECTTIMEOUT;
- Debug((DEBUG_DEBUG, "c(%s)=%d p %d a %d",
- cptr->name, cptr->status, ping,
+ max_ping = IsRegistered(cptr) ? get_client_ping(cptr) : CONNECTTIMEOUT;
+
+ Debug((DEBUG_DEBUG, "check_pings(%s)=status:%d ping: %d current: %d",
+ cptr->name, cptr->status, max_ping,
(int)(CurrentTime - cptr->lasttime)));
+
/*
* Ok, so goto's are ugly and can be avoided here but this code
* is already indented enough so I think its justified. -avalon
*/
- if (IsRegistered(cptr) && (ping >= CurrentTime - cptr->lasttime))
+ /*
+ * If this is a registered client that we've heard of in a reasonable
+ * time, then skip them.
+ */
+ if (IsRegistered(cptr) && (max_ping >= CurrentTime - cptr->lasttime))
goto ping_timeout;
/*
* If the server hasnt talked to us in 2 * ping seconds
"ftp://ftp.undernet.org/pub/irc/clients",
me.name, ERR_BADPING, cptr->name);
}
- exit_client_msg(cptr, cptr, &me, "Ping timeout for %s",
- get_client_name(cptr, HIDE_IP));
+ exit_client_msg(cptr, cptr, &me, "Ping timeout");
}
continue;
}
sendto_one(cptr, "%s " TOK_PING " :%s", NumServ(&me), me.name);
}
ping_timeout:
- timeout = cptr->lasttime + ping;
+ timeout = cptr->lasttime + max_ping;
while (timeout <= CurrentTime)
- timeout += ping;
+ timeout += max_ping;
if (timeout < oldest)
oldest = timeout;
}
return (oldest);
}
+#endif
/*
* bad_command
servs.inuse++;
#endif
cptr->serv = serv;
+ cptr->serv->lag = 10000;
*serv->by = '\0';
DupString(serv->last_error_msg, "<>"); /* String must be non-empty */
}
ircd_strncpy(nick, parv[1], NICKLEN);
nick[NICKLEN] = '\0';
- if (IsServer(sptr)) {
- lastnick = atoi(parv[3]);
- if (lastnick > OLDEST_TS)
- sptr->serv->lag = TStime() - lastnick;
- }
- else {
- lastnick = atoi(parv[2]);
- if (lastnick > OLDEST_TS)
- sptr->user->server->serv->lag = TStime() - lastnick;
+ if (!IsBurstOrBurstAck(sptr)) {
+ if (IsServer(sptr)) {
+ lastnick = atoi(parv[3]);
+ if (lastnick > OLDEST_TS)
+ sptr->serv->lag = TStime() - lastnick;
+ }
+ else {
+ lastnick = atoi(parv[2]);
+ if (lastnick > OLDEST_TS)
+ sptr->user->server->serv->lag = TStime() - lastnick;
+ }
}
/*
* If do_nick_name() returns a null name OR if the server sent a nick
* If my ircd.conf sucks, I can try to connect to myself:
*/
if (acptr == &me)
- return exit_client_msg(cptr, cptr, &me, "nick collision with me (%s)", host);
+ return exit_client_msg(cptr, cptr, &me, "nick collision with me (%s), check server number?", host);
/*
* Detect wrong numeric.
*/
{
if (LHcptr == 0) {
return exit_new_server(cptr, sptr, host, timestamp,
- (active_lh_line == 2) ? "Non-Hub link %s <- %s(%s)" : "Leaf-only link %s <- %s(%s)",
+ (active_lh_line == 2) ? "Non-Hub link %s <- %s(%s), check H:" :
+ "Leaf-only link %s <- %s(%s), check L:",
cptr->name, host,
lhconf ? (lhconf->name ? lhconf->name : "*") : "!");
}
if (active_lh_line < 3)
{
if (exit_client_msg(cptr, LHcptr, &me,
- (active_lh_line == 2) ? "Non-Hub link %s <- %s(%s)" : "Leaf-only link %s <- %s(%s)",
+ (active_lh_line == 2) ? "Non-Hub link %s <- %s(%s), check H:" :
+ "Leaf-only link %s <- %s(%s), check L:",
cptr->name, host,
lhconf ? (lhconf->name ? lhconf->name : "*") : "!") == CPTR_KILLED)
return CPTR_KILLED;
else
{
ServerStats->is_ref++;
- if (exit_client(cptr, LHcptr, &me, "I'm a leaf") == CPTR_KILLED)
+ if (exit_client(cptr, LHcptr, &me, "I'm a leaf, define HUB") == CPTR_KILLED)
return CPTR_KILLED;
}
/*
if (doall && IsUser(acptr))
continue;
/* Don't show invisible people to unauthorized people when using
- * wildcards -- Is this still needed now /stats is oper only ? */
+ * wildcards -- Is this still needed now /stats is oper only ?
+ * Yeah it is -- non opers can /stats l, just not remotely.
+ */
if (IsInvisible(acptr) && (doall || wilds) &&
!(MyConnect(sptr) && IsOper(sptr)) &&
!IsAnOper(acptr) && (acptr != sptr))
if (prompt_length > 60)
sendto_one(cptr, rpl_str(RPL_MAPMORE), me.name, cptr->name,
prompt, server->name);
- else
+ else {
+ char lag[512];
+ if (server->serv->lag>10000)
+ strcpy(lag,"(--s)");
+ else if (server->serv->lag<0)
+ strcpy(lag,"(0s)");
+ else
+ sprintf(lag,"(%is)",server->serv->lag);
sendto_one(cptr, rpl_str(RPL_MAP), me.name, cptr->name,
- prompt, NumServ(server), server->name,
- server->serv->lag>0 ? server->serv->lag : 0,
+ prompt,
+ ((IsBurstOrBurstAck(server)) ? "*" : ""),
+ server->name,
+ lag,
(server == &me) ? UserStats.local_clients : server->serv->clients);
+ }
if (prompt_length > 0)
{
p[-1] = ' ';
const char* msg = (cptr->error) ? strerror(cptr->error) : "EOF from client";
if (!msg)
msg = "Unknown error";
- exit_client_msg(cptr, cptr, &me, "Read error to %s: %s",
- get_client_name(cptr, HIDE_IP), msg);
+ exit_client_msg(cptr, cptr, &me, "Read error: %s",
+ msg);
}
}
return 0;
const char* msg = (cptr->error) ? strerror(cptr->error) : "EOF from client";
if (!msg)
msg = "Unknown error";
- exit_client_msg(cptr, cptr, &me, "Read error to %s: %s",
- get_client_name(cptr, HIDE_IP), msg);
+ exit_client_msg(cptr, cptr, &me, "Read error: %s",
+ msg);
}
}
return 0;
/* 014 */
{ 0 },
/* 015 */
- { RPL_MAP, ":%s%s:%s (%is) [%i clients]", "015" },
+ { RPL_MAP, ":%s%s%s %s [%i clients]", "015" },
/* 016 */
{ RPL_MAPMORE, ":%s%s --> *more*", "016" },
/* 017 */
va_start(vl, fmt);
if (!IsServer(sptr))
return vexit_client_msg(cptr, cptr, &me, fmt, vl);
- sprintf_irc(buf, ":%s SQUIT %s " TIME_T_FMT " :", me.name, host, timestamp);
+ sprintf_irc(buf, ":%s " TOK_SQUIT " %s " TIME_T_FMT " :", me.name, host, timestamp);
strcat(buf, fmt);
vsendto_one(cptr, buf, vl);
va_end(vl);
* generate ExitClient from the main loop.
*
* If 'notice' is not NULL, it is assumed to be a format
- * for a message to local opers. I can contain only one
+ * for a message to local opers. It can contain only one
* '%s', which will be replaced by the sockhost field of
* the failing link.
*
break;
}
else {
- if (IsDead(to))
- dead_link(to, "Write error, closing link");
+ if (IsDead(to)) {
+ char tmp[512];
+ sprintf(tmp,"Write error: %s",(strerror(to->error)) ? (strerror(to->error)) : "Unknown error" );
+ dead_link(to, tmp);
+ }
break;
}
}