Elements.cc
Go to the documentation of this file.
1/*
2 * Copyright (C) 1996-2023 The Squid Software Foundation and contributors
3 *
4 * Squid software is distributed under GPLv2+ license and includes
5 * contributions from numerous individuals and organizations.
6 * Please see the COPYING and CONTRIBUTORS files for details.
7 */
8
9#include "squid.h"
10#include "parser/Tokenizer.h"
11#include "proxyp/Elements.h"
12#include "sbuf/Stream.h"
13
14#include <algorithm>
15#include <limits>
16#include <vector>
17
18namespace ProxyProtocol {
19namespace Two {
20
22typedef std::vector< std::pair<SBuf, FieldType> > FieldMap;
24 { SBuf(":version"), htPseudoVersion },
25 { SBuf(":command"), htPseudoCommand },
26 { SBuf(":src_addr"), htPseudoSrcAddr },
27 { SBuf(":dst_addr"), htPseudoDstAddr },
28 { SBuf(":src_port"), htPseudoSrcPort },
29 { SBuf(":dst_port"), htPseudoDstPort }
30};
31
32} // namespace Two
33
34static Two::FieldType NameToFieldType(const SBuf &);
36
37} // namespace ProxyProtocol
38
39const SBuf &
41{
42 const auto it = std::find_if(Two::PseudoHeaderFields.begin(), Two::PseudoHeaderFields.end(),
43 [fieldType](const Two::FieldMap::value_type &item) {
44 return item.second == fieldType;
45 });
46
48 return it->first;
49}
50
54{
55 const auto it = std::find_if(Two::PseudoHeaderFields.begin(), Two::PseudoHeaderFields.end(),
56 [&name](const Two::FieldMap::value_type &item) {
57 return item.first == name;
58 });
59
60 if (it != Two::PseudoHeaderFields.end())
61 return it->second;
62
63 static const SBuf pseudoMark(":");
64 if (name.startsWith(pseudoMark))
65 throw TexcHere(ToSBuf("Unsupported PROXY protocol pseudo header: ", name));
66
67 throw TexcHere(ToSBuf("Invalid PROXY protocol pseudo header or TLV type name. ",
68 "Expected a pseudo header like :src_addr but got '", name, "'"));
69}
70
74{
75 int64_t tlvType = 0;
76
77 Parser::Tokenizer ptok(rawInteger);
78 if (ptok.skip('0')) {
79 if (!ptok.atEnd())
80 throw TexcHere(ToSBuf("Invalid PROXY protocol TLV type value. ",
81 "Expected a decimal integer without leading zeros but got '",
82 rawInteger, "'")); // e.g., 077, 0xFF, or 0b101
83 // tlvType stays zero
84 } else {
85 Must(ptok.int64(tlvType, 10, false)); // the first character is a DIGIT
86 if (!ptok.atEnd())
87 throw TexcHere(ToSBuf("Invalid PROXY protocol TLV type value. ",
88 "Trailing garbage after ", tlvType, " in '",
89 rawInteger, "'")); // e.g., 1.0 or 5e0
90 }
91
92 const auto limit = std::numeric_limits<uint8_t>::max();
93 if (tlvType > limit)
94 throw TexcHere(ToSBuf("Invalid PROXY protocol TLV type value. ",
95 "Expected an integer less than ", limit,
96 " but got '", tlvType, "'"));
97
98 return Two::FieldType(tlvType);
99}
100
103{
104 // we could branch on ":" instead of DIGIT but then field names that lack a
105 // leading ":" (like "version") would get a less accurate error message
106 return Parser::Tokenizer(tlvTypeRaw).skipOne(CharacterSet::DIGIT) ?
107 IntegerToFieldType(tlvTypeRaw):
108 NameToFieldType(tlvTypeRaw);
109}
110
#define TexcHere(msg)
legacy convenience macro; it is not difficult to type Here() now
Definition: TextException.h:63
#define Must(condition)
Definition: TextException.h:75
#define assert(EX)
Definition: assert.h:17
static const CharacterSet DIGIT
Definition: CharacterSet.h:84
bool skipOne(const CharacterSet &discardables)
Definition: Tokenizer.cc:161
bool int64(int64_t &result, int base=0, bool allowSign=true, SBuf::size_type limit=SBuf::npos)
Definition: Tokenizer.cc:238
bool atEnd() const
whether the end of the buffer has been reached
Definition: Tokenizer.h:41
bool skip(const SBuf &tokenToSkip)
Definition: Tokenizer.cc:189
Definition: SBuf.h:94
bool startsWith(const SBuf &S, const SBufCaseSensitive isCaseSensitive=caseSensitive) const
Definition: SBuf.cc:442
A const & max(A const &lhs, A const &rhs)
static const FieldMap PseudoHeaderFields
Definition: Elements.cc:23
std::vector< std::pair< SBuf, FieldType > > FieldMap
a mapping between pseudo header names and ids
Definition: Elements.cc:22
FieldType
numeric IDs of registered PROXY protocol TLV types and pseudo headers
Definition: Elements.h:19
static Two::FieldType NameToFieldType(const SBuf &)
FieldNameToFieldType() helper that handles pseudo headers.
Definition: Elements.cc:53
const SBuf & PseudoFieldTypeToFieldName(const Two::FieldType)
Definition: Elements.cc:40
static Two::FieldType IntegerToFieldType(const SBuf &)
FieldNameToFieldType() helper that handles integer TLV types.
Definition: Elements.cc:73
Two::FieldType FieldNameToFieldType(const SBuf &nameOrId)
Definition: Elements.cc:102
SBuf ToSBuf(Args &&... args)
slowly stream-prints all arguments into a freshly allocated SBuf
Definition: Stream.h:63

 

Introduction

Documentation

Support

Miscellaneous

Web Site Translations

Mirrors