]> 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)
committerTimo Sirainen <timo.sirainen@dovecot.fi>
Mon, 10 Apr 2017 10:28:38 +0000 (13:28 +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 789682d8951ac8b485ed465ac6cfd370470620c5..cc7ed93a7851a7815a288c393643148d031f8f9d 100644 (file)
@@ -22,9 +22,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,
@@ -34,6 +53,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;
 }