blob: 10b4df07058b249c1b42e6eaf5f93b3c1586e59e [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 Tarreau0c303ee2008-07-07 00:09:58 +020021#include <common/ticks.h>
Willy Tarreau2dd0d472006-06-29 17:53:05 +020022#include <common/time.h>
Willy Tarreaubaaee002006-06-26 02:48:02 +020023
24#include <types/buffers.h>
25#include <types/global.h>
26#include <types/proxy.h>
27#include <types/server.h>
28
29#include <proto/task.h>
30
Krzysztof Piotr Oledzkia643baf2008-05-29 23:53:44 +020031static struct task *appsess_refresh = NULL;
Willy Tarreau63963c62007-05-13 21:29:55 +020032struct pool_head *pool2_appsess;
Willy Tarreaubaaee002006-06-26 02:48:02 +020033struct app_pool apools;
34int have_appsession;
35
Willy Tarreaubaaee002006-06-26 02:48:02 +020036int appsession_init(void)
37{
38 static int initialized = 0;
39 int idlen;
40 struct server *s;
41 struct proxy *p = proxy;
42
43 if (!initialized) {
Willy Tarreau63963c62007-05-13 21:29:55 +020044 pool2_appsess = create_pool("appsess", sizeof(appsess), MEM_F_SHARED);
45 if (pool2_appsess == NULL)
46 return -1;
47
Willy Tarreaubaaee002006-06-26 02:48:02 +020048 if (!appsession_task_init()) {
Willy Tarreau63963c62007-05-13 21:29:55 +020049 int ser_msize, ses_msize;
50
Willy Tarreaubaaee002006-06-26 02:48:02 +020051 apools.sessid = NULL;
52 apools.serverid = NULL;
Willy Tarreau63963c62007-05-13 21:29:55 +020053
54 ser_msize = sizeof(void *);
55 ses_msize = sizeof(void *);
Willy Tarreaubaaee002006-06-26 02:48:02 +020056 while (p) {
57 s = p->srv;
Willy Tarreau63963c62007-05-13 21:29:55 +020058 if (ses_msize < p->appsession_len)
59 ses_msize = p->appsession_len;
Willy Tarreaubaaee002006-06-26 02:48:02 +020060 while (s) {
61 idlen = strlen(s->id);
Willy Tarreau63963c62007-05-13 21:29:55 +020062 if (ser_msize < idlen)
63 ser_msize = idlen;
Willy Tarreaubaaee002006-06-26 02:48:02 +020064 s = s->next;
65 }
66 p = p->next;
67 }
68 /* we use strings, so reserve space for '\0' */
Willy Tarreau63963c62007-05-13 21:29:55 +020069 ser_msize ++;
70 ses_msize ++;
71
72 apools.sessid = create_pool("sessid", ses_msize, MEM_F_SHARED);
73 if (!apools.sessid)
74 return -1;
75 apools.serverid = create_pool("serverid", ser_msize, MEM_F_SHARED);
76 if (!apools.serverid)
77 return -1;
Willy Tarreaubaaee002006-06-26 02:48:02 +020078 }
79 else {
80 fprintf(stderr, "appsession_task_init failed\n");
81 return -1;
82 }
83 initialized ++;
84 }
85 return 0;
86}
87
88int appsession_task_init(void)
89{
90 static int initialized = 0;
Willy Tarreaubaaee002006-06-26 02:48:02 +020091 if (!initialized) {
Krzysztof Piotr Oledzkia643baf2008-05-29 23:53:44 +020092 if ((appsess_refresh = pool_alloc2(pool2_task)) == NULL)
Willy Tarreaubaaee002006-06-26 02:48:02 +020093 return -1;
Krzysztof Piotr Oledzkia643baf2008-05-29 23:53:44 +020094
Willy Tarreau9789f7b2008-06-24 08:17:16 +020095 task_init(appsess_refresh);
Krzysztof Piotr Oledzkia643baf2008-05-29 23:53:44 +020096 appsess_refresh->context = NULL;
Willy Tarreau0c303ee2008-07-07 00:09:58 +020097 appsess_refresh->expire = tick_add(now_ms, MS_TO_TICKS(TBLCHKINT));
Krzysztof Piotr Oledzkia643baf2008-05-29 23:53:44 +020098 appsess_refresh->process = appsession_refresh;
99 task_queue(appsess_refresh);
Willy Tarreaubaaee002006-06-26 02:48:02 +0200100 initialized ++;
101 }
102 return 0;
103}
104
Willy Tarreau0c303ee2008-07-07 00:09:58 +0200105void appsession_refresh(struct task *t, int *next)
Willy Tarreaubaaee002006-06-26 02:48:02 +0200106{
Willy Tarreau51041c72007-09-09 21:56:53 +0200107 struct proxy *p = proxy;
108 struct appsession_hash *htbl;
109 appsess *element, *back;
110 int i;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200111
112 while (p) {
113 if (p->appsession_name != NULL) {
114 htbl = &p->htbl_proxy;
Willy Tarreau51041c72007-09-09 21:56:53 +0200115 as_hash_for_each_entry_safe(i, element, back, &p->htbl_proxy, hash_list) {
Willy Tarreau0c303ee2008-07-07 00:09:58 +0200116 if (tick_is_expired(element->expire, now_ms)) {
Willy Tarreau51041c72007-09-09 21:56:53 +0200117 if ((global.mode & MODE_DEBUG) &&
118 (!(global.mode & MODE_QUIET) || (global.mode & MODE_VERBOSE))) {
119 int len;
120 /*
121 on Linux NULL pointers are caught by sprintf, on solaris -> segfault
122 */
123 len = sprintf(trash, "appsession_refresh: cleaning up expired Session '%s' on Server %s\n",
124 element->sessid, element->serverid?element->serverid:"(null)");
125 write(1, trash, len);
126 }
127 /* delete the expired element from within the hash table */
128 LIST_DEL(&element->hash_list);
129 htbl->destroy(element);
130 }/* end if (tv_isle(&asession->expire, &now)) */
Willy Tarreaubaaee002006-06-26 02:48:02 +0200131 }
132 }
133 p = p->next;
134 }
Willy Tarreau0c303ee2008-07-07 00:09:58 +0200135 t->expire = tick_add(now_ms, MS_TO_TICKS(TBLCHKINT)); /* check expiration every 5 seconds */
Willy Tarreau63963c62007-05-13 21:29:55 +0200136 task_queue(t);
Willy Tarreaud825eef2007-05-12 22:35:00 +0200137 *next = t->expire;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200138} /* end appsession_refresh */
139
140int match_str(const void *key1, const void *key2)
141{
142 appsess *temp1,*temp2;
143 temp1 = (appsess *)key1;
144 temp2 = (appsess *)key2;
145
146 //fprintf(stdout,">>>>>>>>>>>>>>temp1->sessid :%s:\n",temp1->sessid);
147 //fprintf(stdout,">>>>>>>>>>>>>>temp2->sessid :%s:\n",temp2->sessid);
148
149 return (strcmp(temp1->sessid,temp2->sessid) == 0);
150}/* end match_str */
151
Willy Tarreau51041c72007-09-09 21:56:53 +0200152void destroy(appsess *temp1) {
Willy Tarreaubaaee002006-06-26 02:48:02 +0200153 if (temp1->sessid)
Willy Tarreau63963c62007-05-13 21:29:55 +0200154 pool_free2(apools.sessid, temp1->sessid);
Willy Tarreaubaaee002006-06-26 02:48:02 +0200155
156 if (temp1->serverid)
Willy Tarreau63963c62007-05-13 21:29:55 +0200157 pool_free2(apools.serverid, temp1->serverid);
Willy Tarreaubaaee002006-06-26 02:48:02 +0200158
Willy Tarreau63963c62007-05-13 21:29:55 +0200159 pool_free2(pool2_appsess, temp1);
Willy Tarreaubaaee002006-06-26 02:48:02 +0200160} /* end destroy */
161
162void appsession_cleanup( void )
163{
164 struct proxy *p = proxy;
165
166 while(p) {
Willy Tarreau51041c72007-09-09 21:56:53 +0200167 appsession_hash_destroy(&(p->htbl_proxy));
Willy Tarreaubaaee002006-06-26 02:48:02 +0200168 p = p->next;
169 }
Krzysztof Piotr Oledzkia643baf2008-05-29 23:53:44 +0200170
171 if (appsess_refresh) {
172 task_delete(appsess_refresh);
173 task_free(appsess_refresh);
174 appsess_refresh = NULL;
175 }
176
Willy Tarreaubaaee002006-06-26 02:48:02 +0200177}/* end appsession_cleanup() */
178
179
180
181/*
182 * Local variables:
183 * c-indent-level: 8
184 * c-basic-offset: 8
185 * End:
186 */