Exemplo n.º 1
0
int ims_pm_pre_script(struct sip_msg *msg,void *param)
{
	str method={0,0};

	if (msg->first_line.type == SIP_REQUEST){		
		method = msg->first_line.u.request.method;	
		if (method.len==s_invite.len && strncasecmp(method.s,s_invite.s,s_invite.len)==0){
			/* INVITE */
			IMS_PM_LOG11(SC_AttSession,cscf_get_call_id(msg,0),cscf_get_cseq(msg,0));
			IMS_PM_LOG21(IC_AttSessionFromOtherNtwkDmn,cscf_get_call_id(msg,0),
				cscf_get_asserted_identity_domain(msg),
				cscf_get_cseq(msg,0));
			IMS_PM_LOG21(IC_AttSessionToOtherNtwkDmn,cscf_get_call_id(msg,0),
				cscf_get_realm_from_ruri(msg),
				cscf_get_cseq(msg,0));			
		}else{
			/* Other requests */
			IMS_PM_LOG21(OTHER_Att,cscf_get_call_id(msg,0),method,cscf_get_cseq(msg,0));
		}						
	}else{
		unsigned int code = msg->first_line.u.reply.statuscode;
		method = cscf_get_cseq_method(msg,0);
		if (method.len==s_invite.len && strncasecmp(method.s,s_invite.s,s_invite.len)==0){
			/* INVITE response */
			if (code<300) IMS_PM_LOG12(SC_SuccSession,cscf_get_call_id(msg,0),cscf_get_cseq(msg,0),code);
			else if (code>=300) {
				IMS_PM_LOG12(SC_FailSession,cscf_get_call_id(msg,0),cscf_get_cseq(msg,0),code);
				if (code==403) {
					IMS_PM_LOG22(IC_403SessionFromOtherNtwkDmn,cscf_get_call_id(msg,0),
						cscf_get_asserted_identity_domain(msg),cscf_get_cseq(msg,0),code);
					IMS_PM_LOG22(IC_403SessionToOtherNtwkDmn,cscf_get_call_id(msg,0),
						cscf_get_realm_from_ruri(msg),cscf_get_cseq(msg,0),code);
				}										
			}			
		}else{	
			/* Other responses */
			if (code>=200 && code<300) IMS_PM_LOG22(OTHER_Succ,cscf_get_call_id(msg,0),method,cscf_get_cseq(msg,0),code);
			else if (code>=300)	IMS_PM_LOG22(OTHER_Fail,cscf_get_call_id(msg,0),method,cscf_get_cseq(msg,0),code);
		}		
	}
	return 1;
}
Exemplo n.º 2
0
/**
 * Perform User Authorization Request.
 * creates and send the user authorization query
 * @param msg - the SIP message
 * @param str1 - the realm
 * @param str2 - if to do capabilities
 * @returns true if OK, false if not
 */
