MINOR: stream-int: Add src and dst addresses to the stream-interface
For now, these addresses are never set. But the idea is to be able to set, at least first, the client source and destination addresses at the stream level without updating the session or connection ones. Of course, because these addresses are carried by the strream-interface, it would be possible to set server source and destination addresses at this level too. Functions to fill these addresses have been added: si_get_src() and si_get_dst(). If not already set, these functions relies on underlying layers to fill stream-interface addresses. On the frontend side, the session addresses are used if set, otherwise the client connection ones are used. On the backend side, the server connection addresses are used. And just like for sessions and conncetions, si_src() and si_dst() may be used to get source and destination addresses or the stream-interface. And, if not set, same mechanism as above is used.
This commit is contained in:
parent
f46e1ea1ad
commit
859ff84f8c
@ -81,7 +81,6 @@
|
||||
#define SF_SRV_REUSED 0x00100000 /* the server-side connection was reused */
|
||||
#define SF_SRV_REUSED_ANTICIPATED 0x00200000 /* the connection was reused but the mux is not ready yet */
|
||||
|
||||
|
||||
/* flags for the proxy of the master CLI */
|
||||
/* 0x1.. to 0x3 are reserved for ACCESS_LVL_MASK */
|
||||
|
||||
|
@ -105,6 +105,9 @@ enum {
|
||||
SI_FL_RX_WAIT_EP = 0x00200000, /* stream-int waits for more data from the end point */
|
||||
SI_FL_L7_RETRY = 0x01000000, /* The stream interface may attempt L7 retries */
|
||||
SI_FL_D_L7_RETRY = 0x02000000, /* Disable L7 retries on this stream interface, even if configured to do it */
|
||||
|
||||
SI_FL_ADDR_FROM_SET = 0x04000000, /* source address is set */
|
||||
SI_FL_ADDR_TO_SET = 0x08000000 /* destination address is set */
|
||||
};
|
||||
|
||||
/* A stream interface has 3 parts :
|
||||
@ -126,11 +129,14 @@ struct stream_interface {
|
||||
unsigned int flags; /* SI_FL_* */
|
||||
enum obj_type *end; /* points to the end point (connection or appctx) */
|
||||
struct si_ops *ops; /* general operations at the stream interface layer */
|
||||
struct sockaddr_storage *src; /* source address (pool), when known, otherwise NULL */
|
||||
struct sockaddr_storage *dst; /* destination address (pool), when known, otherwise NULL */
|
||||
unsigned int exp; /* wake up time for connect, queue, turn-around, ... */
|
||||
|
||||
/* struct members below are the "remote" part, as seen from the buffer side */
|
||||
unsigned int err_type; /* first error detected, one of SI_ET_* */
|
||||
int conn_retries; /* number of connect retries left */
|
||||
|
||||
unsigned int hcto; /* half-closed timeout (0 = unset) */
|
||||
struct wait_event wait_event; /* We're in a wait list */
|
||||
struct buffer l7_buffer; /* To store the data, in case we have to retry */
|
||||
|
@ -112,6 +112,8 @@ static inline struct stream_interface *si_opposite(struct stream_interface *si)
|
||||
*/
|
||||
static inline int si_reset(struct stream_interface *si)
|
||||
{
|
||||
si->src = NULL;
|
||||
si->dst = NULL;
|
||||
si->err_type = SI_ET_NONE;
|
||||
si->conn_retries = 0; /* used for logging too */
|
||||
si->exp = TICK_ETERNITY;
|
||||
@ -562,6 +564,108 @@ static inline const char *si_state_str(int state)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Returns the source address of the stream-int and, if not set, fallbacks on
|
||||
* the session for frontend SI and the server connection for the backend SI. It
|
||||
* returns a const address on succes or NULL on failure.
|
||||
*/
|
||||
static inline const struct sockaddr_storage *si_src(struct stream_interface *si)
|
||||
{
|
||||
if (si->flags & SI_FL_ADDR_FROM_SET)
|
||||
return si->src;
|
||||
if (!(si->flags & SI_FL_ISBACK))
|
||||
return sess_src(strm_sess(si_strm(si)));
|
||||
else {
|
||||
struct conn_stream *cs = objt_cs(si->end);
|
||||
|
||||
if (cs && cs->conn)
|
||||
return conn_src(cs->conn);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/* Returns the destination address of the stream-int and, if not set, fallbacks
|
||||
* on the session for frontend SI and the server connection for the backend
|
||||
* SI. It returns a const address on succes or NULL on failure.
|
||||
*/
|
||||
static inline const struct sockaddr_storage *si_dst(struct stream_interface *si)
|
||||
{
|
||||
if (si->flags & SI_FL_ADDR_TO_SET)
|
||||
return si->dst;
|
||||
if (!(si->flags & SI_FL_ISBACK))
|
||||
return sess_dst(strm_sess(si_strm(si)));
|
||||
else {
|
||||
struct conn_stream *cs = objt_cs(si->end);
|
||||
|
||||
if (cs && cs->conn)
|
||||
return conn_dst(cs->conn);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Retrieves the source address of the stream-int. Returns non-zero on success
|
||||
* or zero on failure. The operation is only performed once and the address is
|
||||
* stored in the stream-int for future use. On the first call, the stream-int
|
||||
* source address is copied from the session one for frontend SI and the server
|
||||
* connection for the backend SI.
|
||||
*/
|
||||
static inline int si_get_src(struct stream_interface *si)
|
||||
{
|
||||
const struct sockaddr_storage *src = NULL;
|
||||
|
||||
if (si->flags & SI_FL_ADDR_FROM_SET)
|
||||
return 1;
|
||||
|
||||
if (!(si->flags & SI_FL_ISBACK))
|
||||
src = sess_src(strm_sess(si_strm(si)));
|
||||
else {
|
||||
struct conn_stream *cs = objt_cs(si->end);
|
||||
|
||||
if (cs && cs->conn)
|
||||
src = conn_src(cs->conn);
|
||||
}
|
||||
if (!src)
|
||||
return 0;
|
||||
|
||||
if (!sockaddr_alloc(&si->src, src, sizeof(*src)))
|
||||
return 0;
|
||||
|
||||
si->flags |= SI_FL_ADDR_FROM_SET;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Retrieves the destination address of the stream-int. Returns non-zero on
|
||||
* success or zero on failure. The operation is only performed once and the
|
||||
* address is stored in the stream-int for future use. On the first call, the
|
||||
* stream-int destination address is copied from the session one for frontend SI
|
||||
* and the server connection for the backend SI.
|
||||
*/
|
||||
static inline int si_get_dst(struct stream_interface *si)
|
||||
{
|
||||
const struct sockaddr_storage *dst = NULL;
|
||||
|
||||
if (si->flags & SI_FL_ADDR_TO_SET)
|
||||
return 1;
|
||||
|
||||
if (!(si->flags & SI_FL_ISBACK))
|
||||
dst = sess_dst(strm_sess(si_strm(si)));
|
||||
else {
|
||||
struct conn_stream *cs = objt_cs(si->end);
|
||||
|
||||
if (cs && cs->conn)
|
||||
dst = conn_dst(cs->conn);
|
||||
}
|
||||
if (!dst)
|
||||
return 0;
|
||||
|
||||
if (!sockaddr_alloc(&si->dst, dst, sizeof(*dst)))
|
||||
return 0;
|
||||
|
||||
si->flags |= SI_FL_ADDR_TO_SET;
|
||||
return 1;
|
||||
}
|
||||
|
||||
#endif /* _HAPROXY_STREAM_INTERFACE_H */
|
||||
|
||||
/*
|
||||
|
@ -744,6 +744,10 @@ static void stream_free(struct stream *s)
|
||||
}
|
||||
|
||||
sockaddr_free(&s->target_addr);
|
||||
sockaddr_free(&s->si[0].src);
|
||||
sockaddr_free(&s->si[0].dst);
|
||||
sockaddr_free(&s->si[1].src);
|
||||
sockaddr_free(&s->si[1].dst);
|
||||
pool_free(pool_head_stream, s);
|
||||
|
||||
/* We may want to free the maximum amount of pools if the proxy is stopping */
|
||||
|
Loading…
x
Reference in New Issue
Block a user