2006-06-26 00:48:02 +00:00
|
|
|
/*
|
|
|
|
* AppSession functions.
|
|
|
|
*
|
|
|
|
* Copyright 2004-2006 Alexander Lazic, Klaus Wagner
|
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU General Public License
|
|
|
|
* as published by the Free Software Foundation; either version
|
|
|
|
* 2 of the License, or (at your option) any later version.
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <stdio.h>
|
2006-06-29 15:53:05 +00:00
|
|
|
#include <string.h>
|
2006-06-26 00:48:02 +00:00
|
|
|
|
2006-06-29 15:53:05 +00:00
|
|
|
#include <common/appsession.h>
|
|
|
|
#include <common/chtbl.h>
|
2006-06-29 16:54:54 +00:00
|
|
|
#include <common/config.h>
|
2006-06-29 15:53:05 +00:00
|
|
|
#include <common/list.h>
|
|
|
|
#include <common/time.h>
|
2006-06-26 00:48:02 +00:00
|
|
|
|
|
|
|
#include <types/buffers.h>
|
|
|
|
#include <types/global.h>
|
|
|
|
#include <types/proxy.h>
|
|
|
|
#include <types/server.h>
|
|
|
|
|
|
|
|
#include <proto/task.h>
|
|
|
|
|
|
|
|
|
|
|
|
void **pool_appsess = NULL;
|
|
|
|
struct app_pool apools;
|
|
|
|
int have_appsession;
|
|
|
|
|
|
|
|
#if defined(DEBUG_HASH)
|
|
|
|
void print_table(const CHTbl *htbl)
|
|
|
|
{
|
|
|
|
ListElmt *element;
|
|
|
|
int i;
|
|
|
|
appsess *asession;
|
|
|
|
|
|
|
|
/*********************************************************************
|
|
|
|
* *
|
|
|
|
* Display the chained hash table. *
|
|
|
|
* *
|
|
|
|
*********************************************************************/
|
|
|
|
|
|
|
|
fprintf(stdout, "Table size is %d\n", chtbl_size(htbl));
|
|
|
|
|
|
|
|
for (i = 0; i < TBLSIZ; i++) {
|
|
|
|
fprintf(stdout, "Bucket[%03d]\n", i);
|
|
|
|
|
|
|
|
for (element = list_head(&htbl->table[i]);
|
|
|
|
element != NULL; element = list_next(element)) {
|
|
|
|
//fprintf(stdout, "%c", *(char *)list_data(element));
|
|
|
|
asession = (appsess *)list_data(element);
|
|
|
|
fprintf(stdout, "ELEM :%s:", asession->sessid);
|
|
|
|
fprintf(stdout, " Server :%s: \n", asession->serverid);
|
|
|
|
//fprintf(stdout, " Server request_count :%li:\n",asession->request_count);
|
|
|
|
}
|
|
|
|
|
|
|
|
fprintf(stdout, "\n");
|
|
|
|
}
|
|
|
|
return;
|
|
|
|
} /* end print_table */
|
|
|
|
#endif
|
|
|
|
|
|
|
|
int appsession_init(void)
|
|
|
|
{
|
|
|
|
static int initialized = 0;
|
|
|
|
int idlen;
|
|
|
|
struct server *s;
|
|
|
|
struct proxy *p = proxy;
|
|
|
|
|
|
|
|
if (!initialized) {
|
|
|
|
if (!appsession_task_init()) {
|
|
|
|
apools.sessid = NULL;
|
|
|
|
apools.serverid = NULL;
|
|
|
|
apools.ser_waste = 0;
|
|
|
|
apools.ser_use = 0;
|
|
|
|
apools.ser_msize = sizeof(void *);
|
|
|
|
apools.ses_waste = 0;
|
|
|
|
apools.ses_use = 0;
|
|
|
|
apools.ses_msize = sizeof(void *);
|
|
|
|
while (p) {
|
|
|
|
s = p->srv;
|
|
|
|
if (apools.ses_msize < p->appsession_len)
|
|
|
|
apools.ses_msize = p->appsession_len;
|
|
|
|
while (s) {
|
|
|
|
idlen = strlen(s->id);
|
|
|
|
if (apools.ser_msize < idlen)
|
|
|
|
apools.ser_msize = idlen;
|
|
|
|
s = s->next;
|
|
|
|
}
|
|
|
|
p = p->next;
|
|
|
|
}
|
|
|
|
/* we use strings, so reserve space for '\0' */
|
|
|
|
apools.ser_msize ++;
|
|
|
|
apools.ses_msize ++;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
fprintf(stderr, "appsession_task_init failed\n");
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
initialized ++;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int appsession_task_init(void)
|
|
|
|
{
|
|
|
|
static int initialized = 0;
|
|
|
|
struct task *t;
|
|
|
|
if (!initialized) {
|
2007-05-13 17:43:47 +00:00
|
|
|
if ((t = pool_alloc2(pool2_task)) == NULL)
|
2006-06-26 00:48:02 +00:00
|
|
|
return -1;
|
2007-01-06 23:38:00 +00:00
|
|
|
t->wq = NULL;
|
2007-04-29 08:41:56 +00:00
|
|
|
t->qlist.p = NULL;
|
2006-06-26 00:48:02 +00:00
|
|
|
t->state = TASK_IDLE;
|
|
|
|
t->context = NULL;
|
2007-04-29 15:43:56 +00:00
|
|
|
tv_ms_add(&t->expire, &now, TBLCHKINT);
|
2006-06-26 00:48:02 +00:00
|
|
|
task_queue(t);
|
|
|
|
t->process = appsession_refresh;
|
|
|
|
initialized ++;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2007-05-12 20:35:00 +00:00
|
|
|
void appsession_refresh(struct task *t, struct timeval *next)
|
2006-06-26 00:48:02 +00:00
|
|
|
{
|
|
|
|
struct proxy *p = proxy;
|
|
|
|
CHTbl *htbl;
|
|
|
|
ListElmt *element, *last;
|
|
|
|
int i;
|
|
|
|
appsess *asession;
|
|
|
|
void *data;
|
|
|
|
|
|
|
|
while (p) {
|
|
|
|
if (p->appsession_name != NULL) {
|
|
|
|
htbl = &p->htbl_proxy;
|
|
|
|
/* if we ever give up the use of TBLSIZ, we need to change this */
|
|
|
|
for (i = 0; i < TBLSIZ; i++) {
|
|
|
|
last = NULL;
|
|
|
|
for (element = list_head(&htbl->table[i]);
|
|
|
|
element != NULL; element = list_next(element)) {
|
|
|
|
asession = (appsess *)list_data(element);
|
2007-05-13 14:08:19 +00:00
|
|
|
if (tv_isle(&asession->expire, &now)) {
|
2006-06-26 00:48:02 +00:00
|
|
|
if ((global.mode & MODE_DEBUG) &&
|
|
|
|
(!(global.mode & MODE_QUIET) || (global.mode & MODE_VERBOSE))) {
|
|
|
|
int len;
|
|
|
|
/*
|
|
|
|
on Linux NULL pointers are catched by sprintf, on solaris -> segfault
|
|
|
|
*/
|
|
|
|
len = sprintf(trash, "appsession_refresh: cleaning up expired Session '%s' on Server %s\n",
|
|
|
|
asession->sessid, asession->serverid?asession->serverid:"(null)");
|
|
|
|
write(1, trash, len);
|
|
|
|
}
|
|
|
|
/* delete the expired element from within the hash table */
|
|
|
|
if ((list_rem_next(&htbl->table[i], last, (void **)&data) == 0)
|
|
|
|
&& (htbl->table[i].destroy != NULL)) {
|
|
|
|
htbl->table[i].destroy(data);
|
|
|
|
}
|
|
|
|
if (last == NULL) {/* patient lost his head, get a new one */
|
|
|
|
element = list_head(&htbl->table[i]);
|
|
|
|
if (element == NULL) break; /* no heads left, go to next patient */
|
|
|
|
}
|
|
|
|
else
|
|
|
|
element = last;
|
2007-05-13 14:08:19 +00:00
|
|
|
}/* end if (tv_isle(&asession->expire, &now)) */
|
2006-06-26 00:48:02 +00:00
|
|
|
else
|
|
|
|
last = element;
|
|
|
|
}/* end for (element = list_head(&htbl->table[i]); element != NULL; element = list_next(element)) */
|
|
|
|
}
|
|
|
|
}
|
|
|
|
p = p->next;
|
|
|
|
}
|
2007-04-29 15:43:56 +00:00
|
|
|
tv_ms_add(&t->expire, &now, TBLCHKINT); /* check expiration every 5 seconds */
|
2007-05-12 20:35:00 +00:00
|
|
|
*next = t->expire;
|
2006-06-26 00:48:02 +00:00
|
|
|
} /* end appsession_refresh */
|
|
|
|
|
|
|
|
int match_str(const void *key1, const void *key2)
|
|
|
|
{
|
|
|
|
appsess *temp1,*temp2;
|
|
|
|
temp1 = (appsess *)key1;
|
|
|
|
temp2 = (appsess *)key2;
|
|
|
|
|
|
|
|
//fprintf(stdout,">>>>>>>>>>>>>>temp1->sessid :%s:\n",temp1->sessid);
|
|
|
|
//fprintf(stdout,">>>>>>>>>>>>>>temp2->sessid :%s:\n",temp2->sessid);
|
|
|
|
|
|
|
|
return (strcmp(temp1->sessid,temp2->sessid) == 0);
|
|
|
|
}/* end match_str */
|
|
|
|
|
|
|
|
void destroy(void *data) {
|
|
|
|
appsess *temp1;
|
|
|
|
|
|
|
|
//printf("destroy called\n");
|
|
|
|
temp1 = (appsess *)data;
|
|
|
|
|
|
|
|
if (temp1->sessid)
|
|
|
|
pool_free_to(apools.sessid, temp1->sessid);
|
|
|
|
|
|
|
|
if (temp1->serverid)
|
|
|
|
pool_free_to(apools.serverid, temp1->serverid);
|
|
|
|
|
|
|
|
pool_free(appsess, temp1);
|
|
|
|
} /* end destroy */
|
|
|
|
|
|
|
|
void appsession_cleanup( void )
|
|
|
|
{
|
|
|
|
struct proxy *p = proxy;
|
|
|
|
|
|
|
|
while(p) {
|
|
|
|
chtbl_destroy(&(p->htbl_proxy));
|
|
|
|
p = p->next;
|
|
|
|
}
|
|
|
|
}/* end appsession_cleanup() */
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Local variables:
|
|
|
|
* c-indent-level: 8
|
|
|
|
* c-basic-offset: 8
|
|
|
|
* End:
|
|
|
|
*/
|