Beispiel #1
0
/**
 * Sends a message to the peer.
 * \note Must be called with a lock on the peer.
 * @param p - peer to send to
 * @param msg - message to send
 */
void Snd_Message(peer *p, AAAMessage *msg)
{
	AAASession *session=0;
	int rcode;
	int send_message_before_session_sm=0;
	touch_peer(p);
	if (msg->sessionId) session = get_session(msg->sessionId->data);
	
	if (session){
		switch (session->type){
			case AUTH_CLIENT_STATEFULL:
				if (is_req(msg))
					auth_client_statefull_sm_process(session,AUTH_EV_SEND_REQ,msg);
				else {
					if (msg->commandCode == IMS_ASA){
						if (!msg->res_code){
							msg->res_code = AAAFindMatchingAVP(msg,0,AVP_Result_Code,0,0);
						}
						if (!msg->res_code) auth_client_statefull_sm_process(session,AUTH_EV_SEND_ASA_UNSUCCESS,msg);
						else {
							rcode = get_4bytes(msg->res_code->data.s);
							if (rcode>=2000 && rcode<3000) {
								peer_send_msg(p,msg);
								send_message_before_session_sm=1;
								auth_client_statefull_sm_process(session,AUTH_EV_SEND_ASA_SUCCESS,msg);
							}
							else auth_client_statefull_sm_process(session,AUTH_EV_SEND_ASA_UNSUCCESS,msg);
						}
						
					}else
						auth_client_statefull_sm_process(session,AUTH_EV_SEND_ANS,msg);
				}
				break;
			case AUTH_SERVER_STATEFULL:
				if (is_req(msg))
				{
					if (msg->commandCode== IMS_ASR)
					{
						auth_server_statefull_sm_process(session,AUTH_EV_SEND_ASR,msg);
					} else {
						//would be a RAR but ok!
						auth_server_statefull_sm_process(session,AUTH_EV_SEND_REQ,msg);
					}
				} else {
					if (msg->commandCode == IMS_STR)
						auth_server_statefull_sm_process(session,AUTH_EV_SEND_STA,msg);
					else
						auth_server_statefull_sm_process(session,AUTH_EV_SEND_ANS,msg);
				}
				break;				 
			default:
				break;
		}
		sessions_unlock(session->hash);
	}
	if (!send_message_before_session_sm) peer_send_msg(p,msg);
	
}
void session_timer(time_t now, void* ptr)
{
	int hash;
	cdp_session_t *x;
	AAASessionCallback_f *cb;
	LOG(L_DBG,"-------session timer --------\n");
	for(hash=0;hash<sessions_hash_size;hash++){		
		sessions_lock(hash);
		for(x = sessions[hash].head;x;x=x->next) {
			
			
			LOG(L_DBG,"session of type [%i] with id %.*s in hash %u\n",x->type,x->id.len,x->id.s,hash);
			if (x->type==AUTH_CLIENT_STATEFULL) {
				LOG(L_DBG,"auth state [%i] timeout [%li]\n",x->u.auth.state,x->u.auth.timeout-now);
			} else LOG(L_INFO,"\n");
			
			
			 
			switch (x->type){
				case AUTH_CLIENT_STATEFULL:
					if (x->u.auth.timeout!=0 && x->u.auth.timeout<=now){
						//Session timeout
						LOG(L_CRIT,"session TIMEOUT\n");
						if (x->cb) {
							cb = x->cb;
							(cb)(AUTH_EV_SESSION_TIMEOUT,x->cb_param,x);
						}
						auth_client_statefull_sm_process(x,AUTH_EV_SESSION_TIMEOUT,0);
					}
					if (x->u.auth.timeout!=0 && x->u.auth.lifetime+x->u.auth.grace_period<=now){
						//lifetime + grace timeout
						LOG(L_CRIT,"grace TIMEOUT\n");
						if (x->cb){
							cb = x->cb;	
							(cb)(AUTH_EV_SESSION_GRACE_TIMEOUT,x->cb_param,x);
						}
						auth_client_statefull_sm_process(x,AUTH_EV_SESSION_GRACE_TIMEOUT,0);
					}
					break;
				default:
					break;
					
			}
		}
		sessions_unlock(hash);
	}
	LOG(L_DBG,"-------------------------------\n");
					
}
/**
 * Adds the session to the session list.
 * \note If you use x after this then lock first!!!
 * @param x - the session to add
 */
