Пример #1
0
/**
 * Checks if there is a match on REGISTER.
 * Inserts route headers and set the dst_uri
 * @param msg - the message to check
 * @param str1 - if the user was previously registered 0 - for initial registration, 1 for re/de-registration
 * @param str2 - not used
 * @returns #ISC_RETURN_TRUE if found, #ISC_RETURN_FALSE if not
 */
int ISC_match_filter_reg(struct sip_msg *msg,char *str1,char *str2)
{
	int k;
	isc_match *m;
	str s={0,0};
	int ret = ISC_RETURN_FALSE;
	isc_mark old_mark;
	
	enum dialog_direction dir = DLG_MOBILE_ORIGINATING;
	
	LOG(L_INFO,"INFO:"M_NAME":ISC_match_filter_reg(): Checking triggers\n");
	
	if (!isc_is_register(msg)) return ISC_RETURN_FALSE;
		
	/* starting or resuming? */
	memset(&old_mark,0,sizeof(isc_mark));
	LOG(L_INFO,"INFO:"M_NAME":ISC_match_filter_reg(): Starting triggering\n");				

	/* originating leg */

	if (dir==DLG_MOBILE_ORIGINATING){
		k = isc_get_originating_user(msg,&old_mark,&s);
		if (k){
			if (str1==0||strlen(str1)!=1){
				LOG(L_ERR,"ERR:"M_NAME":ISC_match_filter_reg(): wrong parameter - must be \"0\" (initial registration) or \"1\"(previously registered) \n");
				return ret;
			}else
			if (str1[0]=='0') k = 0;
			else k=1;				
				
			LOG(L_INFO,"INFO:"M_NAME":ISC_match_filter_reg(): Orig User <%.*s> [%d]\n",s.len,s.s,k);
			m = isc_checker_find(s,old_mark.direction,old_mark.skip,msg,k);
			while (m){ 
				LOG(L_INFO,"INFO:"M_NAME":ISC_match_filter_reg(): REGISTER match found in filter criteria\n");
				ret = isc_third_party_reg(msg,m,&old_mark);
				old_mark.skip = m->index+1;
				isc_free_match(m);
				m = isc_checker_find(s,old_mark.direction,old_mark.skip,msg,k);
			}

			if(ret == ISC_RETURN_FALSE)
				LOG(L_INFO,"INFO:"M_NAME":ISC_match_filter_reg(): No REGISTER match found in filter criteria\n");
		}
	}
	return ret;
}
Пример #2
0
/**
 * Checks if there is a match.
 * Inserts route headers and set the dst_uri
 * @param msg - the message to check
 * @param str1 - the direction of the request orig/term
 * @param str2 - not used
 * @returns #ISC_RETURN_TRUE if found, #ISC_RETURN_FALSE if not, #ISC_RETURN_BREAK on error
 */
