Author: Perry Lorier <isomer@undernet.org>
authorPerry Lorier <isomer@undernet.org>
Sat, 14 Jul 2007 02:40:01 +0000 (02:40 +0000)
committerPerry Lorier <isomer@undernet.org>
Sat, 14 Jul 2007 02:40:01 +0000 (02:40 +0000)
Log message:

Try and fix issues with large numbers of invisible (or non invisible) users.
Do this by always calling set_user_mode() for all mode setting/unsetting.
This requires an extra flag so we can limit which userflags can be set in
some situations.

git-svn-id: file:///home/klmitch/undernet-ircu/undernet-ircu-svn/ircu2/branches/u2_10_12_branch@1818 c9e4aea6-c8fd-4c43-8297-357d70d61c8c

ChangeLog
include/s_user.h
ircd/m_lusers.c
ircd/m_mode.c
ircd/m_user.c
ircd/s_auth.c
ircd/s_misc.c
ircd/s_user.c

index 37f80a7f5659d7b851111fe9936dbc11fbf20b70..6869bc14d14d37f1fb27a55b4882cd0db89251cd 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,26 @@
+2007-07-12  Perry Lorier <isomer@undernet.org>
+       Reconsider how we manage modes before registration, to avoid stats
+       getting out of sync.
+
+       * ircd/s_user.c (set_user_mode): Add new parameter to set_user_mode to
+       ignore some modes.
+       (register_user): Use set_user_mode to parse default usermode for
+       users.
+
+       * ircd/m_user.c: Add extra parameter to set_user_mode call
+
+       * ircd/s_auth.c: Add extra parameter to set_user_mode call
+
+       * ircd/m_mode.c: Add extra parameter to set_user_mode call
+
+       * ircd/s_misc.c: Verify stats are consistant.
+
+       * include/s_user.h: Change prototype, add flag definitions.
+
+       * ircd/m_lusers.c (m_users): Assert that we're generating sane stats,
+       include "unknowns" in the total user connections to avoid negative
+       wrap arounds.
+
 2007-07-12  Perry Lorier <isomer@undernet.org>
        
        * ircd/m_user.c (m_luser): Fix broken RFC 2812 on connect user mode 
index 205776c2d9321e6db886d28e94ace31d290f858f..63ed134d2c52bf193e39799344a673533a2a29f3 100644 (file)
@@ -50,6 +50,10 @@ struct Flags;
 #define MATCH_SERVER  1 /**< flag for relay_masked_message (etc) to indicate the mask matches a server name */
 #define MATCH_HOST    2 /**< flag for relay_masked_message (etc) to indicate the mask matches host name */
 
+/* used for parsing user modes */
+#define ALLOWMODES_ANY 0 /**< Allow any user mode */
+#define ALLOWMODES_DEFAULT  1 /**< Only allow the subset of modes that are legit defaults */
+
 /** Formatter function for send_user_info().
  * @param who Client being displayed.
  * @param sptr Client requesting information.
@@ -77,7 +81,7 @@ extern void send_user_info(struct Client* to, char* names, int rpl,
 
 extern int hide_hostmask(struct Client *cptr, unsigned int flags);
 extern int set_user_mode(struct Client *cptr, struct Client *sptr,
-                         int parc, char *parv[]);
+                         int parc, char *parv[], int allow_modes);
 extern int is_silenced(struct Client *sptr, struct Client *acptr);
 extern int hunt_server_cmd(struct Client *from, const char *cmd,
                           const char *tok, struct Client *one,
index b1b7afdc9dfb5bae93d1b12524414335e96c94fa..573fa52c58c83edc55f365a7321e791595a2ec5c 100644 (file)
@@ -112,7 +112,10 @@ int m_lusers(struct Client* cptr, struct Client* sptr, int parc, char* parv[])
                         "%s :%C", 2, parc, parv) != HUNTED_ISME)
       return 0;
 
-  send_reply(sptr, RPL_LUSERCLIENT, UserStats.clients - UserStats.inv_clients,
+  assert(UserStats.inv_clients <= UserStats.clients + UserStats.unknowns);
+
+  send_reply(sptr, RPL_LUSERCLIENT, 
+            UserStats.clients - UserStats.inv_clients + UserStats.unknowns,
             UserStats.inv_clients, UserStats.servers);
   if (longoutput && UserStats.opers)
     send_reply(sptr, RPL_LUSEROP, UserStats.opers);
index 8b91fd58e56cf4e1b0a00feb60002e2995b4d1d3..e85398d26646e57790efc55f261ebbaaeeb5e04f 100644 (file)
@@ -127,7 +127,7 @@ m_mode(struct Client *cptr, struct Client *sptr, int parc, char *parv[])
       send_reply(sptr, ERR_USERSDONTMATCH);
       return 0;
     }
-    return set_user_mode(cptr, sptr, parc, parv);
+    return set_user_mode(cptr, sptr, parc, parv, ALLOWMODES_ANY);
   }
 
   ClrFlag(sptr, FLAG_TS8);
@@ -198,7 +198,7 @@ ms_mode(struct Client *cptr, struct Client *sptr, int parc, char *parv[])
                               cli_name(cptr), cli_name(sptr));
       return 0;
     }
-    return set_user_mode(cptr, sptr, parc, parv);
+    return set_user_mode(cptr, sptr, parc, parv, ALLOWMODES_ANY);
   }
 
   ClrFlag(sptr, FLAG_TS8);
index 6316463cb22f56a668b4845e9b553a0137075f11..2ef132058735e44ffa1a1284f3cd829310c748f7 100644 (file)
@@ -142,13 +142,15 @@ int m_user(struct Client *cptr, struct Client *sptr, int parc, char *parv[])
   if ((mode_request = strtoul(parv[2], &term, 10)) != 0
       && term != NULL && *term == '\0')
   {
+    char *invisible[4] = { NULL, NULL, "+i", NULL };
+    char *wallops[4] = { NULL, NULL, "+w" , NULL };
     /* These bitmask values are codified in RFC 2812, showing
      * ... well, something that is probably best not said.
      */
     if (mode_request & 8)
