mirror of
https://git.haproxy.org/git/haproxy.git/
synced 2025-09-21 13:51:26 +02:00
[MEDIUM] store the original destination address in the session
There are multiple places where the client's destination address is required. Let's store it in the session when needed, and add a flag to inform that it has been retrieved.
This commit is contained in:
parent
d077a8e67c
commit
14c8aac63b
@ -2,7 +2,7 @@
|
|||||||
include/proto/client.h
|
include/proto/client.h
|
||||||
This file contains client-side definitions.
|
This file contains client-side definitions.
|
||||||
|
|
||||||
Copyright (C) 2000-2006 Willy Tarreau - w@1wt.eu
|
Copyright (C) 2000-2007 Willy Tarreau - w@1wt.eu
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
This library is free software; you can redistribute it and/or
|
||||||
modify it under the terms of the GNU Lesser General Public
|
modify it under the terms of the GNU Lesser General Public
|
||||||
@ -24,7 +24,9 @@
|
|||||||
|
|
||||||
#include <common/config.h>
|
#include <common/config.h>
|
||||||
#include <types/client.h>
|
#include <types/client.h>
|
||||||
|
#include <types/session.h>
|
||||||
|
|
||||||
|
void get_frt_addr(struct session *s);
|
||||||
int event_accept(int fd);
|
int event_accept(int fd);
|
||||||
|
|
||||||
|
|
||||||
|
@ -47,7 +47,7 @@
|
|||||||
#define SN_CONN_CLOSED 0x00000010 /* "Connection: close" was present or added */
|
#define SN_CONN_CLOSED 0x00000010 /* "Connection: close" was present or added */
|
||||||
#define SN_MONITOR 0x00000020 /* this session comes from a monitoring system */
|
#define SN_MONITOR 0x00000020 /* this session comes from a monitoring system */
|
||||||
#define SN_SELF_GEN 0x00000040 /* the proxy generates data for the client (eg: stats) */
|
#define SN_SELF_GEN 0x00000040 /* the proxy generates data for the client (eg: stats) */
|
||||||
/* unused: 0x00000080 */
|
#define SN_FRT_ADDR_SET 0x00000080 /* set if the frontend address has been filled */
|
||||||
|
|
||||||
/* session termination conditions, bits values 0x100 to 0x700 (0-7 shift 8) */
|
/* session termination conditions, bits values 0x100 to 0x700 (0-7 shift 8) */
|
||||||
#define SN_ERR_NONE 0x00000000
|
#define SN_ERR_NONE 0x00000000
|
||||||
@ -92,6 +92,7 @@ struct session {
|
|||||||
struct buffer *req; /* request buffer */
|
struct buffer *req; /* request buffer */
|
||||||
struct buffer *rep; /* response buffer */
|
struct buffer *rep; /* response buffer */
|
||||||
struct sockaddr_storage cli_addr; /* the client address */
|
struct sockaddr_storage cli_addr; /* the client address */
|
||||||
|
struct sockaddr_storage frt_addr; /* the frontend address reached by the client if SN_FRT_ADDR_SET is set */
|
||||||
struct sockaddr_in srv_addr; /* the address to connect to */
|
struct sockaddr_in srv_addr; /* the address to connect to */
|
||||||
struct server *srv; /* the server being used */
|
struct server *srv; /* the server being used */
|
||||||
struct pendconn *pend_pos; /* if not NULL, points to the position in the pending queue */
|
struct pendconn *pend_pos; /* if not NULL, points to the position in the pending queue */
|
||||||
|
@ -29,6 +29,7 @@
|
|||||||
#include <types/session.h>
|
#include <types/session.h>
|
||||||
|
|
||||||
#include <proto/backend.h>
|
#include <proto/backend.h>
|
||||||
|
#include <proto/client.h>
|
||||||
#include <proto/fd.h>
|
#include <proto/fd.h>
|
||||||
#include <proto/httperr.h>
|
#include <proto/httperr.h>
|
||||||
#include <proto/log.h>
|
#include <proto/log.h>
|
||||||
@ -235,13 +236,15 @@ int assign_server_address(struct session *s)
|
|||||||
/* if this server remaps proxied ports, we'll use
|
/* if this server remaps proxied ports, we'll use
|
||||||
* the port the client connected to with an offset. */
|
* the port the client connected to with an offset. */
|
||||||
if (s->srv->state & SRV_MAPPORTS) {
|
if (s->srv->state & SRV_MAPPORTS) {
|
||||||
struct sockaddr_in sockname;
|
if (!(s->fe->options & PR_O_TRANSP) && !(s->flags & SN_FRT_ADDR_SET))
|
||||||
socklen_t namelen = sizeof(sockname);
|
get_frt_addr(s);
|
||||||
|
if (s->frt_addr.ss_family == AF_INET) {
|
||||||
if (!(s->fe->options & PR_O_TRANSP) ||
|
s->srv_addr.sin_port = htons(ntohs(s->srv_addr.sin_port) +
|
||||||
get_original_dst(s->cli_fd, (struct sockaddr_in *)&sockname, &namelen) == -1)
|
ntohs(((struct sockaddr_in *)&s->frt_addr)->sin_port));
|
||||||
getsockname(s->cli_fd, (struct sockaddr *)&sockname, &namelen);
|
} else {
|
||||||
s->srv_addr.sin_port = htons(ntohs(s->srv_addr.sin_port) + ntohs(sockname.sin_port));
|
s->srv_addr.sin_port = htons(ntohs(s->srv_addr.sin_port) +
|
||||||
|
ntohs(((struct sockaddr_in6 *)&s->frt_addr)->sin6_port));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (*(int *)&s->be->dispatch_addr.sin_addr) {
|
else if (*(int *)&s->be->dispatch_addr.sin_addr) {
|
||||||
|
44
src/client.c
44
src/client.c
@ -43,6 +43,17 @@
|
|||||||
#include <proto/task.h>
|
#include <proto/task.h>
|
||||||
|
|
||||||
|
|
||||||
|
/* Retrieves the original destination address used by the client, and sets the
|
||||||
|
* SN_FRT_ADDR_SET flag.
|
||||||
|
*/
|
||||||
|
void get_frt_addr(struct session *s)
|
||||||
|
{
|
||||||
|
socklen_t namelen = sizeof(s->frt_addr);
|
||||||
|
|
||||||
|
if (get_original_dst(s->cli_fd, (struct sockaddr_in *)&s->frt_addr, &namelen) == -1)
|
||||||
|
getsockname(s->cli_fd, (struct sockaddr *)&s->frt_addr, &namelen);
|
||||||
|
s->flags |= SN_FRT_ADDR_SET;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* FIXME: This should move to the STREAM_SOCK code then split into TCP and HTTP.
|
* FIXME: This should move to the STREAM_SOCK code then split into TCP and HTTP.
|
||||||
@ -263,14 +274,6 @@ int event_accept(int fd) {
|
|||||||
|
|
||||||
if ((p->mode == PR_MODE_TCP || p->mode == PR_MODE_HTTP)
|
if ((p->mode == PR_MODE_TCP || p->mode == PR_MODE_HTTP)
|
||||||
&& (p->logfac1 >= 0 || p->logfac2 >= 0)) {
|
&& (p->logfac1 >= 0 || p->logfac2 >= 0)) {
|
||||||
struct sockaddr_storage sockname;
|
|
||||||
socklen_t namelen = sizeof(sockname);
|
|
||||||
|
|
||||||
if (addr.ss_family != AF_INET ||
|
|
||||||
!(s->fe->options & PR_O_TRANSP) ||
|
|
||||||
get_original_dst(cfd, (struct sockaddr_in *)&sockname, &namelen) == -1)
|
|
||||||
getsockname(cfd, (struct sockaddr *)&sockname, &namelen);
|
|
||||||
|
|
||||||
if (p->to_log) {
|
if (p->to_log) {
|
||||||
/* we have the client ip */
|
/* we have the client ip */
|
||||||
if (s->logs.logwait & LW_CLIP)
|
if (s->logs.logwait & LW_CLIP)
|
||||||
@ -279,38 +282,43 @@ int event_accept(int fd) {
|
|||||||
}
|
}
|
||||||
else if (s->cli_addr.ss_family == AF_INET) {
|
else if (s->cli_addr.ss_family == AF_INET) {
|
||||||
char pn[INET_ADDRSTRLEN], sn[INET_ADDRSTRLEN];
|
char pn[INET_ADDRSTRLEN], sn[INET_ADDRSTRLEN];
|
||||||
if (inet_ntop(AF_INET, (const void *)&((struct sockaddr_in *)&sockname)->sin_addr,
|
|
||||||
|
if (!(s->flags & SN_FRT_ADDR_SET))
|
||||||
|
get_frt_addr(s);
|
||||||
|
|
||||||
|
if (inet_ntop(AF_INET, (const void *)&((struct sockaddr_in *)&s->frt_addr)->sin_addr,
|
||||||
sn, sizeof(sn)) &&
|
sn, sizeof(sn)) &&
|
||||||
inet_ntop(AF_INET, (const void *)&((struct sockaddr_in *)&s->cli_addr)->sin_addr,
|
inet_ntop(AF_INET, (const void *)&((struct sockaddr_in *)&s->cli_addr)->sin_addr,
|
||||||
pn, sizeof(pn))) {
|
pn, sizeof(pn))) {
|
||||||
send_log(p, LOG_INFO, "Connect from %s:%d to %s:%d (%s/%s)\n",
|
send_log(p, LOG_INFO, "Connect from %s:%d to %s:%d (%s/%s)\n",
|
||||||
pn, ntohs(((struct sockaddr_in *)&s->cli_addr)->sin_port),
|
pn, ntohs(((struct sockaddr_in *)&s->cli_addr)->sin_port),
|
||||||
sn, ntohs(((struct sockaddr_in *)&sockname)->sin_port),
|
sn, ntohs(((struct sockaddr_in *)&s->frt_addr)->sin_port),
|
||||||
p->id, (p->mode == PR_MODE_HTTP) ? "HTTP" : "TCP");
|
p->id, (p->mode == PR_MODE_HTTP) ? "HTTP" : "TCP");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
char pn[INET6_ADDRSTRLEN], sn[INET6_ADDRSTRLEN];
|
char pn[INET6_ADDRSTRLEN], sn[INET6_ADDRSTRLEN];
|
||||||
if (inet_ntop(AF_INET6, (const void *)&((struct sockaddr_in6 *)&sockname)->sin6_addr,
|
|
||||||
|
if (!(s->flags & SN_FRT_ADDR_SET))
|
||||||
|
get_frt_addr(s);
|
||||||
|
|
||||||
|
if (inet_ntop(AF_INET6, (const void *)&((struct sockaddr_in6 *)&s->frt_addr)->sin6_addr,
|
||||||
sn, sizeof(sn)) &&
|
sn, sizeof(sn)) &&
|
||||||
inet_ntop(AF_INET6, (const void *)&((struct sockaddr_in6 *)&s->cli_addr)->sin6_addr,
|
inet_ntop(AF_INET6, (const void *)&((struct sockaddr_in6 *)&s->cli_addr)->sin6_addr,
|
||||||
pn, sizeof(pn))) {
|
pn, sizeof(pn))) {
|
||||||
send_log(p, LOG_INFO, "Connect from %s:%d to %s:%d (%s/%s)\n",
|
send_log(p, LOG_INFO, "Connect from %s:%d to %s:%d (%s/%s)\n",
|
||||||
pn, ntohs(((struct sockaddr_in6 *)&s->cli_addr)->sin6_port),
|
pn, ntohs(((struct sockaddr_in6 *)&s->cli_addr)->sin6_port),
|
||||||
sn, ntohs(((struct sockaddr_in6 *)&sockname)->sin6_port),
|
sn, ntohs(((struct sockaddr_in6 *)&s->frt_addr)->sin6_port),
|
||||||
p->id, (p->mode == PR_MODE_HTTP) ? "HTTP" : "TCP");
|
p->id, (p->mode == PR_MODE_HTTP) ? "HTTP" : "TCP");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((global.mode & MODE_DEBUG) && (!(global.mode & MODE_QUIET) || (global.mode & MODE_VERBOSE))) {
|
if ((global.mode & MODE_DEBUG) && (!(global.mode & MODE_QUIET) || (global.mode & MODE_VERBOSE))) {
|
||||||
struct sockaddr_in sockname;
|
|
||||||
socklen_t namelen = sizeof(sockname);
|
|
||||||
int len;
|
int len;
|
||||||
if (addr.ss_family != AF_INET ||
|
|
||||||
!(s->fe->options & PR_O_TRANSP) ||
|
if (!(s->flags & SN_FRT_ADDR_SET))
|
||||||
get_original_dst(cfd, (struct sockaddr_in *)&sockname, &namelen) == -1)
|
get_frt_addr(s);
|
||||||
getsockname(cfd, (struct sockaddr *)&sockname, &namelen);
|
|
||||||
|
|
||||||
if (s->cli_addr.ss_family == AF_INET) {
|
if (s->cli_addr.ss_family == AF_INET) {
|
||||||
char pn[INET_ADDRSTRLEN];
|
char pn[INET_ADDRSTRLEN];
|
||||||
|
Loading…
x
Reference in New Issue
Block a user