int isc_match_filter(struct sip_msg *msg, char *str1, udomain_t* d) {
    int k = 0;
    isc_match *m = NULL;
    str s = {0, 0};

    //sometimes s is populated by an ims_getter method cscf_get_terminating_user that alloc memory that must be free-ed at the end
    int free_s = 0;


    int ret = ISC_RETURN_FALSE;
    isc_mark new_mark, old_mark;

    enum dialog_direction dir = get_dialog_direction(str1);

    LM_INFO("Checking triggers\n");

    if (dir == DLG_MOBILE_UNKNOWN)
        return ISC_RETURN_BREAK;

    if (!cscf_is_initial_request(msg))
        return ISC_RETURN_FALSE;

    /* starting or resuming? */
    memset(&old_mark, 0, sizeof (isc_mark));
    memset(&new_mark, 0, sizeof (isc_mark));
    if (isc_mark_get_from_msg(msg, &old_mark)) {
        LM_DBG("Message returned s=%d;h=%d;d=%d;a=%.*s\n", old_mark.skip, old_mark.handling, old_mark.direction, old_mark.aor.len, old_mark.aor.s);
    } else {
        LM_DBG("Starting triggering\n");
    }

    if (is_route_type(FAILURE_ROUTE)) {
        /* need to find the handling for the failed trigger */
        if (dir == DLG_MOBILE_ORIGINATING) {
            k = cscf_get_originating_user(msg, &s);
            if (k) {
                k = isc_is_registered(&s, d);
                if (k == IMPU_NOT_REGISTERED) {
                    ret = ISC_RETURN_FALSE;
                    goto done;
                }
                new_mark.direction = IFC_ORIGINATING_SESSION;
                LM_DBG("Orig User <%.*s> [%d]\n", s.len, s.s, k);
            } else
                goto done;
        }
        if (dir == DLG_MOBILE_TERMINATING) {
            k = cscf_get_terminating_user(msg, &s);
            //sometimes s is populated by an ims_getter method cscf_get_terminating_user that alloc memory that must be free-ed at the end
            free_s = 1;

            if (k) {
                k = isc_is_registered(&s, d);
                //LOG(L_DBG,"after isc_is_registered in ISC_match_filter\n");
                if (k == IMPU_REGISTERED) {
                    new_mark.direction = IFC_TERMINATING_SESSION;
                } else {
                    new_mark.direction = IFC_TERMINATING_UNREGISTERED;
                }
                LM_DBG("Term User <%.*s> [%d]\n", s.len, s.s, k);
            } else {
                goto done;
            }
        }
        struct cell * t = isc_tmb.t_gett();
        LM_CRIT("SKIP: %d\n", old_mark.skip);
        int index = old_mark.skip;
        for (k = 0; k < t->nr_of_outgoings; k++) {
            m = isc_checker_find(s, new_mark.direction, index, msg,
                    isc_is_registered(&s, d), d);
            if (m) {
                index = m->index;
                if (k < t->nr_of_outgoings - 1)
                    isc_free_match(m);
            } else {
                LM_ERR("On failure, previously matched trigger no longer matches?!\n");
                ret = ISC_RETURN_BREAK;
                goto done;
            }
        }
        if (m->default_handling == IFC_SESSION_TERMINATED) {
            /* Terminate the session */
            LM_DBG("Terminating session.\n");
            isc_tmb.t_reply(msg, IFC_AS_UNAVAILABLE_STATUS_CODE, "AS Contacting Failed - iFC terminated dialog");
            LM_DBG("Responding with %d to URI: %.*s\n",
                    IFC_AS_UNAVAILABLE_STATUS_CODE, msg->first_line.u.request.uri.len, msg->first_line.u.request.uri.s);
            isc_free_match(m);
            ret = ISC_RETURN_BREAK;
            goto done;
        }
        /* skip the failed triggers (IFC_SESSION_CONTINUED) */
        old_mark.skip = index + 1;

        isc_free_match(m);
        isc_mark_drop_route(msg);
    }

    LM_DBG("Checking if ISC is for originating user\n");
    /* originating leg */
    if (dir == DLG_MOBILE_ORIGINATING) {
        k = cscf_get_originating_user(msg, &s);
        LM_DBG("ISC is for Orig user\n");
        if (k) {
            LM_DBG("Orig user is [%.*s]\n", s.len, s.s);
            k = isc_is_registered(&s, d);
            if (k == IMPU_NOT_REGISTERED) {
                LM_DBG("User is not registered\n");
                return ISC_RETURN_FALSE;
            }

            LM_DBG("Orig User <%.*s> [%d]\n", s.len, s.s, k);
            //CHECK if this is a new call (According to spec if the new uri and old mark URI are different then this is a new call and should
            //be triggered accordingly
            LM_DBG("Checking if RURI has changed...comparing: <%.*s> and <%.*s>\n",
                    old_mark.aor.len, old_mark.aor.s,
                    s.len, s.s);
            if ((old_mark.aor.len == s.len) && memcmp(old_mark.aor.s, s.s, s.len) != 0) {
                LM_DBG("This is a new call....... trigger accordingly\n");
                m = isc_checker_find(s, old_mark.direction, 0, msg,
                        isc_is_registered(&s, d), d);
            } else {
                m = isc_checker_find(s, old_mark.direction, old_mark.skip, msg,
                        isc_is_registered(&s, d), d);
            }
            if (m) {
                new_mark.direction = IFC_ORIGINATING_SESSION;
                new_mark.skip = m->index + 1;
                new_mark.handling = m->default_handling;
                new_mark.aor = s;
                ret = isc_forward(msg, m, &new_mark);
                isc_free_match(m);
                goto done;
            }
        }
        goto done;
    }
    LM_DBG("Checking if ISC is for terminating user\n");
    /* terminating leg */
    if (dir == DLG_MOBILE_TERMINATING) {
        k = cscf_get_terminating_user(msg, &s);
        //sometimes s is populated by an ims_getter method cscf_get_terminating_user that alloc memory that must be free-ed at the end
        free_s = 1;
        LM_DBG("ISC is for Term user\n");
        if (k) {
            k = isc_is_registered(&s, d);
            if (k == IMPU_REGISTERED) {
                new_mark.direction = IFC_TERMINATING_SESSION;
            } else {
                new_mark.direction = IFC_TERMINATING_UNREGISTERED;
            }
            LM_DBG("Term User <%.*s> [%d]\n", s.len, s.s, k);
            //CHECK if this is a new call (According to spec if the new uri and old mark URI are different then this is a new call and should
            //be triggered accordingly
            LM_DBG("Checking if RURI has changed...comparing: <%.*s> and <%.*s>\n",
                    old_mark.aor.len, old_mark.aor.s,
                    s.len, s.s);
            if ((old_mark.aor.len == s.len) && memcmp(old_mark.aor.s, s.s, s.len) != 0) {
                LM_DBG("This is a new call....... trigger accordingly\n");
                m = isc_checker_find(s, new_mark.direction, 0, msg, isc_is_registered(&s, d), d);
            } else {
                LM_DBG("Resuming triggering\n");
                m = isc_checker_find(s, new_mark.direction, old_mark.skip, msg, isc_is_registered(&s, d), d);
            }
            if (m) {
                new_mark.skip = m->index + 1;
                new_mark.handling = m->default_handling;
                new_mark.aor = s;
                ret = isc_forward(msg, m, &new_mark);
                isc_free_match(m);
                goto done;
            }
        }
        goto done;
    }

done:

    if (s.s && free_s == 1)
        shm_free(s.s); // shm_malloc in cscf_get_terminating_user  

    if (old_mark.aor.s)
        pkg_free(old_mark.aor.s);
    return ret;
}
Пример #3
0
/**
 * Checks if there is a match.
 * Inserts route headers and set the dst_uri
 * @param msg - the message to check
 * @param str1 - the direction of the request orig/term
 * @param str2 - not used
 * @returns #ISC_RETURN_TRUE if found, #ISC_RETURN_FALSE if not, #ISC_RETURN_BREAK on error
 */
