src/backend.c
int assign_server_address(struct session *s)
{
#ifdef DEBUG_FULL
	fprintf(stderr,"assign_server_address : s=%p\n",s);
#endif

	if ((s->flags & SN_DIRECT) || (s->be->lbprm.algo & BE_LB_KIND)) {
		/* A server is necessarily known for this session */
		if (!(s->flags & SN_ASSIGNED))
			return SRV_STATUS_INTERNAL;

		s->req->cons->conn->addr.to = objt_server(s->target)->addr;

		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))
				conn_get_to_addr(s->req->prod->conn);

			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;
			}
		}

		/* if this server remaps proxied ports, we'll use
		 * the port the client connected to with an offset. */
		if (objt_server(s->target)->state & SRV_MAPPORTS) {
			int base_port;

			if (!(s->be->options & PR_O_TRANSP))
				conn_get_to_addr(s->req->prod->conn);

			/* First, retrieve the port from the incoming connection */
			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->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->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 */
		conn_get_to_addr(s->req->prod->conn);

		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");
		//return SRV_STATUS_INTERNAL;
	}
	else if (s->be->options & PR_O_HTTP_PROXY) {
		/* If HTTP PROXY option is set, then server is already assigned
		 * during incoming client request parsing. */
	}
	else {
		/* no server and no LB algorithm ! */
		return SRV_STATUS_INTERNAL;
	}

	s->flags |= SN_ADDR_SET;
	return SRV_STATUS_OK;
}
/*
 * This function assigns a server address to a session, and sets SN_ADDR_SET.
 * The address is taken from the currently assigned server, or from the
 * dispatch or transparent address.
 *
 * It may return :
 *   SRV_STATUS_OK       if everything is OK.
 *   SRV_STATUS_INTERNAL for other unrecoverable errors.
 *
 * Upon successful return, the session flag SN_ADDR_SET is set. This flag is
 * not cleared, so it's to the caller to clear it if required.
 *
 */
This function assigns a server address to a session, and sets SN_ADDR_SET.
The address is taken from the currently assigned server, or from the
dispatch or transparent address.

It may return :
SRV_STATUS_OK       if everything is OK.
SRV_STATUS_INTERNAL for other unrecoverable errors.

Upon successful return, the session flag SN_ADDR_SET is set. This flag is
not cleared, so it's to the caller to clear it if required.
This function assigns a server address to a session and sets SN_ADDR_SET . The address is taken from the currently assigned server or from the dispatch or transparent address . It may return : SRV_STATUS_OK if everything is OK . SRV_STATUS_INTERNAL for other unrecoverable errors . Upon successful return the session flag SN_ADDR_SET is set . This flag is not cleared so it ' s to the caller to clear it if required .
int assign_server_address(struct session *s)
{
#ifdef DEBUG_FULL
	fprintf(stderr,"assign_server_address : s=%p\n",s);
#endif
	if ((s->flags & SN_DIRECT) || (s->be->lbprm.algo & BE_LB_KIND)) {
		if (!(s->flags & SN_ASSIGNED))
			return SRV_STATUS_INTERNAL;
		s->req->cons->conn->addr.to = objt_server(s->target)->addr;
		if (!is_addr(&s->req->cons->conn->addr.to)) {
			if (!(s->be->options & PR_O_TRANSP))
				conn_get_to_addr(s->req->prod->conn);
			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;
			}
		}
		if (objt_server(s->target)->state & SRV_MAPPORTS) {
			int base_port;
			if (!(s->be->options & PR_O_TRANSP))
				conn_get_to_addr(s->req->prod->conn);
			base_port = get_host_port(&s->req->prod->conn->addr.to);
			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) {
		s->req->cons->conn->addr.to = s->be->dispatch_addr;
	}
	else if (s->be->options & PR_O_TRANSP) {
		conn_get_to_addr(s->req->prod->conn);
		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)));
		}
	}
	else if (s->be->options & PR_O_HTTP_PROXY) {
	}
	else {
		return SRV_STATUS_INTERNAL;
	}
	s->flags |= SN_ADDR_SET;
	return SRV_STATUS_OK;
}
int assign_server_address ( struct session * s ) { #ifdef DEBUG_FULL fprintf ( stderr , " \n " , s ) ; #endif if ( ( s -> flags & SN_DIRECT ) || ( s -> be -> lbprm . algo & BE_LB_KIND ) ) { if ( ! ( s -> flags & SN_ASSIGNED ) ) return SRV_STATUS_INTERNAL ; s -> req -> cons -> conn -> addr . to = objt_server ( s -> target ) -> addr ; if ( ! is_addr ( & s -> req -> cons -> conn -> addr . to ) ) { if ( ! ( s -> be -> options & PR_O_TRANSP ) ) conn_get_to_addr ( s -> req -> prod -> conn ) ; 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 ; } } if ( objt_server ( s -> target ) -> state & SRV_MAPPORTS ) { int base_port ; if ( ! ( s -> be -> options & PR_O_TRANSP ) ) conn_get_to_addr ( s -> req -> prod -> conn ) ; base_port = get_host_port ( & s -> req -> prod -> conn -> addr . to ) ; 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 ) { s -> req -> cons -> conn -> addr . to = s -> be -> dispatch_addr ; } else if ( s -> be -> options & PR_O_TRANSP ) { conn_get_to_addr ( s -> req -> prod -> conn ) ; 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 ) ) ) ; } } else if ( s -> be -> options & PR_O_HTTP_PROXY ) { } else { return SRV_STATUS_INTERNAL ; } s -> flags |= SN_ADDR_SET ; return SRV_STATUS_OK ; }
This function assigns a server address to a session, and sets SN_ADDR_SET.
This function assigns a server address to a session and sets SN_ADDR_SET .
/* A server is necessarily known for this session */ /* 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 this server remaps proxied ports, we'll use
		 * the port the client connected to with an offset. */ /* First, retrieve the port from the incoming connection */ /* Second, assign the outgoing connection's port */ /* connect to the defined dispatch addr */ /* in transparent mode, use the original dest addr if no dispatch specified */ /* when we support IPv6 on the backend, we may add other tests */ //qfprintf(stderr, "Cannot get original server address.\n"); //return SRV_STATUS_INTERNAL; /* If HTTP PROXY option is set, then server is already assigned
		 * during incoming client request parsing. */ /* no server and no LB algorithm ! */