Beispiel #1
0
/**
 * 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;
}
Beispiel #2
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;
}