whois.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/* DEBUG: section 75 WHOIS protocol */
10
11#include "squid.h"
12#include "comm.h"
13#include "comm/Read.h"
14#include "comm/Write.h"
15#include "errorpage.h"
16#include "FwdState.h"
17#include "HttpReply.h"
18#include "HttpRequest.h"
19#include "SquidConfig.h"
20#include "StatCounters.h"
21#include "Store.h"
22#include "tools.h"
23#include "whois.h"
24
25#include <cerrno>
26
28{
30
31public:
32 void readReply(const Comm::ConnectionPointer &, char *aBuffer, size_t aBufferLength, Comm::Flag flag, int xerrno);
33 void setReplyToOK(StoreEntry *sentry);
37 char buf[BUFSIZ+1]; /* readReply adds terminating NULL */
39};
40
42
46
47/* PUBLIC */
48
49static void
50whoisWriteComplete(const Comm::ConnectionPointer &, char *buf, size_t, Comm::Flag, int, void *)
51{
52 xfree(buf);
53}
54
55void
57{
58 WhoisState *p = new WhoisState;
59 p->request = fwd->request;
60 p->entry = fwd->entry;
61 p->fwd = fwd;
62 p->dataWritten = false;
63
64 p->entry->lock("whoisStart");
66
67 size_t l = p->request->url.path().length() + 3;
68 char *buf = (char *)xmalloc(l);
69
70 const SBuf str_print = p->request->url.path().substr(1);
71 snprintf(buf, l, SQUIDSBUFPH "\r\n", SQUIDSBUFPRINT(str_print));
72
73 AsyncCall::Pointer writeCall = commCbCall(5,5, "whoisWriteComplete",
75 Comm::Write(fwd->serverConnection(), buf, strlen(buf), writeCall, nullptr);
76 AsyncCall::Pointer readCall = commCbCall(5,4, "whoisReadReply",
78 comm_read(fwd->serverConnection(), p->buf, BUFSIZ, readCall);
79 AsyncCall::Pointer timeoutCall = commCbCall(5, 4, "whoisTimeout",
82}
83
84/* PRIVATE */
85
86static void
88{
89 WhoisState *p = static_cast<WhoisState *>(io.data);
90 debugs(75, 3, io.conn << ", URL " << p->entry->url());
91 io.conn->close();
92}
93
94static void
95whoisReadReply(const Comm::ConnectionPointer &conn, char *buf, size_t len, Comm::Flag flag, int xerrno, void *data)
96{
97 WhoisState *p = (WhoisState *)data;
98 p->readReply(conn, buf, len, flag, xerrno);
99}
100
101void
103{
104 HttpReply *reply = new HttpReply;
105 sentry->buffer();
106 reply->setHeaders(Http::scOkay, "Gatewaying", "text/plain", -1, -1, -2);
108 sentry->replaceHttpReply(reply);
109}
110
111void
112WhoisState::readReply(const Comm::ConnectionPointer &conn, char *aBuffer, size_t aBufferLength, Comm::Flag flag, int xerrno)
113{
114 /* Bail out early on Comm::ERR_CLOSING - close handlers will tidy up for us */
115 if (flag == Comm::ERR_CLOSING)
116 return;
117
118 aBuffer[aBufferLength] = '\0';
119 debugs(75, 3, conn << " read " << aBufferLength << " bytes");
120 debugs(75, 5, "{" << aBuffer << "}");
121
122 // TODO: Honor delay pools.
123
124 // XXX: Update statCounter before bailing
125 if (!entry->isAccepting()) {
126 debugs(52, 3, "terminating due to bad " << *entry);
127 // TODO: Do not abuse connection for triggering cleanup.
128 conn->close();
129 return;
130 }
131
132 if (flag != Comm::OK) {
133 debugs(50, 2, conn << ": read failure: " << xstrerr(xerrno));
134
135 if (ignoreErrno(xerrno)) {
136 AsyncCall::Pointer call = commCbCall(5,4, "whoisReadReply",
138 comm_read(conn, aBuffer, BUFSIZ, call);
139 } else {
141 err->xerrno = xerrno;
142 fwd->fail(err);
143 conn->close();
144 }
145 return;
146 }
147
148 if (aBufferLength > 0) {
149 if (!dataWritten)
151
152 statCounter.server.all.kbytes_in += aBufferLength;
153 statCounter.server.http.kbytes_in += aBufferLength;
154
155 /* No range support, we always grab it all */
156 dataWritten = true;
157 entry->append(aBuffer, aBufferLength);
158 entry->flush();
159
160 AsyncCall::Pointer call = commCbCall(5,4, "whoisReadReply",
162 comm_read(conn, aBuffer, BUFSIZ, call);
163 return;
164 }
165
166 /* no bytes read. stop reading */
168 entry->flush();
169
170 if (!entry->makePublic())
171 entry->makePrivate(true);
172
173 if (dataWritten) // treat zero-length responses as incomplete
174 fwd->markStoredReplyAsWhole("whois received/stored the entire response");
175 else
177
178 fwd->complete();
179 debugs(75, 3, "whoisReadReply: Done: " << entry->url());
180 conn->close();
181}
182
183static void
185{
186 WhoisState *p = (WhoisState *)params.data;
187 debugs(75, 3, "whoisClose: FD " << params.fd);
188 // We do not own a Connection. Assume that FwdState is also monitoring.
189 p->entry->unlock("whoisClose");
190 delete p;
191}
192
CommCbFunPtrCallT< Dialer > * commCbCall(int debugSection, int debugLevel, const char *callName, const Dialer &dialer)
Definition: CommCalls.h:312
void CTCB(const CommTimeoutCbParams &params)
Definition: CommCalls.h:37
void IOCB(const Comm::ConnectionPointer &conn, char *, size_t size, Comm::Flag flag, int xerrno, void *data)
Definition: CommCalls.h:34
void CLCB(const CommCloseCbParams &params)
Definition: CommCalls.h:40
void comm_read(const Comm::ConnectionPointer &conn, char *buf, int len, AsyncCall::Pointer &callback)
Definition: Read.h:59
#define SQUIDSBUFPH
Definition: SBuf.h:31
#define SQUIDSBUFPRINT(s)
Definition: SBuf.h:32
class SquidConfig Config
Definition: SquidConfig.cc:12
StatCounters statCounter
Definition: StatCounters.cc:12
int conn
the current server connection FD
Definition: Transport.cc:26
#define CBDATA_CLASS_INIT(type)
Definition: cbdata.h:320
#define CBDATA_CLASS(type)
Definition: cbdata.h:289
void path(const char *p)
Definition: Uri.h:101
int fd
FD which the call was about. Set by the async call creator.
Definition: CommCalls.h:85
Comm::ConnectionPointer conn
Definition: CommCalls.h:80
HttpRequest * request
Definition: FwdState.h:169
void complete()
Definition: FwdState.cc:531
Comm::ConnectionPointer const & serverConnection() const
Definition: FwdState.h:104
void fail(ErrorState *err)
Definition: FwdState.cc:463
StoreEntry * entry
Definition: FwdState.h:168
void markStoredReplyAsWhole(const char *whyWeAreSure)
Definition: FwdState.cc:580
AccessLogEntryPointer al
info for the future access.log entry
Definition: FwdState.h:170
void setHeaders(Http::StatusCode status, const char *reason, const char *ctype, int64_t clen, time_t lmt, time_t expires)
Definition: HttpReply.cc:170
AnyP::Uri url
the request URI
Definition: HttpRequest.h:115
@ srcWhois
Whois server.
Definition: Message.h:43
uint32_t sources
The message sources.
Definition: Message.h:99
Definition: SBuf.h:94
time_t read
Definition: SquidConfig.h:112
struct SquidConfig::@93 Timeout
struct StatCounters::@123::@133 all
struct StatCounters::@123::@133 http
ByteCounter kbytes_in
Definition: StatCounters.h:45
struct StatCounters::@123 server
bool isAccepting() const
Definition: store.cc:1975
int unlock(const char *context)
Definition: store.cc:455
const char * url() const
Definition: store.cc:1552
void lock(const char *context)
Definition: store.cc:431
void flush() override
Definition: store.cc:1598
bool makePublic(const KeyScope keyScope=ksDefault)
Definition: store.cc:166
bool timestampsSet()
Definition: store.cc:1373
void makePrivate(const bool shareable)
Definition: store.cc:173
void replaceHttpReply(const HttpReplyPointer &, const bool andStartWriting=true)
Definition: store.cc:1691
void append(char const *, int) override
Appends a c-string to existing packed data.
Definition: store.cc:789
void buffer() override
Definition: store.cc:1587
void readReply(const Comm::ConnectionPointer &, char *aBuffer, size_t aBufferLength, Comm::Flag flag, int xerrno)
Definition: whois.cc:112
StoreEntry * entry
Definition: whois.cc:34
char buf[BUFSIZ+1]
Definition: whois.cc:37
bool dataWritten
Definition: whois.cc:38
void setReplyToOK(StoreEntry *sentry)
Definition: whois.cc:102
HttpRequest::Pointer request
Definition: whois.cc:35
FwdState::Pointer fwd
Definition: whois.cc:36
int commSetConnTimeout(const Comm::ConnectionPointer &conn, time_t timeout, AsyncCall::Pointer &callback)
Definition: comm.cc:595
AsyncCall::Pointer comm_add_close_handler(int fd, CLCB *handler, void *data)
Definition: comm.cc:949
int ignoreErrno(int ierrno)
Definition: comm.cc:1440
#define debugs(SECTION, LEVEL, CONTENT)
Definition: Stream.h:194
#define BUFSIZ
Definition: defines.h:20
@ ERR_ZERO_SIZE_OBJECT
Definition: forward.h:46
@ ERR_READ_ERROR
Definition: forward.h:28
void whoisStart(FwdState *fwd)
Definition: whois.cc:56
void Write(const Comm::ConnectionPointer &conn, const char *buf, int size, AsyncCall::Pointer &callback, FREE *free_func)
Definition: Write.cc:33
Flag
Definition: Flag.h:15
@ OK
Definition: Flag.h:16
@ ERR_CLOSING
Definition: Flag.h:24
@ scInternalServerError
Definition: StatusCode.h:71
@ scOkay
Definition: StatusCode.h:26
@ scBadGateway
Definition: StatusCode.h:73
#define xfree
#define xmalloc
static void whoisWriteComplete(const Comm::ConnectionPointer &, char *buf, size_t, Comm::Flag, int, void *)
Definition: whois.cc:50
static CTCB whoisTimeout
Definition: whois.cc:44
static IOCB whoisReadReply
Definition: whois.cc:45
static CLCB whoisClose
Definition: whois.cc:43
const char * xstrerr(int error)
Definition: xstrerror.cc:83

 

Introduction

Documentation

Support

Miscellaneous

Web Site Translations

Mirrors