/** * Find the next match and fill up the ifc_match structure with the position of the match * @param uri - URI of the user for which to apply the IFC * @param direction - direction of the session * @param skip - how many IFCs to skip because already matched * @param msg - the SIP initial request to check on * @return - TRUE if found, FALSE if none found, end of search space */ isc_match* isc_checker_find(str uri, char direction, int skip, struct sip_msg *msg, int registered, udomain_t *d) { int expires; char registration_type; int i, j, k, cnt, si, sj, next; impurecord_t *p; int ret; ims_service_profile *sp; ims_filter_criteria *fc; isc_match *r; if (skip == 0) LM_DBG("isc_checker_find: starting search\n"); else LM_DBG("isc_checker_find: resuming search from %d\n", skip); expires = cscf_get_expires(msg); if (!registered) registration_type = IFC_INITIAL_REGISTRATION; else if (expires > 0) registration_type = IFC_RE_REGISTRATION; else registration_type = IFC_DE_REGISTRATION; isc_ulb.lock_udomain(d, &uri); //need to get the urecord if ((ret = isc_ulb.get_impurecord(d, &uri, &p)) != 0) { isc_ulb.unlock_udomain(d, &uri); LM_ERR("Failure getting record"); return 0; }; LM_DBG("isc_checker_find(): got a r_public for the user %.*s\n", uri.len, uri.s); if (!p->s) { LM_DBG("isc_checker_find() : got an user without a subscription\n"); //need to free the record somewhere //isc_ulb.release_impurecord(p); //need to do an unlock on the domain somewhere isc_ulb.unlock_udomain(d, &uri); return 0; } /* find the starting fc as the skip-th one*/ cnt = 0; si = 0; sj = 0; LM_DBG("About to try p->s->service_profiles_cnt!! #profiles is %d\n", p->s->service_profiles_cnt); while (si < p->s->service_profiles_cnt) { LM_DBG("About to try p->s->service_profiles[a].filter_criterai_cnt\n"); next = cnt + p->s->service_profiles[si].filter_criteria_cnt; if (cnt <= skip && skip < next) { sj = skip - cnt; cnt += sj; break; } cnt = next; si++; } LM_DBG("DEBUG ISC: SECOND TIME About to try p->s->service_profiles_cnt!!\n"); /* iterate through the rest and check for matches */ i = si; while (i < p->s->service_profiles_cnt) { LM_DBG("DEBUG ISC : About to try p->s->service_profiles\n"); sp = p->s->service_profiles + i; k = 0; LM_DBG("DEBUG ISC : About to try public identities\n"); for (j = 0; j < sp->public_identities_cnt; j++) { LM_DBG("DEBUG ISC : About to try WPSI\n"); if (p->s->wpsi) { // here i should regexec again! // to check this , but anyway if i already got p // from the get_r_public , that is already checked... // or not if there is no wildcardPSI but ... then ... //isc_check_wpsi_match(); k = 1; break; } else { if (sp->public_identities[j].public_identity.len == uri.len && strncasecmp( sp->public_identities[j].public_identity.s, uri.s, uri.len) == 0) { k = 1; break; } } } if (!k) {/* this sp is not for this id */ cnt += sp->filter_criteria_cnt; } else { for (j = sj; j < sp->filter_criteria_cnt; j++) { fc = sp->filter_criteria + j; if (fc->profile_part_indicator) { if (((registered == IMS_USER_REGISTERED) && (*fc->profile_part_indicator)) || ((registered == IMS_USER_UNREGISTERED) && !(*fc->profile_part_indicator))) { LM_DBG("isc_checker_find: this one is not good... ppindicator wrong \n"); cnt++; continue; } } if (isc_check_filter_criteria(fc, msg, direction, registration_type)) { LM_DBG("isc_checker_find: MATCH -> %.*s (%.*s) handling %d \n", fc->application_server.server_name.len, fc->application_server.server_name.s, fc->application_server.service_info.len, fc->application_server.service_info.s, fc->application_server.default_handling); r = isc_new_match(fc, cnt); //need to free the record somewhere //isc_ulb.release_urecord(p); //need to do an unlock on the domain somewhere isc_ulb.unlock_udomain(d, &uri); return r; } else { cnt++; continue; } } } i++; sj = 0; } //need to free the record somewhere // isc_ulb.release_urecord(p); //need to do an unlock on the domain somewhere isc_ulb.unlock_udomain(d, &uri); return 0; }
/*! \brief * Check if the originating REGISTER message was formed correctly * The whole message must be parsed before calling the function * _s indicates whether the contact was star */ int check_contacts(struct sip_msg* _m, int* _s) { struct hdr_field* p; contact_t* c; *_s = 0; /* Message without contacts is OK */ if (_m->contact == 0) return 0; if (((contact_body_t*) _m->contact->parsed)->star == 1) { /* The first Contact HF is star */ /* Expires must be zero */ if (cscf_get_expires(_m) != 0) { rerrno = R_STAR_EXP; return 1; } /* Message must contain no contacts */ if (((contact_body_t*) _m->contact->parsed)->contacts) { rerrno = R_STAR_CONT; return 1; } /* Message must contain no other Contact HFs */ p = _m->contact->next; while (p) { if (p->type == HDR_CONTACT_T) { rerrno = R_STAR_CONT; return 1; } p = p->next; } *_s = 1; } else { /* The first Contact HF is not star */ /* Message must contain no star Contact HF */ p = _m->contact->next; while (p) { if (p->type == HDR_CONTACT_T) { if (((contact_body_t*) p->parsed)->star == 1) { rerrno = R_STAR_CONT; return 1; } /* check also the lenght of all contacts */ for (c = ((contact_body_t*) p->parsed)->contacts; c; c = c->next) { if (c->uri.len > CONTACT_MAX_SIZE || (c->received && c->received->len > RECEIVED_MAX_SIZE)) { rerrno = R_CONTACT_LEN; return 1; } } } p = p->next; } } return 0; }