void add_session(cdp_session_t *x)
{
//	unsigned int hash;
	if (!x) return;
//	hash = get_str_hash(x->id,sessions_hash_size);
//	x->hash = hash;
	LOG(L_DBG,"adding a session with id %.*s\n",x->id.len,x->id.s);
	sessions_lock(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;
	sessions_unlock(x->hash);
}
/**
 * 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* get_session(str id)
{
	unsigned int hash;
	cdp_session_t *x;
	hash = get_str_hash(id,sessions_hash_size);
	LOG(L_DBG,"calling get session with id %.*s and hash %u\n",id.len,id.s,hash);
	sessions_lock(hash);
		for(x = sessions[hash].head;x;x=x->next)
		{
			LOG(L_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;
		}
	sessions_unlock(hash);		
	return 0;
}
Beispiel #5
0
/**
 * Processes an incoming message.
 * This actually just puts the message into a message queue. One worker will pick-it-up
 * and do the actual processing.
 * \note Must be called with a lock on the peer.
 * @param p - peer received from
 * @param msg - the message received
 */ 
void Rcv_Process(peer *p, AAAMessage *msg)
{
	AAASession *session=0;
	unsigned int hash; // we need this here because after the sm_processing , we might end up
					   // with no session any more
	if (msg->sessionId) session = get_session(msg->sessionId->data);
	
	if (session){
		hash=session->hash;
		switch (session->type){
			case AUTH_CLIENT_STATEFULL:
				if (is_req(msg)){
					if (msg->commandCode==IMS_ASR)
						auth_client_statefull_sm_process(session,AUTH_EV_RECV_ASR,msg);
					else 
						auth_client_statefull_sm_process(session,AUTH_EV_RECV_REQ,msg);
				}else {
					if (msg->commandCode==IMS_STA)
						auth_client_statefull_sm_process(session,AUTH_EV_RECV_STA,msg);
					else
						auth_client_statefull_sm_process(session,AUTH_EV_RECV_ANS,msg);
				}
				break;
			 case AUTH_SERVER_STATEFULL:
			 	if (is_req(msg))
			 	{
			 		auth_server_statefull_sm_process(session,AUTH_EV_RECV_REQ,msg);
			 	}else{
			 		if (msg->commandCode==IMS_ASA)
			 			auth_server_statefull_sm_process(session,AUTH_EV_RECV_ASA,msg);
			 		else
			 			auth_server_statefull_sm_process(session,AUTH_EV_RECV_ANS,msg);
			 	}
			 	break;
			default:
				break;			 
		}
		sessions_unlock(hash);
	}else{
		if (msg->sessionId){
			if (msg->commandCode == IMS_ASR) 
				auth_client_statefull_sm_process(0,AUTH_EV_RECV_ASR,msg);
			if (msg->commandCode == IMS_AAR)
			{
				session=AAACreateAuthSession(0,0,1,0,0);
				
				shm_str_dup(session->id,msg->sessionId->data); 
				auth_server_statefull_sm_process(0,AUTH_EV_RECV_REQ,msg);				
			}
			// Any other cases to think about?	 
		} 
				 
	}

	if (!put_task(p,msg)){
		LOG(L_ERR,"ERROR:Rcv_Process(): Queue refused task\n");
		AAAFreeMessage(&msg);
	}
	LOG(L_DBG,"DBG:Rcv_Process(): task added to queue\n");
	
//	AAAPrintMessage(msg);
	
}