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