コード例 #1
0
ファイル: peerstatemachine.c プロジェクト: 4N7HR4X/kamailio
/**
 * 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);
	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 ACCT_CC_CLIENT:
				if (is_req(msg)) {
					LM_DBG("this is a request for CC app\n");
					cc_acc_client_stateful_sm_process(session, ACC_CC_EV_SEND_REQ, msg);
					session = 0;
				} else {
					LM_DBG("this is a response to CC app\n");
				}
				break;
			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);

}
コード例 #2
0
ファイル: peerstatemachine.c プロジェクト: 4N7HR4X/kamailio
/**
 * 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);

}
コード例 #3
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;
}