diff --git a/include/proto/connection.h b/include/proto/connection.h index abc7e2226..7c8e2cb0d 100644 --- a/include/proto/connection.h +++ b/include/proto/connection.h @@ -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 */ /* diff --git a/include/proto/proto_tcp.h b/include/proto/proto_tcp.h index 6aadb5ae2..cdc1d3744 100644 --- a/include/proto/proto_tcp.h +++ b/include/proto/proto_tcp.h @@ -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; diff --git a/include/proto/stream_interface.h b/include/proto/stream_interface.h index 7536e95cd..8cd4a31bd 100644 --- a/include/proto/stream_interface.h +++ b/include/proto/stream_interface.h @@ -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) { diff --git a/include/types/connection.h b/include/types/connection.h index b1637307f..2612eaf92 100644 --- a/include/types/connection.h +++ b/include/types/connection.h @@ -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 */ diff --git a/include/types/stream_interface.h b/include/types/stream_interface.h index 9001c60a6..edc97d097 100644 --- a/include/types/stream_interface.h +++ b/include/types/stream_interface.h @@ -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 */ diff --git a/src/backend.c b/src/backend.c index 845c93b92..3cb10fe86 100644 --- a/src/backend.c +++ b/src/backend.c @@ -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); diff --git a/src/dumpstats.c b/src/dumpstats.c index 7728616d3..2e775d945 100644 --- a/src/dumpstats.c +++ b/src/dumpstats.c @@ -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= (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= (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 : "", target_srv(&curr_sess->target) ? target_srv(&curr_sess->target)->id : "" diff --git a/src/frontend.c b/src/frontend.c index 8b168360a..415960a51 100644 --- a/src/frontend.c +++ b/src/frontend.c @@ -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; diff --git a/src/log.c b/src/log.c index bdb0060d5..2d33856ec 100644 --- a/src/log.c +++ b/src/log.c @@ -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; diff --git a/src/peers.c b/src/peers.c index eb9b13b4b..6af5d9cb1 100644 --- a/src/peers.c +++ b/src/peers.c @@ -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; diff --git a/src/proto_http.c b/src/proto_http.c index 0344d965b..a5df1fd9e 100644 --- a/src/proto_http.c +++ b/src/proto_http.c @@ -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; diff --git a/src/proto_tcp.c b/src/proto_tcp.c index de7f4c5c0..b793df393 100644 --- a/src/proto_tcp.c +++ b/src/proto_tcp.c @@ -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; diff --git a/src/session.c b/src/session.c index b5c7645c3..07824191f 100644 --- a/src/session.c +++ b/src/session.c @@ -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; diff --git a/src/stream_interface.c b/src/stream_interface.c index 5776519a2..cb33476ed 100644 --- a/src/stream_interface.c +++ b/src/stream_interface.c @@ -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;