MAJOR: connection: move the addr field from the stream_interface

We need to have the source and destination addresses in the connection.
They were lying in the stream interface so let's move them. The flags
SI_FL_FROM_SET and SI_FL_TO_SET have been moved as well.

It's worth noting that tcp_connect_server() almost does not use the
stream interface anymore except for a few flags.

It has been identified that once we detach the connection from the SI,
it will probably be needed to keep a copy of the server-side addresses
in the SI just for logging purposes. This has not been implemented right
now though.
This commit is contained in:
Willy Tarreau 2012-08-30 21:11:38 +02:00 committed by Willy Tarreau
parent 3cefd521fa
commit 986a9d2d12
14 changed files with 178 additions and 187 deletions

View File

@ -371,6 +371,39 @@ static inline struct listener *target_client(struct target *t)
return t->ptr.l;
}
/* Retrieves the connection's source address */
static inline void conn_get_from_addr(struct connection *conn)
{
if (conn->flags & CO_FL_ADDR_FROM_SET)
return;
if (!conn->ctrl || !conn->ctrl->get_src)
return;
if (conn->ctrl->get_src(conn->t.sock.fd, (struct sockaddr *)&conn->addr.from,
sizeof(conn->addr.from),
conn->target.type != TARG_TYPE_CLIENT) == -1)
return;
conn->flags |= CO_FL_ADDR_FROM_SET;
}
/* Retrieves the connection's original destination address */
static inline void conn_get_to_addr(struct connection *conn)
{
if (conn->flags & CO_FL_ADDR_TO_SET)
return;
if (!conn->ctrl || !conn->ctrl->get_dst)
return;
if (conn->ctrl->get_dst(conn->t.sock.fd, (struct sockaddr *)&conn->addr.to,
sizeof(conn->addr.to),
conn->target.type != TARG_TYPE_CLIENT) == -1)
return;
conn->flags |= CO_FL_ADDR_TO_SET;
}
#endif /* _PROTO_CONNECTION_H */
/*

View File

@ -46,12 +46,12 @@ int smp_fetch_rdp_cookie(struct proxy *px, struct session *l4, void *l7, unsigne
*/
static inline struct stktable_key *tcp_src_to_stktable_key(struct session *s)
{
switch (s->si[0].addr.from.ss_family) {
switch (s->si[0].conn.addr.from.ss_family) {
case AF_INET:
static_table_key.key = (void *)&((struct sockaddr_in *)&s->si[0].addr.from)->sin_addr;
static_table_key.key = (void *)&((struct sockaddr_in *)&s->si[0].conn.addr.from)->sin_addr;
break;
case AF_INET6:
static_table_key.key = (void *)&((struct sockaddr_in6 *)&s->si[0].addr.from)->sin6_addr;
static_table_key.key = (void *)&((struct sockaddr_in6 *)&s->si[0].conn.addr.from)->sin6_addr;
break;
default:
return NULL;

View File

@ -93,38 +93,6 @@ static inline void si_prepare_task(struct stream_interface *si)
si->conn.data_ctx = NULL;
}
/* Retrieves the source address for the stream interface. */
static inline void si_get_from_addr(struct stream_interface *si)
{
if (si->flags & SI_FL_FROM_SET)
return;
if (!si_ctrl(si) || !si_ctrl(si)->get_src)
return;
if (si_ctrl(si)->get_src(si_fd(si), (struct sockaddr *)&si->addr.from,
sizeof(si->addr.from),
si->conn.target.type != TARG_TYPE_CLIENT) == -1)
return;
si->flags |= SI_FL_FROM_SET;
}
/* Retrieves the original destination address for the stream interface. */
static inline void si_get_to_addr(struct stream_interface *si)
{
if (si->flags & SI_FL_TO_SET)
return;
if (!si_ctrl(si) || !si_ctrl(si)->get_dst)
return;
if (si_ctrl(si)->get_dst(si_fd(si), (struct sockaddr *)&si->addr.to,
sizeof(si->addr.to),
si->conn.target.type != TARG_TYPE_CLIENT) == -1)
return;
si->flags |= SI_FL_TO_SET;
}
/* Sends a shutr to the connection using the data layer */
static inline void si_shutr(struct stream_interface *si)
{

View File

@ -80,6 +80,10 @@ enum {
*/
CO_FL_POLL_SOCK = CO_FL_HANDSHAKE | CO_FL_WAIT_L4_CONN | CO_FL_WAIT_L6_CONN,
/* These flags are used to report whether the from/to addresses are set or not */
CO_FL_ADDR_FROM_SET = 0x00001000, /* addr.from is set */
CO_FL_ADDR_TO_SET = 0x00002000, /* addr.to is set */
/* These flags are used by data layers to indicate to their iterators
* whether they had to stop due to missing data or missing room. Their
* callers must reset them before calling the data layer handlers.
@ -181,8 +185,10 @@ struct connection {
int data_st; /* data layer state, initialized to zero */
void *data_ctx; /* general purpose pointer, initialized to NULL */
struct target target; /* the target to connect to (server, proxy, applet, ...) */
struct sockaddr *peeraddr; /* pointer to peer's network address, or NULL if unset */
socklen_t peerlen; /* peer's address length, or 0 if unset */
struct {
struct sockaddr_storage from; /* client address, or address to spoof when connecting to the server */
struct sockaddr_storage to; /* address reached by the client if SN_FRT_ADDR_SET is set, or address to connect to */
} addr; /* addresses of the remote side, client for producer and server for consumer */
};
#endif /* _TYPES_CONNECTION_H */

View File

@ -75,8 +75,6 @@ enum {
SI_FL_NOLINGER = 0x0080, /* may close without lingering. One-shot. */
SI_FL_NOHALF = 0x0100, /* no half close, close both sides at once */
SI_FL_SRC_ADDR = 0x1000, /* get the source ip/port with getsockname */
SI_FL_TO_SET = 0x2000, /* addr.to is set */
SI_FL_FROM_SET = 0x4000, /* addr.from is set */
};
#define SI_FL_CAP_SPLICE (SI_FL_CAP_SPLTCP)
@ -160,10 +158,6 @@ struct stream_interface {
} cli;
} ctx; /* used by stats I/O handlers to dump the stats */
} applet;
struct {
struct sockaddr_storage from; /* client address, or address to spoof when connecting to the server */
struct sockaddr_storage to; /* address reached by the client if SN_FRT_ADDR_SET is set, or address to connect to */
} addr; /* addresses of the remote side, client for producer and server for consumer */
};
/* An applet designed to run in a stream interface */

