示例#1
0
文件: session.c 项目: 2pac/kamailio
/**
 * Destroys the session related structures.
 */
int cdp_sessions_destroy()
{
	int i;
	cdp_session_t *n,*x;

	if (session_lock){
		lock_get(session_lock);
		lock_destroy(session_lock);
		lock_dealloc((void*)session_lock);
		session_lock=0;
	}
	for(i=0;i<sessions_hash_size;i++){
		AAASessionsLock(i);
		for(x = sessions[i].head; x; x = n){
			n = x->next;
			free_session(x);
		}
		lock_destroy(sessions[i].lock);
		lock_dealloc((void*)sessions[i].lock);
	}
	shm_free(sessions);

	shm_free(session_id1);
	shm_free(session_id2);
	return 1;
}
示例#2
0
文件: session.c 项目: 2pac/kamailio
/**
 * Adds the session to the session list.
 * \note This returns with a lock, so unlock when done
 * @param x - the session to add
 */
void cdp_add_session(cdp_session_t *x)
{
//	unsigned int hash;
	if (!x) return;
//	hash = get_str_hash(x->id,sessions_hash_size);
//	x->hash = hash;
	LM_DBG("adding a session with id %.*s\n",x->id.len,x->id.s);
	AAASessionsLock(x->hash);
	x->next = 0;
	x->prev = sessions[x->hash].tail;
	if (sessions[x->hash].tail) sessions[x->hash].tail->next = x;
	sessions[x->hash].tail = x;
	if (!sessions[x->hash].head) sessions[x->hash].head = x;
}
示例#3
0
文件: session.c 项目: 2pac/kamailio
/**
 * Finds a session in the session hash table.
 * \note Returns with a lock on the sessions[x->hash].lock!!!
 * @param id - the id of the session
 * @returns the session if found or 0 if not
 */
cdp_session_t* cdp_get_session(str id)
{
	unsigned int hash;
	cdp_session_t *x;
	if (!id.len) return 0;
	hash = get_str_hash(id,sessions_hash_size);
	LM_DBG("called get session with id %.*s and hash %u\n",id.len,id.s,hash);
	AAASessionsLock(hash);
		for(x = sessions[hash].head;x;x=x->next){
			LM_DBG("looking for |%.*s| in |%.*s|\n",id.len,id.s,x->id.len,x->id.s);
			if (x->id.len == id.len &&
				strncasecmp(x->id.s,id.s,id.len)==0)
					return x;
		}
	AAASessionsUnlock(hash);
	LM_DBG("no session found\n");
	return 0;
}
示例#4
0
文件: session.c 项目: 2pac/kamailio
void cdp_sessions_log()
{
	int hash;
	cdp_session_t *x;

	LM_DBG(ANSI_MAGENTA"------- CDP Sessions ----------------\n"ANSI_GREEN);
	for(hash=0;hash<sessions_hash_size;hash++){
		AAASessionsLock(hash);
		for(x = sessions[hash].head;x;x=x->next) {
			LM_DBG(ANSI_GRAY" %3u. [%.*s] AppId [%d] Type [%d]\n",
					hash,
					x->id.len,x->id.s,
					x->application_id,
					x->type);
			switch (x->type){
				case AUTH_CLIENT_STATEFULL:
				case AUTH_SERVER_STATEFULL:
					LM_DBG(ANSI_GRAY"\tAuth State [%d] Timeout [%d] Lifetime [%d] Grace [%d] Generic [%p]\n",
							x->u.auth.state,
							(int)(x->u.auth.timeout-time(0)),
							x->u.auth.lifetime?(int)(x->u.auth.lifetime-time(0)):-1,
							(int)(x->u.auth.grace_period),
							x->u.auth.generic_data);
					break;
				case ACCT_CC_CLIENT:
					LM_DBG(ANSI_GRAY"\tCCAcct State [%d] Charging Active [%c (%d)s] Reserved Units(valid=%ds) [%d] Generic [%p]\n",
							x->u.cc_acc.state,
							(x->u.cc_acc.charging_start_time&&x->u.cc_acc.state!=ACC_CC_ST_DISCON)?'Y':'N',
							x->u.cc_acc.charging_start_time?(int)((int)time(0) - (int)x->u.cc_acc.charging_start_time):-1,
							x->u.cc_acc.reserved_units?(int)((int)x->u.cc_acc.last_reservation_request_time + x->u.cc_acc.reserved_units_validity_time) - (int)time(0):-1,
							x->u.cc_acc.reserved_units,
							x->u.cc_acc.generic_data);
					break;
				default:
					break;
			}
		}
		AAASessionsUnlock(hash);
	}
	LM_DBG(ANSI_MAGENTA"-------------------------------------\n"ANSI_GREEN);
}
示例#5
0
/**
 * Get the first peer that is connected from the list of routing entries.
 * @param r - the list of routing entries to look into
 * @returns - the peer or null if none connected
 */
