int section_type, struct proxy *curpx,
struct track_ctr_prm *prm,
struct proxy *defpx, char **err);
-int conn_session_complete(struct connection *conn, int flag);
/* Remove the refcount from the session to the tracked counters, and clear the
* pointer to ensure this is only performed once. The caller is responsible for
/* below we have all handshake flags grouped into one */
CO_FL_HANDSHAKE = CO_FL_SI_SEND_PROXY | CO_FL_SSL_WAIT_HS | CO_FL_ACCEPT_PROXY,
- CO_FL_INIT_SESS = 0x00000800, /* initialize a session before using data */
+ CO_FL_INIT_DATA = 0x00000800, /* initialize the data layer before using it */
/* when any of these flags is set, polling is defined by socket-layer
* operations, as opposed to data-layer. Transport is explicitly not
if (!(conn->flags & CO_FL_POLL_SOCK))
__conn_sock_stop_both(conn);
- /* Maybe we need to finish initializing an incoming session. The
- * function may fail and cause the connection to be destroyed, thus
+ /* The data layer might not be ready yet (eg: when using embryonic
+ * sessions). If we're about to move data, we must initialize it first.
+ * The function may fail and cause the connection to be destroyed, thus
* we must not use it anymore and should immediately leave instead.
*/
- if ((conn->flags & CO_FL_INIT_SESS) &&
- conn_session_complete(conn, CO_FL_INIT_SESS) < 0)
+ if ((conn->flags & CO_FL_INIT_DATA) && conn->data->init(conn) < 0)
return 0;
/* The data transfer starts here and stops on error and handshakes */
}
leave:
- /* we may need to release the connection which is an embryonic session */
- if ((conn->flags & (CO_FL_ERROR|CO_FL_INIT_SESS)) == (CO_FL_ERROR|CO_FL_INIT_SESS)) {
- conn->flags |= CO_FL_ERROR;
- conn_session_complete(conn, CO_FL_INIT_SESS);
+ /* we may need to release the connection which is an embryonic session
+ * in case of failure. For this we use the init callback which will
+ * detect the error and clean everything up.
+ */
+ if ((conn->flags & (CO_FL_ERROR|CO_FL_INIT_DATA)) == (CO_FL_ERROR|CO_FL_INIT_DATA)) {
+ conn->data->init(conn);
return 0;
}
struct pool_head *pool2_session;
struct list sessions;
+static int conn_session_complete(struct connection *conn);
static struct task *expire_mini_session(struct task *t);
int session_complete(struct session *s);
.recv = NULL,
.send = NULL,
.wake = NULL,
- .init = NULL,
+ .init = conn_session_complete,
};
/* This function is called from the protocol layer accept() in order to
t->process = expire_mini_session;
t->expire = tick_add_ifset(now_ms, p->timeout.client);
task_queue(t);
- s->si[0].conn.flags |= CO_FL_INIT_SESS;
+ s->si[0].conn.flags |= CO_FL_INIT_DATA;
return 1;
}
/* Finish initializing a session from a connection, or kills it if the
* connection shows and error. Returns <0 if the connection was killed.
*/
-int conn_session_complete(struct connection *conn, int flag)
+static int conn_session_complete(struct connection *conn)
{
struct session *s = conn->owner;
if (!(conn->flags & CO_FL_ERROR) && (session_complete(s) > 0)) {
- conn->flags &= ~flag;
+ conn->flags &= ~CO_FL_INIT_DATA;
return 0;
}