int ISC_match_filter(struct sip_msg *msg,char *str1,char *str2)
{
	int k = 0;
	isc_match *m = NULL;
	str s={0,0};
	int ret = ISC_RETURN_FALSE;
	isc_mark new_mark,old_mark;
	
	enum dialog_direction dir = get_dialog_direction(str1);
	
	LOG(L_INFO,"INFO:"M_NAME":ISC_match_filter(%s): Checking triggers\n",str1);
	
	if (dir==DLG_MOBILE_UNKNOWN) 
		return ISC_RETURN_BREAK;
	
	if (!isc_is_initial_request(msg)) return ISC_RETURN_FALSE;
		
	/* starting or resuming? */
	memset(&old_mark,0,sizeof(isc_mark));
	memset(&new_mark,0,sizeof(isc_mark));
	if (isc_mark_get_from_msg(msg,&old_mark)){		
		LOG(L_INFO,"INFO:"M_NAME":ISC_match_filter(%s): Message returned s=%d;h=%d;d=%d;a=%.*s\n",
			str1,old_mark.skip,old_mark.handling,old_mark.direction,old_mark.aor.len,old_mark.aor.s);
	}
	else {
		LOG(L_INFO,"INFO:"M_NAME":ISC_match_filter(%s): Starting triggering\n",str1);				
	}
	
	if (
#ifdef SER_MOD_INTERFACE
	is_route_type(FAILURE_ROUTE)
#else
	*isc_tmb.route_mode==MODE_ONFAILURE
#endif
		){
		LOG(L_INFO,"INFO:"M_NAME":ISC_match_filter(%s): failure\n",str1);
		
		/* need to find the handling for the failed trigger */
		if (dir==DLG_MOBILE_ORIGINATING){
			k = isc_get_originating_user(msg,&old_mark,&s);
			if (k){
				k = isc_is_registered(&s);
				if (k==NOT_REGISTERED) {
					ret = ISC_MSG_NOT_FORWARDED;
					goto done;
				}
				new_mark.direction = IFC_ORIGINATING_SESSION;
				LOG(L_INFO,"INFO:"M_NAME":ISC_match_filter(%s): Orig User <%.*s> [%d]\n",str1,
					s.len,s.s,k);
			} else goto done;
		}
		if (dir==DLG_MOBILE_TERMINATING){
			k = isc_get_terminating_user(msg,&old_mark,&s);
			if (k){
				k = isc_is_registered(&s);
				//LOG(L_DBG,"after isc_is_registered in ISC_match_filter\n");
				if (k==REGISTERED) {
					new_mark.direction = IFC_TERMINATING_SESSION;
				} else {
					new_mark.direction = IFC_TERMINATING_UNREGISTERED;
				}
				LOG(L_INFO,"INFO:"M_NAME":ISC_match_filter(%s): Term User <%.*s> [%d]\n",str1,
					s.len,s.s,k);
			} else {
				goto done;
			}
		}
		struct cell * t = isc_tmb.t_gett();
		LOG(L_CRIT,"SKIP: %d\n",old_mark.skip);
		int index = old_mark.skip;
		for (k=0;k<t->nr_of_outgoings;k++) {
			m = isc_checker_find(s,new_mark.direction,index,msg,isc_is_registered(&s));
			if (m) {
				index = m->index;
				if (k < t->nr_of_outgoings - 1) isc_free_match(m);
			} else {
				LOG(L_ERR,"ERR:"M_NAME":ISC_match_filter(%s): On failure, previously matched trigger no longer matches?!\n", str1);
				ret = ISC_RETURN_BREAK;
				goto done;
			}
		}
		if (m->default_handling==IFC_SESSION_TERMINATED) {
			/* Terminate the session */
			DBG("DEBUG:"M_NAME":ISC_match_filter(%s): Terminating session.\n", str1);
			isc_tmb.t_reply(msg,IFC_AS_UNAVAILABLE_STATUS_CODE,
				"AS Contacting Failed - iFC terminated dialog");
			LOG(L_INFO,"INFO:"M_NAME":ISC_match_filter(%s): Responding with %d "
				"to URI: %.*s\n",str1, IFC_AS_UNAVAILABLE_STATUS_CODE,
				msg->first_line.u.request.uri.len,
				msg->first_line.u.request.uri.s);
			isc_free_match(m);
			ret = ISC_RETURN_BREAK;
			goto done;
		}
		
		/* skip the failed triggers (IFC_SESSION_CONTINUED) */
		old_mark.skip = index + 1;
		
		isc_free_match(m);
		isc_mark_drop_route(msg);
	}

	/* originating leg */
	if (dir==DLG_MOBILE_ORIGINATING){
		k = isc_get_originating_user(msg,&old_mark,&s);
		if (k){
			k = isc_is_registered(&s);
			if (k==NOT_REGISTERED) return ISC_MSG_NOT_FORWARDED;
			
			LOG(L_INFO,"INFO:"M_NAME":ISC_match_filter(%s): Orig User <%.*s> [%d]\n",str1,
				s.len,s.s,k);
			m = isc_checker_find(s,old_mark.direction,old_mark.skip,msg,isc_is_registered(&s));
			if (m){
				new_mark.direction = IFC_ORIGINATING_SESSION;
				new_mark.skip = m->index+1;
				new_mark.handling = m->default_handling;
				new_mark.aor = s;
				ret = isc_forward(msg,m,&new_mark);
				isc_free_match(m);
				goto done;
			}
		}
		goto done;
	}

	/* terminating leg */
	if (dir==DLG_MOBILE_TERMINATING){
		k = isc_get_terminating_user(msg,&old_mark,&s);
		if (k){
			k = isc_is_registered(&s);
			if (k==REGISTERED) {
				new_mark.direction = IFC_TERMINATING_SESSION;
			} else {
				new_mark.direction = IFC_TERMINATING_UNREGISTERED;
			}
			LOG(L_INFO,"INFO:"M_NAME":ISC_match_filter(%s): Term User <%.*s> [%d]\n",str1,
				s.len,s.s,k);
			
			m = isc_checker_find(s,new_mark.direction,old_mark.skip,msg,isc_is_registered(&s));
			if (m){
				new_mark.skip = m->index+1;
				new_mark.handling = m->default_handling;
				new_mark.aor = s;
				ret = isc_forward(msg,m,&new_mark);
				isc_free_match(m);
				goto done;
			}
		}
		goto done;
	}				
	
done:
	if (old_mark.aor.s) pkg_free(old_mark.aor.s);		
	return ret;
}
Пример #4
0
/**
 * Checks if there is a match.
 * Inserts route headers and set the dst_uri
 * @param msg - the message to check
 * @param str1 - the direction of the request orig/term
 * @param str2 - not used
 * @returns #ISC_RETURN_TRUE if found, #ISC_RETURN_FALSE if not, #ISC_RETURN_BREAK on error
 */
