From: Timo Sirainen Date: Wed, 5 Apr 2017 09:52:14 +0000 (+0300) Subject: doveadm who: Don't aggregate empty usernames with different IPs X-Git-Tag: 2.2.30.rc1~149 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=86306a33cb79999d8c16894b71f5b2c902168140;p=thirdparty%2Fdovecot%2Fcore.git doveadm who: Don't aggregate empty usernames with different IPs We'll assume that in that case anvil is used to track IP addresses rather than usernames. (Dovecot core doesn't currently use this.) --- diff --git a/src/doveadm/doveadm-who.c b/src/doveadm/doveadm-who.c index 789682d895..cc7ed93a78 100644 --- a/src/doveadm/doveadm-who.c +++ b/src/doveadm/doveadm-who.c @@ -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; }