static void mail_session_free(struct mail_session *session) { i_assert(session->refcount == 0); global_memory_free(mail_session_memsize(session)); if (session->to_idle != NULL) timeout_remove(&session->to_idle); if (!session->disconnected) hash_table_remove(mail_sessions_hash, session->id); DLLIST_REMOVE_FULL(&stable_mail_sessions, session, stable_prev, stable_next); DLLIST2_REMOVE_FULL(&mail_sessions_head, &mail_sessions_tail, session, sorted_prev, sorted_next); DLLIST_REMOVE_FULL(&session->user->sessions, session, user_prev, user_next); mail_user_unref(&session->user); if (session->ip != NULL) { DLLIST_REMOVE_FULL(&session->ip->sessions, session, ip_prev, ip_next); mail_ip_unref(&session->ip); } str_table_unref(services, &session->service); i_free(session->id); i_free(session); }
int mail_session_connect_parse(const char *const *args, const char **error_r) { struct mail_session *session; const char *session_id; pid_t pid; struct ip_addr ip; unsigned int i; /* <session id> <username> <service> <pid> [key=value ..] */ if (str_array_length(args) < 4) { *error_r = "CONNECT: Too few parameters"; return -1; } session_id = args[0]; if (str_to_pid(args[3], &pid) < 0) { *error_r = t_strdup_printf("CONNECT: Invalid pid %s for session ID %s", args[3], session_id); return -1; } session = hash_table_lookup(mail_sessions_hash, session_id); if (session != NULL) { *error_r = t_strdup_printf( "CONNECT: Duplicate session ID %s for user %s service %s", session_id, args[1], args[2]); return -1; } session = i_malloc(sizeof(struct mail_session) + stats_alloc_size()); session->stats = (void *)(session + 1); session->refcount = 1; /* unrefed at disconnect */ session->id = i_strdup(session_id); session->service = str_table_ref(services, args[2]); session->pid = pid; session->last_update = ioloop_timeval; session->to_idle = timeout_add(MAIL_SESSION_IDLE_TIMEOUT_MSECS, mail_session_idle_timeout, session); session->user = mail_user_login(args[1]); for (i = 3; args[i] != NULL; i++) { if (strncmp(args[i], "rip=", 4) == 0 && net_addr2ip(args[i] + 4, &ip) == 0) session->ip = mail_ip_login(&ip); } hash_table_insert(mail_sessions_hash, session->id, session); DLLIST_PREPEND_FULL(&stable_mail_sessions, session, stable_prev, stable_next); DLLIST2_APPEND_FULL(&mail_sessions_head, &mail_sessions_tail, session, sorted_prev, sorted_next); DLLIST_PREPEND_FULL(&session->user->sessions, session, user_prev, user_next); mail_user_ref(session->user); if (session->ip != NULL) { DLLIST_PREPEND_FULL(&session->ip->sessions, session, ip_prev, ip_next); mail_ip_ref(session->ip); } global_memory_alloc(mail_session_memsize(session)); return 0; }
int mail_session_connect_parse(const char *const *args, const char **error_r) { struct mail_session *session; guid_128_t session_guid; uint8_t *guid_p; pid_t pid; struct ip_addr ip; unsigned int i; /* <session guid> <username> <service> <pid> [key=value ..] */ if (str_array_length(args) < 4) { *error_r = "CONNECT: Too few parameters"; return -1; } if (guid_128_from_string(args[0], session_guid) < 0) { *error_r = "CONNECT: Invalid GUID"; return -1; } if (str_to_pid(args[3], &pid) < 0) { *error_r = "CONNECT: Invalid pid"; return -1; } guid_p = session_guid; session = hash_table_lookup(mail_sessions_hash, guid_p); if (session != NULL) { *error_r = "CONNECT: Duplicate session GUID"; return -1; } session = i_new(struct mail_session, 1); session->refcount = 1; /* unrefed at disconnect */ session->service = i_strdup(args[2]); memcpy(session->guid, session_guid, sizeof(session->guid)); session->pid = pid; session->last_update = ioloop_timeval; session->to_idle = timeout_add(MAIL_SESSION_IDLE_TIMEOUT_MSECS, mail_session_idle_timeout, session); session->user = mail_user_login(args[1]); for (i = 3; args[i] != NULL; i++) { if (strncmp(args[i], "rip=", 4) == 0 && net_addr2ip(args[i] + 4, &ip) == 0) session->ip = mail_ip_login(&ip); } guid_p = session->guid; hash_table_insert(mail_sessions_hash, guid_p, session); DLLIST_PREPEND_FULL(&stable_mail_sessions, session, stable_prev, stable_next); DLLIST2_APPEND_FULL(&mail_sessions_head, &mail_sessions_tail, session, sorted_prev, sorted_next); DLLIST_PREPEND_FULL(&session->user->sessions, session, user_prev, user_next); mail_user_ref(session->user); if (session->ip != NULL) { DLLIST_PREPEND_FULL(&session->ip->sessions, session, ip_prev, ip_next); mail_ip_ref(session->ip); } global_memory_alloc(mail_session_memsize(session)); return 0; }