int ISC_match_filter(struct sip_msg *msg,char *str1,char *str2)
{
	int k;
	isc_match *m;
	str s={0,0};
	int ret = ISC_RETURN_FALSE;
	isc_mark new_mark,old_mark;
	
	enum dialog_direction dir = get_dialog_direction(str1);
	
	LOG(L_INFO,"INFO:"M_NAME":ISC_match_filter(%s): Checking triggers\n",str1);
	
	if (dir==DLG_MOBILE_UNKNOWN) 
		return ISC_RETURN_BREAK;
	
	if (!isc_is_initial_request(msg)) return ISC_RETURN_FALSE;
		
	/* starting or resuming? */
	memset(&old_mark,0,sizeof(isc_mark));
	if (isc_mark_get_from_msg(msg,&old_mark)){		
		LOG(L_INFO,"INFO:"M_NAME":ISC_match_filter(%s): Message returned s=%d;h=%d;d=%d\n",
			str1,old_mark.skip,old_mark.handling,old_mark.direction);
	}
	else {
		LOG(L_INFO,"INFO:"M_NAME":ISC_match_filter(%s): Starting triggering\n",str1);				
	}

	/* originating leg */
	if (dir==DLG_MOBILE_ORIGINATING){
		k = isc_get_originating_user(msg,&s);
		if (k){
			k = isc_is_registered(&s);
			if (k==NOT_REGISTERED) return ISC_MSG_NOT_FORWARDED;
			
			LOG(L_INFO,"INFO:"M_NAME":ISC_match_filter(%s): Orig User <%.*s> [%d]\n",str1,
				s.len,s.s,k);
			m = isc_checker_find(s,old_mark.direction,old_mark.skip,msg);
			if (m){
				new_mark.direction = IFC_ORIGINATING_SESSION;
				new_mark.skip = m->index+1;
				new_mark.handling = m->default_handling;
				ret = isc_forward(msg,m,&new_mark);
				isc_free_match(m);
				return ret;
			}
		}
		return ret;
	}

	/* terminating leg */
	if (dir==DLG_MOBILE_TERMINATING){
		k = isc_get_terminating_user(msg,&s);
		if (k){
			k = isc_is_registered(&s);
			if (k==REGISTERED) {
				new_mark.direction = IFC_TERMINATING_SESSION;
			} else {
				new_mark.direction = IFC_TERMINATING_UNREGISTERED;
			}
			LOG(L_INFO,"INFO:"M_NAME":ISC_match_filter(%s): Orig User <%.*s> [%d]\n",str1,
				s.len,s.s,k);
			m = isc_checker_find(s,new_mark.direction,old_mark.skip,msg);
			if (m){
				new_mark.skip = m->index+1;
				new_mark.handling = m->default_handling;
				ret = isc_forward(msg,m,&new_mark);
				isc_free_match(m);
				if (s.s) pkg_free(s.s);	
				return ret;
			}
		}
		if (s.s) pkg_free(s.s);	
		return ret;
	}					
		
	return ret;
}