The apparent remote address for a proxy connection is the gateway, but
in fact the information is going to some remote server. Therefore, once
we've identified a proxy connection, overwrite the remote address in
the query with the true remote host.
This means fixing up the query structure with the gateway address next
time, so keep track of the connection remote address and restore it on
each query.
* query is our gateway then don't check the remote address in the
* field (but do check the port number).
*/
* query is our gateway then don't check the remote address in the
* field (but do check the port number).
*/
- if (q->ao->sys->parseaddr(&p, &s[0].addr)) goto next_row;
+ if (q->ao->sys->parseaddr(&p, &s[i].addr)) goto next_row;
if (*p != ':') break; p++;
if (*p != ':') break; p++;
- s[0].port = strtoul(p, 0, 16);
+ s[i].port = strtoul(p, 0, 16);
- q->s[R].port != s[0].port :
- !sockeq(q->ao, &q->s[i], &s[0]))
+ q->s[R].port != s[i].port :
+ !sockeq(q->ao, &q->s[i], &s[i]))
goto next_row;
}
/* We got to the end, and everything matched. If we found a UID then
goto next_row;
}
/* We got to the end, and everything matched. If we found a UID then
+ * we're done. If the apparent remote address is our gateway then copy
+ * the true one into the query structure.
*/
if (uid != -1) {
q->resp = R_UID;
q->u.uid = uid;
*/
if (uid != -1) {
q->resp = R_UID;
q->u.uid = uid;
+ if (gwp) q->s[R].addr = s[i].addr;
struct client {
int fd; /* The connection to the client */
selbuf b; /* Accumulate lines of input */
struct client {
int fd; /* The connection to the client */
selbuf b; /* Accumulate lines of input */
+ union addr raddr; /* Remote address */
struct query q; /* The clients query and our reply */
struct sel_timer t; /* Timeout for idle or doomed conn */
struct listen *l; /* Back to the listener (and ops) */
struct query q; /* The clients query and our reply */
struct sel_timer t; /* Timeout for idle or doomed conn */
struct listen *l; /* Back to the listener (and ops) */
skipws(&q); if (*q) goto bad;
/* Identify the connection. Act on the result. */
skipws(&q); if (*q) goto bad;
/* Identify the connection. Act on the result. */
+ c->q.s[R].addr = c->raddr;
identify(&c->q);
switch (c->q.resp) {
identify(&c->q);
switch (c->q.resp) {
c->q.ao = l->ao;
/* Collect the local and remote addresses. */
c->q.ao = l->ao;
/* Collect the local and remote addresses. */
- l->ao->sockaddr_to_addr(&ssr, &c->q.s[R].addr);
+ l->ao->sockaddr_to_addr(&ssr, &c->raddr);
ssz = sizeof(ssl);
if (getsockname(sk, (struct sockaddr *)&ssl, &ssz)) {
logmsg(0, LOG_ERR,
ssz = sizeof(ssl);
if (getsockname(sk, (struct sockaddr *)&ssl, &ssz)) {
logmsg(0, LOG_ERR,