MEDIUM: sessions: Don't keep an infinite number of idling connections.
In session, don't keep an infinite number of connection that can idle.
Add a new frontend parameter, "max-session-srv-conns" to set a max number,
with a default value of 5.
diff --git a/include/proto/session.h b/include/proto/session.h
index bc5498a..8c99e7d 100644
--- a/include/proto/session.h
+++ b/include/proto/session.h
@@ -30,7 +30,9 @@
#include <types/global.h>
#include <types/session.h>
+#include <proto/obj_type.h>
#include <proto/stick_table.h>
+#include <proto/server.h>
extern struct pool_head *pool_head_session;
struct session *session_new(struct proxy *fe, struct listener *li, enum obj_type *origin);
@@ -76,6 +78,7 @@
int avail = -1;
int i;
+ sess->resp_conns++;
for (i = 0; i < MAX_SRV_LIST; i++) {
if (sess->srv_list[i].target == target) {
avail = i;
@@ -99,6 +102,7 @@
}
/* Now unown all the connections */
list_for_each_entry_safe(conn, conn_back, &sess->srv_list[avail].list, session_list) {
+ sess->resp_conns--;
conn->owner = NULL;
LIST_DEL(&conn->session_list);
LIST_INIT(&conn->session_list);
@@ -111,6 +115,24 @@
LIST_ADDQ(&sess->srv_list[avail].list, &conn->session_list);
}
+/* Returns 0 if the session can keep the idle conn, -1 if it was destroyed, or 1 if it was added to the server list */
+static inline int session_check_idle_conn(struct session *sess, struct connection *conn)
+{
+ if (sess->resp_conns > sess->fe->max_out_conns) {
+ /* We can't keep the connection, let's try to add it to the server idle list */
+ LIST_DEL(&conn->session_list);
+ LIST_INIT(&conn->session_list);
+ conn->owner = NULL;
+ sess->resp_conns--;
+ if (!srv_add_to_idle_list(objt_server(conn->target), conn)) {
+ /* The server doesn't want it, let's kill the connection right away */
+ conn->mux->destroy(conn);
+ return -1;
+ }
+ return 1;
+ }
+ return 0;
+}
#endif /* _PROTO_SESSION_H */