[MAJOR] add a connection error state to the stream_interface
Tracking connection status changes was hard, and some code was
redundant. A new SI_ST_CER state was added to the stream interface
to indicate a past connection error, and an SI_FL_ERR flag was
added to report past I/O error. The stream_sock code does not set
the connection to SI_ST_CLO anymore in case of I/O error, it's
the upper layer which does it. This makes it possible to know
exactly when the file descriptors are allocated.
The new SI_ST_CER state permitted to split tcp_connection_status()
in two parts, one processing SI_ST_CON and the other one SI_ST_CER.
Synchronous connection errors now make use of this last state, hence
eliminating duplicate code.
Some ib<->ob copy paste errors were found and fixed, and all entities
setting SI_ST_CLO also shut the buffers down.
Some of these stream_interface specific functions and structures
have migrated to a new stream_interface.c file.
Some types of errors are still not detected by the buffers. For
instance, let's assume the following scenario in one single pass
of process_session: a connection sits in SI_ST_TAR state during
a retry. At TAR expiration, a new connection attempt is made, the
connection is obtained and srv->cur_sess is increased. Then the
buffer timeout is fires and everything is cleared, the new state
becomes SI_ST_CLO. The cleaning code checks that previous state
was either SI_ST_CON or SI_ST_EST to release the connection. But
that's wrong because last state is still SI_ST_TAR. So the
server's connection count does not get decreased.
This means that prev_state must not be used, and must be replaced
by some transition detection instead of level detection.
The following debugging line was useful to track state changes :
fprintf(stderr, "%s:%d: cs=%d ss=%d(%d) rqf=0x%08x rpf=0x%08x\n", __FUNCTION__, __LINE__,
s->si[0].state, s->si[1].state, s->si[1].err_type, s->req->flags, s-> rep->flags);
2008-11-03 05:26:53 +00:00
|
|
|
/*
|
2009-10-18 21:56:35 +00:00
|
|
|
* include/proto/stream_interface.h
|
|
|
|
* This file contains stream_interface function prototypes
|
|
|
|
*
|
2014-11-28 10:11:05 +00:00
|
|
|
* Copyright (C) 2000-2014 Willy Tarreau - w@1wt.eu
|
2009-10-18 21:56:35 +00:00
|
|
|
*
|
|
|
|
* This library is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
|
|
* License as published by the Free Software Foundation, version 2.1
|
|
|
|
* exclusively.
|
|
|
|
*
|
|
|
|
* This library is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
* Lesser General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
|
|
* License along with this library; if not, write to the Free Software
|
|
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
|
|
*/
|
[MAJOR] add a connection error state to the stream_interface
Tracking connection status changes was hard, and some code was
redundant. A new SI_ST_CER state was added to the stream interface
to indicate a past connection error, and an SI_FL_ERR flag was
added to report past I/O error. The stream_sock code does not set
the connection to SI_ST_CLO anymore in case of I/O error, it's
the upper layer which does it. This makes it possible to know
exactly when the file descriptors are allocated.
The new SI_ST_CER state permitted to split tcp_connection_status()
in two parts, one processing SI_ST_CON and the other one SI_ST_CER.
Synchronous connection errors now make use of this last state, hence
eliminating duplicate code.
Some ib<->ob copy paste errors were found and fixed, and all entities
setting SI_ST_CLO also shut the buffers down.
Some of these stream_interface specific functions and structures
have migrated to a new stream_interface.c file.
Some types of errors are still not detected by the buffers. For
instance, let's assume the following scenario in one single pass
of process_session: a connection sits in SI_ST_TAR state during
a retry. At TAR expiration, a new connection attempt is made, the
connection is obtained and srv->cur_sess is increased. Then the
buffer timeout is fires and everything is cleared, the new state
becomes SI_ST_CLO. The cleaning code checks that previous state
was either SI_ST_CON or SI_ST_EST to release the connection. But
that's wrong because last state is still SI_ST_TAR. So the
server's connection count does not get decreased.
This means that prev_state must not be used, and must be replaced
by some transition detection instead of level detection.
The following debugging line was useful to track state changes :
fprintf(stderr, "%s:%d: cs=%d ss=%d(%d) rqf=0x%08x rpf=0x%08x\n", __FUNCTION__, __LINE__,
s->si[0].state, s->si[1].state, s->si[1].err_type, s->req->flags, s-> rep->flags);
2008-11-03 05:26:53 +00:00
|
|
|
|
|
|
|
#ifndef _PROTO_STREAM_INTERFACE_H
|
|
|
|
#define _PROTO_STREAM_INTERFACE_H
|
|
|
|
|
|
|
|
#include <stdlib.h>
|
|
|
|
|
|
|
|
#include <common/config.h>
|
REORG/MAJOR: session: rename the "session" entity to "stream"
With HTTP/2, we'll have to support multiplexed streams. A stream is in
fact the largest part of what we currently call a session, it has buffers,
logs, etc.
In order to catch any error, this commit removes any reference to the
struct session and tries to rename most "session" occurrences in function
names to "stream" and "sess" to "strm" when that's related to a session.
The files stream.{c,h} were added and session.{c,h} removed.
The session will be reintroduced later and a few parts of the stream
will progressively be moved overthere. It will more or less contain
only what we need in an embryonic session.
Sample fetch functions and converters will have to change a bit so
that they'll use an L5 (session) instead of what's currently called
"L4" which is in fact L6 for now.
Once all changes are completed, we should see approximately this :
L7 - http_txn
L6 - stream
L5 - session
L4 - connection | applet
There will be at most one http_txn per stream, and a same session will
possibly be referenced by multiple streams. A connection will point to
a session and to a stream. The session will hold all the information
we need to keep even when we don't yet have a stream.
Some more cleanup is needed because some code was already far from
being clean. The server queue management still refers to sessions at
many places while comments talk about connections. This will have to
be cleaned up once we have a server-side connection pool manager.
Stream flags "SN_*" still need to be renamed, it doesn't seem like
any of them will need to move to the session.
2015-04-02 22:22:06 +00:00
|
|
|
#include <types/stream.h>
|
[MAJOR] add a connection error state to the stream_interface
Tracking connection status changes was hard, and some code was
redundant. A new SI_ST_CER state was added to the stream interface
to indicate a past connection error, and an SI_FL_ERR flag was
added to report past I/O error. The stream_sock code does not set
the connection to SI_ST_CLO anymore in case of I/O error, it's
the upper layer which does it. This makes it possible to know
exactly when the file descriptors are allocated.
The new SI_ST_CER state permitted to split tcp_connection_status()
in two parts, one processing SI_ST_CON and the other one SI_ST_CER.
Synchronous connection errors now make use of this last state, hence
eliminating duplicate code.
Some ib<->ob copy paste errors were found and fixed, and all entities
setting SI_ST_CLO also shut the buffers down.
Some of these stream_interface specific functions and structures
have migrated to a new stream_interface.c file.
Some types of errors are still not detected by the buffers. For
instance, let's assume the following scenario in one single pass
of process_session: a connection sits in SI_ST_TAR state during
a retry. At TAR expiration, a new connection attempt is made, the
connection is obtained and srv->cur_sess is increased. Then the
buffer timeout is fires and everything is cleared, the new state
becomes SI_ST_CLO. The cleaning code checks that previous state
was either SI_ST_CON or SI_ST_EST to release the connection. But
that's wrong because last state is still SI_ST_TAR. So the
server's connection count does not get decreased.
This means that prev_state must not be used, and must be replaced
by some transition detection instead of level detection.
The following debugging line was useful to track state changes :
fprintf(stderr, "%s:%d: cs=%d ss=%d(%d) rqf=0x%08x rpf=0x%08x\n", __FUNCTION__, __LINE__,
s->si[0].state, s->si[1].state, s->si[1].err_type, s->req->flags, s-> rep->flags);
2008-11-03 05:26:53 +00:00
|
|
|
#include <types/stream_interface.h>
|
2012-08-30 20:23:13 +00:00
|
|
|
#include <proto/channel.h>
|
2012-08-17 15:33:53 +00:00
|
|
|
#include <proto/connection.h>
|
[MAJOR] add a connection error state to the stream_interface
Tracking connection status changes was hard, and some code was
redundant. A new SI_ST_CER state was added to the stream interface
to indicate a past connection error, and an SI_FL_ERR flag was
added to report past I/O error. The stream_sock code does not set
the connection to SI_ST_CLO anymore in case of I/O error, it's
the upper layer which does it. This makes it possible to know
exactly when the file descriptors are allocated.
The new SI_ST_CER state permitted to split tcp_connection_status()
in two parts, one processing SI_ST_CON and the other one SI_ST_CER.
Synchronous connection errors now make use of this last state, hence
eliminating duplicate code.
Some ib<->ob copy paste errors were found and fixed, and all entities
setting SI_ST_CLO also shut the buffers down.
Some of these stream_interface specific functions and structures
have migrated to a new stream_interface.c file.
Some types of errors are still not detected by the buffers. For
instance, let's assume the following scenario in one single pass
of process_session: a connection sits in SI_ST_TAR state during
a retry. At TAR expiration, a new connection attempt is made, the
connection is obtained and srv->cur_sess is increased. Then the
buffer timeout is fires and everything is cleared, the new state
becomes SI_ST_CLO. The cleaning code checks that previous state
was either SI_ST_CON or SI_ST_EST to release the connection. But
that's wrong because last state is still SI_ST_TAR. So the
server's connection count does not get decreased.
This means that prev_state must not be used, and must be replaced
by some transition detection instead of level detection.
The following debugging line was useful to track state changes :
fprintf(stderr, "%s:%d: cs=%d ss=%d(%d) rqf=0x%08x rpf=0x%08x\n", __FUNCTION__, __LINE__,
s->si[0].state, s->si[1].state, s->si[1].err_type, s->req->flags, s-> rep->flags);
2008-11-03 05:26:53 +00:00
|
|
|
|
|
|
|
|
|
|
|
/* main event functions used to move data between sockets and buffers */
|
2009-09-20 18:14:49 +00:00
|
|
|
int stream_int_check_timeouts(struct stream_interface *si);
|
[MAJOR] add a connection error state to the stream_interface
Tracking connection status changes was hard, and some code was
redundant. A new SI_ST_CER state was added to the stream interface
to indicate a past connection error, and an SI_FL_ERR flag was
added to report past I/O error. The stream_sock code does not set
the connection to SI_ST_CLO anymore in case of I/O error, it's
the upper layer which does it. This makes it possible to know
exactly when the file descriptors are allocated.
The new SI_ST_CER state permitted to split tcp_connection_status()
in two parts, one processing SI_ST_CON and the other one SI_ST_CER.
Synchronous connection errors now make use of this last state, hence
eliminating duplicate code.
Some ib<->ob copy paste errors were found and fixed, and all entities
setting SI_ST_CLO also shut the buffers down.
Some of these stream_interface specific functions and structures
have migrated to a new stream_interface.c file.
Some types of errors are still not detected by the buffers. For
instance, let's assume the following scenario in one single pass
of process_session: a connection sits in SI_ST_TAR state during
a retry. At TAR expiration, a new connection attempt is made, the
connection is obtained and srv->cur_sess is increased. Then the
buffer timeout is fires and everything is cleared, the new state
becomes SI_ST_CLO. The cleaning code checks that previous state
was either SI_ST_CON or SI_ST_EST to release the connection. But
that's wrong because last state is still SI_ST_TAR. So the
server's connection count does not get decreased.
This means that prev_state must not be used, and must be replaced
by some transition detection instead of level detection.
The following debugging line was useful to track state changes :
fprintf(stderr, "%s:%d: cs=%d ss=%d(%d) rqf=0x%08x rpf=0x%08x\n", __FUNCTION__, __LINE__,
s->si[0].state, s->si[1].state, s->si[1].err_type, s->req->flags, s-> rep->flags);
2008-11-03 05:26:53 +00:00
|
|
|
void stream_int_report_error(struct stream_interface *si);
|
2008-11-30 18:48:07 +00:00
|
|
|
void stream_int_retnclose(struct stream_interface *si, const struct chunk *msg);
|
2012-07-06 15:12:34 +00:00
|
|
|
int conn_si_send_proxy(struct connection *conn, unsigned int flag);
|
2012-08-20 13:38:41 +00:00
|
|
|
void stream_sock_read0(struct stream_interface *si);
|
[MAJOR] add a connection error state to the stream_interface
Tracking connection status changes was hard, and some code was
redundant. A new SI_ST_CER state was added to the stream interface
to indicate a past connection error, and an SI_FL_ERR flag was
added to report past I/O error. The stream_sock code does not set
the connection to SI_ST_CLO anymore in case of I/O error, it's
the upper layer which does it. This makes it possible to know
exactly when the file descriptors are allocated.
The new SI_ST_CER state permitted to split tcp_connection_status()
in two parts, one processing SI_ST_CON and the other one SI_ST_CER.
Synchronous connection errors now make use of this last state, hence
eliminating duplicate code.
Some ib<->ob copy paste errors were found and fixed, and all entities
setting SI_ST_CLO also shut the buffers down.
Some of these stream_interface specific functions and structures
have migrated to a new stream_interface.c file.
Some types of errors are still not detected by the buffers. For
instance, let's assume the following scenario in one single pass
of process_session: a connection sits in SI_ST_TAR state during
a retry. At TAR expiration, a new connection attempt is made, the
connection is obtained and srv->cur_sess is increased. Then the
buffer timeout is fires and everything is cleared, the new state
becomes SI_ST_CLO. The cleaning code checks that previous state
was either SI_ST_CON or SI_ST_EST to release the connection. But
that's wrong because last state is still SI_ST_TAR. So the
server's connection count does not get decreased.
This means that prev_state must not be used, and must be replaced
by some transition detection instead of level detection.
The following debugging line was useful to track state changes :
fprintf(stderr, "%s:%d: cs=%d ss=%d(%d) rqf=0x%08x rpf=0x%08x\n", __FUNCTION__, __LINE__,
s->si[0].state, s->si[1].state, s->si[1].err_type, s->req->flags, s-> rep->flags);
2008-11-03 05:26:53 +00:00
|
|
|
|
2012-08-24 16:12:41 +00:00
|
|
|
extern struct si_ops si_embedded_ops;
|
|
|
|
extern struct si_ops si_conn_ops;
|
2012-10-02 22:41:04 +00:00
|
|
|
extern struct data_cb si_conn_cb;
|
2013-12-16 23:00:28 +00:00
|
|
|
extern struct data_cb si_idle_conn_cb;
|
2012-05-07 15:15:39 +00:00
|
|
|
|
2013-12-01 08:35:41 +00:00
|
|
|
struct appctx *stream_int_register_handler(struct stream_interface *si, struct si_applet *app);
|
2009-09-05 18:57:35 +00:00
|
|
|
void stream_int_unregister_handler(struct stream_interface *si);
|
|
|
|
|
2014-11-28 10:11:05 +00:00
|
|
|
/* returns the channel which receives data from this stream interface (input channel) */
|
|
|
|
static inline struct channel *si_ic(struct stream_interface *si)
|
|
|
|
{
|
2014-11-28 10:50:38 +00:00
|
|
|
if (si->flags & SI_FL_ISBACK)
|
REORG/MAJOR: session: rename the "session" entity to "stream"
With HTTP/2, we'll have to support multiplexed streams. A stream is in
fact the largest part of what we currently call a session, it has buffers,
logs, etc.
In order to catch any error, this commit removes any reference to the
struct session and tries to rename most "session" occurrences in function
names to "stream" and "sess" to "strm" when that's related to a session.
The files stream.{c,h} were added and session.{c,h} removed.
The session will be reintroduced later and a few parts of the stream
will progressively be moved overthere. It will more or less contain
only what we need in an embryonic session.
Sample fetch functions and converters will have to change a bit so
that they'll use an L5 (session) instead of what's currently called
"L4" which is in fact L6 for now.
Once all changes are completed, we should see approximately this :
L7 - http_txn
L6 - stream
L5 - session
L4 - connection | applet
There will be at most one http_txn per stream, and a same session will
possibly be referenced by multiple streams. A connection will point to
a session and to a stream. The session will hold all the information
we need to keep even when we don't yet have a stream.
Some more cleanup is needed because some code was already far from
being clean. The server queue management still refers to sessions at
many places while comments talk about connections. This will have to
be cleaned up once we have a server-side connection pool manager.
Stream flags "SN_*" still need to be renamed, it doesn't seem like
any of them will need to move to the session.
2015-04-02 22:22:06 +00:00
|
|
|
return &LIST_ELEM(si, struct stream *, si[1])->res;
|
2014-11-28 10:50:38 +00:00
|
|
|
else
|
REORG/MAJOR: session: rename the "session" entity to "stream"
With HTTP/2, we'll have to support multiplexed streams. A stream is in
fact the largest part of what we currently call a session, it has buffers,
logs, etc.
In order to catch any error, this commit removes any reference to the
struct session and tries to rename most "session" occurrences in function
names to "stream" and "sess" to "strm" when that's related to a session.
The files stream.{c,h} were added and session.{c,h} removed.
The session will be reintroduced later and a few parts of the stream
will progressively be moved overthere. It will more or less contain
only what we need in an embryonic session.
Sample fetch functions and converters will have to change a bit so
that they'll use an L5 (session) instead of what's currently called
"L4" which is in fact L6 for now.
Once all changes are completed, we should see approximately this :
L7 - http_txn
L6 - stream
L5 - session
L4 - connection | applet
There will be at most one http_txn per stream, and a same session will
possibly be referenced by multiple streams. A connection will point to
a session and to a stream. The session will hold all the information
we need to keep even when we don't yet have a stream.
Some more cleanup is needed because some code was already far from
being clean. The server queue management still refers to sessions at
many places while comments talk about connections. This will have to
be cleaned up once we have a server-side connection pool manager.
Stream flags "SN_*" still need to be renamed, it doesn't seem like
any of them will need to move to the session.
2015-04-02 22:22:06 +00:00
|
|
|
return &LIST_ELEM(si, struct stream *, si[0])->req;
|
2014-11-28 10:11:05 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* returns the channel which feeds data to this stream interface (output channel) */
|
|
|
|
static inline struct channel *si_oc(struct stream_interface *si)
|
|
|
|
{
|
2014-11-28 10:50:38 +00:00
|
|
|
if (si->flags & SI_FL_ISBACK)
|
REORG/MAJOR: session: rename the "session" entity to "stream"
With HTTP/2, we'll have to support multiplexed streams. A stream is in
fact the largest part of what we currently call a session, it has buffers,
logs, etc.
In order to catch any error, this commit removes any reference to the
struct session and tries to rename most "session" occurrences in function
names to "stream" and "sess" to "strm" when that's related to a session.
The files stream.{c,h} were added and session.{c,h} removed.
The session will be reintroduced later and a few parts of the stream
will progressively be moved overthere. It will more or less contain
only what we need in an embryonic session.
Sample fetch functions and converters will have to change a bit so
that they'll use an L5 (session) instead of what's currently called
"L4" which is in fact L6 for now.
Once all changes are completed, we should see approximately this :
L7 - http_txn
L6 - stream
L5 - session
L4 - connection | applet
There will be at most one http_txn per stream, and a same session will
possibly be referenced by multiple streams. A connection will point to
a session and to a stream. The session will hold all the information
we need to keep even when we don't yet have a stream.
Some more cleanup is needed because some code was already far from
being clean. The server queue management still refers to sessions at
many places while comments talk about connections. This will have to
be cleaned up once we have a server-side connection pool manager.
Stream flags "SN_*" still need to be renamed, it doesn't seem like
any of them will need to move to the session.
2015-04-02 22:22:06 +00:00
|
|
|
return &LIST_ELEM(si, struct stream *, si[1])->req;
|
2014-11-28 10:50:38 +00:00
|
|
|
else
|
REORG/MAJOR: session: rename the "session" entity to "stream"
With HTTP/2, we'll have to support multiplexed streams. A stream is in
fact the largest part of what we currently call a session, it has buffers,
logs, etc.
In order to catch any error, this commit removes any reference to the
struct session and tries to rename most "session" occurrences in function
names to "stream" and "sess" to "strm" when that's related to a session.
The files stream.{c,h} were added and session.{c,h} removed.
The session will be reintroduced later and a few parts of the stream
will progressively be moved overthere. It will more or less contain
only what we need in an embryonic session.
Sample fetch functions and converters will have to change a bit so
that they'll use an L5 (session) instead of what's currently called
"L4" which is in fact L6 for now.
Once all changes are completed, we should see approximately this :
L7 - http_txn
L6 - stream
L5 - session
L4 - connection | applet
There will be at most one http_txn per stream, and a same session will
possibly be referenced by multiple streams. A connection will point to
a session and to a stream. The session will hold all the information
we need to keep even when we don't yet have a stream.
Some more cleanup is needed because some code was already far from
being clean. The server queue management still refers to sessions at
many places while comments talk about connections. This will have to
be cleaned up once we have a server-side connection pool manager.
Stream flags "SN_*" still need to be renamed, it doesn't seem like
any of them will need to move to the session.
2015-04-02 22:22:06 +00:00
|
|
|
return &LIST_ELEM(si, struct stream *, si[0])->res;
|
2014-11-28 10:11:05 +00:00
|
|
|
}
|
|
|
|
|
2014-11-28 11:18:45 +00:00
|
|
|
/* returns the buffer which receives data from this stream interface (input channel's buffer) */
|
|
|
|
static inline struct buffer *si_ib(struct stream_interface *si)
|
|
|
|
{
|
|
|
|
return si_ic(si)->buf;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* returns the buffer which feeds data to this stream interface (output channel's buffer) */
|
|
|
|
static inline struct buffer *si_ob(struct stream_interface *si)
|
|
|
|
{
|
|
|
|
return si_oc(si)->buf;
|
|
|
|
}
|
|
|
|
|
REORG/MAJOR: session: rename the "session" entity to "stream"
With HTTP/2, we'll have to support multiplexed streams. A stream is in
fact the largest part of what we currently call a session, it has buffers,
logs, etc.
In order to catch any error, this commit removes any reference to the
struct session and tries to rename most "session" occurrences in function
names to "stream" and "sess" to "strm" when that's related to a session.
The files stream.{c,h} were added and session.{c,h} removed.
The session will be reintroduced later and a few parts of the stream
will progressively be moved overthere. It will more or less contain
only what we need in an embryonic session.
Sample fetch functions and converters will have to change a bit so
that they'll use an L5 (session) instead of what's currently called
"L4" which is in fact L6 for now.
Once all changes are completed, we should see approximately this :
L7 - http_txn
L6 - stream
L5 - session
L4 - connection | applet
There will be at most one http_txn per stream, and a same session will
possibly be referenced by multiple streams. A connection will point to
a session and to a stream. The session will hold all the information
we need to keep even when we don't yet have a stream.
Some more cleanup is needed because some code was already far from
being clean. The server queue management still refers to sessions at
many places while comments talk about connections. This will have to
be cleaned up once we have a server-side connection pool manager.
Stream flags "SN_*" still need to be renamed, it doesn't seem like
any of them will need to move to the session.
2015-04-02 22:22:06 +00:00
|
|
|
/* returns the stream associated to a stream interface */
|
|
|
|
static inline struct stream *si_strm(struct stream_interface *si)
|
2014-11-28 11:03:32 +00:00
|
|
|
{
|
|
|
|
if (si->flags & SI_FL_ISBACK)
|
REORG/MAJOR: session: rename the "session" entity to "stream"
With HTTP/2, we'll have to support multiplexed streams. A stream is in
fact the largest part of what we currently call a session, it has buffers,
logs, etc.
In order to catch any error, this commit removes any reference to the
struct session and tries to rename most "session" occurrences in function
names to "stream" and "sess" to "strm" when that's related to a session.
The files stream.{c,h} were added and session.{c,h} removed.
The session will be reintroduced later and a few parts of the stream
will progressively be moved overthere. It will more or less contain
only what we need in an embryonic session.
Sample fetch functions and converters will have to change a bit so
that they'll use an L5 (session) instead of what's currently called
"L4" which is in fact L6 for now.
Once all changes are completed, we should see approximately this :
L7 - http_txn
L6 - stream
L5 - session
L4 - connection | applet
There will be at most one http_txn per stream, and a same session will
possibly be referenced by multiple streams. A connection will point to
a session and to a stream. The session will hold all the information
we need to keep even when we don't yet have a stream.
Some more cleanup is needed because some code was already far from
being clean. The server queue management still refers to sessions at
many places while comments talk about connections. This will have to
be cleaned up once we have a server-side connection pool manager.
Stream flags "SN_*" still need to be renamed, it doesn't seem like
any of them will need to move to the session.
2015-04-02 22:22:06 +00:00
|
|
|
return LIST_ELEM(si, struct stream *, si[1]);
|
2014-11-28 11:03:32 +00:00
|
|
|
else
|
REORG/MAJOR: session: rename the "session" entity to "stream"
With HTTP/2, we'll have to support multiplexed streams. A stream is in
fact the largest part of what we currently call a session, it has buffers,
logs, etc.
In order to catch any error, this commit removes any reference to the
struct session and tries to rename most "session" occurrences in function
names to "stream" and "sess" to "strm" when that's related to a session.
The files stream.{c,h} were added and session.{c,h} removed.
The session will be reintroduced later and a few parts of the stream
will progressively be moved overthere. It will more or less contain
only what we need in an embryonic session.
Sample fetch functions and converters will have to change a bit so
that they'll use an L5 (session) instead of what's currently called
"L4" which is in fact L6 for now.
Once all changes are completed, we should see approximately this :
L7 - http_txn
L6 - stream
L5 - session
L4 - connection | applet
There will be at most one http_txn per stream, and a same session will
possibly be referenced by multiple streams. A connection will point to
a session and to a stream. The session will hold all the information
we need to keep even when we don't yet have a stream.
Some more cleanup is needed because some code was already far from
being clean. The server queue management still refers to sessions at
many places while comments talk about connections. This will have to
be cleaned up once we have a server-side connection pool manager.
Stream flags "SN_*" still need to be renamed, it doesn't seem like
any of them will need to move to the session.
2015-04-02 22:22:06 +00:00
|
|
|
return LIST_ELEM(si, struct stream *, si[0]);
|
2014-11-28 11:03:32 +00:00
|
|
|
}
|
|
|
|
|
2014-11-28 11:08:47 +00:00
|
|
|
/* returns the task associated to this stream interface */
|
|
|
|
static inline struct task *si_task(struct stream_interface *si)
|
|
|
|
{
|
|
|
|
if (si->flags & SI_FL_ISBACK)
|
REORG/MAJOR: session: rename the "session" entity to "stream"
With HTTP/2, we'll have to support multiplexed streams. A stream is in
fact the largest part of what we currently call a session, it has buffers,
logs, etc.
In order to catch any error, this commit removes any reference to the
struct session and tries to rename most "session" occurrences in function
names to "stream" and "sess" to "strm" when that's related to a session.
The files stream.{c,h} were added and session.{c,h} removed.
The session will be reintroduced later and a few parts of the stream
will progressively be moved overthere. It will more or less contain
only what we need in an embryonic session.
Sample fetch functions and converters will have to change a bit so
that they'll use an L5 (session) instead of what's currently called
"L4" which is in fact L6 for now.
Once all changes are completed, we should see approximately this :
L7 - http_txn
L6 - stream
L5 - session
L4 - connection | applet
There will be at most one http_txn per stream, and a same session will
possibly be referenced by multiple streams. A connection will point to
a session and to a stream. The session will hold all the information
we need to keep even when we don't yet have a stream.
Some more cleanup is needed because some code was already far from
being clean. The server queue management still refers to sessions at
many places while comments talk about connections. This will have to
be cleaned up once we have a server-side connection pool manager.
Stream flags "SN_*" still need to be renamed, it doesn't seem like
any of them will need to move to the session.
2015-04-02 22:22:06 +00:00
|
|
|
return LIST_ELEM(si, struct stream *, si[1])->task;
|
2014-11-28 11:08:47 +00:00
|
|
|
else
|
REORG/MAJOR: session: rename the "session" entity to "stream"
With HTTP/2, we'll have to support multiplexed streams. A stream is in
fact the largest part of what we currently call a session, it has buffers,
logs, etc.
In order to catch any error, this commit removes any reference to the
struct session and tries to rename most "session" occurrences in function
names to "stream" and "sess" to "strm" when that's related to a session.
The files stream.{c,h} were added and session.{c,h} removed.
The session will be reintroduced later and a few parts of the stream
will progressively be moved overthere. It will more or less contain
only what we need in an embryonic session.
Sample fetch functions and converters will have to change a bit so
that they'll use an L5 (session) instead of what's currently called
"L4" which is in fact L6 for now.
Once all changes are completed, we should see approximately this :
L7 - http_txn
L6 - stream
L5 - session
L4 - connection | applet
There will be at most one http_txn per stream, and a same session will
possibly be referenced by multiple streams. A connection will point to
a session and to a stream. The session will hold all the information
we need to keep even when we don't yet have a stream.
Some more cleanup is needed because some code was already far from
being clean. The server queue management still refers to sessions at
many places while comments talk about connections. This will have to
be cleaned up once we have a server-side connection pool manager.
Stream flags "SN_*" still need to be renamed, it doesn't seem like
any of them will need to move to the session.
2015-04-02 22:22:06 +00:00
|
|
|
return LIST_ELEM(si, struct stream *, si[0])->task;
|
2014-11-28 11:08:47 +00:00
|
|
|
}
|
|
|
|
|
2014-11-28 12:59:31 +00:00
|
|
|
/* returns the stream interface on the other side. Used during forwarding. */
|
|
|
|
static inline struct stream_interface *si_opposite(struct stream_interface *si)
|
|
|
|
{
|
|
|
|
if (si->flags & SI_FL_ISBACK)
|
REORG/MAJOR: session: rename the "session" entity to "stream"
With HTTP/2, we'll have to support multiplexed streams. A stream is in
fact the largest part of what we currently call a session, it has buffers,
logs, etc.
In order to catch any error, this commit removes any reference to the
struct session and tries to rename most "session" occurrences in function
names to "stream" and "sess" to "strm" when that's related to a session.
The files stream.{c,h} were added and session.{c,h} removed.
The session will be reintroduced later and a few parts of the stream
will progressively be moved overthere. It will more or less contain
only what we need in an embryonic session.
Sample fetch functions and converters will have to change a bit so
that they'll use an L5 (session) instead of what's currently called
"L4" which is in fact L6 for now.
Once all changes are completed, we should see approximately this :
L7 - http_txn
L6 - stream
L5 - session
L4 - connection | applet
There will be at most one http_txn per stream, and a same session will
possibly be referenced by multiple streams. A connection will point to
a session and to a stream. The session will hold all the information
we need to keep even when we don't yet have a stream.
Some more cleanup is needed because some code was already far from
being clean. The server queue management still refers to sessions at
many places while comments talk about connections. This will have to
be cleaned up once we have a server-side connection pool manager.
Stream flags "SN_*" still need to be renamed, it doesn't seem like
any of them will need to move to the session.
2015-04-02 22:22:06 +00:00
|
|
|
return &LIST_ELEM(si, struct stream *, si[1])->si[0];
|
2014-11-28 12:59:31 +00:00
|
|
|
else
|
REORG/MAJOR: session: rename the "session" entity to "stream"
With HTTP/2, we'll have to support multiplexed streams. A stream is in
fact the largest part of what we currently call a session, it has buffers,
logs, etc.
In order to catch any error, this commit removes any reference to the
struct session and tries to rename most "session" occurrences in function
names to "stream" and "sess" to "strm" when that's related to a session.
The files stream.{c,h} were added and session.{c,h} removed.
The session will be reintroduced later and a few parts of the stream
will progressively be moved overthere. It will more or less contain
only what we need in an embryonic session.
Sample fetch functions and converters will have to change a bit so
that they'll use an L5 (session) instead of what's currently called
"L4" which is in fact L6 for now.
Once all changes are completed, we should see approximately this :
L7 - http_txn
L6 - stream
L5 - session
L4 - connection | applet
There will be at most one http_txn per stream, and a same session will
possibly be referenced by multiple streams. A connection will point to
a session and to a stream. The session will hold all the information
we need to keep even when we don't yet have a stream.
Some more cleanup is needed because some code was already far from
being clean. The server queue management still refers to sessions at
many places while comments talk about connections. This will have to
be cleaned up once we have a server-side connection pool manager.
Stream flags "SN_*" still need to be renamed, it doesn't seem like
any of them will need to move to the session.
2015-04-02 22:22:06 +00:00
|
|
|
return &LIST_ELEM(si, struct stream *, si[0])->si[1];
|
2014-11-28 12:59:31 +00:00
|
|
|
}
|
|
|
|
|
2013-12-01 10:31:38 +00:00
|
|
|
/* Initializes all required fields for a new appctx. Note that it does the
|
|
|
|
* minimum acceptable initialization for an appctx. This means only the
|
|
|
|
* 3 integer states st0, st1, st2 are zeroed.
|
|
|
|
*/
|
|
|
|
static inline void appctx_init(struct appctx *appctx)
|
|
|
|
{
|
|
|
|
appctx->st0 = appctx->st1 = appctx->st2 = 0;
|
|
|
|
}
|
|
|
|
|
2015-04-04 22:15:26 +00:00
|
|
|
/* Tries to allocate a new appctx and initialize its main fields. The appctx
|
|
|
|
* is returned on success, NULL on failure. The appctx must be released using
|
|
|
|
* pool_free2(connection) or appctx_free(), since it's allocated from the
|
|
|
|
* connection pool. <applet> is assigned as the applet, but it can be NULL.
|
2013-12-01 10:31:38 +00:00
|
|
|
*/
|
2015-04-04 22:15:26 +00:00
|
|
|
static inline struct appctx *appctx_new(struct si_applet *applet)
|
2013-12-01 10:31:38 +00:00
|
|
|
{
|
|
|
|
struct appctx *appctx;
|
|
|
|
|
|
|
|
appctx = pool_alloc2(pool2_connection);
|
|
|
|
if (likely(appctx != NULL)) {
|
|
|
|
appctx->obj_type = OBJ_TYPE_APPCTX;
|
2015-04-04 22:15:26 +00:00
|
|
|
appctx->applet = applet;
|
2013-12-01 10:31:38 +00:00
|
|
|
appctx_init(appctx);
|
|
|
|
}
|
|
|
|
return appctx;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Releases an appctx previously allocated by appctx_new(). Note that
|
|
|
|
* we share the connection pool.
|
|
|
|
*/
|
|
|
|
static inline void appctx_free(struct appctx *appctx)
|
|
|
|
{
|
|
|
|
pool_free2(pool2_connection, appctx);
|
|
|
|
}
|
|
|
|
|
2013-10-24 09:51:38 +00:00
|
|
|
/* initializes a stream interface in the SI_ST_INI state. It's detached from
|
2014-11-28 11:12:34 +00:00
|
|
|
* any endpoint and only keeps its side which is expected to have already been
|
|
|
|
* set.
|
2013-10-24 09:51:38 +00:00
|
|
|
*/
|
2014-11-28 11:12:34 +00:00
|
|
|
static inline void si_reset(struct stream_interface *si)
|
2013-10-24 09:51:38 +00:00
|
|
|
{
|
|
|
|
si->err_type = SI_ET_NONE;
|
|
|
|
si->conn_retries = 0; /* used for logging too */
|
|
|
|
si->exp = TICK_ETERNITY;
|
2014-11-28 10:26:07 +00:00
|
|
|
si->flags &= SI_FL_ISBACK;
|
2013-10-24 09:51:38 +00:00
|
|
|
si->end = NULL;
|
|
|
|
si->state = si->prev_state = SI_ST_INI;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* sets the current and previous state of a stream interface to <state>. This
|
|
|
|
* is mainly used to create one in the established state on incoming
|
|
|
|
* conncetions.
|
|
|
|
*/
|
|
|
|
static inline void si_set_state(struct stream_interface *si, int state)
|
|
|
|
{
|
|
|
|
si->state = si->prev_state = state;
|
|
|
|
}
|
|
|
|
|
2013-12-01 10:31:38 +00:00
|
|
|
/* Release the endpoint if it's a connection or an applet, then nullify it.
|
|
|
|
* Note: released connections are closed then freed.
|
|
|
|
*/
|
2013-10-11 17:34:20 +00:00
|
|
|
static inline void si_release_endpoint(struct stream_interface *si)
|
2013-09-29 15:19:56 +00:00
|
|
|
{
|
2013-10-11 17:34:20 +00:00
|
|
|
struct connection *conn;
|
2013-12-01 10:31:38 +00:00
|
|
|
struct appctx *appctx;
|
2013-10-11 17:34:20 +00:00
|
|
|
|
2013-12-01 10:31:38 +00:00
|
|
|
if (!si->end)
|
|
|
|
return;
|
|
|
|
|
|
|
|
if ((conn = objt_conn(si->end))) {
|
|
|
|
conn_force_close(conn);
|
|
|
|
conn_free(conn);
|
|
|
|
}
|
|
|
|
else if ((appctx = objt_appctx(si->end))) {
|
|
|
|
if (appctx->applet->release)
|
|
|
|
appctx->applet->release(si);
|
|
|
|
appctx_free(appctx); /* we share the connection pool */
|
|
|
|
}
|
2013-09-29 14:05:22 +00:00
|
|
|
si->end = NULL;
|
2013-09-29 15:19:56 +00:00
|
|
|
}
|
|
|
|
|
2013-10-11 17:34:20 +00:00
|
|
|
static inline void si_detach(struct stream_interface *si)
|
|
|
|
{
|
|
|
|
si_release_endpoint(si);
|
|
|
|
si->ops = &si_embedded_ops;
|
|
|
|
}
|
|
|
|
|
2013-12-16 23:00:28 +00:00
|
|
|
/* Turn a possibly existing connection endpoint of stream interface <si> to
|
|
|
|
* idle mode, which means that the connection will be polled for incoming events
|
|
|
|
* and might be killed by the underlying I/O handler.
|
|
|
|
*/
|
|
|
|
static inline void si_idle_conn(struct stream_interface *si)
|
|
|
|
{
|
|
|
|
struct connection *conn = objt_conn(si->end);
|
|
|
|
|
|
|
|
if (!conn)
|
|
|
|
return;
|
|
|
|
|
|
|
|
conn_attach(conn, si, &si_idle_conn_cb);
|
|
|
|
conn_data_want_recv(conn);
|
|
|
|
}
|
|
|
|
|
2013-10-24 13:50:53 +00:00
|
|
|
/* Attach connection <conn> to the stream interface <si>. The stream interface
|
|
|
|
* is configured to work with a connection and the connection it configured
|
|
|
|
* with a stream interface data layer.
|
2013-10-01 08:45:07 +00:00
|
|
|
*/
|
2013-10-24 13:50:53 +00:00
|
|
|
static inline void si_attach_conn(struct stream_interface *si, struct connection *conn)
|
2012-10-02 18:57:19 +00:00
|
|
|
{
|
|
|
|
si->ops = &si_conn_ops;
|
2013-10-01 08:45:07 +00:00
|
|
|
si->end = &conn->obj_type;
|
2013-10-24 13:31:04 +00:00
|
|
|
conn_attach(conn, si, &si_conn_cb);
|
2012-10-02 18:57:19 +00:00
|
|
|
}
|
|
|
|
|
2013-12-15 09:23:20 +00:00
|
|
|
/* Returns true if a connection is attached to the stream interface <si> and
|
|
|
|
* if this connection is ready.
|
|
|
|
*/
|
|
|
|
static inline int si_conn_ready(struct stream_interface *si)
|
|
|
|
{
|
|
|
|
struct connection *conn = objt_conn(si->end);
|
|
|
|
|
|
|
|
return conn && conn_ctrl_ready(conn) && conn_xprt_ready(conn);
|
|
|
|
}
|
|
|
|
|
2013-12-01 10:31:38 +00:00
|
|
|
/* Attach appctx <appctx> to the stream interface <si>. The stream interface
|
2015-04-04 22:15:26 +00:00
|
|
|
* is configured to work with an applet context.
|
2013-12-01 10:31:38 +00:00
|
|
|
*/
|
|
|
|
static inline void si_attach_appctx(struct stream_interface *si, struct appctx *appctx)
|
2012-08-24 16:12:41 +00:00
|
|
|
{
|
|
|
|
si->ops = &si_embedded_ops;
|
2013-12-01 10:31:38 +00:00
|
|
|
si->end = &appctx->obj_type;
|
2012-08-24 16:12:41 +00:00
|
|
|
}
|
|
|
|
|
2013-12-01 08:15:12 +00:00
|
|
|
/* returns a pointer to the appctx being run in the SI or NULL if none */
|
|
|
|
static inline struct appctx *si_appctx(struct stream_interface *si)
|
|
|
|
{
|
|
|
|
return objt_appctx(si->end);
|
|
|
|
}
|
|
|
|
|
2013-10-24 18:10:45 +00:00
|
|
|
/* returns a pointer to the applet being run in the SI or NULL if none */
|
|
|
|
static inline const struct si_applet *si_applet(struct stream_interface *si)
|
|
|
|
{
|
2013-12-01 08:15:12 +00:00
|
|
|
const struct appctx *appctx;
|
|
|
|
|
|
|
|
appctx = si_appctx(si);
|
|
|
|
if (appctx)
|
|
|
|
return appctx->applet;
|
2013-09-29 15:19:56 +00:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Call the applet's main function when an appctx is attached to the stream
|
|
|
|
* interface. Returns zero if no call was made, or non-zero if a call was made.
|
|
|
|
*/
|
|
|
|
static inline int si_applet_call(struct stream_interface *si)
|
|
|
|
{
|
|
|
|
const struct si_applet *applet;
|
|
|
|
|
|
|
|
applet = si_applet(si);
|
|
|
|
if (applet) {
|
|
|
|
applet->fct(si);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
return 0;
|
2013-10-24 18:10:45 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* call the applet's release function if any. Needs to be called upon close() */
|
|
|
|
static inline void si_applet_release(struct stream_interface *si)
|
|
|
|
{
|
|
|
|
const struct si_applet *applet;
|
|
|
|
|
|
|
|
applet = si_applet(si);
|
|
|
|
if (applet && applet->release)
|
|
|
|
applet->release(si);
|
|
|
|
}
|
|
|
|
|
2013-12-15 12:31:35 +00:00
|
|
|
/* Try to allocate a new connection and assign it to the interface. If
|
|
|
|
* a connection was previously allocated and the <reuse> flag is set,
|
|
|
|
* it is returned unmodified. Otherwise it is reset.
|
|
|
|
*/
|
2013-10-11 17:34:20 +00:00
|
|
|
/* Returns the stream interface's existing connection if one such already
|
|
|
|
* exists, or tries to allocate and initialize a new one which is then
|
|
|
|
* assigned to the stream interface.
|
|
|
|
*/
|
2013-12-15 12:31:35 +00:00
|
|
|
static inline struct connection *si_alloc_conn(struct stream_interface *si, int reuse)
|
2013-10-11 17:34:20 +00:00
|
|
|
{
|
|
|
|
struct connection *conn;
|
|
|
|
|
2013-12-01 10:31:38 +00:00
|
|
|
/* If we find a connection, we return it, otherwise it's an applet
|
|
|
|
* and we start by releasing it.
|
2013-10-11 17:34:20 +00:00
|
|
|
*/
|
2013-12-01 10:31:38 +00:00
|
|
|
if (si->end) {
|
|
|
|
conn = objt_conn(si->end);
|
2013-12-15 12:31:35 +00:00
|
|
|
if (conn) {
|
|
|
|
if (!reuse) {
|
|
|
|
conn_force_close(conn);
|
|
|
|
conn_init(conn);
|
|
|
|
}
|
2013-12-01 10:31:38 +00:00
|
|
|
return conn;
|
2013-12-15 12:31:35 +00:00
|
|
|
}
|
2013-12-01 10:31:38 +00:00
|
|
|
/* it was an applet then */
|
|
|
|
si_release_endpoint(si);
|
|
|
|
}
|
2013-10-11 17:34:20 +00:00
|
|
|
|
|
|
|
conn = conn_new();
|
|
|
|
if (conn)
|
|
|
|
si_attach_conn(si, conn);
|
|
|
|
|
|
|
|
return conn;
|
|
|
|
}
|
|
|
|
|
2013-12-01 10:31:38 +00:00
|
|
|
/* Release the interface's existing endpoint (connection or appctx) and
|
|
|
|
* allocate then initialize a new appctx which is assigned to the interface
|
2015-04-04 22:15:26 +00:00
|
|
|
* and returned. NULL may be returned upon memory shortage. Applet <applet>
|
|
|
|
* is assigned to the appctx, but it may be NULL.
|
2013-12-01 10:31:38 +00:00
|
|
|
*/
|
2015-04-04 22:15:26 +00:00
|
|
|
static inline struct appctx *si_alloc_appctx(struct stream_interface *si, struct si_applet *applet)
|
2013-12-01 10:31:38 +00:00
|
|
|
{
|
|
|
|
struct appctx *appctx;
|
|
|
|
|
|
|
|
si_release_endpoint(si);
|
2015-04-04 22:15:26 +00:00
|
|
|
appctx = appctx_new(applet);
|
2013-12-01 10:31:38 +00:00
|
|
|
if (appctx)
|
|
|
|
si_attach_appctx(si, appctx);
|
|
|
|
|
|
|
|
return appctx;
|
|
|
|
}
|
|
|
|
|
2012-05-21 14:31:45 +00:00
|
|
|
/* Sends a shutr to the connection using the data layer */
|
|
|
|
static inline void si_shutr(struct stream_interface *si)
|
|
|
|
{
|
2013-09-29 13:16:03 +00:00
|
|
|
si->ops->shutr(si);
|
2012-05-21 14:31:45 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Sends a shutw to the connection using the data layer */
|
|
|
|
static inline void si_shutw(struct stream_interface *si)
|
|
|
|
{
|
2013-09-29 13:16:03 +00:00
|
|
|
si->ops->shutw(si);
|
2012-05-21 14:31:45 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Calls the data state update on the stream interfaace */
|
|
|
|
static inline void si_update(struct stream_interface *si)
|
|
|
|
{
|
2012-08-24 16:12:41 +00:00
|
|
|
si->ops->update(si);
|
2012-05-21 14:31:45 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Calls chk_rcv on the connection using the data layer */
|
|
|
|
static inline void si_chk_rcv(struct stream_interface *si)
|
|
|
|
{
|
2012-08-24 16:12:41 +00:00
|
|
|
si->ops->chk_rcv(si);
|
2012-05-21 14:31:45 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Calls chk_snd on the connection using the data layer */
|
|
|
|
static inline void si_chk_snd(struct stream_interface *si)
|
|
|
|
{
|
2012-08-24 16:12:41 +00:00
|
|
|
si->ops->chk_snd(si);
|
2012-05-21 14:31:45 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Calls chk_snd on the connection using the ctrl layer */
|
|
|
|
static inline int si_connect(struct stream_interface *si)
|
|
|
|
{
|
2013-10-01 08:45:07 +00:00
|
|
|
struct connection *conn = objt_conn(si->end);
|
2015-04-02 23:14:29 +00:00
|
|
|
int ret = SF_ERR_NONE;
|
2012-08-30 20:23:13 +00:00
|
|
|
|
2013-10-01 08:45:07 +00:00
|
|
|
if (unlikely(!conn || !conn->ctrl || !conn->ctrl->connect))
|
2015-04-02 23:14:29 +00:00
|
|
|
return SF_ERR_INTERNAL;
|
2012-08-30 20:23:13 +00:00
|
|
|
|
2013-12-15 15:20:50 +00:00
|
|
|
if (!conn_ctrl_ready(conn) || !conn_xprt_ready(conn)) {
|
2014-11-28 10:11:05 +00:00
|
|
|
ret = conn->ctrl->connect(conn, !channel_is_empty(si_oc(si)), 0);
|
2015-04-02 23:14:29 +00:00
|
|
|
if (ret != SF_ERR_NONE)
|
2013-12-15 15:20:50 +00:00
|
|
|
return ret;
|
2013-12-31 22:32:12 +00:00
|
|
|
|
|
|
|
/* we need to be notified about connection establishment */
|
|
|
|
conn->flags |= CO_FL_WAKE_DATA;
|
|
|
|
|
|
|
|
/* we're in the process of establishing a connection */
|
|
|
|
si->state = SI_ST_CON;
|
2013-12-15 15:20:50 +00:00
|
|
|
}
|
2014-11-28 10:11:05 +00:00
|
|
|
else if (!channel_is_empty(si_oc(si))) {
|
2013-12-15 15:20:50 +00:00
|
|
|
/* reuse the existing connection, we'll have to send a
|
|
|
|
* request there.
|
|
|
|
*/
|
|
|
|
conn_data_want_send(conn);
|
2013-12-31 22:32:12 +00:00
|
|
|
|
|
|
|
/* the connection is established */
|
|
|
|
si->state = SI_ST_EST;
|
2013-12-15 15:20:50 +00:00
|
|
|
}
|
2012-08-30 20:23:13 +00:00
|
|
|
|
|
|
|
/* needs src ip/port for logging */
|
|
|
|
if (si->flags & SI_FL_SRC_ADDR)
|
2013-10-01 08:45:07 +00:00
|
|
|
conn_get_from_addr(conn);
|
2012-08-30 20:23:13 +00:00
|
|
|
|
|
|
|
return ret;
|
2012-05-21 14:31:45 +00:00
|
|
|
}
|
2012-05-11 14:16:40 +00:00
|
|
|
|
2012-12-08 16:48:47 +00:00
|
|
|
/* for debugging, reports the stream interface state name */
|
|
|
|
static inline const char *si_state_str(int state)
|
|
|
|
{
|
|
|
|
switch (state) {
|
|
|
|
case SI_ST_INI: return "INI";
|
|
|
|
case SI_ST_REQ: return "REQ";
|
|
|
|
case SI_ST_QUE: return "QUE";
|
|
|
|
case SI_ST_TAR: return "TAR";
|
|
|
|
case SI_ST_ASS: return "ASS";
|
|
|
|
case SI_ST_CON: return "CON";
|
|
|
|
case SI_ST_CER: return "CER";
|
|
|
|
case SI_ST_EST: return "EST";
|
|
|
|
case SI_ST_DIS: return "DIS";
|
|
|
|
case SI_ST_CLO: return "CLO";
|
|
|
|
default: return "???";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
[MAJOR] add a connection error state to the stream_interface
Tracking connection status changes was hard, and some code was
redundant. A new SI_ST_CER state was added to the stream interface
to indicate a past connection error, and an SI_FL_ERR flag was
added to report past I/O error. The stream_sock code does not set
the connection to SI_ST_CLO anymore in case of I/O error, it's
the upper layer which does it. This makes it possible to know
exactly when the file descriptors are allocated.
The new SI_ST_CER state permitted to split tcp_connection_status()
in two parts, one processing SI_ST_CON and the other one SI_ST_CER.
Synchronous connection errors now make use of this last state, hence
eliminating duplicate code.
Some ib<->ob copy paste errors were found and fixed, and all entities
setting SI_ST_CLO also shut the buffers down.
Some of these stream_interface specific functions and structures
have migrated to a new stream_interface.c file.
Some types of errors are still not detected by the buffers. For
instance, let's assume the following scenario in one single pass
of process_session: a connection sits in SI_ST_TAR state during
a retry. At TAR expiration, a new connection attempt is made, the
connection is obtained and srv->cur_sess is increased. Then the
buffer timeout is fires and everything is cleared, the new state
becomes SI_ST_CLO. The cleaning code checks that previous state
was either SI_ST_CON or SI_ST_EST to release the connection. But
that's wrong because last state is still SI_ST_TAR. So the
server's connection count does not get decreased.
This means that prev_state must not be used, and must be replaced
by some transition detection instead of level detection.
The following debugging line was useful to track state changes :
fprintf(stderr, "%s:%d: cs=%d ss=%d(%d) rqf=0x%08x rpf=0x%08x\n", __FUNCTION__, __LINE__,
s->si[0].state, s->si[1].state, s->si[1].err_type, s->req->flags, s-> rep->flags);
2008-11-03 05:26:53 +00:00
|
|
|
#endif /* _PROTO_STREAM_INTERFACE_H */
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Local variables:
|
|
|
|
* c-indent-level: 8
|
|
|
|
* c-basic-offset: 8
|
|
|
|
* End:
|
|
|
|
*/
|