/* * AppSession functions. * * Copyright 2004-2006 Alexander Lazic, Klaus Wagner * Copyright 2006-2007 Willy Tarreau * * 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 #include #include #include #include #include #include #include #include #include #include #include #include static struct task *appsess_refresh = NULL; struct pool_head *pool2_appsess; struct app_pool apools; int have_appsession; int appsession_init(void) { static int initialized = 0; int idlen; struct server *s; struct proxy *p = proxy; if (!initialized) { pool2_appsess = create_pool("appsess", sizeof(appsess), MEM_F_SHARED); if (pool2_appsess == NULL) return -1; if (!appsession_task_init()) { int ser_msize, ses_msize; apools.sessid = NULL; apools.serverid = NULL; ser_msize = sizeof(void *); ses_msize = sizeof(void *); while (p) { s = p->srv; if (ses_msize < p->appsession_len) ses_msize = p->appsession_len; while (s) { idlen = strlen(s->id); if (ser_msize < idlen) ser_msize = idlen; s = s->next; } p = p->next; } /* we use strings, so reserve space for '\0' */ ser_msize ++; ses_msize ++; apools.sessid = create_pool("sessid", ses_msize, MEM_F_SHARED); if (!apools.sessid) return -1; apools.serverid = create_pool("serverid", ser_msize, MEM_F_SHARED); if (!apools.serverid) return -1; } else { fprintf(stderr, "appsession_task_init failed\n"); return -1; } initialized ++; } return 0; } int appsession_task_init(void) { static int initialized = 0; if (!initialized) { if ((appsess_refresh = pool_alloc2(pool2_task)) == NULL) return -1; task_init(appsess_refresh); appsess_refresh->context = NULL; appsess_refresh->expire = tick_add(now_ms, MS_TO_TICKS(TBLCHKINT)); appsess_refresh->process = appsession_refresh; task_queue(appsess_refresh); initialized ++; } return 0; } void appsession_refresh(struct task *t, int *next) { struct proxy *p = proxy; struct appsession_hash *htbl; appsess *element, *back; int i; while (p) { if (p->appsession_name != NULL) { htbl = &p->htbl_proxy; as_hash_for_each_entry_safe(i, element, back, &p->htbl_proxy, hash_list) { if (tick_is_expired(element->expire, now_ms)) { if ((global.mode & MODE_DEBUG) && (!(global.mode & MODE_QUIET) || (global.mode & MODE_VERBOSE))) { int len; /* on Linux NULL pointers are caught by sprintf, on solaris -> segfault */ len = sprintf(trash, "appsession_refresh: cleaning up expired Session '%s' on Server %s\n", element->sessid, element->serverid?element->serverid:"(null)"); write(1, trash, len); } /* delete the expired element from within the hash table */ LIST_DEL(&element->hash_list); htbl->destroy(element); }/* end if (tv_isle(&asession->expire, &now)) */ } } p = p->next; } t->expire = tick_add(now_ms, MS_TO_TICKS(TBLCHKINT)); /* check expiration every 5 seconds */ task_queue(t); *next = t->expire; } /* 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(appsess *temp1) { if (temp1->sessid) pool_free2(apools.sessid, temp1->sessid); if (temp1->serverid) pool_free2(apools.serverid, temp1->serverid); pool_free2(pool2_appsess, temp1); } /* end destroy */ void appsession_cleanup( void ) { struct proxy *p = proxy; while(p) { appsession_hash_destroy(&(p->htbl_proxy)); p = p->next; } if (appsess_refresh) { task_delete(appsess_refresh); task_free(appsess_refresh); appsess_refresh = NULL; } }/* end appsession_cleanup() */ /* * Local variables: * c-indent-level: 8 * c-basic-offset: 8 * End: */