Exemplo n.º 1
0
/* Finish initializing a session from a connection, or kills it if the
 * connection shows and error. Returns <0 if the connection was killed.
 */
static int conn_complete_session(struct connection *conn)
{
	struct task *task = conn->owner;
	struct session *sess = task->context;
	struct stream *strm;

	if (conn->flags & CO_FL_ERROR)
		goto fail;

	/* we want the connection handler to notify the stream interface about updates. */
	conn->flags |= CO_FL_WAKE_DATA;

	/* if logs require transport layer information, note it on the connection */
	if (sess->fe->to_log & LW_XPRT)
		conn->flags |= CO_FL_XPRT_TRACKED;

	session_count_new(sess);
	task->process = sess->listener->handler;
	strm = stream_new(sess, task, &conn->obj_type);
	if (!strm)
		goto fail;

	strm->target        = sess->listener->default_target;
	strm->req.analysers = sess->listener->analysers;
	conn->flags &= ~CO_FL_INIT_DATA;

	return 0;

 fail:
	session_kill_embryonic(sess);
	return -1;
}
Exemplo n.º 2
0
/* Manages the embryonic session timeout. It is only called when the timeout
 * strikes and performs the required cleanup.
 */
static struct task *session_expire_embryonic(struct task *t)
{
	struct session *sess = t->context;

	if (!(t->state & TASK_WOKEN_TIMER))
		return t;

	session_kill_embryonic(sess);
	return NULL;
}
Exemplo n.º 3
0
/* Update a session status. The connection is killed in case of
 * error, and <0 will be returned. Otherwise it does nothing.
 */
static int conn_update_session(struct connection *conn)
{
	struct task *task = conn->owner;
	struct session *sess = task->context;

	if (conn->flags & CO_FL_ERROR) {
		session_kill_embryonic(sess);
		return -1;
	}
	return 0;
}
Exemplo n.º 4
0
/* Finish initializing a session from a connection, or kills it if the
 * connection shows and error. Returns <0 if the connection was killed. It may
 * be called either asynchronously as an xprt_done callback with an embryonic
 * session, or synchronously to finalize the session. The distinction is made
 * on sess->task which is only set in the embryonic session case.
 */
static int conn_complete_session(struct connection *conn)
{
	struct session *sess = conn->owner;

	sess->t_handshake = tv_ms_elapsed(&sess->tv_accept, &now);

	conn_clear_xprt_done_cb(conn);

	/* Verify if the connection just established. */
	if (unlikely(!(conn->flags & (CO_FL_WAIT_L4_CONN | CO_FL_WAIT_L6_CONN | CO_FL_CONNECTED))))
		conn->flags |= CO_FL_CONNECTED;

	if (conn->flags & CO_FL_ERROR)
		goto fail;

	/* if logs require transport layer information, note it on the connection */
	if (sess->fe->to_log & LW_XPRT)
		conn->flags |= CO_FL_XPRT_TRACKED;

	/* we may have some tcp-request-session rules */
	if ((sess->listener->options & LI_O_TCP_L5_RULES) && !tcp_exec_l5_rules(sess))
		goto fail;

	session_count_new(sess);
	if (conn_install_best_mux(conn, sess->fe->mode == PR_MODE_HTTP, NULL) < 0)
		goto fail;

	/* the embryonic session's task is not needed anymore */
	if (sess->task) {
		task_delete(sess->task);
		task_free(sess->task);
		sess->task = NULL;
	}

	conn_set_owner(conn, sess, conn_session_free);

	return 0;

 fail:
	if (sess->task)
		session_kill_embryonic(sess);
	return -1;
}