]>
Commit | Line | Data |
---|---|---|
36c774f7 | 1 | /* |
f70aedc4 | 2 | * Copyright (C) 1996-2021 The Squid Software Foundation and contributors |
36c774f7 EB |
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" | |
e015580e | 10 | #include "base/EnumIterator.h" |
36c774f7 EB |
11 | #include "proxyp/Elements.h" |
12 | #include "proxyp/Header.h" | |
13 | #include "sbuf/Stream.h" | |
14 | #include "sbuf/StringConvert.h" | |
15 | #include "SquidConfig.h" | |
16 | #include "StrList.h" | |
17 | ||
18 | ProxyProtocol::Header::Header(const SBuf &ver, const Two::Command cmd): | |
19 | version_(ver), | |
20 | command_(cmd), | |
21 | ignoreAddresses_(false) | |
22 | {} | |
23 | ||
24 | SBuf | |
25 | ProxyProtocol::Header::toMime() const | |
26 | { | |
27 | SBufStream result; | |
e015580e EB |
28 | for (const auto fieldType: EnumRange(Two::htPseudoBegin, Two::htPseudoEnd)) { |
29 | const auto value = getValues(fieldType); | |
36c774f7 | 30 | if (!value.isEmpty()) |
e015580e | 31 | result << PseudoFieldTypeToFieldName(fieldType) << ": " << value << "\r\n"; |
36c774f7 EB |
32 | } |
33 | // cannot reuse Header::getValues(): need the original TLVs layout | |
34 | for (const auto &tlv: tlvs) | |
35 | result << tlv.type << ": " << tlv.value << "\r\n"; | |
36 | return result.buf(); | |
37 | } | |
38 | ||
39 | SBuf | |
40 | ProxyProtocol::Header::getValues(const uint32_t headerType, const char sep) const | |
41 | { | |
42 | switch (headerType) { | |
43 | ||
44 | case Two::htPseudoVersion: | |
45 | return version_; | |
46 | ||
47 | case Two::htPseudoCommand: | |
48 | return ToSBuf(command_); | |
49 | ||
50 | case Two::htPseudoSrcAddr: { | |
51 | if (!hasAddresses()) | |
52 | return SBuf(); | |
53 | auto logAddr = sourceAddress; | |
54 | logAddr.applyClientMask(Config.Addrs.client_netmask); | |
55 | char ipBuf[MAX_IPSTRLEN]; | |
56 | return SBuf(logAddr.toStr(ipBuf, sizeof(ipBuf))); | |
57 | } | |
58 | ||
59 | case Two::htPseudoDstAddr: { | |
60 | if (!hasAddresses()) | |
61 | return SBuf(); | |
62 | char ipBuf[MAX_IPSTRLEN]; | |
63 | return SBuf(destinationAddress.toStr(ipBuf, sizeof(ipBuf))); | |
64 | } | |
65 | ||
66 | case Two::htPseudoSrcPort: { | |
67 | return hasAddresses() ? ToSBuf(sourceAddress.port()) : SBuf(); | |
68 | } | |
69 | ||
70 | case Two::htPseudoDstPort: { | |
71 | return hasAddresses() ? ToSBuf(destinationAddress.port()) : SBuf(); | |
72 | } | |
73 | ||
74 | default: { | |
75 | SBufStream result; | |
76 | for (const auto &m: tlvs) { | |
77 | if (m.type == headerType) { | |
78 | // XXX: result.tellp() always returns -1 | |
79 | if (!result.buf().isEmpty()) | |
80 | result << sep; | |
81 | result << m.value; | |
82 | } | |
83 | } | |
84 | return result.buf(); | |
85 | } | |
86 | } | |
87 | } | |
88 | ||
89 | SBuf | |
90 | ProxyProtocol::Header::getElem(const uint32_t headerType, const char *member, const char sep) const | |
91 | { | |
92 | const auto whole = SBufToString(getValues(headerType, sep)); | |
93 | return getListMember(whole, member, sep); | |
94 | } | |
95 | ||
96 | const SBuf & | |
97 | ProxyProtocol::Header::addressFamily() const | |
98 | { | |
99 | static const SBuf v4("4"); | |
100 | static const SBuf v6("6"); | |
101 | static const SBuf vMix("mix"); | |
102 | return | |
103 | (sourceAddress.isIPv6() && destinationAddress.isIPv6()) ? v6 : | |
104 | (sourceAddress.isIPv4() && destinationAddress.isIPv4()) ? v4 : | |
105 | vMix; | |
106 | } | |
107 |