/** * Checks if there is a match on REGISTER. * 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 */ 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,&s); if (k){ k = isc_is_registered(&s); 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); 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); } 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; }
/** * 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; }
/** * 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; }
/** * Get terminating type for a user. * This uses the S-CSCF registrar to get the state. * @param uri - uri of the user to check * @returns #IFC_TERMINATING_SESSION if the user is registered or else #IFC_TERMINATING_UNREGISTERED */ inline int isc_get_terminating_type(str *uri) { if (isc_is_registered(uri)) return IFC_TERMINATING_SESSION; else return IFC_TERMINATING_UNREGISTERED; }
/** * 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; }