]> git.ipfire.org Git - thirdparty/squid.git/blame - src/adaptation/ecap/Host.cc
transaction_initiator ACL for detecting various unusual transactions
[thirdparty/squid.git] / src / adaptation / ecap / Host.cc
CommitLineData
b510f3a1 1/*
4ac4a490 2 * Copyright (C) 1996-2017 The Squid Software Foundation and contributors
bbc27441
AJ
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.
b510f3a1 7 */
bbc27441
AJ
8
9/* DEBUG: section 93 eCAP Interface */
10
582c2af2 11#include "squid.h"
fdc96a39 12#include <libecap/adapter/service.h>
530f96dd 13#include <libecap/common/names.h>
76fc7e57 14#include <libecap/common/registry.h>
1f3c65fc 15#include "adaptation/ecap/Host.h"
cc7b2f6c 16#include "adaptation/ecap/MessageRep.h"
602d9612
A
17#include "adaptation/ecap/ServiceRep.h"
18#include "base/TextException.h"
cc7b2f6c 19#include "HttpReply.h"
602d9612 20#include "HttpRequest.h"
5ceaee75 21#include "MasterXaction.h"
fdc96a39 22
574b508c
AR
23const libecap::Name Adaptation::Ecap::protocolInternal("internal", libecap::Name::NextId());
24const libecap::Name Adaptation::Ecap::protocolCacheObj("cache_object", libecap::Name::NextId());
25const libecap::Name Adaptation::Ecap::protocolIcp("ICP", libecap::Name::NextId());
530f96dd 26#if USE_HTCP
574b508c 27const libecap::Name Adaptation::Ecap::protocolHtcp("Htcp", libecap::Name::NextId());
530f96dd 28#endif
555aedbf
AR
29const libecap::Name Adaptation::Ecap::protocolIcy("ICY", libecap::Name::NextId());
30const libecap::Name Adaptation::Ecap::protocolUnknown("_unknown_", libecap::Name::NextId());
31
22fff3bf 32const libecap::Name Adaptation::Ecap::metaBypassable("bypassable", libecap::Name::NextId());
530f96dd 33
76fc7e57
AJ
34/// the host application (i.e., Squid) wrapper registered with libecap
35static libecap::shared_ptr<Adaptation::Ecap::Host> TheHost;
36
574b508c 37Adaptation::Ecap::Host::Host()
530f96dd
AR
38{
39 // assign our host-specific IDs to well-known names
76fc7e57
AJ
40 // this code can run only once
41
789217a2
FC
42 libecap::headerTransferEncoding.assignHostId(Http::HdrType::TRANSFER_ENCODING);
43 libecap::headerReferer.assignHostId(Http::HdrType::REFERER);
44 libecap::headerContentLength.assignHostId(Http::HdrType::CONTENT_LENGTH);
45 libecap::headerVia.assignHostId(Http::HdrType::VIA);
46 // TODO: libecap::headerXClientIp.assignHostId(Http::HdrType::X_CLIENT_IP);
47 // TODO: libecap::headerXServerIp.assignHostId(Http::HdrType::X_SERVER_IP);
530f96dd 48
39a19cb7
AJ
49 libecap::protocolHttp.assignHostId(AnyP::PROTO_HTTP);
50 libecap::protocolHttps.assignHostId(AnyP::PROTO_HTTPS);
51 libecap::protocolFtp.assignHostId(AnyP::PROTO_FTP);
52 libecap::protocolGopher.assignHostId(AnyP::PROTO_GOPHER);
53 libecap::protocolWais.assignHostId(AnyP::PROTO_WAIS);
54 libecap::protocolUrn.assignHostId(AnyP::PROTO_URN);
55 libecap::protocolWhois.assignHostId(AnyP::PROTO_WHOIS);
39a19cb7
AJ
56 protocolCacheObj.assignHostId(AnyP::PROTO_CACHE_OBJECT);
57 protocolIcp.assignHostId(AnyP::PROTO_ICP);
530f96dd 58#if USE_HTCP
39a19cb7 59 protocolHtcp.assignHostId(AnyP::PROTO_HTCP);
530f96dd 60#endif
555aedbf
AR
61 protocolIcy.assignHostId(AnyP::PROTO_ICY);
62 protocolUnknown.assignHostId(AnyP::PROTO_UNKNOWN);
22fff3bf
AR
63
64 // allows adapter to safely ignore this in adapter::Service::configure()
65 metaBypassable.assignHostId(1);
530f96dd 66}
fdc96a39
AR
67
68std::string
574b508c 69Adaptation::Ecap::Host::uri() const
fdc96a39
AR
70{
71 return "ecap://squid-cache.org/ecap/hosts/squid";
72}
73
74void
574b508c 75Adaptation::Ecap::Host::describe(std::ostream &os) const
fdc96a39
AR
76{
77 os << PACKAGE_NAME << " v" << PACKAGE_VERSION;
78}
79
0a720258
AR
80/// Strips libecap version components not affecting compatibility decisions.
81static SBuf
82EssentialVersion(const SBuf &raw)
83{
84 // all libecap x.y.* releases are supposed to be compatible so we strip
85 // everything after the second period
86 const SBuf::size_type minorPos = raw.find('.');
87 const SBuf::size_type microPos = minorPos == SBuf::npos ?
86c63190 88 SBuf::npos : raw.find('.', minorPos+1);
0a720258
AR
89 return raw.substr(0, microPos); // becomes raw if microPos is npos
90}
91
92/// If "their" libecap version is not compatible with what Squid has been built
93/// with, then complain and return false.
94static bool
95SupportedVersion(const char *vTheir, const char *them)
96{
97 if (!vTheir || !*vTheir) {
98 debugs(93, DBG_CRITICAL, "ERROR: Cannot use " << them <<
99 " with libecap prior to v1.0.");
100 return false;
101 }
102
103 // we support what we are built with
104 const SBuf vSupported(LIBECAP_VERSION);
105 debugs(93, 2, them << " with libecap v" << vTheir << "; us: v" << vSupported);
106
107 if (EssentialVersion(SBuf(vTheir)) == EssentialVersion(vSupported))
108 return true; // their version is supported
109
110 debugs(93, DBG_CRITICAL, "ERROR: Cannot use " << them <<
111 " with libecap v" << vTheir <<
112 ": incompatible with supported libecap v" << vSupported);
113 return false;
114}
115
fdc96a39 116void
0a720258 117Adaptation::Ecap::Host::noteVersionedService(const char *vGiven, const libecap::weak_ptr<libecap::adapter::Service> &weak)
fdc96a39 118{
0a720258
AR
119 /*
120 * Check that libecap used to build the service is compatible with ours.
121 * This has to be done using vGiven string and not Service object itself
122 * because dereferencing a Service pointer coming from an unsupported
123 * version is unsafe.
124 */
125 if (SupportedVersion(vGiven, "eCAP service built")) {
126 Must(!weak.expired());
127 RegisterAdapterService(weak.lock());
128 }
fdc96a39
AR
129}
130
131static int
132SquidLogLevel(libecap::LogVerbosity lv)
133{
26ac0430
AJ
134 if (lv.critical())
135 return DBG_CRITICAL; // is it a good idea to ignore other flags?
fdc96a39 136
26ac0430
AJ
137 if (lv.large())
138 return DBG_DATA; // is it a good idea to ignore other flags?
fdc96a39 139
26ac0430 140 if (lv.application())
deca180d 141 return lv.normal() ? DBG_IMPORTANT : 2;
fdc96a39 142
26ac0430 143 return 2 + 2*lv.debugging() + 3*lv.operation() + 2*lv.xaction();
fdc96a39
AR
144}
145
146std::ostream *
574b508c 147Adaptation::Ecap::Host::openDebug(libecap::LogVerbosity lv)
fdc96a39
AR
148{
149 const int squidLevel = SquidLogLevel(lv);
150 const int squidSection = 93; // XXX: this should be a global constant
014adac1
AR
151 return Debug::Enabled(squidSection, squidLevel) ?
152 &Debug::Start(squidSection, squidLevel) :
153 nullptr;
fdc96a39
AR
154}
155
156void
574b508c 157Adaptation::Ecap::Host::closeDebug(std::ostream *debug)
fdc96a39 158{
26ac0430 159 if (debug)
014adac1 160 Debug::Finish();
fdc96a39 161}
76fc7e57 162
cc7b2f6c
AR
163Adaptation::Ecap::Host::MessagePtr
164Adaptation::Ecap::Host::newRequest() const
165{
5ceaee75
CT
166 static const MasterXaction::Pointer mx = new MasterXaction(XactionInitiator::initAdaptationOrphan_);
167 return MessagePtr(new Adaptation::Ecap::MessageRep(new HttpRequest(mx)));
cc7b2f6c
AR
168}
169
170Adaptation::Ecap::Host::MessagePtr
171Adaptation::Ecap::Host::newResponse() const
172{
173 return MessagePtr(new Adaptation::Ecap::MessageRep(new HttpReply));
174}
175
76fc7e57
AJ
176void
177Adaptation::Ecap::Host::Register()
178{
0a720258
AR
179 if (!TheHost && SupportedVersion(libecap::VersionString(),
180 "Squid executable dynamically linked")) {
76fc7e57
AJ
181 TheHost.reset(new Adaptation::Ecap::Host);
182 libecap::RegisterHost(TheHost);
183 }
184}
f53969cc 185