]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
doveadm who: Don't aggregate empty usernames with different IPs
authorTimo Sirainen <timo.sirainen@dovecot.fi>
Wed, 5 Apr 2017 09:52:14 +0000 (12:52 +0300)
committerGitLab <gitlab@git.dovecot.net>
Mon, 10 Apr 2017 07:00:38 +0000 (10:00 +0300)
We'll assume that in that case anvil is used to track IP addresses rather
than usernames. (Dovecot core doesn't currently use this.)

src/doveadm/doveadm-who.c

index 0b9d771dc42f1fb0b82eb61f4b139b4d6006efb9..2e6e252411bd0efef37d2a064570abab1c2a1719 100644 (file)
@@ -23,9 +23,28 @@ struct who_user {
        unsigned int connection_count;
 };
 
+static void who_user_ip(const struct who_user *user, struct ip_addr *ip_r)
+{
+       if (array_count(&user->ips) == 0)
+               i_zero(ip_r);
+       else {
+               const struct ip_addr *ip = array_idx(&user->ips, 0);
+               *ip_r = *ip;
+       }
+}
+
 static unsigned int who_user_hash(const struct who_user *user)
 {
-       return str_hash(user->username) + str_hash(user->service);
+       struct ip_addr ip;
+       unsigned int hash = str_hash(user->service);
+
+       if (user->username[0] != '\0')
+               hash += str_hash(user->username);
+       else {
+               who_user_ip(user, &ip);
+               hash += net_ip_hash(&ip);
+       }
+       return hash;
 }
 
 static int who_user_cmp(const struct who_user *user1,
@@ -35,6 +54,15 @@ static int who_user_cmp(const struct who_user *user1,
                return 1;
        if (strcmp(user1->service, user2->service) != 0)
                return 1;
+
+       if (user1->username[0] == '\0') {
+               /* tracking only IP addresses, not usernames */
+               struct ip_addr ip1, ip2;
+
+               who_user_ip(user1, &ip1);
+               who_user_ip(user2, &ip2);
+               return net_ip_cmp(&ip1, &ip2);
+       }
        return 0;
 }