There is a bug in current ssl_crtd code. The bug descriptions exists here:
http://bugs.squid-cache.org/show_bug.cgi?id=3214
A patch fixing the bug uploaded here.
I am also posting the patch here, because it changes a little the
helpers behaviour, so maybe a discussion required. This patch add the
possibility to use other characters than the '\n' as the end of helper
response mark.
Regards,
Christos
Bug fix for "helperHandleRead: unexpected read from ssl_crtd" errors.
Squid would read the beginning of a crtd response split across multiple
read operations and treat it as a complete response, causing various
certificate-related errors.
This patch:
- allow the use of other than the '\n' character as the end of message mark
for helper responses.
- Use the '\1' char as end-of-message char for crtd helper. This char looks
safe because the crtd messages are clear text only messages.
=== modified file 'src/helper.cc'
--- src/helper.cc 2011-03-16 12:03:03 +0000
+++ src/helper.cc 2011-05-04 14:36:12 +0000
@@ -881,30 +881,25 @@
srv->rbuf[0] = '\0';
}
- if (hlp->return_full_reply) {
- debugs(84, 3, HERE << "Return entire buffer");
- helperReturnBuffer(0, srv, hlp, srv->rbuf, srv->rbuf + srv->roffset);
- } else {
- while ((t = strchr(srv->rbuf, '\n'))) {
- /* end of reply found */
- char *msg = srv->rbuf;
- int i = 0;
- debugs(84, 3, "helperHandleRead: end of reply found");
-
- if (t > srv->rbuf && t[-1] == '\r')
- t[-1] = '\0';
-
- *t++ = '\0';
-
- if (hlp->childs.concurrency) {
- i = strtol(msg, &msg, 10);
-
- while (*msg && xisspace(*msg))
- msg++;
- }
-
- helperReturnBuffer(i, srv, hlp, msg, t);
+ while ((t = strchr(srv->rbuf, hlp->eom))) {
+ /* end of reply found */
+ char *msg = srv->rbuf;
+ int i = 0;
+ debugs(84, 3, "helperHandleRead: end of reply found");
+
+ if (t > srv->rbuf && t[-1] == '\r' && hlp->eom == '\n')
+ t[-1] = '\0';
+
+ *t++ = '\0';
+
+ if (hlp->childs.concurrency) {
+ i = strtol(msg, &msg, 10);
+
+ while (*msg && xisspace(*msg))
+ msg++;
}
+
+ helperReturnBuffer(i, srv, hlp, msg, t);
}
if (srv->rfd != -1)
@@ -950,12 +945,12 @@
srv->roffset = 0;
}
- if ((t = strchr(srv->rbuf, '\n'))) {
+ if ((t = strchr(srv->rbuf, hlp->eom))) {
/* end of reply found */
int called = 1;
debugs(84, 3, "helperStatefulHandleRead: end of reply found");
- if (t > srv->rbuf && t[-1] == '\r')
+ if (t > srv->rbuf && t[-1] == '\r' && hlp->eom == '\n')
t[-1] = '\0';
*t = '\0';
=== modified file 'src/helper.h'
--- src/helper.h 2010-11-18 08:01:53 +0000
+++ src/helper.h 2011-05-04 20:12:06 +0000
@@ -49,7 +49,7 @@
class helper
{
public:
- inline helper(const char *name) : cmdline(NULL), id_name(name) {};
+ inline helper(const char *name) : cmdline(NULL), id_name(name), eom('\n') {}
~helper();
public:
@@ -62,6 +62,7 @@
Ip::Address addr;
time_t last_queue_warn;
time_t last_restart;
+ char eom; ///< The char which marks the end of (response) message, normally '\n'
struct _stats {
int requests;
@@ -69,8 +70,6 @@
int queue_size;
int avg_svc_time;
} stats;
- /// True if callback expects the whole helper output, as a c-string.
- bool return_full_reply;
private:
CBDATA_CLASS2(helper);
=== modified file 'src/ssl/crtd_message.cc'
--- src/ssl/crtd_message.cc 2010-12-30 11:16:21 +0000
+++ src/ssl/crtd_message.cc 2011-05-04 16:36:19 +0000
@@ -126,7 +126,7 @@
if (code.empty()) return std::string();
char buffer[10];
snprintf(buffer, sizeof(buffer), "%zd", body.length());
- return code + ' ' + buffer + ' ' + body + '\n';
+ return code + ' ' + buffer + ' ' + body;
}
void Ssl::CrtdMessage::clear()
=== modified file 'src/ssl/helper.cc'
--- src/ssl/helper.cc 2010-11-18 08:01:53 +0000
+++ src/ssl/helper.cc 2011-05-04 16:35:10 +0000
@@ -30,6 +30,9 @@
ssl_crtd = new helper("ssl_crtd");
ssl_crtd->childs = Ssl::TheConfig.ssl_crtdChildren;
ssl_crtd->ipc_type = IPC_STREAM;
+ // The crtd messages may contain the eol ('\n') character. We are
+ // going to use the '\1' char as the end-of-message mark.
+ ssl_crtd->eom = '\1';
assert(ssl_crtd->cmdline == NULL);
{
char *tmp = xstrdup(Ssl::TheConfig.ssl_crtd);
@@ -57,7 +60,6 @@
}
safe_free(tmp_begin);
}
- ssl_crtd->return_full_reply = true;
helperOpenServers(ssl_crtd);
}
@@ -88,5 +90,7 @@
}
first_warn = 0;
- helperSubmit(ssl_crtd, message.compose().c_str(), callback, data);
+ std::string msg = message.compose();
+ msg += '\n';
+ helperSubmit(ssl_crtd, msg.c_str(), callback, data);
}
=== modified file 'src/ssl/ssl_crtd.cc'
--- src/ssl/ssl_crtd.cc 2010-11-18 08:01:53 +0000
+++ src/ssl/ssl_crtd.cc 2011-05-04 21:52:40 +0000
@@ -245,7 +245,8 @@
response_message.setCode("ok");
response_message.setBody(bufferToWrite);
- std::cout << response_message.compose();
+ // Use the '\1' char as end-of-message character
+ std::cout << response_message.compose() << '\1' << std::flush;
return true;
}