Esempio n. 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);
	
}
Esempio n. 2
0
/**
 * Creates a Authorization Session for the Server, from the application specific Session starting request
 * It generates a new id and adds the session to the cdp list of sessions
 * \note Returns with a lock on AAASession->hash. Unlock when done working with the result
 * @returns the new AAASession or null on error
 */
AAASession* AAACreateServerAuthSession(AAAMessage *msg,int is_statefull,AAASessionCallback_f *cb,void *generic_data)
{
	AAASession *s;
	str id;

	if (!msg||!msg->sessionId||!msg->sessionId->data.len){
		LM_ERR("Error retrieving the Session-Id from the message.\n");
		return 0;
	}
	id.s = shm_malloc(msg->sessionId->data.len);
	if (!id.s){
		LM_ERR("Error allocating %d bytes of shm!\n",msg->sessionId->data.len);
		return 0;
	}else{
		id.len = msg->sessionId->data.len;
		memcpy(id.s,msg->sessionId->data.s,id.len);
		s=cdp_new_auth_session(id,0,is_statefull);
		if (s) {
			s->u.auth.generic_data = generic_data;
			s->cb = cb;
			if (s->cb)
				(s->cb)(AUTH_EV_SESSION_CREATED,s);
			update_auth_session_timers(&(s->u.auth),msg);
			auth_server_statefull_sm_process(s,AUTH_EV_RECV_REQ,msg);
			// this is a special exception where the session lock is not released
			//s=0;
		}
	}
	return s;
}
Esempio n. 3
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;
	int nput=0;
	if (msg->sessionId) session = cdp_get_session(msg->sessionId->data);

	if (session){
		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);
					session = 0;
				}else {
					if (msg->commandCode==IMS_STA)
						nput=auth_client_statefull_sm_process(session,AUTH_EV_RECV_STA,msg);
					else
						auth_client_statefull_sm_process(session,AUTH_EV_RECV_ANS,msg);
					session = 0;
				}
				break;
			 case AUTH_SERVER_STATEFULL:
			 	if (is_req(msg))
			 	{
			 		if (msg->commandCode==IMS_STR)
			 		{
			 			auth_server_statefull_sm_process(session,AUTH_EV_RECV_STR,msg);
			 		} else {
			 			auth_server_statefull_sm_process(session,AUTH_EV_RECV_REQ,msg);
			 		}
					session = 0;			 		
			 	}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);
					session = 0;			 		
			 	}
			 	break;
			default:
				AAASessionsUnlock(session->hash);
				session =0;
				break;			 
		}
	}else{
		if (msg->sessionId){
			if (msg->commandCode == IMS_ASR) 
				auth_client_statefull_sm_process(0,AUTH_EV_RECV_ASR,msg);
		} 
				 
	}
	if (!nput && !put_task(p,msg)){
		LM_ERR("Rcv_Process(): Queue refused task\n");
		if (msg) AAAFreeMessage(&msg); 
	}
	//if (msg) LM_ERR("Rcv_Process(): task added to queue command %d, flags %#1x endtoend %u hopbyhop %u\n",msg->commandCode,msg->flags,msg->endtoendId,msg->hopbyhopId);
	
//	AAAPrintMessage(msg);
	
}
Esempio n. 4
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;
	LM_DBG("Snd_Message called to peer [%.*s] for %s with code %d \n",
		p->fqdn.len,p->fqdn.s,is_req(msg)?"request":"response",msg->commandCode);
	touch_peer(p);
	if (msg->sessionId) session = cdp_get_session(msg->sessionId->data);
	
	if (session){
		LM_DBG("There is a session of type %d\n",session->type);
		switch (session->type){
			case AUTH_CLIENT_STATEFULL:
				if (is_req(msg)) {
					auth_client_statefull_sm_process(session,AUTH_EV_SEND_REQ,msg);
					session = 0;
				}
				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);
							session = 0;
						}
						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);
								session = 0;
							}
							else {
								auth_client_statefull_sm_process(session,AUTH_EV_SEND_ASA_UNSUCCESS,msg);
								session = 0;
							}
						}
						
					}else {
						auth_client_statefull_sm_process(session,AUTH_EV_SEND_ANS,msg);
						session = 0;
					}
				}
				break;
			case AUTH_SERVER_STATEFULL:
				LM_DBG("this message is matched here to see what request or reply it is\n");
				if (is_req(msg))
				{
					if (msg->commandCode== IMS_ASR)
					{
						LM_DBG("ASR\n");
						auth_server_statefull_sm_process(session,AUTH_EV_SEND_ASR,msg);
						session = 0;
					} else {
						//would be a RAR but ok!
						LM_DBG("other request\n");
						auth_server_statefull_sm_process(session,AUTH_EV_SEND_REQ,msg);
						session = 0;
					}
				} else {
					if (msg->commandCode == IMS_STR)
					{
						LM_DBG("STA\n");
						auth_server_statefull_sm_process(session,AUTH_EV_SEND_STA,msg);
						session = 0;
					} else {
						LM_DBG("other reply\n");
						auth_server_statefull_sm_process(session,AUTH_EV_SEND_ANS,msg);
						session = 0;
					}
				}
				break;				 
			default:
				break;
		}
		if (session) AAASessionsUnlock(session->hash);
	}
	if (!send_message_before_session_sm) peer_send_msg(p,msg);
	
}
Esempio n. 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;
	int nput=0;
	if (msg->sessionId) session = cdp_get_session(msg->sessionId->data);

	if (session){
		switch (session->type){
			case ACCT_CC_CLIENT:
				if (is_req(msg)){
					LM_WARN("unhandled receive request on Credit Control Acct session\n");
					AAASessionsUnlock(session->hash);	//must be called because we dont call state machine here
					session = 0; //we dont call SM here so we mustnt set to 0
				} else {
					cc_acc_client_stateful_sm_process(session, ACC_CC_EV_RECV_ANS, msg);
					session = 0;
				}
				break;
			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);
					session = 0;
				}else {
					if (msg->commandCode==IMS_STA)
						nput=auth_client_statefull_sm_process(session,AUTH_EV_RECV_STA,msg);
					else
						auth_client_statefull_sm_process(session,AUTH_EV_RECV_ANS,msg);
					session = 0;
				}
				break;
			case AUTH_SERVER_STATEFULL:
				if (is_req(msg))
				{
					if (msg->commandCode==IMS_STR)
					{
						auth_server_statefull_sm_process(session,AUTH_EV_RECV_STR,msg);
					} else {
						auth_server_statefull_sm_process(session,AUTH_EV_RECV_REQ,msg);
					}
					session = 0;
				}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);
					session = 0;
				}
				break;
			default:
				AAASessionsUnlock(session->hash);
				session =0;
				break;
		}
	}else{
		if (msg->sessionId){
			if (msg->commandCode == IMS_ASR)
				auth_client_statefull_sm_process(0,AUTH_EV_RECV_ASR,msg);
		}

	}
	if (!nput && !put_task(p,msg)){
		LM_ERR("Rcv_Process(): Queue refused task\n");
		if (msg) AAAFreeMessage(&msg);
	}
	//if (msg) LM_ERR("Rcv_Process(): task added to queue command %d, flags %#1x endtoend %u hopbyhop %u\n",msg->commandCode,msg->flags,msg->endtoendId,msg->hopbyhopId);

	//	AAAPrintMessage(msg);

}
Esempio n. 6
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);
	
}
Esempio n. 7
0
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;
}