On Mon, 2011-09-19 at 10:49 +1200, Amos Jeffries wrote:
> The session helper in Squid-3 is concurrent.
Ah, okay.
> The user_key is the opaque
> channel-ID. (Probably should be renamed to match the protocol
> documentation).
> http://wiki.squid-cache.org/Features/AddonHelpers#Access_Control_.28ACL.29
I've renamed to channel_id
> The correct way to fix this is to detect the segfault case add a stderr
> ERROR: message that the helper is concurrent and requires a config
> update.
I've added a fatal error message to STDERR, but I can't get it to output
anywhere (see below).
> stderr should appear in cache.log whenever sent.
Hmmm, it doesn't seem to be.
> Most of the lines so
> far appear to be debug messages
Does that include the failure to open a database? This is written to
STDERR as per any other message, but it does not make it anywhere.
> , which depend on the -d option to
> display.
Do you mean the -d option to the Squid binary? If so, this doesn't seem
to make any difference; it just prints all the log messages to the
display as well as the log file.
I've tried increasing the log level to 9, but to no avail.
> Also....the .8 manual needs to mention the concurrency rather than just
> implying it in the example config.
Done. Also, the following page should be updated:
http://wiki.squid-cache.org/ConfigExamples/Portal/Splash
I'm happy to do it myself, if you can give me wiki edit rights?
> The helper version should get a bump
> to 1.1 as well.
Done in the manual. Is it specified anywhere else as well?
I've also added:
- A new option: "-h". This causes a "hard" timeout, regardless of user
activity. This is because, for many uses of a splash page (adverts etc)
one would want the message to displayed every n hours, regardless of
user activity (certainly that is my requirement).
- A db->sync command. I have found that with more than one child
started, that they do not necessarily share data because each child's
data has not been flushed to disk. This fixes that. However, I am not
sure whether it has other implications, such as much greater disk
overhead. Do you think it should be a configurable option?
Is there anything else that needs updating? RELEASENOTES.html?
Please find attached updated patch for comment.
Thanks,
Andy
=== modified file 'helpers/external_acl/session/ext_session_acl.8'
--- helpers/external_acl/session/ext_session_acl.8 2010-09-16 13:07:02 +0000
+++ helpers/external_acl/session/ext_session_acl.8 2011-09-19 22:42:10 +0000
@@ -1,11 +1,11 @@
-.if !'po4a'hide' .TH ext_session_acl 8 "19 March 2006"
+.if !'po4a'hide' .TH ext_session_acl 8 "19 September 2011"
.
.SH NAME
.if !'po4a'hide' .B ext_session_acl
.if !'po4a'hide' \-
Squid session tracking external acl helper.
.PP
-Version 1.0
+Version 1.1
.
.SH SYNOPSIS
.if !'po4a'hide' .B ext_session_acl
@@ -19,7 +19,7 @@
.B ext_session_acl
maintains a concept of sessions by monitoring requests
and timing out sessions if no requests have been seen for the idle timeout
-timer.
+timer (unless -h is specified).
.PP
Intended use is for displaying "terms of use" pages, ad popups etc.
.
@@ -34,7 +34,7 @@
.B Path
to persistent database. If not specified the session details
will be kept in memory only and all sessions will reset each time
-Squid restarts it's helpers (Squid restart or rotation of logs).
+Squid restarts its helpers (Squid restart or rotation of logs).
.
.if !'po4a'hide' .TP
.if !'po4a'hide' .B \-a
@@ -43,12 +43,22 @@
.B LOGIN
, or terminated by the argument
.B LOGOUT
-.PP
Without this flag the helper automatically starts the session after
the first request.
.
+.if !'po4a'hide' .TP
+.if !'po4a'hide' .B \-h
+Hard timeout mode. In this mode sessions only last for
+.B timeout
+seconds, regardless of the user's activity.
.SH CONFIGURATION
.PP
+The
+.B ext_session_acl
+helper is a concurrent helper; therefore, the concurrency= option
+.B must
+be specified in the configuration.
+.PP
Configuration example using the default automatic mode
.if !'po4a'hide' .RS
.if !'po4a'hide' .B external_acl_type session ttl=300 negative_ttl=0 children=1 concurrency=200 %LOGIN /usr/local/squid/libexec/ext_session_acl
=== modified file 'helpers/external_acl/session/ext_session_acl.cc'
--- helpers/external_acl/session/ext_session_acl.cc 2010-07-29 14:23:35 +0000
+++ helpers/external_acl/session/ext_session_acl.cc 2011-09-19 22:42:03 +0000
@@ -52,6 +52,7 @@
#endif
static int session_ttl = 3600;
+static int hard_timeout = 0;
char *db_path = NULL;
const char *program_name;
@@ -101,6 +102,7 @@
data.data = &now;
data.size = sizeof(now);
db->put(db, &key, &data, 0);
+ db->sync(db, 0);
}
static void session_logout(const char *details, size_t len)
@@ -113,10 +115,11 @@
static void usage(void)
{
- fprintf(stderr, "Usage: %s [-t session_timeout] [-b dbpath] [-a]\n", program_name);
+ fprintf(stderr, "Usage: %s [-t session_timeout] [-b dbpath] [-a] [-h]\n", program_name);
fprintf(stderr, " -t sessiontimeout Idle timeout after which sessions will be forgotten\n");
fprintf(stderr, " -b dbpath Path where persistent session database will be kept\n");
fprintf(stderr, " -a Active mode requiring LOGIN argument to start a session\n");
+ fprintf(stderr, " -h Hard timeout. Forget session after sessiontimeout regardless of activity\n");
}
int main(int argc, char **argv)
{
@@ -126,7 +129,7 @@
program_name = argv[0];
- while ((opt = getopt(argc, argv, "t:b:a?")) != -1) {
+ while ((opt = getopt(argc, argv, "t:b:a?:h?")) != -1) {
switch (opt) {
case 't':
session_ttl = strtol(optarg, NULL, 0);
@@ -137,6 +140,9 @@
case 'a':
default_action = 0;
break;
+ case 'h':
+ hard_timeout = 1;
+ break;
case '?':
usage();
exit(0);
@@ -150,8 +156,13 @@
while (fgets(request, HELPER_INPUT_BUFFER, stdin)) {
int action = 0;
- const char *user_key = strtok(request, " \n");
+ const char *channel_id = strtok(request, " ");
const char *detail = strtok(NULL, "\n");
+ if (detail == NULL) {
+ // Only 1 paramater supplied. We are expecting at least 2 (including the channel ID)
+ fprintf(stderr, "FATAL: %s is concurrent and requires the concurrency option to be specified.\n", program_name);
+ exit(1);
+ }
const char *lastdetail = strrchr(detail, ' ');
size_t detail_len = strlen(detail);
if (lastdetail) {
@@ -165,18 +176,20 @@
}
if (action == -1) {
session_logout(detail, detail_len);
- printf("%s OK message=\"Bye\"\n", user_key);
+ printf("%s OK message=\"Bye\"\n", channel_id);
} else if (action == 1) {
session_login(detail, detail_len);
- printf("%s OK message=\"Welcome\"\n", user_key);
+ printf("%s OK message=\"Welcome\"\n", channel_id);
} else if (session_active(detail, detail_len)) {
- session_login(detail, detail_len);
- printf("%s OK\n", user_key);
+ if (hard_timeout == 0) {
+ session_login(detail, detail_len);
+ }
+ printf("%s OK\n", channel_id);
} else if (default_action == 1) {
session_login(detail, detail_len);
- printf("%s ERR message=\"Welcome\"\n", user_key);
+ printf("%s ERR message=\"Welcome\"\n", channel_id);
} else {
- printf("%s ERR message=\"No session available\"\n", user_key);
+ printf("%s ERR message=\"No session available\"\n", channel_id);
}
}
shutdown_db();