-      SetInvisible(cptr);
+      set_user_mode(cptr, sptr, 3, invisible, ALLOWMODES_ANY);
     if (mode_request & 4)
-      SetWallops(cptr);
+      set_user_mode(cptr, sptr, 3, wallops, ALLOWMODES_ANY);
   }
   else if (parv[2][0] == '+')
   {
@@ -157,7 +159,7 @@ int m_user(struct Client *cptr, struct Client *sptr, int parc, char *parv[])
     user_modes[1] = NULL;
     user_modes[2] = parv[2];
     user_modes[3] = NULL;
-    set_user_mode(cptr, sptr, 3, user_modes);
+    set_user_mode(cptr, sptr, 3, user_modes, ALLOWMODES_ANY);
   }
 
   info     = (EmptyString(parv[4])) ? "No Info" : parv[4];
index 2aeef4ba5323517180531f1d290a986df07d9384..226420278487a89a359048e26d115db378aa0b8b 100644 (file)
@@ -1917,7 +1917,7 @@ static int iauth_cmd_usermode(struct IAuth *iauth, struct Client *cli,
 {
   if (params[0][0] == '+')
   {
-    set_user_mode(cli, cli, parc + 2, params - 2);
+    set_user_mode(cli, cli, parc + 2, params - 2, ALLOWMODES_ANY);
   }
   return 0;
 }
index 8eab44ee5e59ca346dccd5302e4b7ce28e3e1c75..b5324fa3fffd49344bb3add2c05af2d12a727830 100644 (file)
@@ -223,10 +223,14 @@ static void exit_one_client(struct Client* bcptr, const char* comment)
     if (MyUser(bcptr))
       set_snomask(bcptr, ~0, SNO_DEL);
 
-    if (IsInvisible(bcptr))
+    if (IsInvisible(bcptr)) {
+      assert(UserStats.inv_clients > 0);
       --UserStats.inv_clients;
-    if (IsOper(bcptr))
+    }
+    if (IsOper(bcptr)) {
+      assert(UserStats.opers > 0);
       --UserStats.opers;
+    }
     if (MyConnect(bcptr))
       Count_clientdisconnects(bcptr, UserStats);
     else
index fb08e0bcc8fb7307c5161ebe10f5820fd3786223..a5a75a1817c2110926d47aa9ee3841f40fe64cc2 100644 (file)
@@ -118,6 +118,7 @@ void free_user(struct User* user)
     assert(0 == user->channel);
 
     MyFree(user);
+    assert(userCount>0);
     --userCount;
   }
 }
@@ -452,10 +453,6 @@ int register_user(struct Client *cptr, struct Client *sptr)
     SetUser(sptr);
   }
 
-  if (IsInvisible(sptr))
-    ++UserStats.inv_clients;
-  if (IsOper(sptr))
-    ++UserStats.opers;
   /* If they get both +x and an account during registration, hide
    * their hostmask here.  Calling hide_hostmask() from IAuth's
    * account assignment causes a numeric reply during registration.
@@ -984,9 +981,12 @@ hide_hostmask(struct Client *cptr, unsigned int flag)
  * @param[in] sptr Client who sent the mode change message.
  * @param[in] parc Number of parameters in \a parv.
  * @param[in] parv Parameters to MODE.
+ * @param[in] allow_modes ALLOWMODES_ANY for any mode, ALLOWMODES_DEFAULT for 
+ *                        only permitting legitimate default user modes.
  * @return Zero.
  */
-int set_user_mode(struct Client *cptr, struct Client *sptr, int parc, char *parv[])
+int set_user_mode(struct Client *cptr, struct Client *sptr, int parc, 
+               char *parv[], int allow_modes)
 {
   char** p;
   char*  m;
@@ -1186,18 +1186,23 @@ int set_user_mode(struct Client *cptr, struct Client *sptr, int parc, char *parv
   if (FlagHas(&setflags, FLAG_OPER) && !IsOper(sptr))
   {
     /* user no longer oper */
+    assert(UserStats.opers > 0);
     --UserStats.opers;
     client_set_privs(sptr, NULL); /* will clear propagate privilege */
   }
-  if (FlagHas(&setflags, FLAG_INVISIBLE) && !IsInvisible(sptr))
+  if (FlagHas(&setflags, FLAG_INVISIBLE) && !IsInvisible(sptr)) {
+    assert(UserStats.inv_clients > 0);
     --UserStats.inv_clients;
+  }
   if (!FlagHas(&setflags, FLAG_INVISIBLE) && IsInvisible(sptr))
     ++UserStats.inv_clients;
-  if (!FlagHas(&setflags, FLAG_HIDDENHOST) && do_host_hiding)
+  if (!FlagHas(&setflags, FLAG_HIDDENHOST) && do_host_hiding && allow_modes != ALLOWMODES_DEFAULT)
     hide_hostmask(sptr, FLAG_HIDDENHOST);
   if (IsRegistered(sptr))
     send_umode_out(cptr, sptr, &setflags, prop);
 
+  assert(UserStats.opers <= UserStats.clients + UserStats.unknowns);
+  assert(UserStats.inv_clients <= UserStats.clients + UserStats.unknowns);
   return 0;
 }