blob: fcd4e02543e902c303152a272b0e2aae711be714 [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
Krzysztof Piotr Oledzkia643baf2008-05-29 23:53:44 +020030static struct task *appsess_refresh = NULL;
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;
Willy Tarreaubaaee002006-06-26 02:48:02 +020090 if (!initialized) {
Krzysztof Piotr Oledzkia643baf2008-05-29 23:53:44 +020091 if ((appsess_refresh = pool_alloc2(pool2_task)) == NULL)
Willy Tarreaubaaee002006-06-26 02:48:02 +020092 return -1;
Krzysztof Piotr Oledzkia643baf2008-05-29 23:53:44 +020093
Willy Tarreau9789f7b2008-06-24 08:17:16 +020094 task_init(appsess_refresh);
Krzysztof Piotr Oledzkia643baf2008-05-29 23:53:44 +020095 appsess_refresh->context = NULL;
96 tv_ms_add(&appsess_refresh->expire, &now, TBLCHKINT);
97 appsess_refresh->process = appsession_refresh;
98 task_queue(appsess_refresh);
Willy Tarreaubaaee002006-06-26 02:48:02 +020099 initialized ++;
100 }
101 return 0;
102}
103
Willy Tarreaud825eef2007-05-12 22:35:00 +0200104void appsession_refresh(struct task *t, struct timeval *next)
Willy Tarreaubaaee002006-06-26 02:48:02 +0200105{
Willy Tarreau51041c72007-09-09 21:56:53 +0200106 struct proxy *p = proxy;
107 struct appsession_hash *htbl;
108 appsess *element, *back;
109 int i;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200110
111 while (p) {
112 if (p->appsession_name != NULL) {
113 htbl = &p->htbl_proxy;
Willy Tarreau51041c72007-09-09 21:56:53 +0200114 as_hash_for_each_entry_safe(i, element, back, &p->htbl_proxy, hash_list) {
115 if (tv_isle(&element->expire, &now)) {
116 if ((global.mode & MODE_DEBUG) &&
117 (!(global.mode & MODE_QUIET) || (global.mode & MODE_VERBOSE))) {
118 int len;
119 /*
120 on Linux NULL pointers are caught by sprintf, on solaris -> segfault
121 */
122 len = sprintf(trash, "appsession_refresh: cleaning up expired Session '%s' on Server %s\n",
123 element->sessid, element->serverid?element->serverid:"(null)");
124 write(1, trash, len);
125 }
126 /* delete the expired element from within the hash table */
127 LIST_DEL(&element->hash_list);
128 htbl->destroy(element);
129 }/* end if (tv_isle(&asession->expire, &now)) */
Willy Tarreaubaaee002006-06-26 02:48:02 +0200130 }
131 }
132 p = p->next;
133 }
Willy Tarreau42aae5c2007-04-29 17:43:56 +0200134 tv_ms_add(&t->expire, &now, TBLCHKINT); /* check expiration every 5 seconds */
Willy Tarreau63963c62007-05-13 21:29:55 +0200135 task_queue(t);
Willy Tarreaud825eef2007-05-12 22:35:00 +0200136 *next = t->expire;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200137} /* end appsession_refresh */
138
139int match_str(const void *key1, const void *key2)
140{
141 appsess *temp1,*temp2;
142 temp1 = (appsess *)key1;
143 temp2 = (appsess *)key2;
144
145 //fprintf(stdout,">>>>>>>>>>>>>>temp1->sessid :%s:\n",temp1->sessid);
146 //fprintf(stdout,">>>>>>>>>>>>>>temp2->sessid :%s:\n",temp2->sessid);
147
148 return (strcmp(temp1->sessid,temp2->sessid) == 0);
149}/* end match_str */
150
Willy Tarreau51041c72007-09-09 21:56:53 +0200151void destroy(appsess *temp1) {
Willy Tarreaubaaee002006-06-26 02:48:02 +0200152 if (temp1->sessid)
Willy Tarreau63963c62007-05-13 21:29:55 +0200153 pool_free2(apools.sessid, temp1->sessid);
Willy Tarreaubaaee002006-06-26 02:48:02 +0200154
155 if (temp1->serverid)
Willy Tarreau63963c62007-05-13 21:29:55 +0200156 pool_free2(apools.serverid, temp1->serverid);
Willy Tarreaubaaee002006-06-26 02:48:02 +0200157
Willy Tarreau63963c62007-05-13 21:29:55 +0200158 pool_free2(pool2_appsess, temp1);
Willy Tarreaubaaee002006-06-26 02:48:02 +0200159} /* end destroy */
160
161void appsession_cleanup( void )
162{
163 struct proxy *p = proxy;
164
165 while(p) {
Willy Tarreau51041c72007-09-09 21:56:53 +0200166 appsession_hash_destroy(&(p->htbl_proxy));
Willy Tarreaubaaee002006-06-26 02:48:02 +0200167 p = p->next;
168 }
Krzysztof Piotr Oledzkia643baf2008-05-29 23:53:44 +0200169
170 if (appsess_refresh) {
171 task_delete(appsess_refresh);
172 task_free(appsess_refresh);
173 appsess_refresh = NULL;
174 }
175
Willy Tarreaubaaee002006-06-26 02:48:02 +0200176}/* end appsession_cleanup() */
177
178
179
180/*
181 * Local variables:
182 * c-indent-level: 8
183 * c-basic-offset: 8
184 * End:
185 */