/** * Check if the message is from the AS. * 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 session should continue, #ISC_RETURN_FALSE if not, #ISC_RETURN_BREAK on error */ int ISC_is_session_continued(struct sip_msg *msg,char *str1,char *str2) { int ret = ISC_RETURN_FALSE; isc_mark old_mark; struct sip_msg *req; req = cscf_get_request_from_reply(msg); if (!req) { LOG(L_ERR,"ERR:"M_NAME":ISC_is_session_continued(): There is no transaction \n"); return ISC_RETURN_FALSE; } if (!isc_is_initial_request(req)) { LOG(L_ERR,"ERR:"M_NAME":ISC_is_session_continued(): This is no initial request \n"); return ISC_RETURN_FALSE; } /* starting or resuming? */ if (isc_mark_get_from_lump(req,&old_mark)){ LOG(L_INFO,"INFO:"M_NAME":ISC_is_session_continued(): Message returned handling [%d] \n",old_mark.handling); if (old_mark.handling == IFC_SESSION_CONTINUED) ret = ISC_RETURN_TRUE; else ret = ISC_RETURN_FALSE; } else { LOG(L_ERR,"ERR:"M_NAME":ISC_is_session_continued(): mark not found in lump \n"); ret = ISC_RETURN_ERROR; } return ret; }
/** * Check if the message is from the AS. * 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 from AS, #ISC_RETURN_FALSE if not, #ISC_RETURN_BREAK on error */ int ISC_from_AS(struct sip_msg *msg,char *str1,char *str2) { int ret = ISC_RETURN_FALSE; isc_mark old_mark; enum dialog_direction dir = get_dialog_direction(str1); if (dir==DLG_MOBILE_UNKNOWN) return ISC_RETURN_BREAK; if (!isc_is_initial_request(msg)) return ISC_RETURN_FALSE; /* starting or resuming? */ if (isc_mark_get_from_msg(msg,&old_mark)){ LOG(L_INFO,"INFO:"M_NAME":ISC_from_AS(%s): Message returned s=%d;h=%d;d=%d\n", str1,old_mark.skip,old_mark.handling,old_mark.direction); if (old_mark.direction==IFC_ORIGINATING_SESSION && dir!=DLG_MOBILE_ORIGINATING) ret = ISC_RETURN_FALSE; else if ((old_mark.direction==IFC_TERMINATING_SESSION||old_mark.direction==IFC_TERMINATING_UNREGISTERED) && dir!=DLG_MOBILE_TERMINATING) ret = ISC_RETURN_FALSE; else ret = ISC_RETURN_TRUE; } else { ret = ISC_RETURN_FALSE; } 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,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; }