--- /dev/null
+/*
+ * $Id$
+ */
+
+#include <stdio.h>
+#include <assert.h>
+#include <pthread.h>
+
+#include "libvarnish.h"
+#include "vcl_lang.h"
+#include "cache.h"
+
+static TAILQ_HEAD(, sess) shd = TAILQ_HEAD_INITIALIZER(shd);
+
+static pthread_mutex_t shdmtx;
+static pthread_cond_t shdcnd;
+
+static void *
+CacheWorker(void *priv __unused)
+{
+ struct sess *sp;
+
+ while (1) {
+ AZ(pthread_mutex_lock(&shdmtx));
+ while (1) {
+ sp = TAILQ_FIRST(&shd);
+ if (sp != NULL)
+ break;
+ AZ(pthread_cond_wait(&shdcnd, &shdmtx));
+ }
+ TAILQ_REMOVE(&shd, sp, list);
+ AZ(pthread_mutex_unlock(&shdmtx));
+
+ HttpdAnalyze(sp);
+
+ /*
+ * XXX send session to acceptor for reuse/disposal
+ */
+ }
+}
+
+void
+DealWithSession(struct sess *sp)
+{
+ AZ(pthread_mutex_lock(&shdmtx));
+ TAILQ_INSERT_TAIL(&shd, sp, list);
+ AZ(pthread_mutex_unlock(&shdmtx));
+ AZ(pthread_cond_signal(&shdcnd));
+}
+
+void
+CacheInitPool(void)
+{
+ pthread_t tp;
+
+ AZ(pthread_mutex_init(&shdmtx, NULL));
+ AZ(pthread_cond_init(&shdcnd, NULL));
+
+ AZ(pthread_create(&tp, NULL, CacheWorker, NULL));
+ AZ(pthread_detach(tp));
+}
* XXX: *MUST* be rerun.
*/
+#include <sys/queue.h>
struct vcl_ref {
unsigned line;
unsigned mask;
};
-struct client {
- unsigned ip;
-};
+#define VCA_RXBUFSIZE 1024
+#define VCA_ADDRBUFSIZE 32
+
+struct sess {
+ int fd;
+
+ /* formatted ascii client address */
+ char addr[VCA_ADDRBUFSIZE];
+
+ /* Receive buffer for HTTP header */
+ char rcv[VCA_RXBUFSIZE + 1];
+ unsigned rcv_len;
+
+ /* HTTP request info, points into rcv */
+ const char *req_b;
+ const char *req_e;
+ const char *url_b;
+ const char *url_e;
+ const char *proto_b;
+ const char *proto_e;
+ const char *hdr_b;
+ const char *hdr_e;
-struct req {
- char *req;
- char *useragent;
- struct {
- char *path;
- char *host;
- } url;
- double ttlfactor;
- struct backend *backend;
+ enum {
+ HND_Unclass,
+ HND_Handle,
+ HND_Pass
+ } handling;
+
+ char done;
+
+ TAILQ_ENTRY(sess) list;
+
+ /* Various internal stuff */
+ struct event *rd_e;
+ struct sessmem *mem;
};
struct backend {
int down;
};
-struct obj {
- int exists;
- double ttl;
- unsigned result;
- unsigned size;
- unsigned usage;
-};
-
-#define VCL_FARGS struct client *client, struct obj *obj, struct req *req, struct backend *backend
-#define VCL_PASS_ARGS client, obj, req, backend
+#define VCL_FARGS struct sess *sess
+#define VCL_PASS_ARGS sess
void VCL_count(unsigned);
void VCL_no_cache();
int string_match(const char *, const char *);
int VCL_rewrite(const char *, const char *);
int VCL_error(unsigned, const char *);
+void VCL_pass(VCL_FARGS);
int VCL_fetch(void);
int VCL_switch_config(const char *);
typedef void vcl_init_f(void);
+typedef void vcl_func_f(VCL_FARGS);
struct VCL_conf {
unsigned magic;
#define VCL_CONF_MAGIC 0x7406c509 /* from /dev/random */
vcl_init_f *init_func;
+ vcl_func_f *main_func;
struct backend *default_backend;
struct vcl_ref *ref;
unsigned nref;
*q = p + 4;
return (T_PROC);
}
+ if (p[0] == 'p' && p[1] == 'a' && p[2] == 's' &&
+ p[3] == 's' && !isvar(p[4])) {
+ *q = p + 4;
+ return (T_PASS);
+ }
return (0);
case 'r':
if (p[0] == 'r' && p[1] == 'e' && p[2] == 'w' &&
vcl_tnames[T_NEQ] = "!=";
vcl_tnames[T_NO_CACHE] = "no_cache";
vcl_tnames[T_NO_NEW_CACHE] = "no_new_cache";
+ vcl_tnames[T_PASS] = "pass";
vcl_tnames[T_PROC] = "proc";
vcl_tnames[T_REWRITE] = "rewrite";
vcl_tnames[T_SET] = "set";
fputs(" * XXX: *MUST* be rerun.\n", f);
fputs(" */\n", f);
fputs("\n", f);
+ fputs("#include <sys/queue.h>\n", f);
fputs("\n", f);
fputs("struct vcl_ref {\n", f);
fputs(" unsigned line;\n", f);
fputs(" unsigned mask;\n", f);
fputs("};\n", f);
fputs("\n", f);
- fputs("struct client {\n", f);
- fputs(" unsigned ip;\n", f);
- fputs("};\n", f);
+ fputs("#define VCA_RXBUFSIZE 1024\n", f);
+ fputs("#define VCA_ADDRBUFSIZE 32\n", f);
+ fputs("\n", f);
+ fputs("struct sess {\n", f);
+ fputs(" int fd;\n", f);
+ fputs("\n", f);
+ fputs(" /* formatted ascii client address */\n", f);
+ fputs(" char addr[VCA_ADDRBUFSIZE];\n", f);
fputs("\n", f);
- fputs("struct req {\n", f);
- fputs(" char *req;\n", f);
- fputs(" char *useragent;\n", f);
- fputs(" struct {\n", f);
- fputs(" char *path;\n", f);
- fputs(" char *host;\n", f);
- fputs(" } url;\n", f);
- fputs(" double ttlfactor;\n", f);
- fputs(" struct backend *backend;\n", f);
+ fputs(" /* Receive buffer for HTTP header */\n", f);
+ fputs(" char rcv[VCA_RXBUFSIZE + 1];\n", f);
+ fputs(" unsigned rcv_len;\n", f);
+ fputs("\n", f);
+ fputs(" /* HTTP request info, points into rcv */\n", f);
+ fputs(" const char *req_b;\n", f);
+ fputs(" const char *req_e;\n", f);
+ fputs(" const char *url_b;\n", f);
+ fputs(" const char *url_e;\n", f);
+ fputs(" const char *proto_b;\n", f);
+ fputs(" const char *proto_e;\n", f);
+ fputs(" const char *hdr_b;\n", f);
+ fputs(" const char *hdr_e;\n", f);
+ fputs("\n", f);
+ fputs(" enum {\n", f);
+ fputs(" HND_Unclass,\n", f);
+ fputs(" HND_Handle,\n", f);
+ fputs(" HND_Pass\n", f);
+ fputs(" } handling;\n", f);
+ fputs("\n", f);
+ fputs(" char done;\n", f);
+ fputs("\n", f);
+ fputs(" /* Various internal stuff */\n", f);
+ fputs(" struct event *rd_e;\n", f);
+ fputs(" struct sessmem *mem;\n", f);
fputs("};\n", f);
fputs("\n", f);
fputs("struct backend {\n", f);
fputs(" int down;\n", f);
fputs("};\n", f);
fputs("\n", f);
- fputs("struct obj {\n", f);
- fputs(" int exists;\n", f);
- fputs(" double ttl;\n", f);
- fputs(" unsigned result;\n", f);
- fputs(" unsigned size;\n", f);
- fputs(" unsigned usage;\n", f);
- fputs("};\n", f);
- fputs("\n", f);
- fputs("#define VCL_FARGS struct client *client, struct obj *obj, struct req *req, struct backend *backend\n", f);
- fputs("#define VCL_PASS_ARGS client, obj, req, backend\n", f);
+ fputs("#define VCL_FARGS struct sess *sess\n", f);
+ fputs("#define VCL_PASS_ARGS sess\n", f);
fputs("\n", f);
fputs("void VCL_count(unsigned);\n", f);
fputs("void VCL_no_cache();\n", f);
fputs("int string_match(const char *, const char *);\n", f);
fputs("int VCL_rewrite(const char *, const char *);\n", f);
fputs("int VCL_error(unsigned, const char *);\n", f);
+ fputs("void VCL_pass(VCL_FARGS);\n", f);
fputs("int VCL_fetch(void);\n", f);
fputs("int VCL_switch_config(const char *);\n", f);
fputs("\n", f);
fputs("typedef void vcl_init_f(void);\n", f);
+ fputs("typedef void vcl_func_f(VCL_FARGS);\n", f);
fputs("\n", f);
fputs("struct VCL_conf {\n", f);
fputs(" unsigned magic;\n", f);
fputs("#define VCL_CONF_MAGIC 0x7406c509 /* from /dev/random */\n", f);
fputs(" vcl_init_f *init_func;\n", f);
+ fputs(" vcl_func_f *main_func;\n", f);
fputs(" struct backend *default_backend;\n", f);
fputs(" struct vcl_ref *ref;\n", f);
fputs(" unsigned nref;\n", f);