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.3.0.rc1~1764 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f6b8ff28fe15eff03e0127f11cd122d3eb872e2e;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 0b9d771dc4..2e6e252411 100644 --- a/src/doveadm/doveadm-who.c +++ b/src/doveadm/doveadm-who.c @@ -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; }