blob: 9b6868c3ae08283a6e9e2243e07de4f418929267 [file] [log] [blame]
Willy Tarreaubaaee002006-06-26 02:48:02 +02001/*
2 * AppSession functions.
3 *
4 * Copyright 2004-2006 Alexander Lazic, Klaus Wagner
Willy Tarreau63963c62007-05-13 21:29:55 +02005 * Copyright 2006-2007 Willy Tarreau
Willy Tarreaubaaee002006-06-26 02:48:02 +02006 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version
10 * 2 of the License, or (at your option) any later version.
11 *
12 */
13
14#include <stdio.h>
Willy Tarreau2dd0d472006-06-29 17:53:05 +020015#include <string.h>
Willy Tarreaubaaee002006-06-26 02:48:02 +020016
Willy Tarreau2dd0d472006-06-29 17:53:05 +020017#include <common/appsession.h>
Willy Tarreaue3ba5f02006-06-29 18:54:54 +020018#include <common/config.h>
Willy Tarreau63963c62007-05-13 21:29:55 +020019#include <common/memory.h>
Willy Tarreau51041c72007-09-09 21:56:53 +020020#include <common/sessionhash.h>
Willy Tarreau2dd0d472006-06-29 17:53:05 +020021#include <common/time.h>
Willy Tarreaubaaee002006-06-26 02:48:02 +020022
23#include <types/buffers.h>
24#include <types/global.h>
25#include <types/proxy.h>
26#include <types/server.h>
27
28#include <proto/task.h>
29
30
Willy Tarreau63963c62007-05-13 21:29:55 +020031struct pool_head *pool2_appsess;
Willy Tarreaubaaee002006-06-26 02:48:02 +020032struct app_pool apools;
33int have_appsession;
34
Willy Tarreaubaaee002006-06-26 02:48:02 +020035int appsession_init(void)
36{
37 static int initialized = 0;
38 int idlen;
39 struct server *s;
40 struct proxy *p = proxy;
41
42 if (!initialized) {
Willy Tarreau63963c62007-05-13 21:29:55 +020043 pool2_appsess = create_pool("appsess", sizeof(appsess), MEM_F_SHARED);
44 if (pool2_appsess == NULL)
45 return -1;
46
Willy Tarreaubaaee002006-06-26 02:48:02 +020047 if (!appsession_task_init()) {
Willy Tarreau63963c62007-05-13 21:29:55 +020048 int ser_msize, ses_msize;
49
Willy Tarreaubaaee002006-06-26 02:48:02 +020050 apools.sessid = NULL;
51 apools.serverid = NULL;
Willy Tarreau63963c62007-05-13 21:29:55 +020052
53 ser_msize = sizeof(void *);
54 ses_msize = sizeof(void *);
Willy Tarreaubaaee002006-06-26 02:48:02 +020055 while (p) {
56 s = p->srv;
Willy Tarreau63963c62007-05-13 21:29:55 +020057 if (ses_msize < p->appsession_len)
58 ses_msize = p->appsession_len;
Willy Tarreaubaaee002006-06-26 02:48:02 +020059 while (s) {
60 idlen = strlen(s->id);
Willy Tarreau63963c62007-05-13 21:29:55 +020061 if (ser_msize < idlen)
62 ser_msize = idlen;
Willy Tarreaubaaee002006-06-26 02:48:02 +020063 s = s->next;
64 }
65 p = p->next;
66 }
67 /* we use strings, so reserve space for '\0' */
Willy Tarreau63963c62007-05-13 21:29:55 +020068 ser_msize ++;
69 ses_msize ++;
70
71 apools.sessid = create_pool("sessid", ses_msize, MEM_F_SHARED);
72 if (!apools.sessid)
73 return -1;
74 apools.serverid = create_pool("serverid", ser_msize, MEM_F_SHARED);
75 if (!apools.serverid)
76 return -1;
Willy Tarreaubaaee002006-06-26 02:48:02 +020077 }
78 else {
79 fprintf(stderr, "appsession_task_init failed\n");
80 return -1;
81 }
82 initialized ++;
83 }
84 return 0;
85}
86
87int appsession_task_init(void)
88{
89 static int initialized = 0;
90 struct task *t;
91 if (!initialized) {
Willy Tarreauc6ca1a02007-05-13 19:43:47 +020092 if ((t = pool_alloc2(pool2_task)) == NULL)
Willy Tarreaubaaee002006-06-26 02:48:02 +020093 return -1;
Willy Tarreau964c9362007-01-07 00:38:00 +010094 t->wq = NULL;
Willy Tarreau96bcfd72007-04-29 10:41:56 +020095 t->qlist.p = NULL;
Willy Tarreaubaaee002006-06-26 02:48:02 +020096 t->state = TASK_IDLE;
97 t->context = NULL;
Willy Tarreau42aae5c2007-04-29 17:43:56 +020098 tv_ms_add(&t->expire, &now, TBLCHKINT);
Willy Tarreaubaaee002006-06-26 02:48:02 +020099 t->process = appsession_refresh;
Willy Tarreau63963c62007-05-13 21:29:55 +0200100 task_queue(t);
Willy Tarreaubaaee002006-06-26 02:48:02 +0200101 initialized ++;
102 }
103 return 0;
104}
105
Willy Tarreaud825eef2007-05-12 22:35:00 +0200106void appsession_refresh(struct task *t, struct timeval *next)
Willy Tarreaubaaee002006-06-26 02:48:02 +0200107{
Willy Tarreau51041c72007-09-09 21:56:53 +0200108 struct proxy *p = proxy;
109 struct appsession_hash *htbl;
110 appsess *element, *back;
111 int i;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200112
113 while (p) {
114 if (p->appsession_name != NULL) {
115 htbl = &p->htbl_proxy;
Willy Tarreau51041c72007-09-09 21:56:53 +0200116 as_hash_for_each_entry_safe(i, element, back, &p->htbl_proxy, hash_list) {
117 if (tv_isle(&element->expire, &now)) {
118 if ((global.mode & MODE_DEBUG) &&
119 (!(global.mode & MODE_QUIET) || (global.mode & MODE_VERBOSE))) {
120 int len;
121 /*
122 on Linux NULL pointers are caught by sprintf, on solaris -> segfault
123 */
124 len = sprintf(trash, "appsession_refresh: cleaning up expired Session '%s' on Server %s\n",
125 element->sessid, element->serverid?element->serverid:"(null)");
126 write(1, trash, len);
127 }
128 /* delete the expired element from within the hash table */
129 LIST_DEL(&element->hash_list);
130 htbl->destroy(element);
131 }/* end if (tv_isle(&asession->expire, &now)) */
Willy Tarreaubaaee002006-06-26 02:48:02 +0200132 }
133 }
134 p = p->next;
135 }
Willy Tarreau42aae5c2007-04-29 17:43:56 +0200136 tv_ms_add(&t->expire, &now, TBLCHKINT); /* check expiration every 5 seconds */
Willy Tarreau63963c62007-05-13 21:29:55 +0200137 task_queue(t);
Willy Tarreaud825eef2007-05-12 22:35:00 +0200138 *next = t->expire;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200139} /* end appsession_refresh */
140
141int match_str(const void *key1, const void *key2)
142{
143 appsess *temp1,*temp2;
144 temp1 = (appsess *)key1;
145 temp2 = (appsess *)key2;
146
147 //fprintf(stdout,">>>>>>>>>>>>>>temp1->sessid :%s:\n",temp1->sessid);
148 //fprintf(stdout,">>>>>>>>>>>>>>temp2->sessid :%s:\n",temp2->sessid);
149
150 return (strcmp(temp1->sessid,temp2->sessid) == 0);
151}/* end match_str */
152
Willy Tarreau51041c72007-09-09 21:56:53 +0200153void destroy(appsess *temp1) {
Willy Tarreaubaaee002006-06-26 02:48:02 +0200154 if (temp1->sessid)
Willy Tarreau63963c62007-05-13 21:29:55 +0200155 pool_free2(apools.sessid, temp1->sessid);
Willy Tarreaubaaee002006-06-26 02:48:02 +0200156
157 if (temp1->serverid)
Willy Tarreau63963c62007-05-13 21:29:55 +0200158 pool_free2(apools.serverid, temp1->serverid);
Willy Tarreaubaaee002006-06-26 02:48:02 +0200159
Willy Tarreau63963c62007-05-13 21:29:55 +0200160 pool_free2(pool2_appsess, temp1);
Willy Tarreaubaaee002006-06-26 02:48:02 +0200161} /* end destroy */
162
163void appsession_cleanup( void )
164{
165 struct proxy *p = proxy;
166
167 while(p) {
Willy Tarreau51041c72007-09-09 21:56:53 +0200168 appsession_hash_destroy(&(p->htbl_proxy));
Willy Tarreaubaaee002006-06-26 02:48:02 +0200169 p = p->next;
170 }
171}/* end appsession_cleanup() */
172
173
174
175/*
176 * Local variables:
177 * c-indent-level: 8
178 * c-basic-offset: 8
179 * End:
180 */