View File

@ -547,14 +547,14 @@ int assign_server(struct session *s)
switch (s->be->lbprm.algo & BE_LB_PARM) {
case BE_LB_HASH_SRC:
if (s->req->prod->addr.from.ss_family == AF_INET) {
if (s->req->prod->conn.addr.from.ss_family == AF_INET) {
srv = get_server_sh(s->be,
(void *)&((struct sockaddr_in *)&s->req->prod->addr.from)->sin_addr,
(void *)&((struct sockaddr_in *)&s->req->prod->conn.addr.from)->sin_addr,
4);
}
else if (s->req->prod->addr.from.ss_family == AF_INET6) {
else if (s->req->prod->conn.addr.from.ss_family == AF_INET6) {
srv = get_server_sh(s->be,
(void *)&((struct sockaddr_in6 *)&s->req->prod->addr.from)->sin6_addr,
(void *)&((struct sockaddr_in6 *)&s->req->prod->conn.addr.from)->sin6_addr,
16);
}
else {
@ -637,7 +637,7 @@ int assign_server(struct session *s)
set_target_proxy(&s->target, s->be);
}
else if ((s->be->options & PR_O_HTTP_PROXY) &&
is_addr(&s->req->cons->addr.to)) {
is_addr(&s->req->cons->conn.addr.to)) {
/* in proxy mode, we need a valid destination address */
set_target_proxy(&s->target, s->be);
}
@ -691,20 +691,20 @@ int assign_server_address(struct session *s)
if (!(s->flags & SN_ASSIGNED))
return SRV_STATUS_INTERNAL;
s->req->cons->addr.to = target_srv(&s->target)->addr;
s->req->cons->conn.addr.to = target_srv(&s->target)->addr;
if (!is_addr(&s->req->cons->addr.to)) {
if (!is_addr(&s->req->cons->conn.addr.to)) {
/* if the server has no address, we use the same address
* the client asked, which is handy for remapping ports
* locally on multiple addresses at once.
*/
if (!(s->be->options & PR_O_TRANSP))
si_get_to_addr(s->req->prod);
conn_get_to_addr(&s->req->prod->conn);
if (s->req->prod->addr.to.ss_family == AF_INET) {
((struct sockaddr_in *)&s->req->cons->addr.to)->sin_addr = ((struct sockaddr_in *)&s->req->prod->addr.to)->sin_addr;
} else if (s->req->prod->addr.to.ss_family == AF_INET6) {
((struct sockaddr_in6 *)&s->req->cons->addr.to)->sin6_addr = ((struct sockaddr_in6 *)&s->req->prod->addr.to)->sin6_addr;
if (s->req->prod->conn.addr.to.ss_family == AF_INET) {
((struct sockaddr_in *)&s->req->cons->conn.addr.to)->sin_addr = ((struct sockaddr_in *)&s->req->prod->conn.addr.to)->sin_addr;
} else if (s->req->prod->conn.addr.to.ss_family == AF_INET6) {
((struct sockaddr_in6 *)&s->req->cons->conn.addr.to)->sin6_addr = ((struct sockaddr_in6 *)&s->req->prod->conn.addr.to)->sin6_addr;
}
}
@ -714,26 +714,26 @@ int assign_server_address(struct session *s)
int base_port;
if (!(s->be->options & PR_O_TRANSP))
si_get_to_addr(s->req->prod);
conn_get_to_addr(&s->req->prod->conn);
/* First, retrieve the port from the incoming connection */
base_port = get_host_port(&s->req->prod->addr.to);
base_port = get_host_port(&s->req->prod->conn.addr.to);
/* Second, assign the outgoing connection's port */
base_port += get_host_port(&s->req->cons->addr.to);
set_host_port(&s->req->cons->addr.to, base_port);
base_port += get_host_port(&s->req->cons->conn.addr.to);
set_host_port(&s->req->cons->conn.addr.to, base_port);
}
}
else if (s->be->options & PR_O_DISPATCH) {
/* connect to the defined dispatch addr */
s->req->cons->addr.to = s->be->dispatch_addr;
s->req->cons->conn.addr.to = s->be->dispatch_addr;
}
else if (s->be->options & PR_O_TRANSP) {
/* in transparent mode, use the original dest addr if no dispatch specified */
si_get_to_addr(s->req->prod);
conn_get_to_addr(&s->req->prod->conn);
if (s->req->prod->addr.to.ss_family == AF_INET || s->req->prod->addr.to.ss_family == AF_INET6) {
memcpy(&s->req->cons->addr.to, &s->req->prod->addr.to, MIN(sizeof(s->req->cons->addr.to), sizeof(s->req->prod->addr.to)));
if (s->req->prod->conn.addr.to.ss_family == AF_INET || s->req->prod->conn.addr.to.ss_family == AF_INET6) {
memcpy(&s->req->cons->conn.addr.to, &s->req->prod->conn.addr.to, MIN(sizeof(s->req->cons->conn.addr.to), sizeof(s->req->prod->conn.addr.to)));
}
/* when we support IPv6 on the backend, we may add other tests */
//qfprintf(stderr, "Cannot get original server address.\n");
@ -887,12 +887,12 @@ static void assign_tproxy_address(struct session *s)
if (srv && srv->state & SRV_BIND_SRC) {
switch (srv->state & SRV_TPROXY_MASK) {
case SRV_TPROXY_ADDR:
s->req->cons->addr.from = srv->tproxy_addr;
s->req->cons->conn.addr.from = srv->tproxy_addr;
break;
case SRV_TPROXY_CLI:
case SRV_TPROXY_CIP:
/* FIXME: what can we do if the client connects in IPv6 or unix socket ? */
s->req->cons->addr.from = s->req->prod->addr.from;
s->req->cons->conn.addr.from = s->req->prod->conn.addr.from;
break;
case SRV_TPROXY_DYN:
if (srv->bind_hdr_occ) {
@ -901,32 +901,32 @@ static void assign_tproxy_address(struct session *s)
int rewind;
/* bind to the IP in a header */
((struct sockaddr_in *)&s->req->cons->addr.from)->sin_family = AF_INET;
((struct sockaddr_in *)&s->req->cons->addr.from)->sin_port = 0;
((struct sockaddr_in *)&s->req->cons->addr.from)->sin_addr.s_addr = 0;
((struct sockaddr_in *)&s->req->cons->conn.addr.from)->sin_family = AF_INET;
((struct sockaddr_in *)&s->req->cons->conn.addr.from)->sin_port = 0;
((struct sockaddr_in *)&s->req->cons->conn.addr.from)->sin_addr.s_addr = 0;
b_rew(&s->req->buf, rewind = s->req->buf.o);
if (http_get_hdr(&s->txn.req, srv->bind_hdr_name, srv->bind_hdr_len,
&s->txn.hdr_idx, srv->bind_hdr_occ, NULL, &vptr, &vlen)) {
((struct sockaddr_in *)&s->req->cons->addr.from)->sin_addr.s_addr =
((struct sockaddr_in *)&s->req->cons->conn.addr.from)->sin_addr.s_addr =
htonl(inetaddr_host_lim(vptr, vptr + vlen));
}
b_adv(&s->req->buf, rewind);
}
break;
default:
memset(&s->req->cons->addr.from, 0, sizeof(s->req->cons->addr.from));
memset(&s->req->cons->conn.addr.from, 0, sizeof(s->req->cons->conn.addr.from));
}
}
else if (s->be->options & PR_O_BIND_SRC) {
switch (s->be->options & PR_O_TPXY_MASK) {
case PR_O_TPXY_ADDR:
s->req->cons->addr.from = s->be->tproxy_addr;
s->req->cons->conn.addr.from = s->be->tproxy_addr;
break;
case PR_O_TPXY_CLI:
case PR_O_TPXY_CIP:
/* FIXME: what can we do if the client connects in IPv6 or socket unix? */
s->req->cons->addr.from = s->req->prod->addr.from;
s->req->cons->conn.addr.from = s->req->prod->conn.addr.from;
break;
case PR_O_TPXY_DYN:
if (s->be->bind_hdr_occ) {
@ -935,21 +935,21 @@ static void assign_tproxy_address(struct session *s)
int rewind;
/* bind to the IP in a header */
((struct sockaddr_in *)&s->req->cons->addr.from)->sin_family = AF_INET;
((struct sockaddr_in *)&s->req->cons->addr.from)->sin_port = 0;
((struct sockaddr_in *)&s->req->cons->addr.from)->sin_addr.s_addr = 0;
((struct sockaddr_in *)&s->req->cons->conn.addr.from)->sin_family = AF_INET;
((struct sockaddr_in *)&s->req->cons->conn.addr.from)->sin_port = 0;
((struct sockaddr_in *)&s->req->cons->conn.addr.from)->sin_addr.s_addr = 0;
b_rew(&s->req->buf, rewind = s->req->buf.o);
if (http_get_hdr(&s->txn.req, s->be->bind_hdr_name, s->be->bind_hdr_len,
&s->txn.hdr_idx, s->be->bind_hdr_occ, NULL, &vptr, &vlen)) {
((struct sockaddr_in *)&s->req->cons->addr.from)->sin_addr.s_addr =
((struct sockaddr_in *)&s->req->cons->conn.addr.from)->sin_addr.s_addr =
htonl(inetaddr_host_lim(vptr, vptr + vlen));
}
b_adv(&s->req->buf, rewind);
}
break;
default:
memset(&s->req->cons->addr.from, 0, sizeof(s->req->cons->addr.from));
memset(&s->req->cons->conn.addr.from, 0, sizeof(s->req->cons->conn.addr.from));
}
}
#endif
@ -989,7 +989,7 @@ int connect_server(struct session *s)
}
else if (s->target.type == TARG_TYPE_PROXY) {
/* proxies exclusively run on raw_sock right now */
si_prepare_conn(s->req->cons, protocol_by_family(s->req->cons->addr.to.ss_family), &raw_sock);
si_prepare_conn(s->req->cons, protocol_by_family(s->req->cons->conn.addr.to.ss_family), &raw_sock);
if (!si_ctrl(s->req->cons))
return SN_ERR_INTERNAL;
}
@ -1000,7 +1000,7 @@ int connect_server(struct session *s)
s->req->cons->send_proxy_ofs = 0;
if (s->target.type == TARG_TYPE_SERVER && (s->target.ptr.s->state & SRV_SEND_PROXY)) {
s->req->cons->send_proxy_ofs = 1; /* must compute size */
si_get_to_addr(s->req->prod);
conn_get_to_addr(&s->req->prod->conn);
}
assign_tproxy_address(s);

View File

@ -3330,11 +3330,11 @@ static int stats_dump_full_sess_to_buffer(struct stream_interface *si)
sess->uniq_id,
sess->listener->proto->name);
switch (addr_to_str(&sess->si[0].addr.from, pn, sizeof(pn))) {
switch (addr_to_str(&sess->si[0].conn.addr.from, pn, sizeof(pn))) {
case AF_INET:
case AF_INET6:
chunk_printf(&msg, " source=%s:%d\n",
pn, get_host_port(&sess->si[0].addr.from));
pn, get_host_port(&sess->si[0].conn.addr.from));
break;
case AF_UNIX:
chunk_printf(&msg, " source=unix:%d\n", sess->listener->luid);
@ -3355,12 +3355,12 @@ static int stats_dump_full_sess_to_buffer(struct stream_interface *si)
sess->listener ? sess->listener->name ? sess->listener->name : "?" : "?",
sess->listener ? sess->listener->luid : 0);
si_get_to_addr(&sess->si[0]);
switch (addr_to_str(&sess->si[0].addr.to, pn, sizeof(pn))) {
conn_get_to_addr(&sess->si[0].conn);
switch (addr_to_str(&sess->si[0].conn.addr.to, pn, sizeof(pn))) {
case AF_INET:
case AF_INET6:
chunk_printf(&msg, " addr=%s:%d\n",
pn, get_host_port(&sess->si[0].addr.to));
pn, get_host_port(&sess->si[0].conn.addr.to));
break;
case AF_UNIX:
chunk_printf(&msg, " addr=unix:%d\n", sess->listener->luid);
@ -3379,12 +3379,12 @@ static int stats_dump_full_sess_to_buffer(struct stream_interface *si)
else
chunk_printf(&msg, " backend=<NONE> (id=-1 mode=-)");
si_get_from_addr(&sess->si[1]);
switch (addr_to_str(&sess->si[1].addr.from, pn, sizeof(pn))) {
conn_get_from_addr(&sess->si[1].conn);
switch (addr_to_str(&sess->si[1].conn.addr.from, pn, sizeof(pn))) {
case AF_INET:
case AF_INET6:
chunk_printf(&msg, " addr=%s:%d\n",
pn, get_host_port(&sess->si[1].addr.from));
pn, get_host_port(&sess->si[1].conn.addr.from));
break;
case AF_UNIX:
chunk_printf(&msg, " addr=unix\n");
@ -3403,12 +3403,12 @@ static int stats_dump_full_sess_to_buffer(struct stream_interface *si)
else
chunk_printf(&msg, " server=<NONE> (id=-1)");
si_get_to_addr(&sess->si[1]);
switch (addr_to_str(&sess->si[1].addr.to, pn, sizeof(pn))) {
conn_get_to_addr(&sess->si[1].conn);
switch (addr_to_str(&sess->si[1].conn.addr.to, pn, sizeof(pn))) {
case AF_INET:
case AF_INET6:
chunk_printf(&msg, " addr=%s:%d\n",
pn, get_host_port(&sess->si[1].addr.to));
pn, get_host_port(&sess->si[1].conn.addr.to));
break;
case AF_UNIX:
chunk_printf(&msg, " addr=unix\n");
@ -3610,13 +3610,13 @@ static int stats_dump_sess_to_buffer(struct stream_interface *si)
curr_sess->listener->proto->name);
switch (addr_to_str(&curr_sess->si[0].addr.from, pn, sizeof(pn))) {
switch (addr_to_str(&curr_sess->si[0].conn.addr.from, pn, sizeof(pn))) {
case AF_INET:
case AF_INET6:
chunk_printf(&msg,
" src=%s:%d fe=%s be=%s srv=%s",
pn,
get_host_port(&curr_sess->si[0].addr.from),
get_host_port(&curr_sess->si[0].conn.addr.from),
curr_sess->fe->id,
(curr_sess->be->cap & PR_CAP_BE) ? curr_sess->be->id : "<NONE>",
target_srv(&curr_sess->target) ? target_srv(&curr_sess->target)->id : "<none>"

View File

@ -139,16 +139,16 @@ int frontend_accept(struct session *s)
else {
char pn[INET6_ADDRSTRLEN], sn[INET6_ADDRSTRLEN];
si_get_from_addr(s->req->prod);
si_get_to_addr(s->req->prod);
conn_get_from_addr(&s->req->prod->conn);
conn_get_to_addr(&s->req->prod->conn);
switch (addr_to_str(&s->req->prod->addr.from, pn, sizeof(pn))) {
switch (addr_to_str(&s->req->prod->conn.addr.from, pn, sizeof(pn))) {
case AF_INET:
case AF_INET6:
addr_to_str(&s->req->prod->addr.to, sn, sizeof(sn));
addr_to_str(&s->req->prod->conn.addr.to, sn, sizeof(sn));
send_log(s->fe, LOG_INFO, "Connect from %s:%d to %s:%d (%s/%s)\n",
pn, get_host_port(&s->req->prod->addr.from),
sn, get_host_port(&s->req->prod->addr.to),
pn, get_host_port(&s->req->prod->conn.addr.from),
sn, get_host_port(&s->req->prod->conn.addr.to),
s->fe->id, (s->fe->mode == PR_MODE_HTTP) ? "HTTP" : "TCP");
break;
case AF_UNIX:
@ -165,14 +165,14 @@ int frontend_accept(struct session *s)
char pn[INET6_ADDRSTRLEN];
int len = 0;
si_get_from_addr(s->req->prod);
conn_get_from_addr(&s->req->prod->conn);
switch (addr_to_str(&s->req->prod->addr.from, pn, sizeof(pn))) {
switch (addr_to_str(&s->req->prod->conn.addr.from, pn, sizeof(pn))) {
case AF_INET:
case AF_INET6:
len = sprintf(trash, "%08x:%s.accept(%04x)=%04x from [%s:%d]\n",
s->uniq_id, s->fe->id, (unsigned short)s->listener->fd, (unsigned short)cfd,
pn, get_host_port(&s->req->prod->addr.from));
pn, get_host_port(&s->req->prod->conn.addr.from));
break;
case AF_UNIX:
/* UNIX socket, only the destination is known */
@ -313,14 +313,14 @@ int frontend_decode_proxy_request(struct session *s, struct channel *req, int an
goto fail;
/* update the session's addresses and mark them set */
((struct sockaddr_in *)&s->si[0].addr.from)->sin_family = AF_INET;
((struct sockaddr_in *)&s->si[0].addr.from)->sin_addr.s_addr = htonl(src3);
((struct sockaddr_in *)&s->si[0].addr.from)->sin_port = htons(sport);
((struct sockaddr_in *)&s->si[0].conn.addr.from)->sin_family = AF_INET;
((struct sockaddr_in *)&s->si[0].conn.addr.from)->sin_addr.s_addr = htonl(src3);
((struct sockaddr_in *)&s->si[0].conn.addr.from)->sin_port = htons(sport);
((struct sockaddr_in *)&s->si[0].addr.to)->sin_family = AF_INET;
((struct sockaddr_in *)&s->si[0].addr.to)->sin_addr.s_addr = htonl(dst3);
((struct sockaddr_in *)&s->si[0].addr.to)->sin_port = htons(dport);
s->si[0].flags |= SI_FL_FROM_SET | SI_FL_TO_SET;
((struct sockaddr_in *)&s->si[0].conn.addr.to)->sin_family = AF_INET;
((struct sockaddr_in *)&s->si[0].conn.addr.to)->sin_addr.s_addr = htonl(dst3);
((struct sockaddr_in *)&s->si[0].conn.addr.to)->sin_port = htons(dport);
s->si[0].conn.flags |= CO_FL_ADDR_FROM_SET | CO_FL_ADDR_TO_SET;
}
else if (!memcmp(line, "TCP6 ", 5) != 0) {
u32 sport, dport;
@ -374,14 +374,14 @@ int frontend_decode_proxy_request(struct session *s, struct channel *req, int an
goto fail;
/* update the session's addresses and mark them set */
((struct sockaddr_in6 *)&s->si[0].addr.from)->sin6_family = AF_INET6;
memcpy(&((struct sockaddr_in6 *)&s->si[0].addr.from)->sin6_addr, &src3, sizeof(struct in6_addr));
((struct sockaddr_in6 *)&s->si[0].addr.from)->sin6_port = htons(sport);
((struct sockaddr_in6 *)&s->si[0].conn.addr.from)->sin6_family = AF_INET6;
memcpy(&((struct sockaddr_in6 *)&s->si[0].conn.addr.from)->sin6_addr, &src3, sizeof(struct in6_addr));
((struct sockaddr_in6 *)&s->si[0].conn.addr.from)->sin6_port = htons(sport);
((struct sockaddr_in6 *)&s->si[0].addr.to)->sin6_family = AF_INET6;
memcpy(&((struct sockaddr_in6 *)&s->si[0].addr.to)->sin6_addr, &dst3, sizeof(struct in6_addr));
((struct sockaddr_in6 *)&s->si[0].addr.to)->sin6_port = htons(dport);
s->si[0].flags |= SI_FL_FROM_SET | SI_FL_TO_SET;
((struct sockaddr_in6 *)&s->si[0].conn.addr.to)->sin6_family = AF_INET6;
memcpy(&((struct sockaddr_in6 *)&s->si[0].conn.addr.to)->sin6_addr, &dst3, sizeof(struct in6_addr));
((struct sockaddr_in6 *)&s->si[0].conn.addr.to)->sin6_port = htons(dport);
s->si[0].conn.flags |= CO_FL_ADDR_FROM_SET | CO_FL_ADDR_TO_SET;
}
else {
goto fail;

View File

@ -836,7 +836,7 @@ int build_logline(struct session *s, char *dst, size_t maxsize, struct list *lis
break;
case LOG_FMT_CLIENTIP: // %Ci
ret = lf_ip(tmplog, (struct sockaddr *)&s->req->prod->addr.from,
ret = lf_ip(tmplog, (struct sockaddr *)&s->req->prod->conn.addr.from,
dst + maxsize - tmplog, tmp);
if (ret == NULL)
goto out;
@ -845,10 +845,10 @@ int build_logline(struct session *s, char *dst, size_t maxsize, struct list *lis
break;
case LOG_FMT_CLIENTPORT: // %Cp
if (s->req->prod->addr.from.ss_family == AF_UNIX) {
if (s->req->prod->conn.addr.from.ss_family == AF_UNIX) {
ret = ltoa_o(s->listener->luid, tmplog, dst + maxsize - tmplog);
} else {
ret = lf_port(tmplog, (struct sockaddr *)&s->req->prod->addr.from,
ret = lf_port(tmplog, (struct sockaddr *)&s->req->prod->conn.addr.from,
dst + maxsize - tmplog, tmp);
}
if (ret == NULL)
@ -858,8 +858,8 @@ int build_logline(struct session *s, char *dst, size_t maxsize, struct list *lis
break;
case LOG_FMT_FRONTENDIP: // %Fi
si_get_to_addr(s->req->prod);
ret = lf_ip(tmplog, (struct sockaddr *)&s->req->prod->addr.to,
conn_get_to_addr(&s->req->prod->conn);
ret = lf_ip(tmplog, (struct sockaddr *)&s->req->prod->conn.addr.to,
dst + maxsize - tmplog, tmp);
if (ret == NULL)
goto out;
@ -868,12 +868,12 @@ int build_logline(struct session *s, char *dst, size_t maxsize, struct list *lis
break;
case LOG_FMT_FRONTENDPORT: // %Fp
si_get_to_addr(s->req->prod);
if (s->req->prod->addr.to.ss_family == AF_UNIX) {
conn_get_to_addr(&s->req->prod->conn);
if (s->req->prod->conn.addr.to.ss_family == AF_UNIX) {
ret = ltoa_o(s->listener->luid,
tmplog, dst + maxsize - tmplog);
} else {
ret = lf_port(tmplog, (struct sockaddr *)&s->req->prod->addr.to,
ret = lf_port(tmplog, (struct sockaddr *)&s->req->prod->conn.addr.to,
dst + maxsize - tmplog, tmp);
}
if (ret == NULL)
@ -883,7 +883,7 @@ int build_logline(struct session *s, char *dst, size_t maxsize, struct list *lis
break;
case LOG_FMT_BACKENDIP: // %Bi
ret = lf_ip(tmplog, (struct sockaddr *)&s->req->cons->addr.from,
ret = lf_ip(tmplog, (struct sockaddr *)&s->req->cons->conn.addr.from,
dst + maxsize - tmplog, tmp);
if (ret == NULL)
goto out;
@ -892,7 +892,7 @@ int build_logline(struct session *s, char *dst, size_t maxsize, struct list *lis
break;
case LOG_FMT_BACKENDPORT: // %Bp
ret = lf_port(tmplog, (struct sockaddr *)&s->req->cons->addr.from,
ret = lf_port(tmplog, (struct sockaddr *)&s->req->cons->conn.addr.from,
dst + maxsize - tmplog, tmp);
if (ret == NULL)
goto out;
@ -901,7 +901,7 @@ int build_logline(struct session *s, char *dst, size_t maxsize, struct list *lis
break;
case LOG_FMT_SERVERIP: // %Si
ret = lf_ip(tmplog, (struct sockaddr *)&s->req->cons->addr.to,
ret = lf_ip(tmplog, (struct sockaddr *)&s->req->cons->conn.addr.to,
dst + maxsize - tmplog, tmp);
if (ret == NULL)
goto out;
@ -910,7 +910,7 @@ int build_logline(struct session *s, char *dst, size_t maxsize, struct list *lis
break;
case LOG_FMT_SERVERPORT: // %Sp
ret = lf_port(tmplog, (struct sockaddr *)&s->req->cons->addr.to,
ret = lf_port(tmplog, (struct sockaddr *)&s->req->cons->conn.addr.to,
dst + maxsize - tmplog, tmp);
if (ret == NULL)
goto out;

View File

@ -1136,7 +1136,7 @@ static struct session *peer_session_create(struct peer *peer, struct peer_sessio
t->context = s;
t->nice = l->nice;
memcpy(&s->si[1].addr.to, &peer->addr, sizeof(s->si[1].addr.to));
memcpy(&s->si[1].conn.addr.to, &peer->addr, sizeof(s->si[1].conn.addr.to));
s->task = t;
s->listener = l;
@ -1148,8 +1148,6 @@ static struct session *peer_session_create(struct peer *peer, struct peer_sessio
s->req = s->rep = NULL; /* will be allocated later */
s->si[0].conn.peeraddr = NULL;
s->si[0].conn.peerlen = 0;
s->si[0].conn.t.sock.fd = -1;
s->si[0].conn.flags = CO_FL_NONE;
s->si[0].owner = t;
@ -1168,8 +1166,6 @@ static struct session *peer_session_create(struct peer *peer, struct peer_sessio
s->si[0].applet.st0 = PEER_SESSION_CONNECT;
s->si[0].conn.data_ctx = (void *)ps;
s->si[1].conn.peeraddr = NULL;
s->si[1].conn.peerlen = 0;
s->si[1].conn.t.sock.fd = -1; /* just to help with debugging */
s->si[1].conn.flags = CO_FL_NONE;
s->si[1].owner = t;

View File

@ -3269,7 +3269,7 @@ int http_process_request(struct session *s, struct channel *req, int an_bit)
* parsing incoming request.
*/
if ((s->be->options & PR_O_HTTP_PROXY) && !(s->flags & SN_ADDR_SET)) {
url2sa(req->buf.p + msg->sl.rq.u, msg->sl.rq.u_l, &s->req->cons->addr.to);
url2sa(req->buf.p + msg->sl.rq.u, msg->sl.rq.u_l, &s->req->cons->conn.addr.to);
}
/*
@ -3319,19 +3319,19 @@ int http_process_request(struct session *s, struct channel *req, int an_bit)
* and we found it, so don't do anything.
*/
}
else if (s->req->prod->addr.from.ss_family == AF_INET) {
else if (s->req->prod->conn.addr.from.ss_family == AF_INET) {
/* Add an X-Forwarded-For header unless the source IP is
* in the 'except' network range.
*/
if ((!s->fe->except_mask.s_addr ||
(((struct sockaddr_in *)&s->req->prod->addr.from)->sin_addr.s_addr & s->fe->except_mask.s_addr)
(((struct sockaddr_in *)&s->req->prod->conn.addr.from)->sin_addr.s_addr & s->fe->except_mask.s_addr)
!= s->fe->except_net.s_addr) &&
(!s->be->except_mask.s_addr ||
(((struct sockaddr_in *)&s->req->prod->addr.from)->sin_addr.s_addr & s->be->except_mask.s_addr)
(((struct sockaddr_in *)&s->req->prod->conn.addr.from)->sin_addr.s_addr & s->be->except_mask.s_addr)
!= s->be->except_net.s_addr)) {
int len;
unsigned char *pn;
pn = (unsigned char *)&((struct sockaddr_in *)&s->req->prod->addr.from)->sin_addr;
pn = (unsigned char *)&((struct sockaddr_in *)&s->req->prod->conn.addr.from)->sin_addr;
/* Note: we rely on the backend to get the header name to be used for
* x-forwarded-for, because the header is really meant for the backends.
@ -3351,14 +3351,14 @@ int http_process_request(struct session *s, struct channel *req, int an_bit)
goto return_bad_req;
}
}
else if (s->req->prod->addr.from.ss_family == AF_INET6) {
else if (s->req->prod->conn.addr.from.ss_family == AF_INET6) {
/* FIXME: for the sake of completeness, we should also support
* 'except' here, although it is mostly useless in this case.
*/
int len;
char pn[INET6_ADDRSTRLEN];
inet_ntop(AF_INET6,
(const void *)&((struct sockaddr_in6 *)(&s->req->prod->addr.from))->sin6_addr,
(const void *)&((struct sockaddr_in6 *)(&s->req->prod->conn.addr.from))->sin6_addr,
pn, sizeof(pn));
/* Note: we rely on the backend to get the header name to be used for
@ -3387,22 +3387,22 @@ int http_process_request(struct session *s, struct channel *req, int an_bit)
if ((s->fe->options | s->be->options) & PR_O_ORGTO) {
/* FIXME: don't know if IPv6 can handle that case too. */
if (s->req->prod->addr.from.ss_family == AF_INET) {
if (s->req->prod->conn.addr.from.ss_family == AF_INET) {
/* Add an X-Original-To header unless the destination IP is
* in the 'except' network range.
*/
si_get_to_addr(s->req->prod);
conn_get_to_addr(&s->req->prod->conn);
if (s->req->prod->addr.to.ss_family == AF_INET &&
if (s->req->prod->conn.addr.to.ss_family == AF_INET &&
((!s->fe->except_mask_to.s_addr ||
(((struct sockaddr_in *)&s->req->prod->addr.to)->sin_addr.s_addr & s->fe->except_mask_to.s_addr)
(((struct sockaddr_in *)&s->req->prod->conn.addr.to)->sin_addr.s_addr & s->fe->except_mask_to.s_addr)
!= s->fe->except_to.s_addr) &&
(!s->be->except_mask_to.s_addr ||
(((struct sockaddr_in *)&s->req->prod->addr.to)->sin_addr.s_addr & s->be->except_mask_to.s_addr)
(((struct sockaddr_in *)&s->req->prod->conn.addr.to)->sin_addr.s_addr & s->be->except_mask_to.s_addr)
!= s->be->except_to.s_addr))) {
int len;
unsigned char *pn;
pn = (unsigned char *)&((struct sockaddr_in *)&s->req->prod->addr.to)->sin_addr;
pn = (unsigned char *)&((struct sockaddr_in *)&s->req->prod->conn.addr.to)->sin_addr;
/* Note: we rely on the backend to get the header name to be used for
* x-original-to, because the header is really meant for the backends.
@ -7279,7 +7279,7 @@ void http_capture_bad_message(struct error_snapshot *es, struct session *s,
es->sid = s->uniq_id;
es->srv = target_srv(&s->target);
es->oe = other_end;
es->src = s->req->prod->addr.from;
es->src = s->req->prod->conn.addr.from;
es->state = state;
es->ev_id = error_snapshot_id++;
es->b_flags = buf->flags;
@ -7858,11 +7858,11 @@ smp_fetch_url_ip(struct proxy *px, struct session *l4, void *l7, unsigned int op
CHECK_HTTP_MESSAGE_FIRST();
/* Parse HTTP request */
url2sa(txn->req.buf->buf.p + txn->req.sl.rq.u, txn->req.sl.rq.u_l, &l4->req->cons->addr.to);
if (((struct sockaddr_in *)&l4->req->cons->addr.to)->sin_family != AF_INET)
url2sa(txn->req.buf->buf.p + txn->req.sl.rq.u, txn->req.sl.rq.u_l, &l4->req->cons->conn.addr.to);
if (((struct sockaddr_in *)&l4->req->cons->conn.addr.to)->sin_family != AF_INET)
return 0;
smp->type = SMP_T_IPV4;
smp->data.ipv4 = ((struct sockaddr_in *)&l4->req->cons->addr.to)->sin_addr;
smp->data.ipv4 = ((struct sockaddr_in *)&l4->req->cons->conn.addr.to)->sin_addr;
/*
* If we are parsing url in frontend space, we prepare backend stage
@ -7884,9 +7884,9 @@ smp_fetch_url_port(struct proxy *px, struct session *l4, void *l7, unsigned int
CHECK_HTTP_MESSAGE_FIRST();
/* Same optimization as url_ip */
url2sa(txn->req.buf->buf.p + txn->req.sl.rq.u, txn->req.sl.rq.u_l, &l4->req->cons->addr.to);
url2sa(txn->req.buf->buf.p + txn->req.sl.rq.u, txn->req.sl.rq.u_l, &l4->req->cons->conn.addr.to);
smp->type = SMP_T_UINT;
smp->data.uint = ntohs(((struct sockaddr_in *)&l4->req->cons->addr.to)->sin_port);
smp->data.uint = ntohs(((struct sockaddr_in *)&l4->req->cons->conn.addr.to)->sin_port);
if (px->options & PR_O_HTTP_PROXY)
l4->flags |= SN_ADDR_SET;

View File

@ -232,21 +232,22 @@ int tcp_connect_server(struct stream_interface *si)
int fd;
struct server *srv;
struct proxy *be;
struct connection *conn = &si->conn;
switch (si->conn.target.type) {
switch (conn->target.type) {
case TARG_TYPE_PROXY:
be = si->conn.target.ptr.p;
be = conn->target.ptr.p;
srv = NULL;
break;
case TARG_TYPE_SERVER:
srv = si->conn.target.ptr.s;
srv = conn->target.ptr.s;
be = srv->proxy;
break;
default:
return SN_ERR_INTERNAL;
}
if ((fd = si->conn.t.sock.fd = socket(si->addr.to.ss_family, SOCK_STREAM, IPPROTO_TCP)) == -1) {
if ((fd = conn->t.sock.fd = socket(conn->addr.to.ss_family, SOCK_STREAM, IPPROTO_TCP)) == -1) {
qfprintf(stderr, "Cannot get a server socket.\n");
if (errno == ENFILE)
@ -336,11 +337,11 @@ int tcp_connect_server(struct stream_interface *si)
fdinfo[fd].port_range = srv->sport_range;
set_host_port(&src, fdinfo[fd].local_port);
ret = tcp_bind_socket(fd, flags, &src, &si->addr.from);
ret = tcp_bind_socket(fd, flags, &src, &conn->addr.from);
} while (ret != 0); /* binding NOK */
}
else {
ret = tcp_bind_socket(fd, flags, &srv->source_addr, &si->addr.from);
ret = tcp_bind_socket(fd, flags, &srv->source_addr, &conn->addr.from);
}
if (ret) {
@ -383,7 +384,7 @@ int tcp_connect_server(struct stream_interface *si)
if (be->iface_name)
setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, be->iface_name, be->iface_len + 1);
#endif
ret = tcp_bind_socket(fd, flags, &be->source_addr, &si->addr.from);
ret = tcp_bind_socket(fd, flags, &be->source_addr, &conn->addr.from);
if (ret) {
close(fd);
if (ret == 1) {
@ -418,12 +419,7 @@ int tcp_connect_server(struct stream_interface *si)
if (global.tune.server_rcvbuf)
setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &global.tune.server_rcvbuf, sizeof(global.tune.server_rcvbuf));
si->flags &= ~SI_FL_FROM_SET;
si->conn.peeraddr = (struct sockaddr *)&si->addr.to;
si->conn.peerlen = get_addr_len(&si->addr.to);
if ((connect(fd, si->conn.peeraddr, si->conn.peerlen) == -1) &&
if ((connect(fd, (struct sockaddr *)&conn->addr.to, get_addr_len(&conn->addr.to)) == -1) &&
(errno != EINPROGRESS) && (errno != EALREADY) && (errno != EISCONN)) {
if (errno == EAGAIN || errno == EADDRINUSE) {
@ -459,25 +455,25 @@ int tcp_connect_server(struct stream_interface *si)
/* needs src ip/port for logging */
if (si->flags & SI_FL_SRC_ADDR)
si_get_from_addr(si);
conn_get_from_addr(conn);
fdtab[fd].owner = &si->conn;
fdtab[fd].owner = conn;
fdtab[fd].flags = FD_FL_TCP | FD_FL_TCP_NODELAY;
si->conn.flags = CO_FL_WAIT_L4_CONN; /* connection in progress */
si->conn.flags |= CO_FL_NOTIFY_SI; /* we're on a stream_interface */
conn->flags = CO_FL_WAIT_L4_CONN; /* connection in progress */
conn->flags |= CO_FL_NOTIFY_SI; /* we're on a stream_interface */
/* Prepare to send a few handshakes related to the on-wire protocol. */
if (si->send_proxy_ofs)
si->conn.flags |= CO_FL_SI_SEND_PROXY;
conn->flags |= CO_FL_SI_SEND_PROXY;
fdtab[fd].iocb = conn_fd_handler;
fd_insert(fd);
conn_sock_want_send(&si->conn); /* for connect status */
conn_sock_want_send(conn); /* for connect status */
if (!channel_is_empty(si->ob))
conn_data_want_send(&si->conn); /* prepare to send data if any */
conn_data_want_send(conn); /* prepare to send data if any */
si->state = SI_ST_CON;
if (si->conn.data->rcv_pipe && si->conn.data->snd_pipe)
if (conn->data->rcv_pipe && conn->data->snd_pipe)
si->flags |= SI_FL_CAP_SPLTCP; /* TCP supports splicing */
si->exp = tick_add_ifset(now_ms, be->timeout.connect);
@ -549,7 +545,7 @@ int tcp_connect_probe(struct connection *conn)
* - connecting (EALREADY, EINPROGRESS)
* - connected (EISCONN, 0)
*/
if ((connect(fd, conn->peeraddr, conn->peerlen) < 0)) {
if (connect(fd, (struct sockaddr *)&conn->addr.to, get_addr_len(&conn->addr.to)) < 0) {
if (errno == EALREADY || errno == EINPROGRESS) {
conn_sock_stop_recv(conn);
conn_sock_poll_send(conn);
@ -1505,13 +1501,13 @@ static int
smp_fetch_src(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
const struct arg *args, struct sample *smp)
{
switch (l4->si[0].addr.from.ss_family) {
switch (l4->si[0].conn.addr.from.ss_family) {
case AF_INET:
smp->data.ipv4 = ((struct sockaddr_in *)&l4->si[0].addr.from)->sin_addr;
smp->data.ipv4 = ((struct sockaddr_in *)&l4->si[0].conn.addr.from)->sin_addr;
smp->type = SMP_T_IPV4;
break;
case AF_INET6:
smp->data.ipv6 = ((struct sockaddr_in6 *)(&l4->si[0].addr.from))->sin6_addr;
smp->data.ipv6 = ((struct sockaddr_in6 *)(&l4->si[0].conn.addr.from))->sin6_addr;
smp->type = SMP_T_IPV6;
break;
default:
@ -1528,7 +1524,7 @@ smp_fetch_sport(struct proxy *px, struct session *l4, void *l7, unsigned int opt
const struct arg *args, struct sample *smp)
{
smp->type = SMP_T_UINT;
if (!(smp->data.uint = get_host_port(&l4->si[0].addr.from)))
if (!(smp->data.uint = get_host_port(&l4->si[0].conn.addr.from)))
return 0;
smp->flags = 0;
@ -1540,15 +1536,15 @@ static int
smp_fetch_dst(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
const struct arg *args, struct sample *smp)
{
si_get_to_addr(&l4->si[0]);
conn_get_to_addr(&l4->si[0].conn);
switch (l4->si[0].addr.to.ss_family) {
switch (l4->si[0].conn.addr.to.ss_family) {
case AF_INET:
smp->data.ipv4 = ((struct sockaddr_in *)&l4->si[0].addr.to)->sin_addr;
smp->data.ipv4 = ((struct sockaddr_in *)&l4->si[0].conn.addr.to)->sin_addr;
smp->type = SMP_T_IPV4;
break;
case AF_INET6:
smp->data.ipv6 = ((struct sockaddr_in6 *)(&l4->si[0].addr.to))->sin6_addr;
smp->data.ipv6 = ((struct sockaddr_in6 *)(&l4->si[0].conn.addr.to))->sin6_addr;
smp->type = SMP_T_IPV6;
break;
default:
@ -1564,10 +1560,10 @@ static int
smp_fetch_dport(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
const struct arg *args, struct sample *smp)
{
si_get_to_addr(&l4->si[0]);
conn_get_to_addr(&l4->si[0].conn);
smp->type = SMP_T_UINT;
if (!(smp->data.uint = get_host_port(&l4->si[0].addr.to)))
if (!(smp->data.uint = get_host_port(&l4->si[0].conn.addr.to)))
return 0;
smp->flags = 0;

View File

@ -87,9 +87,7 @@ int session_accept(struct listener *l, int cfd, struct sockaddr_storage *addr)
s->si[0].conn.t.sock.fd = cfd;
s->si[0].conn.ctrl = l->proto;
s->si[0].conn.flags = CO_FL_NONE | CO_FL_NOTIFY_SI; /* we're on a stream_interface */
s->si[0].addr.from = *addr;
s->si[0].conn.peeraddr = (struct sockaddr *)&s->si[0].addr.from;
s->si[0].conn.peerlen = sizeof(s->si[0].addr.from);
s->si[0].conn.addr.from = *addr;
s->logs.accept_date = date; /* user-visible date for logging */
s->logs.tv_accept = now; /* corrected date for internal use */
s->uniq_id = totalconn;

View File

@ -504,7 +504,7 @@ int conn_si_send_proxy(struct connection *conn, unsigned int flag)
* (which is recomputed every time since it's constant). If
* it is positive, it means we have to send from the start.
*/
ret = make_proxy_line(trash, trashlen, &si->ob->prod->addr.from, &si->ob->prod->addr.to);
ret = make_proxy_line(trash, trashlen, &si->ob->prod->conn.addr.from, &si->ob->prod->conn.addr.to);
if (!ret)
goto out_error;