blob: 3f5e43219c8c5e04902c51e1cf0192b9d74b1ffe [file] [log] [blame]
Willy Tarreauc14b7d92014-06-19 16:03:41 +020012013/10/10 - possibilities for setting source and destination addresses
2
3
4When establishing a connection to a remote device, this device is designated
5as a target, which designates an entity defined in the configuration. A same
6target appears only once in a configuration, and multiple targets may share
7the same settings if needed.
8
9The following types of targets are currently supported :
10
11 - listener : all connections with this type of target come from clients ;
12 - server : connections to such targets are for "server" lines ;
13 - peer : connections to such target address "peer" lines in "peers"
14 sections ;
15 - proxy : these targets are used by "dispatch", "option transparent"
16 or "option http_proxy" statements.
17
18A connection might not be reused between two different targets, even if all
19parameters seem similar. One of the reason is that some parameters are specific
20to the target and are not easy or not cheap to compare (eg: bind to interface,
21mss, ...).
22
23A number of source and destination addresses may be set for a given target.
24
25 - listener :
26 - the "from" address:port is set by accept()
27
28 - the "to" address:port is set if conn_get_to_addr() is called
29
30 - peer :
31 - the "from" address:port is not set
32
33 - the "to" address:port is static and dependent only on the peer
34
35 - server :
36 - the "from" address may be set alone when "source" is used with
37 a forced IP address, or when "usesrc clientip" is used.
38
39 - the "from" port may be set only combined with the address when
40 "source" is used with IP:port, IP:port-range or "usesrc client" is
41 used. Note that in this case, both the address and the port may be
42 0, meaning that the kernel will pick the address or port and that
43 the final value might not match the one explicitly set (eg:
44 important for logging).
45
46 - the "from" address may be forced from a header which implies it
47 may change between two consecutive requests on the same connection.
48
49 - the "to" address and port are set together when connecting to a
50 regular server, or by copying the client's IP address when
51 "server 0.0.0.0" is used. Note that the destination port may be
52 an offset applied to the original destination port.
53
54 - proxy :
55 - the "from" address may be set alone when "source" is used with a
56 forced IP address or when "usesrc clientip" is used.
57
58 - the "from" port may be set only combined with the address when
59 "source" is used with IP:port or with "usesrc client". There is
60 no ip:port range for a proxy as of now. Same comment applies as
61 above when port and/or address are 0.
62
63 - the "from" address may be forced from a header which implies it
64 may change between two consecutive requests on the same connection.
65
66 - the "to" address and port are set together, either by configuration
67 when "dispatch" is used, or dynamically when "transparent" is used
68 (1:1 with client connection) or "option http_proxy" is used, where
69 each client request may lead to a different destination address.
70
71
72At the moment, there are some limits in what might happen between multiple
73concurrent requests to a same target.
74
75 - peers parameter do not change, so no problem.
76
77 - server parameters may change in this way :
78 - a connection may require a source bound to an IP address found in a
79 header, which will fall back to the "source" settings if the address
80 is not found in this header. This means that the source address may
81 switch between a dynamically forced IP address and another forced
82 IP and/or port range.
83
84 - if the element is not found (eg: header), the remaining "forced"
85 source address might very well be empty (unset), so the connection
86 reuse is acceptable when switching in that direction.
87
88 - it is not possible to switch between client and clientip or any of
89 these and hdr_ip() because they're exclusive.
90
91 - using a source address/port belonging to a port range is compatible
92 with connection reuse because there is a single range per target, so
93 switching from a range to another range means we remain in the same
94 range.
95
96 - destination address may currently not change since the only possible
97 case for dynamic destination address setting is the transparent mode,
98 reproducing the client's destination address.
99
100 - proxy parameters may change in this way :
101 - a connection may require a source bound to an IP address found in a
102 header, which will fall back to the "source" settings if the address
103 is not found in this header. This means that the source address may
104 switch between a dynamically forced IP address and another forced
105 IP and/or port range.
106
107 - if the element is not found (eg: header), the remaining "forced"
108 source address might very well be empty (unset), so the connection
109 reuse is acceptable when switching in that direction.
110
111 - it is not possible to switch between client and clientip or any of
112 these and hdr_ip() because they're exclusive.
113
114 - proxies do not support port ranges at the moment.
115
116 - destination address might change in the case where "option http_proxy"
117 is used.
118
119So, for each source element (IP, port), we want to know :
120 - if the element was assigned by static configuration (eg: ":80")
121 - if the element was assigned from a connection-specific value (eg: usesrc clientip)
122 - if the element was assigned from a configuration-specific range (eg: 1024-65535)
123 - if the element was assigned from a request-specific value (eg: hdr_ip(xff))
124 - if the element was not assigned at all
125
126For the destination, we want to know :
127 - if the element was assigned by static configuration (eg: ":80")
128 - if the element was assigned from a connection-specific value (eg: transparent)
129 - if the element was assigned from a request-specific value (eg: http_proxy)
130
131We don't need to store the information about the origin of the dynamic value
132since we have the value itself. So in practice we have :
133 - default value, unknown (not yet checked with getsockname/getpeername)
134 - default value, known (check done)
135 - forced value (known)
136 - forced range (known)
137
138We can't do that on an ip:port basis because the port may be fixed regardless
139of the address and conversely.
140
141So that means :
142
143 enum {
144 CO_ADDR_NONE = 0, /* not set, unknown value */
145 CO_ADDR_KNOWN = 1, /* not set, known value */
146 CO_ADDR_FIXED = 2, /* fixed value, known */
147 CO_ADDR_RANGE = 3, /* from assigned range, known */
148 } conn_addr_values;
149
150 unsigned int new_l3_src_status:2;
151 unsigned int new_l4_src_status:2;
152 unsigned int new_l3_dst_status:2;
153 unsigned int new_l4_dst_status:2;
154
155 unsigned int cur_l3_src_status:2;
156 unsigned int cur_l4_src_status:2;
157 unsigned int cur_l3_dsp_status:2;
158 unsigned int cur_l4_dst_status:2;
159
160 unsigned int new_family:2;
161 unsigned int cur_family:2;
162
163Note: this obsoletes CO_FL_ADDR_FROM_SET and CO_FL_ADDR_TO_SET. These flags
164must be changed to individual l3+l4 checks ORed between old and new values,
165or better, set to cur only which will inherit new.
166
167In the connection, these values may be merged in the same word as err_code.