peer* get_first_connected_route(cdp_session_t* cdp_session, routing_entry *r, int app_id, int vendor_id) {
	peer * peers[LB_MAX_PEERS];
	int peer_count = 0;
	int prev_metric = 0;
	routing_entry *i;
	peer *p;
	int j;
	time_t least_recent_time;
	struct timespec time_spec;

	if (cdp_session) {
		/*try and find an already used peer for this session - sticky*/
		if ((cdp_session->sticky_peer_fqdn.len > 0) && cdp_session->sticky_peer_fqdn.s) {
			//we have an old sticky peer. let's make sure it's up and connected before we use it.
			AAASessionsUnlock(cdp_session->hash); /*V1.1 - Don't attempt to hold two locks at same time */
			p = get_peer_by_fqdn(&cdp_session->sticky_peer_fqdn);
			AAASessionsLock(cdp_session->hash); /*V1.1 - As we were...no call seems to pass cdp_session unlocked */
			if (p && !p->disabled && (p->state == I_Open || p->state == R_Open) && peer_handles_application(p, app_id, vendor_id)) {
				p->last_selected = time(NULL);
				LM_DBG("Found a sticky peer [%.*s] for this session - re-using\n", p->fqdn.len, p->fqdn.s);
				return p;
			}
		}
	}

	for (i = r; i; i = i->next) {
		if (peer_count >= LB_MAX_PEERS)
			break;
		p = get_peer_by_fqdn(&(i->fqdn));
		if (!p)
			LM_DBG("The peer %.*s does not seem to be connected or configured\n",
					i->fqdn.len, i->fqdn.s);
		else
			LM_DBG("The peer %.*s state is %s\n", i->fqdn.len, i->fqdn.s,
					(p->state == I_Open || p->state == R_Open) ? "opened" : "closed");
		if (p && !p->disabled && (p->state == I_Open || p->state == R_Open) && peer_handles_application(p, app_id, vendor_id)) {
			LM_DBG("The peer %.*s matches - will forward there\n", i->fqdn.len, i->fqdn.s);
			if (peer_count != 0) {//check the metric
				if (i->metric != prev_metric)
					break;
				//metric must be the same
				peers[peer_count++] = p;
			} else {//we're first
				prev_metric = i->metric;
				peers[peer_count++] = p;
			}
		}
	}

	if (peer_count == 0) {
		return 0;
	}

	least_recent_time = peers[0]->last_selected;
	LM_DBG("peer [%.*s] was last used @ %ld\n", peers[0]->fqdn.len, peers[0]->fqdn.s, peers[0]->last_selected);
	p = peers[0];
	for (j = 1; j < peer_count; j++) {
		LM_DBG("Peer [%.*s] was last used at [%ld]\n", peers[j]->fqdn.len, peers[j]->fqdn.s, peers[j]->last_selected);
		if (peers[j]->last_selected < least_recent_time) {
			least_recent_time = peers[j]->last_selected;
			p = peers[j];
		}
	}

	ser_clock_gettime(&time_spec);

	p->last_selected = (time_spec.tv_sec*1000000) + round(time_spec.tv_nsec / 1.0e3); // Convert nanoseconds to microseconds
	LM_DBG("chosen peer [%.*s]\n", p->fqdn.len, p->fqdn.s);

	if (cdp_session) {
		if (cdp_session->sticky_peer_fqdn_buflen <= p->fqdn.len) {
			LM_DBG("not enough storage for sticky peer - allocating more\n");
			if (cdp_session->sticky_peer_fqdn.s)
				shm_free(cdp_session->sticky_peer_fqdn.s);

			cdp_session->sticky_peer_fqdn.s = (char*) shm_malloc(p->fqdn.len + 1);
			if (!cdp_session->sticky_peer_fqdn.s) {
				LM_ERR("no more shm memory\n");
				return 0;
			}
			cdp_session->sticky_peer_fqdn_buflen = p->fqdn.len + 1;
			memset(cdp_session->sticky_peer_fqdn.s, 0, p->fqdn.len + 1);
		}
		cdp_session->sticky_peer_fqdn.len = p->fqdn.len;
		memcpy(cdp_session->sticky_peer_fqdn.s, p->fqdn.s, p->fqdn.len);
	}

	return p;
}
示例#6
0
文件: session.c 项目: 2pac/kamailio
int cdp_sessions_timer(time_t now, void* ptr)
{
	int hash;
	cdp_session_t *x,*n;
	for(hash=0;hash<sessions_hash_size;hash++){
		AAASessionsLock(hash);
		for(x = sessions[hash].head;x;x=n) {
			n = x->next;
			switch (x->type){
				case ACCT_CC_CLIENT:
					if (x->u.cc_acc.type == ACC_CC_TYPE_SESSION) {
						//check for old, stale sessions, we need to do something more elegant
						//here to ensure that if a CCR start record is sent and the client never sends anything
						//else that we catch it and clean up the session from within CDP, calling all callbacks, etc
						if ((time(0) > (x->u.cc_acc.discon_time + GRACE_DISCON_TIMEOUT)) && (x->u.cc_acc.state==ACC_CC_ST_DISCON)) {
							cc_acc_client_stateful_sm_process(x, ACC_CC_EV_SESSION_STALE, 0);
						}
						//check reservation timers - again here we are assuming CC-Time applications
						int last_res_timestamp = x->u.cc_acc.last_reservation_request_time;
						int res_valid_for = x->u.cc_acc.reserved_units_validity_time;
						int last_reservation = x->u.cc_acc.reserved_units;
						int buffer_time = 15; //15 seconds - TODO: add as config parameter
						//we should check for reservation expiries if the state is open
						if(x->u.cc_acc.state==ACC_CC_ST_OPEN){
						    if (last_res_timestamp) {
							    //we have obv already started reservations
							    if ((last_res_timestamp + res_valid_for) < (time(0) + last_reservation + buffer_time)) {
								    LM_DBG("reservation about to expire, sending callback\n");
								    cc_acc_client_stateful_sm_process(x, ACC_CC_EV_RSVN_WARNING, 0);
							    }

						    }
						}
						/* TODO: if reservation has expired we need to tear down the session. Ideally 
						 * the client application (module) should do this but for completeness we should
						 * put a failsafe here too.
						 */
					}
					break;
				case AUTH_CLIENT_STATEFULL:
					if (x->u.auth.timeout>=0 && x->u.auth.timeout<=now){
						//Session timeout
						LM_CRIT("session TIMEOUT\n");
						auth_client_statefull_sm_process(x,AUTH_EV_SESSION_TIMEOUT,0);
					} else if (x->u.auth.lifetime>0 && x->u.auth.lifetime+x->u.auth.grace_period<=now){
						//lifetime + grace timeout
						LM_CRIT("lifetime+grace TIMEOUT\n");
						auth_client_statefull_sm_process(x,AUTH_EV_SESSION_GRACE_TIMEOUT,0);
					}else if (x->u.auth.lifetime>0 && x->u.auth.lifetime<=now){
						//lifetime timeout
						LM_CRIT("lifetime+grace TIMEOUT\n");
						auth_client_statefull_sm_process(x,AUTH_EV_SESSION_LIFETIME_TIMEOUT,0);
					}
					break;
				case AUTH_SERVER_STATEFULL:
					if (x->u.auth.timeout>=0 && x->u.auth.timeout<=now){
						//Session timeout
						LM_CRIT("session TIMEOUT\n");
						auth_server_statefull_sm_process(x,AUTH_EV_SESSION_TIMEOUT,0);
					}else if (x->u.auth.lifetime>0 && x->u.auth.lifetime+x->u.auth.grace_period<=now){
						//lifetime + grace timeout
						LM_CRIT("lifetime+grace TIMEOUT\n");
						auth_server_statefull_sm_process(x,AUTH_EV_SESSION_GRACE_TIMEOUT,0);
					}else if (x->u.auth.lifetime>0 && x->u.auth.lifetime<=now){
						//lifetime timeout
						LM_CRIT("lifetime+grace TIMEOUT\n");
						auth_server_statefull_sm_process(x,AUTH_EV_SESSION_LIFETIME_TIMEOUT,0);
					}
					break;
				default:
					break;

			}
		}
		AAASessionsUnlock(hash);
	}
	if (now%5==0)cdp_sessions_log();
	return 1;
}