diff --git a/src/hlua.c b/src/hlua.c index fc638ad65..4613d0170 100644 --- a/src/hlua.c +++ b/src/hlua.c @@ -1998,6 +1998,7 @@ __LJMP static int hlua_socket_new(lua_State *L) { struct hlua_socket *socket; struct appctx *appctx; + struct session *sess; /* Check stack size. */ if (!lua_checkstack(L, 3)) { @@ -2026,8 +2027,8 @@ __LJMP static int hlua_socket_new(lua_State *L) * Get memory for the request. * */ - socket->s->sess = pool_alloc2(pool2_session); - if (!socket->s->sess) { + sess = pool_alloc2(pool2_session); + if (!sess) { hlua_pusherror(L, "socket: out of memory"); goto out_fail_conf; } @@ -2038,6 +2039,7 @@ __LJMP static int hlua_socket_new(lua_State *L) goto out_fail_stream; } + socket->s->sess = sess; socket->s->task = task_new(); if (!socket->s->task) { hlua_pusherror(L, "socket: out of memory"); @@ -2232,7 +2234,7 @@ out_fail_req_buf: out_fail_task: pool_free2(pool2_stream, socket->s); out_fail_stream: - pool_free2(pool2_session, socket->s->sess); + pool_free2(pool2_session, sess); out_fail_conf: WILL_LJMP(lua_error(L)); return 0; diff --git a/src/peers.c b/src/peers.c index 882633b3e..b182024aa 100644 --- a/src/peers.c +++ b/src/peers.c @@ -1112,15 +1112,25 @@ static struct stream *peer_session_create(struct peer *peer, struct peer_session struct listener *l = LIST_NEXT(&peer->peers->peers_fe->conf.listeners, struct listener *, by_fe); struct proxy *p = (struct proxy *)l->frontend; /* attached frontend */ struct appctx *appctx; + struct session *sess; struct stream *s; struct task *t; struct connection *conn; - if ((s = pool_alloc2(pool2_stream)) == NULL) { /* disable this proxy for a while */ + sess = pool_alloc2(pool2_session); + if (!sess) { Alert("out of memory in peer_session_create().\n"); goto out_close; } + sess->listener = l; + sess->fe = p; + + if ((s = pool_alloc2(pool2_stream)) == NULL) { /* disable this proxy for a while */ + Alert("out of memory in peer_session_create().\n"); + goto out_free_sess; + } + LIST_ADDQ(&streams, &s->list); LIST_INIT(&s->back_refs); LIST_INIT(&s->buffer_wait); @@ -1132,7 +1142,7 @@ static struct stream *peer_session_create(struct peer *peer, struct peer_session */ if ((t = task_new()) == NULL) { /* disable this proxy for a while */ Alert("out of memory in peer_session_create().\n"); - goto out_free_stream; + goto out_free_strm; } ps->reconnect = tick_add(now_ms, MS_TO_TICKS(5000)); @@ -1143,14 +1153,7 @@ static struct stream *peer_session_create(struct peer *peer, struct peer_session t->nice = l->nice; s->task = t; - s->sess = pool_alloc2(pool2_session); - if (!s->sess) { - Alert("out of memory in peer_session_create().\n"); - goto out_free_task; - } - - s->sess->listener = l; - s->sess->fe = p; + s->sess = sess; s->be = s->sess->fe; s->req.buf = s->res.buf = NULL; s->req_cap = NULL; @@ -1167,7 +1170,8 @@ static struct stream *peer_session_create(struct peer *peer, struct peer_session appctx = stream_int_register_handler(&s->si[0], &peer_applet); if (!appctx) - goto out_fail_conn1; + goto out_free_task; + appctx->st0 = PEER_SESS_ST_CONNECT; appctx->ctx.peers.ptr = (void *)ps; s->sess->origin = &appctx->obj_type; @@ -1185,7 +1189,7 @@ static struct stream *peer_session_create(struct peer *peer, struct peer_session * pre-initialized connection in si->conn. */ if (unlikely((conn = conn_new()) == NULL)) - goto out_fail_conn1; + goto out_free_strm; conn_prepare(conn, peer->proto, peer->xprt); si_attach_conn(&s->si[1], conn); @@ -1266,13 +1270,13 @@ static struct stream *peer_session_create(struct peer *peer, struct peer_session return s; /* Error unrolling */ - out_fail_conn1: - pool_free2(pool2_session, s->sess); out_free_task: task_free(t); - out_free_stream: + out_free_strm: LIST_DEL(&s->list); pool_free2(pool2_stream, s); + out_free_sess: + pool_free2(pool2_session, sess); out_close: return s; } diff --git a/src/stream.c b/src/stream.c index 9d906edf0..e3a71d827 100644 --- a/src/stream.c +++ b/src/stream.c @@ -79,6 +79,7 @@ int stream_accept(struct listener *l, int cfd, struct sockaddr_storage *addr) { struct connection *cli_conn; struct proxy *p = l->frontend; + struct session *sess; struct stream *s; struct task *t; int ret; @@ -97,9 +98,17 @@ int stream_accept(struct listener *l, int cfd, struct sockaddr_storage *addr) cli_conn->target = &l->obj_type; cli_conn->proxy_netns = l->netns; - if (unlikely((s = pool_alloc2(pool2_stream)) == NULL)) + sess = pool_alloc2(pool2_session); + if (!sess) goto out_free_conn; + sess->listener = l; + sess->fe = p; + sess->origin = &cli_conn->obj_type; + + if (unlikely((s = pool_alloc2(pool2_stream)) == NULL)) + goto out_free_sess; + /* minimum stream initialization required for an embryonic stream is * fairly low. We need very little to execute L4 ACLs, then we need a * task to make the client-side connection live on its own. @@ -117,14 +126,7 @@ int stream_accept(struct listener *l, int cfd, struct sockaddr_storage *addr) memset(s->stkctr, 0, sizeof(s->stkctr)); - s->sess = pool_alloc2(pool2_session); - if (!s->sess) - goto out_free_stream; - - s->sess->listener = l; - s->sess->fe = p; - s->sess->origin = &cli_conn->obj_type; - + s->sess = sess; s->si[0].flags = SI_FL_NONE; s->si[1].flags = SI_FL_ISBACK; @@ -156,7 +158,7 @@ int stream_accept(struct listener *l, int cfd, struct sockaddr_storage *addr) /* let's do a no-linger now to close with a single RST. */ setsockopt(cfd, SOL_SOCKET, SO_LINGER, (struct linger *) &nolinger, sizeof(struct linger)); ret = 0; /* successful termination */ - goto out_free_session; + goto out_free_strm; } /* monitor-net and health mode are processed immediately after TCP @@ -184,7 +186,7 @@ int stream_accept(struct listener *l, int cfd, struct sockaddr_storage *addr) else if (p->mode == PR_MODE_HEALTH) send(cfd, "OK\n", 3, MSG_DONTWAIT|MSG_NOSIGNAL|MSG_MORE); ret = 0; - goto out_free_session; + goto out_free_strm; } /* wait for a PROXY protocol header */ @@ -194,7 +196,7 @@ int stream_accept(struct listener *l, int cfd, struct sockaddr_storage *addr) } if (unlikely((t = task_new()) == NULL)) - goto out_free_session; + goto out_free_strm; t->context = s; t->nice = l->nice; @@ -231,12 +233,12 @@ int stream_accept(struct listener *l, int cfd, struct sockaddr_storage *addr) /* Error unrolling */ out_free_task: task_free(t); - out_free_session: - pool_free2(pool2_session, s->sess); - out_free_stream: + out_free_strm: p->feconn--; stream_store_counters(s); pool_free2(pool2_stream, s); + out_free_sess: + pool_free2(pool2_session, sess); out_free_conn: cli_conn->flags &= ~CO_FL_XPRT_TRACKED; conn_xprt_close(cli_conn);