int I_perform_user_authorization_request(struct sip_msg* msg, char* str1, char* str2) {
    str private_identity, public_identity, visited_network_id;
    int authorization_type = AVP_IMS_UAR_REGISTRATION;
    int expires = 3600;
    struct hdr_field *hdr;
    str realm;
    contact_t *c;
    int sos_reg = 0;
    contact_body_t *b = 0;
    str call_id;
    saved_uar_transaction_t* saved_t;
    tm_cell_t *t = 0;
    int intvalue_param;
    cfg_action_t* cfg_action;

    uar_param_t* ap = (uar_param_t*) str1;
    if (fixup_get_ivalue(msg, ap->ivalue, &intvalue_param) != 0) {
        LM_ERR("no int value param passed\n");
        return CSCF_RETURN_ERROR;
    }
    cfg_action = ap->paction->next;

    realm = cscf_get_realm_from_ruri(msg);

    //check if we received what we should, we do this even though it should be done in cfg file - double checking!
    if (msg->first_line.type != SIP_REQUEST) {
        LM_ERR("ERR:I_UAR: The message is not a request\n");
        return CSCF_RETURN_ERROR;
    }
    if (msg->first_line.u.request.method.len != 8 ||
            memcmp(msg->first_line.u.request.method.s, "REGISTER", 8) != 0) {
        LM_ERR("ERR:I_UAR: The method is not a REGISTER\n");
        return CSCF_RETURN_ERROR;
    }

    private_identity = cscf_get_private_identity(msg, realm);
    if (!private_identity.len) {
        LM_ERR("ERR:I_UAR: Private Identity not found, responding with 400\n");
        cscf_reply_transactional(msg, 400, MSG_400_NO_PRIVATE);
        return CSCF_RETURN_BREAK;
    }

    public_identity = cscf_get_public_identity(msg);
    if (!public_identity.len) {
        LM_ERR("ERR:I_UAR: Public Identity not found, responding with 400\n");
        cscf_reply_transactional(msg, 400, MSG_400_NO_PUBLIC);
        return CSCF_RETURN_BREAK;

    }

    b = cscf_parse_contacts(msg);

    if (!b || (!b->contacts && !b->star)) {
        LM_DBG("DBG:I_UAR: No contacts found\n");
        return CSCF_RETURN_ERROR;
    }

    for (c = b->contacts; c; c = c->next) {

        sos_reg = cscf_get_sos_uri_param(c->uri);
        if (sos_reg == -1) {
            //error case
            LM_ERR("ERR:I_UAR: MSG_400_MALFORMED_CONTACT, responding with 400\n");
            cscf_reply_transactional(msg, 400, MSG_400_MALFORMED_CONTACT);
            return CSCF_RETURN_BREAK;
        } else if (sos_reg == -2) {
            LM_ERR("ERR:I_UAR: MSG_500_SERVER_ERROR_OUT_OF_MEMORY, responding with 500\n");
            cscf_reply_transactional(msg, 500, MSG_500_SERVER_ERROR_OUT_OF_MEMORY);
            return CSCF_RETURN_BREAK;
        }
    }

    visited_network_id = cscf_get_visited_network_id(msg, &hdr);
    if (!visited_network_id.len) {
        LM_ERR("ERR:I_UAR: Visited Network Identity not found, responding with 400\n");
        cscf_reply_transactional(msg, 400, MSG_400_NO_VISITED);
        return CSCF_RETURN_BREAK;
    }

    if (atoi(str1)) authorization_type = AVP_IMS_UAR_REGISTRATION_AND_CAPABILITIES;
    else {
        expires = cscf_get_max_expires(msg, 0);
        if (expires == 0) authorization_type = AVP_IMS_UAR_DE_REGISTRATION;
    }

    LM_DBG("SENDING UAR: PI: [%.*s], PU: [%.*s], VNID: [%.*s]\n", private_identity.len, private_identity.s,
            public_identity.len, public_identity.s,
            visited_network_id.len, visited_network_id.s);

    //before we send lets suspend the transaction
    t = tmb.t_gett();
    if (t == NULL || t == T_UNDEFINED) {
        if (tmb.t_newtran(msg) < 0) {
            LM_ERR("cannot create the transaction for UAR async\n");
            cscf_reply_transactional(msg, 480, MSG_480_DIAMETER_ERROR);
            return CSCF_RETURN_BREAK;
        }
        t = tmb.t_gett();
        if (t == NULL || t == T_UNDEFINED) {
            LM_ERR("cannot lookup the transaction\n");
            cscf_reply_transactional(msg, 480, MSG_480_DIAMETER_ERROR);
            return CSCF_RETURN_BREAK;
        }
    }

    saved_t = shm_malloc(sizeof (saved_uar_transaction_t));
    if (!saved_t) {
        LM_ERR("no more memory trying to save transaction state\n");
        return CSCF_RETURN_ERROR;

    }
    memset(saved_t, 0, sizeof (saved_uar_transaction_t));
    saved_t->act = cfg_action;

    call_id = cscf_get_call_id(msg, 0);
    saved_t->callid.s = (char*) shm_malloc(call_id.len + 1);
    if (!saved_t->callid.s) {
    	LM_ERR("no more memory trying to save transaction state : callid\n");
    	shm_free(saved_t);
    	return CSCF_RETURN_ERROR;
    }
    memset(saved_t->callid.s, 0, call_id.len + 1);
    memcpy(saved_t->callid.s, call_id.s, call_id.len);
    saved_t->callid.len = call_id.len;

    LM_DBG("Setting default AVP return code used for async callbacks to default as ERROR \n");
    create_uaa_return_code(CSCF_RETURN_ERROR);
    
    LM_DBG("Suspending SIP TM transaction\n");
    if (tmb.t_suspend(msg, &saved_t->tindex, &saved_t->tlabel) < 0) {
        LM_ERR("failed to suspend the TM processing\n");
        free_saved_uar_transaction_data(saved_t);

        cscf_reply_transactional(msg, 480, MSG_480_DIAMETER_ERROR);
        return CSCF_RETURN_BREAK;
    }

    if (cxdx_send_uar(msg, private_identity, public_identity, visited_network_id, authorization_type, sos_reg, saved_t) != 0) {
        LM_ERR("ERR:I_UAR: Error sending UAR or UAR time-out\n");
        tmb.t_cancel_suspend(saved_t->tindex, saved_t->tlabel);
        free_saved_uar_transaction_data(saved_t);
        cscf_reply_transactional(msg, 480, MSG_480_DIAMETER_ERROR);
        return CSCF_RETURN_BREAK;

    }
    //we use async replies therefore we send break and not true when successful
    return CSCF_RETURN_BREAK;
}