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();

Reply via email to