diff --git a/include/types/session.h b/include/types/session.h index eaa053fbf..7630bc30c 100644 --- a/include/types/session.h +++ b/include/types/session.h @@ -153,6 +153,7 @@ enum { */ struct session { struct list list; /* position in global sessions list */ + struct list back_refs; /* list of users tracking this session */ struct task *task; /* the task associated with this session */ /* application specific below */ struct listener *listener; /* the listener by which the request arrived */ diff --git a/src/client.c b/src/client.c index a9625dac1..4e8004e76 100644 --- a/src/client.c +++ b/src/client.c @@ -66,6 +66,7 @@ int event_accept(int fd) { struct session *s; struct http_txn *txn; struct task *t; + struct bref *bref, *back; int cfd; int max_accept = global.tune.maxaccept; @@ -108,6 +109,7 @@ int event_accept(int fd) { } LIST_ADDQ(&sessions, &s->list); + LIST_INIT(&s->back_refs); s->flags = 0; s->term_trace = 0; @@ -464,6 +466,11 @@ int event_accept(int fd) { out_free_task: pool_free2(pool2_task, t); out_free_session: + list_for_each_entry_safe(bref, back, &s->back_refs, users) { + LIST_DEL(&bref->users); + LIST_ADDQ(&LIST_ELEM(s->list.n, struct session *, list)->back_refs, &bref->users); + bref->ref = s->list.n; + } LIST_DEL(&s->list); pool_free2(pool2_session, s); out_close: diff --git a/src/proto_uxst.c b/src/proto_uxst.c index 06ec18570..25432687a 100644 --- a/src/proto_uxst.c +++ b/src/proto_uxst.c @@ -360,6 +360,7 @@ int uxst_event_accept(int fd) { struct listener *l = fdtab[fd].owner; struct session *s; struct task *t; + struct bref *bref, *back; int cfd; int max_accept; @@ -409,6 +410,7 @@ int uxst_event_accept(int fd) { } LIST_ADDQ(&sessions, &s->list); + LIST_INIT(&s->back_refs); s->flags = 0; s->term_trace = 0; @@ -545,6 +547,11 @@ int uxst_event_accept(int fd) { out_free_task: pool_free2(pool2_task, t); out_free_session: + list_for_each_entry_safe(bref, back, &s->back_refs, users) { + LIST_DEL(&bref->users); + LIST_ADDQ(&LIST_ELEM(s->list.n, struct session *, list)->back_refs, &bref->users); + bref->ref = s->list.n; + } LIST_DEL(&s->list); pool_free2(pool2_session, s); out_close: diff --git a/src/session.c b/src/session.c index a6190730d..e82bfccdf 100644 --- a/src/session.c +++ b/src/session.c @@ -42,6 +42,7 @@ void session_free(struct session *s) { struct http_txn *txn = &s->txn; struct proxy *fe = s->fe; + struct bref *bref, *back; if (s->pend_pos) pendconn_free(s->pend_pos); @@ -82,6 +83,12 @@ void session_free(struct session *s) pool_free2(pool2_requri, txn->uri); pool_free2(pool2_capture, txn->cli_cookie); pool_free2(pool2_capture, txn->srv_cookie); + + list_for_each_entry_safe(bref, back, &s->back_refs, users) { + LIST_DEL(&bref->users); + LIST_ADDQ(&LIST_ELEM(s->list.n, struct session *, list)->back_refs, &bref->users); + bref->ref = s->list.n; + } LIST_DEL(&s->list); pool_free2(pool2_session, s);