@@ -100,6 +100,14 @@ private static InetAddress doResolve(AgentSpanContext.Extracted context, Mutable
100100 result = coalesce (result , addr );
101101 }
102102
103+ addr = tryHeader (context .getForwarded (), FORWARDED_PARSER );
104+ if (addr != null ) {
105+ if (!isIpAddrPrivate (addr )) {
106+ return addr ;
107+ }
108+ result = coalesce (result , addr );
109+ }
110+
103111 addr = tryHeader (context .getXClusterClientIp (), PLAIN_IP_ADDRESS_PARSER );
104112 if (addr != null ) {
105113 if (!isIpAddrPrivate (addr )) {
@@ -196,95 +204,99 @@ enum ForwardedParseState {
196204
197205 @ Override
198206 public InetAddress apply (String headerValue ) {
199- InetAddress resultPrivate = null ;
200- ForwardedParseState state = ForwardedParseState .BETWEEN ;
201-
202- // https://datatracker.ietf.org/doc/html/rfc7239#section-4
203- int pos = 0 ;
204- int end = headerValue .length ();
205- // compiler requires that these two be initialized:
206- int start = 0 ;
207- boolean considerValue = false ;
208- while (pos < end ) {
209- char c = headerValue .charAt (pos );
210- switch (state ) {
211- case BETWEEN :
212- if (c == ' ' || c == ';' || c == ',' ) {
213- break ;
214- }
215- start = pos ;
216- state = ForwardedParseState .KEY ;
217- break ;
218- case KEY :
219- if (c != '=' ) {
207+ String [] entries = headerValue .split ("," );
208+ for (int i = entries .length - 1 ; i >= 0 ; i --) {
209+ String entry = entries [i ].trim ();
210+ InetAddress resultPrivate = null ;
211+ ForwardedParseState state = ForwardedParseState .BETWEEN ;
212+ // https://datatracker.ietf.org/doc/html/rfc7239#section-4
213+ int pos = 0 ;
214+ int end = entry .length ();
215+ // compiler requires that these two be initialized:
216+ int start = 0 ;
217+ boolean considerValue = false ;
218+ while (pos < end ) {
219+ char c = entry .charAt (pos );
220+ switch (state ) {
221+ case BETWEEN :
222+ if (c == ' ' || c == ';' || c == ',' ) {
223+ break ;
224+ }
225+ start = pos ;
226+ state = ForwardedParseState .KEY ;
220227 break ;
221- }
228+ case KEY :
229+ if (c != '=' ) {
230+ break ;
231+ }
222232
223- state = ForwardedParseState .BEFORE_VALUE ;
224- if (pos - start == 3 ) {
225- String key = headerValue .substring (start , pos );
226- considerValue = key .equalsIgnoreCase ("for" );
227- } else {
228- considerValue = false ;
229- }
230- break ;
231- case BEFORE_VALUE :
232- if (c == '"' ) {
233- start = pos + 1 ;
234- state = ForwardedParseState .VALUE_QUOTED ;
235- } else if (c == ' ' || c == ';' || c == ',' ) {
236- // empty value
237- state = ForwardedParseState .BETWEEN ;
238- } else {
239- start = pos ;
240- state = ForwardedParseState .VALUE_TOKEN ;
241- }
242- break ;
243- case VALUE_TOKEN :
244- {
245- int tokenEnd ;
246- if (c == ' ' || c == ';' || c == ',' ) {
247- tokenEnd = pos ;
248- } else if (pos + 1 == end ) {
249- tokenEnd = end ;
233+ state = ForwardedParseState .BEFORE_VALUE ;
234+ if (pos - start == 3 ) {
235+ String key = entry .substring (start , pos );
236+ considerValue = key .equalsIgnoreCase ("for" );
250237 } else {
251- break ;
238+ considerValue = false ;
239+ }
240+ break ;
241+ case BEFORE_VALUE :
242+ if (c == '"' ) {
243+ start = pos + 1 ;
244+ state = ForwardedParseState .VALUE_QUOTED ;
245+ } else if (c == ' ' || c == ';' || c == ',' ) {
246+ // empty value
247+ state = ForwardedParseState .BETWEEN ;
248+ } else {
249+ start = pos ;
250+ state = ForwardedParseState .VALUE_TOKEN ;
252251 }
252+ break ;
253+ case VALUE_TOKEN :
254+ {
255+ int tokenEnd ;
256+ if (c == ' ' || c == ';' || c == ',' ) {
257+ tokenEnd = pos ;
258+ } else if (pos + 1 == end ) {
259+ tokenEnd = end ;
260+ } else {
261+ break ;
262+ }
253263
254- if (considerValue ) {
255- InetAddress ipAddr =
256- parseIpAddressAndMaybePort (headerValue .substring (start , tokenEnd ));
257- if (ipAddr != null ) {
258- if (isIpAddrPrivate (ipAddr )) {
259- if (resultPrivate == null ) {
260- resultPrivate = ipAddr ;
264+ if (considerValue ) {
265+ InetAddress ipAddr = parseIpAddressAndMaybePort (entry .substring (start , tokenEnd ));
266+ if (ipAddr != null ) {
267+ if (isIpAddrPrivate (ipAddr )) {
268+ if (resultPrivate == null ) {
269+ resultPrivate = ipAddr ;
270+ }
271+ } else {
272+ return ipAddr ;
261273 }
262- } else {
263- return ipAddr ;
264274 }
265275 }
276+ state = ForwardedParseState .BETWEEN ;
277+ break ;
266278 }
267- state = ForwardedParseState .BETWEEN ;
268- break ;
269- }
270- case VALUE_QUOTED :
271- if (c == '"' ) {
272- if (considerValue ) {
273- InetAddress ipAddr = parseIpAddressAndMaybePort (headerValue .substring (start , pos ));
274- if (ipAddr != null && !isIpAddrPrivate (ipAddr )) {
275- return ipAddr ;
279+ case VALUE_QUOTED :
280+ if (c == '"' ) {
281+ if (considerValue ) {
282+ InetAddress ipAddr = parseIpAddressAndMaybePort (entry .substring (start , pos ));
283+ if (ipAddr != null && !isIpAddrPrivate (ipAddr )) {
284+ return ipAddr ;
285+ }
276286 }
287+ state = ForwardedParseState .BETWEEN ;
288+ } else if (c == '\\' ) {
289+ pos ++;
277290 }
278- state = ForwardedParseState .BETWEEN ;
279- } else if (c == '\\' ) {
280- pos ++;
281- }
282- break ;
291+ break ;
292+ }
293+ pos ++;
294+ }
295+ if (resultPrivate != null ) {
296+ return resultPrivate ;
283297 }
284- pos ++;
285298 }
286-
287- return resultPrivate ;
299+ return null ;
288300 }
289301 }
290302
0 commit comments