if (!cmd->header_sent) {
o_stream_nsend_str(client->output,
"domain\treset_timestamp\tlast_update"
- "\tnum_logins\tnum_cmds"MAIL_STATS_HEADER);
+ "\tnum_logins\tnum_cmds\tnum_connected_sessions"MAIL_STATS_HEADER);
cmd->header_sent = TRUE;
}
str_append_tabescaped(cmd->str, domain->name);
str_printfa(cmd->str, "\t%ld", (long)domain->reset_timestamp);
client_export_timeval(cmd->str, &domain->last_update);
- str_printfa(cmd->str, "\t%u\t%u",
- domain->num_logins, domain->num_cmds);
+ str_printfa(cmd->str, "\t%u\t%u\t%u",
+ domain->num_logins, domain->num_cmds,
+ domain->num_connected_sessions);
client_export_mail_stats(cmd->str, &domain->stats);
str_append_c(cmd->str, '\n');
o_stream_nsend(client->output, str_data(cmd->str),
if (!cmd->header_sent) {
o_stream_nsend_str(client->output,
"ip\treset_timestamp\tlast_update"
- "\tnum_logins\tnum_cmds"MAIL_STATS_HEADER);
+ "\tnum_logins\tnum_cmds\tnum_connected_sessions"MAIL_STATS_HEADER);
cmd->header_sent = TRUE;
}
} T_END;
str_printfa(cmd->str, "\t%ld", (long)ip->reset_timestamp);
client_export_timeval(cmd->str, &ip->last_update);
- str_printfa(cmd->str, "\t%u\t%u", ip->num_logins, ip->num_cmds);
+ str_printfa(cmd->str, "\t%u\t%u\t%u",
+ ip->num_logins, ip->num_cmds, ip->num_connected_sessions);
client_export_mail_stats(cmd->str, &ip->stats);
str_append_c(cmd->str, '\n');
o_stream_nsend(client->output, str_data(cmd->str),
return sizeof(*domain) + strlen(domain->name) + 1;
}
-struct mail_domain *mail_domain_login(const char *name)
+struct mail_domain *mail_domain_login_create(const char *name)
{
struct mail_domain *domain;
domain = hash_table_lookup(mail_domains_hash, name);
if (domain != NULL) {
- domain->num_logins++;
- mail_domain_refresh(domain, NULL);
+ mail_domain_login(domain);
return domain;
}
hash_table_insert(mail_domains_hash, domain->name, domain);
DLLIST_PREPEND_FULL(&stable_mail_domains, domain,
stable_prev, stable_next);
- DLLIST2_APPEND_FULL(&mail_domains_head, &mail_domains_tail, domain,
- sorted_prev, sorted_next);
- domain->num_logins++;
- domain->last_update = ioloop_timeval;
+ mail_domain_login(domain);
global_memory_alloc(mail_domain_memsize(domain));
return domain;
}
+void mail_domain_login(struct mail_domain *domain)
+{
+ domain->num_logins++;
+ domain->num_connected_sessions++;
+ mail_domain_refresh(domain, NULL);
+}
+
+void mail_domain_disconnected(struct mail_domain *domain)
+{
+ i_assert(domain->num_connected_sessions > 0);
+ domain->num_connected_sessions--;
+}
+
struct mail_domain *mail_domain_lookup(const char *name)
{
return hash_table_lookup(mail_domains_hash, name);
extern struct mail_domain *stable_mail_domains;
-struct mail_domain *mail_domain_login(const char *name);
+struct mail_domain *mail_domain_login_create(const char *name);
+void mail_domain_login(struct mail_domain *domain);
+void mail_domain_disconnected(struct mail_domain *domain);
struct mail_domain *mail_domain_lookup(const char *name);
void mail_domain_refresh(struct mail_domain *domain,
const struct mail_stats *diff_stats) ATTR_NULL(2);
ip = hash_table_lookup(mail_ips_hash, ip_addr);
if (ip != NULL) {
ip->num_logins++;
+ ip->num_connected_sessions++;
mail_ip_refresh(ip, NULL);
return ip;
}
DLLIST2_APPEND_FULL(&mail_ips_head, &mail_ips_tail, ip,
sorted_prev, sorted_next);
ip->num_logins++;
+ ip->num_connected_sessions++;
ip->last_update = ioloop_timeval;
global_memory_alloc(mail_ip_memsize(ip));
return ip;
}
+void mail_ip_disconnected(struct mail_ip *ip)
+{
+ i_assert(ip->num_connected_sessions > 0);
+ ip->num_connected_sessions--;
+}
+
struct mail_ip *mail_ip_lookup(const struct ip_addr *ip_addr)
{
return hash_table_lookup(mail_ips_hash, ip_addr);
extern struct mail_ip *stable_mail_ips;
struct mail_ip *mail_ip_login(const struct ip_addr *ip_addr);
+void mail_ip_disconnected(struct mail_ip *ip);
struct mail_ip *mail_ip_lookup(const struct ip_addr *ip_addr);
void mail_ip_refresh(struct mail_ip *ip, const struct mail_stats *diff_stats)
ATTR_NULL(2);
{
uint8_t *guid_p = session->guid;
+ i_assert(!session->disconnected);
+
+ mail_user_disconnected(session->user);
+ if (session->ip != NULL)
+ mail_ip_disconnected(session->ip);
+
hash_table_remove(mail_sessions_hash, guid_p);
session->disconnected = TRUE;
timeout_remove(&session->to_idle);
if ((ret = mail_session_lookup(args[0], &session, error_r)) <= 0)
return ret;
- mail_session_disconnect(session);
+ if (!session->disconnected)
+ mail_session_disconnect(session);
return 0;
}
struct mail_stats stats;
unsigned int num_logins;
unsigned int num_cmds;
+ unsigned int num_connected_sessions;
int refcount;
struct mail_user *users;
struct mail_stats stats;
unsigned int num_logins;
unsigned int num_cmds;
+ unsigned int num_connected_sessions;
int refcount;
struct mail_session *sessions;
user = hash_table_lookup(mail_users_hash, username);
if (user != NULL) {
user->num_logins++;
- user->domain->num_logins++;
mail_user_refresh(user, NULL);
+ mail_domain_login(user->domain);
return user;
}
user = i_new(struct mail_user, 1);
user->name = i_strdup(username);
user->reset_timestamp = ioloop_time;
- user->domain = mail_domain_login(domain);
+ user->domain = mail_domain_login_create(domain);
hash_table_insert(mail_users_hash, user->name, user);
DLLIST_PREPEND_FULL(&stable_mail_users, user,
return user;
}
+void mail_user_disconnected(struct mail_user *user)
+{
+ mail_domain_disconnected(user->domain);
+}
+
struct mail_user *mail_user_lookup(const char *username)
{
return hash_table_lookup(mail_users_hash, username);
extern struct mail_user *stable_mail_users;
struct mail_user *mail_user_login(const char *username);
+void mail_user_disconnected(struct mail_user *user);
struct mail_user *mail_user_lookup(const char *username);
void mail_user_refresh(struct mail_user *user,