mirror of
https://git.FreeBSD.org/ports.git
synced 2025-01-08 06:48:28 +00:00
9eff14e488
- login_disabled option before starttls for pop3 - fix compiler warnings for GCC5 - Fix IMAP mailbox maintanence - prevent assertion in p_string_erase - improve crypt authentication, also don't segfault when spasswd is empty - simplify log_query_time duration logic - Disconnect IMAP clients if only few free FDs left - Add primary key constraint to dbmail_authlog - Rework temporary connection failures - Give sensible default for retry 120s - Add retries for binding and searching - Bump search timeout to 60s - Increase ldap timeout to 600s 10 mins - Refactor deprecated functions - Get timeout from config - Remove redundant event_assign - Remove deprecated non functioning g_mem_profile - Add definition for authldap_free - Revert inadvertent event_assign removal - Reduce failed LDAP connection for search to error - Update LDAP to non deprecated search - Clear the ldap connection - Update ldap deprecated unbind - Fix typo - Update to ldap_unbind_ext_s and remove redundant sigaction - Rebalance commit rollback - Ensure mailbox2dbmail is using Python 2 - Tidy mailbox2dbmail man page - Update description of pid file location in server man page - Boundaries fixups ordering of parts do not add newline on - Prepend headers during delivery - Allow for systems that don't use proc PR: 210274 Submitted by: fluffy
149 lines
4.1 KiB
Plaintext
149 lines
4.1 KiB
Plaintext
From 6b7eccfec4f76b7d9d1f865caf741ff3214b5964 Mon Sep 17 00:00:00 2001
|
|
From: Pavlo Lavrenenko <santa.ssh@gmail.com>
|
|
Date: Thu, 2 Jun 2016 08:18:51 +0300
|
|
Subject: [PATCH 07/33] Disconnect IMAP clients if only few free FDs left (#37)
|
|
|
|
After network connection to DB server goes down the processing of IMAP session
|
|
stalls: DB connection pool becomes exhausted as active connections do not
|
|
close till TCP timeout kicks in (true at least for Oracle). While DBMail still
|
|
accepts incoming connections it quickly reaches the RLIMIT_NOFILE and becomes
|
|
unresponsive. Send BYE response if the number of opened FDs reaches the
|
|
RLIMIT_NOFILE value.
|
|
---
|
|
src/dbmail.h.in | 5 +++++
|
|
src/dm_misc.c | 20 ++++++++++++++++++++
|
|
src/dm_misc.h | 8 ++++++++
|
|
src/imap4.c | 23 ++++++++++++++++++++++-
|
|
4 files changed, 55 insertions(+), 1 deletion(-)
|
|
|
|
diff --git src/dbmail.h.in src/dbmail.h.in
|
|
index d826dc3..17215ef 100644
|
|
--- src/dbmail.h.in
|
|
+++ src/dbmail.h.in
|
|
@@ -69,12 +69,14 @@
|
|
#include <string.h>
|
|
#include <strings.h>
|
|
#include <sysexits.h>
|
|
+#include <dirent.h>
|
|
#include <sys/types.h>
|
|
#include <sys/stat.h>
|
|
#include <sys/mman.h>
|
|
#include <sys/socket.h>
|
|
#include <sys/un.h>
|
|
#include <sys/time.h>
|
|
+#include <sys/resource.h>
|
|
#include <sys/wait.h>
|
|
#include <sys/ipc.h>
|
|
#include <sys/shm.h>
|
|
@@ -252,6 +254,9 @@
|
|
/* input reading linelimit */
|
|
#define MAX_LINESIZE (64*1024)
|
|
|
|
+/* minumun number of free file descriptors required to run the daemon */
|
|
+#define FREE_DF_THRESHOLD 16
|
|
+
|
|
/* string length for query */
|
|
#define DEF_QUERYSIZE (32*1024)
|
|
#define DEF_FRAGSIZE 256
|
|
diff --git src/dm_misc.c src/dm_misc.c
|
|
index e27ef34..e795de1 100644
|
|
--- src/dm_misc.c
|
|
+++ src/dm_misc.c
|
|
@@ -104,6 +104,26 @@ int drop_privileges(char *newuser, char *newgroup)
|
|
return 0;
|
|
}
|
|
|
|
+int get_opened_fd_count(void)
|
|
+{
|
|
+ DIR* dir = NULL;
|
|
+ struct dirent* entry = NULL;
|
|
+ char buf[32];
|
|
+ int fd_count = 0;
|
|
+
|
|
+ snprintf(buf, 32, "/proc/%i/fd/", getpid());
|
|
+
|
|
+ dir = opendir(buf);
|
|
+ if (dir == NULL)
|
|
+ return -1;
|
|
+
|
|
+ while ((entry = readdir(dir)) != NULL)
|
|
+ fd_count++;
|
|
+ closedir(dir);
|
|
+
|
|
+ return fd_count - 2; /* exclude '.' and '..' entries */
|
|
+}
|
|
+
|
|
void create_unique_id(char *target, uint64_t message_idnr)
|
|
{
|
|
char md5_str[FIELDSIZE];
|
|
diff --git src/dm_misc.h src/dm_misc.h
|
|
index 9660dfa..b6cf24f 100644
|
|
--- src/dm_misc.h
|
|
+++ src/dm_misc.h
|
|
@@ -45,6 +45,14 @@ void g_string_maybe_shrink(GString *s);
|
|
int drop_privileges(char *newuser, char *newgroup);
|
|
|
|
/**
|
|
+ \brief get the number of opened files (requires /proc mounted)
|
|
+ \return
|
|
+ - -1 on error
|
|
+ - number of opened files
|
|
+*/
|
|
+int get_opened_fd_count(void);
|
|
+
|
|
+/**
|
|
* \brief create a unique id for a message (used for pop, stored per message)
|
|
* \param target target string. Length should be UID_SIZE
|
|
* \param message_idnr message_idnr of message
|
|
diff --git src/imap4.c src/imap4.c
|
|
index 0532f2e..e523edc 100644
|
|
--- src/imap4.c
|
|
+++ src/imap4.c
|
|
@@ -351,6 +351,12 @@ static void send_greeting(ImapSession *session)
|
|
dbmail_imap_session_set_state(session, CLIENTSTATE_NON_AUTHENTICATED);
|
|
}
|
|
|
|
+static void disconnect_user(ImapSession *session)
|
|
+{
|
|
+ imap_session_printf(session, "* BYE [Service unavailable.]\r\n");
|
|
+ imap_handle_abort(session);
|
|
+}
|
|
+
|
|
/*
|
|
* the default timeout callback */
|
|
|
|
@@ -601,6 +607,8 @@ int imap_handle_connection(client_sock *c)
|
|
{
|
|
ImapSession *session;
|
|
ClientBase_T *ci;
|
|
+ struct rlimit fd_limit;
|
|
+ int fd_count;
|
|
|
|
ci = client_init(c);
|
|
|
|
@@ -617,7 +625,20 @@ int imap_handle_connection(client_sock *c)
|
|
Capa_remove(session->capa, "LOGINDISABLED");
|
|
}
|
|
|
|
- send_greeting(session);
|
|
+ fd_count = get_opened_fd_count();
|
|
+ if (fd_count < 0 || getrlimit(RLIMIT_NPROC, &fd_limit) < 0) {
|
|
+ TRACE(TRACE_ERR,
|
|
+ "[%p] failed to retrieve fd limits, dropping client connection",
|
|
+ session);
|
|
+ disconnect_user(session);
|
|
+ } else if (fd_limit.rlim_cur - fd_count < FREE_DF_THRESHOLD) {
|
|
+ TRACE(TRACE_WARNING,
|
|
+ "[%p] fd count [%d], fd limit [%d], fd threshold [%d]: dropping client connection",
|
|
+ session, fd_count, fd_limit.rlim_cur, FREE_DF_THRESHOLD);
|
|
+ disconnect_user(session);
|
|
+ } else {
|
|
+ send_greeting(session);
|
|
+ }
|
|
|
|
reset_callbacks(session);
|
|
|
|
--
|
|
2.10.1 (Apple Git-78)
|
|
|