opensips/modules/enum/enum.c

changeset 19
3374f578f080
parent 18
8ec65b8f6e2c
child 20
2ff1f58715ce
     1.1 --- a/opensips/modules/enum/enum.c	Wed Feb 10 21:25:01 2010 +0100
     1.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.3 @@ -1,1196 +0,0 @@
     1.4 -/*
     1.5 - * $Id: enum.c 5901 2009-07-21 07:45:05Z bogdan_iancu $
     1.6 - *
     1.7 - * Enum and E164 related functions
     1.8 - *
     1.9 - * Copyright (C) 2002-2008 Juha Heinanen
    1.10 - *
    1.11 - * This file is part of opensips, a free SIP server.
    1.12 - *
    1.13 - * opensips is free software; you can redistribute it and/or modify
    1.14 - * it under the terms of the GNU General Public License as published by
    1.15 - * the Free Software Foundation; either version 2 of the License, or
    1.16 - * (at your option) any later version
    1.17 - *
    1.18 - * opensips is distributed in the hope that it will be useful,
    1.19 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
    1.20 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    1.21 - * GNU General Public License for more details.
    1.22 - *
    1.23 - * You should have received a copy of the GNU General Public License 
    1.24 - * along with this program; if not, write to the Free Software 
    1.25 - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    1.26 - *
    1.27 - */
    1.28 -
    1.29 -#include <stdlib.h>
    1.30 -
    1.31 -#include "enum.h"
    1.32 -#include "../../parser/parse_uri.h"
    1.33 -#include "../../parser/parse_from.h"
    1.34 -#include "../../ut.h"
    1.35 -#include "../../resolve.h"
    1.36 -#include "../../mem/mem.h"
    1.37 -#include "../../dset.h"
    1.38 -#include "../../qvalue.h"
    1.39 -#include "enum_mod.h"
    1.40 -#include "../../regexp.h"
    1.41 -#include "../../pvar.h"
    1.42 -
    1.43 -/*
    1.44 - * Input: E.164 number w/o leading +
    1.45 - *
    1.46 - * Output: number of digits in the country code
    1.47 - * 	   0 on invalid number
    1.48 - *
    1.49 - * convention:
    1.50 - *   3 digits is the default length of a country code.
    1.51 - *   country codes 1 and 7 are a single digit.
    1.52 - *   the following country codes are two digits: 20, 27, 30-34, 36, 39,
    1.53 - *     40, 41, 43-49, 51-58, 60-66, 81, 82, 84, 86, 90-95, 98.
    1.54 - */
    1.55 -static int cclen(const char *number)
    1.56 -{
    1.57 -	char d1,d2;
    1.58 -
    1.59 -	if (!number || (strlen(number) < 3))
    1.60 -		return(0);
    1.61 -
    1.62 -	d1 = number[0];
    1.63 -	d2 = number[1];
    1.64 -	
    1.65 -	if (!isdigit((int)d2)) 
    1.66 -		return(0);
    1.67 -
    1.68 -	switch(d1) {
    1.69 -		case '1':
    1.70 -		case '7':
    1.71 -			return(1);
    1.72 -		case '2':
    1.73 -			if ((d2 == '0') || (d1 == '7'))
    1.74 -				return(2);
    1.75 -			break;
    1.76 -		case '3':
    1.77 -			if ((d2 >= '0') && (d1 <= '4'))
    1.78 -				return(2);
    1.79 -			if ((d2 == '6') || (d1 == '9'))
    1.80 -				return(2);
    1.81 -			break;
    1.82 -		case '4':
    1.83 -			if (d2 != '2')
    1.84 -				return(2);
    1.85 -			break;
    1.86 -		case '5':
    1.87 -			if ((d2 >= '1') && (d1 <= '8'))
    1.88 -				return(2);
    1.89 -			break;
    1.90 -		case '6':
    1.91 -			if (d1 <= '6')
    1.92 -				return(2);
    1.93 -			break;
    1.94 -		case '8':
    1.95 -			if ((d2 == '1') || (d1 == '2') || (d1 == '4') || (d1 == '6')) 
    1.96 -				return(2);
    1.97 -			break;
    1.98 -		case '9':
    1.99 -			if (d1 <= '5')
   1.100 -				return(2);
   1.101 -			if (d2 == '8')
   1.102 -				return(2);
   1.103 -			break;
   1.104 -		default:
   1.105 -			return(0);
   1.106 -	}
   1.107 -
   1.108 -	return(3);
   1.109 -}
   1.110 -
   1.111 -
   1.112 -
   1.113 -/* return the length of the string until c, if not found returns n */
   1.114 -static inline int findchr(char* p, int c, unsigned int size)
   1.115 -{
   1.116 -	int len=0;
   1.117 -
   1.118 -	for(;len<size;p++){
   1.119 -		if (*p==(unsigned char)c) {
   1.120 -			return len;
   1.121 -		}
   1.122 -		len++;   
   1.123 -	}
   1.124 -	return len;
   1.125 -}
   1.126 -
   1.127 -
   1.128 -/* Parse NAPTR regexp field of the form !pattern!replacement! and return its
   1.129 - * components in pattern and replacement parameters.  Regexp field starts at
   1.130 - * address first and is len characters long.
   1.131 - */
   1.132 -static inline int parse_naptr_regexp(char* first, int len, str* pattern,
   1.133 -										str* replacement)
   1.134 -{
   1.135 -	char *second, *third;
   1.136 -
   1.137 -	if (len > 0) {
   1.138 -		if (*first == '!') {
   1.139 -			second = (char *)memchr((void *)(first + 1), '!', len - 1);
   1.140 -			if (second) {
   1.141 -				len = len - (second - first + 1);
   1.142 -				if (len > 0) {
   1.143 -					third = memchr(second + 1, '!', len);
   1.144 -					if (third) {
   1.145 -						pattern->len = second - first - 1;
   1.146 -						pattern->s = first + 1;
   1.147 -						replacement->len = third - second - 1;
   1.148 -						replacement->s = second + 1;
   1.149 -						return 1;
   1.150 -					} else {
   1.151 -						LM_ERR("Third ! missing from regexp\n");
   1.152 -						return -1;
   1.153 -					}
   1.154 -				} else {
   1.155 -					LM_ERR("Third ! missing from regexp\n");
   1.156 -					return -2;
   1.157 -				}
   1.158 -			} else {
   1.159 -				LM_ERR("Second ! missing from regexp\n");
   1.160 -				return -3;
   1.161 -			}
   1.162 -		} else {
   1.163 -			LM_ERR("First ! missing from regexp\n");
   1.164 -			return -4;
   1.165 -		}
   1.166 -	} else {
   1.167 -		LM_ERR("Regexp missing\n");
   1.168 -		return -5;
   1.169 -	}
   1.170 -}
   1.171 -/* Checks if NAPTR record has flag u and its services field
   1.172 - * e2u+[service:]sip or
   1.173 - * e2u+service[+service[+service[+...]]]
   1.174 - */
   1.175 -static inline int sip_match( struct naptr_rdata* naptr, str* service)
   1.176 -{
   1.177 -  if (service->len == 0) {
   1.178 -    return (naptr->flags_len == 1) &&
   1.179 -      ((naptr->flags[0] == 'u') || (naptr->flags[0] == 'U')) &&
   1.180 -      (naptr->services_len == 7) &&
   1.181 -      ((strncasecmp(naptr->services, "e2u+sip", 7) == 0) ||
   1.182 -       (strncasecmp(naptr->services, "sip+e2u", 7) == 0));
   1.183 -  } else if (service->s[0] != '+') {
   1.184 -    return (naptr->flags_len == 1) &&
   1.185 -      ((naptr->flags[0] == 'u') || (naptr->flags[0] == 'U')) &&
   1.186 -      (naptr->services_len == service->len + 8) &&
   1.187 -      (strncasecmp(naptr->services, "e2u+", 4) == 0) &&
   1.188 -      (strncasecmp(naptr->services + 4, service->s, service->len) == 0) &&
   1.189 -      (strncasecmp(naptr->services + 4 + service->len, ":sip", 4) == 0);
   1.190 -  } else { /* handle compound NAPTRs and multiple services */
   1.191 -    str bakservice, baknaptr; /* we bakup the str */
   1.192 -    int naptrlen, len;        /* length of the extracted service */
   1.193 -
   1.194 -    /* RFC 3761, NAPTR service field must start with E2U+ */
   1.195 -    if (strncasecmp(naptr->services, "e2u+", 4) != 0) {
   1.196 -      return 0;
   1.197 -    }
   1.198 -    baknaptr.s   = naptr->services + 4; /* leading 'e2u+' */
   1.199 -    baknaptr.len = naptr->services_len - 4;
   1.200 -    for (;;) { /* iterate over services in NAPTR */
   1.201 -      bakservice.s   = service->s + 1; /* leading '+' */
   1.202 -      bakservice.len = service->len - 1;
   1.203 -      naptrlen = findchr(baknaptr.s,'+',baknaptr.len);
   1.204 -
   1.205 -      for (;;) { /* iterate over services in enum_query */
   1.206 -        len = findchr(bakservice.s,'+',bakservice.len);
   1.207 -        if ((naptrlen == len ) && !strncasecmp(baknaptr.s, bakservice.s, len)){
   1.208 -          return 1;
   1.209 -        }
   1.210 -        if ( (bakservice.len -= len+1) > 0) {
   1.211 -          bakservice.s += len+1;
   1.212 -          continue;
   1.213 -        }
   1.214 -        break;
   1.215 -      }
   1.216 -      if ( (baknaptr.len -= naptrlen+1) > 0) {
   1.217 -        baknaptr.s += naptrlen+1;
   1.218 -        continue;
   1.219 -      }
   1.220 -      break;
   1.221 -    }
   1.222 -    /* no matching service found */
   1.223 -    return 0;
   1.224 -  }
   1.225 -}
   1.226 -
   1.227 -
   1.228 -/*
   1.229 - * Checks if argument is an e164 number starting with +
   1.230 - */
   1.231 -static inline int is_e164(str* _user)
   1.232 -{
   1.233 -	int i;
   1.234 -	char c;
   1.235 -	
   1.236 -	if ((_user->len > 2) && (_user->len < 17) && ((_user->s)[0] == '+')) {
   1.237 -		for (i = 1; i < _user->len; i++) {
   1.238 -			c = (_user->s)[i];
   1.239 -			if ((c < '0') || (c > '9')) return -1;
   1.240 -		}
   1.241 -		return 1;
   1.242 -	} else {
   1.243 -	    return -1;
   1.244 -	}
   1.245 -}
   1.246 -				
   1.247 -
   1.248 -/*
   1.249 - * Call is_from_user_enum_2 with module parameter suffix and default service.
   1.250 - */
   1.251 -int is_from_user_enum_0(struct sip_msg* _msg, char* _str1, char* _str2)
   1.252 -{
   1.253 -	return is_from_user_enum_2(_msg, (char *)(&suffix), (char *)(&service));
   1.254 -}
   1.255 -
   1.256 -/*
   1.257 - * Call is_from_user_enum_2 with given suffix and default service.
   1.258 - */
   1.259 -int is_from_user_enum_1(struct sip_msg* _msg, char* _suffix, char* _str2)
   1.260 -{
   1.261 -	return is_from_user_enum_2(_msg, _suffix, (char *)(&service));
   1.262 -}
   1.263 -
   1.264 -/*
   1.265 - * Check if from user is a valid enum based user, and check to make sure
   1.266 - * that the src_ip == an srv record that maps to the enum from user.
   1.267 - */
   1.268 -int is_from_user_enum_2(struct sip_msg* _msg, char* _suffix, char* _service)
   1.269 -{
   1.270 -	struct ip_addr addr;
   1.271 -	struct hostent* he;
   1.272 -	unsigned short zp;
   1.273 -	unsigned short proto;
   1.274 -	char *user_s;
   1.275 -	int user_len, i, j;
   1.276 -	char name[MAX_DOMAIN_SIZE];
   1.277 -	char uri[MAX_URI_SIZE];
   1.278 -	struct sip_uri *furi;
   1.279 -	struct sip_uri luri;
   1.280 -	struct rdata* head;
   1.281 -
   1.282 -	str* suffix;
   1.283 -	str* service;
   1.284 -
   1.285 -	struct rdata* l;
   1.286 -	struct naptr_rdata* naptr;
   1.287 -
   1.288 -	str pattern, replacement, result;
   1.289 -	char string[17];
   1.290 -
   1.291 -	if (parse_from_header(_msg) < 0) {
   1.292 -	    LM_ERR("Failed to parse From header\n");
   1.293 -	    return -1;
   1.294 -	}
   1.295 -	
   1.296 -	if(_msg->from==NULL || get_from(_msg)==NULL) {
   1.297 -	    LM_DBG("No From header\n");
   1.298 -	    return -1;
   1.299 -	}
   1.300 -
   1.301 -	if ((furi = parse_from_uri(_msg)) == NULL) {
   1.302 -	    LM_ERR("Failed to parse From URI\n");
   1.303 -	    return -1;
   1.304 -	}
   1.305 -
   1.306 -	suffix = (str*)_suffix;
   1.307 -	service = (str*)_service;
   1.308 -
   1.309 -	if (is_e164(&(furi->user)) == -1) {
   1.310 -	    LM_ERR("From URI user is not an E164 number\n");
   1.311 -	    return -1;
   1.312 -	}
   1.313 -
   1.314 -	/* assert: the from user is a valid formatted e164 string */
   1.315 -
   1.316 -	user_s = furi->user.s;
   1.317 -	user_len = furi->user.len;
   1.318 -
   1.319 -	j = 0;
   1.320 -	for (i = user_len - 1; i > 0; i--) {
   1.321 -		name[j] = user_s[i];
   1.322 -		name[j + 1] = '.';
   1.323 -		j = j + 2;
   1.324 -	}
   1.325 -
   1.326 -	memcpy(name + j, suffix->s, suffix->len + 1);
   1.327 -
   1.328 -	head = get_record(name, T_NAPTR);
   1.329 -
   1.330 -	if (head == 0) {
   1.331 -		LM_DBG("No NAPTR record found for %s.\n", name);
   1.332 -		return -3;
   1.333 -	}
   1.334 -
   1.335 -	/* we have the naptr records, loop and find an srv record with */
   1.336 -	/* same ip address as source ip address, if we do then true is returned */
   1.337 -
   1.338 -	for (l = head; l; l = l->next) {
   1.339 -
   1.340 -		if (l->type != T_NAPTR) continue; /*should never happen*/
   1.341 -		naptr = (struct naptr_rdata*)l->rdata;
   1.342 -		if (naptr == 0) {
   1.343 -			LM_ERR("Null rdata in DNS response\n");
   1.344 -			free_rdata_list(head);
   1.345 -			return -4;
   1.346 -		}
   1.347 -
   1.348 -		LM_DBG("ENUM query on %s: order %u, pref %u, flen %u, flags "
   1.349 -		       "'%.*s', slen %u, services '%.*s', rlen %u, "
   1.350 -		       "regexp '%.*s'\n",
   1.351 -		       name, naptr->order, naptr->pref,
   1.352 -		    naptr->flags_len, (int)(naptr->flags_len), ZSW(naptr->flags), naptr->services_len,
   1.353 -		    (int)(naptr->services_len), ZSW(naptr->services), naptr->regexp_len,
   1.354 -		    (int)(naptr->regexp_len), ZSW(naptr->regexp));
   1.355 -
   1.356 -		if (sip_match(naptr, service) != 0) {
   1.357 -			if (parse_naptr_regexp(&(naptr->regexp[0]), naptr->regexp_len,
   1.358 -					 &pattern, &replacement) < 0) {
   1.359 -				free_rdata_list(head); /*clean up*/
   1.360 -				LM_ERR("Parsing of NAPTR regexp failed\n");
   1.361 -				return -5;
   1.362 -			}
   1.363 -#ifdef LATER
   1.364 -			if ((pattern.len == 4) && (strncmp(pattern.s, "^.*$", 4) == 0)) {
   1.365 -				LM_DBG("Resulted in replacement: '%.*s'\n",
   1.366 -				       replacement.len, ZSW(replacement.s));				
   1.367 -				retval = set_uri(_msg, replacement.s, replacement.len);
   1.368 -				free_rdata_list(head); /*clean up*/
   1.369 -				return retval;
   1.370 -			}
   1.371 -#endif
   1.372 -			result.s = &(uri[0]);
   1.373 -			result.len = MAX_URI_SIZE;
   1.374 -			/* Avoid making copies of pattern and replacement */
   1.375 -			pattern.s[pattern.len] = (char)0;
   1.376 -			replacement.s[replacement.len] = (char)0;
   1.377 -			/* We have already checked the size of
   1.378 -			   _msg->parsed_uri.user.s */ 
   1.379 -			memcpy(&(string[0]), user_s, user_len);
   1.380 -			string[user_len] = (char)0;
   1.381 -			if (reg_replace(pattern.s, replacement.s, &(string[0]),
   1.382 -					&result) < 0) {
   1.383 -				pattern.s[pattern.len] = '!';
   1.384 -				replacement.s[replacement.len] = '!';
   1.385 -				LM_ERR("Regexp replace failed\n");
   1.386 -				free_rdata_list(head); /*clean up*/
   1.387 -				return -6;
   1.388 -			}
   1.389 -			LM_DBG("Resulted in replacement: '%.*s'\n",
   1.390 -			    result.len, ZSW(result.s));
   1.391 -
   1.392 -			if(parse_uri(result.s, result.len, &luri) < 0)
   1.393 -			{
   1.394 -				LM_ERR("Parsing of URI <%.*s> failed\n",
   1.395 -				       result.len, result.s);
   1.396 -				free_rdata_list(head); /*clean up*/
   1.397 -				return -7;
   1.398 -			}
   1.399 -
   1.400 -			pattern.s[pattern.len] = '!';
   1.401 -			replacement.s[replacement.len] = '!';
   1.402 -
   1.403 -			zp = 0;
   1.404 -			proto = PROTO_NONE;
   1.405 -			he = sip_resolvehost(&luri.host, &zp, &proto,
   1.406 -				(luri.type==SIPS_URI_T)?1:0 , 0);
   1.407 -
   1.408 -			hostent2ip_addr(&addr, he, 0);
   1.409 -
   1.410 -			if(ip_addr_cmp(&addr, &_msg->rcv.src_ip))
   1.411 -			{
   1.412 -				free_rdata_list(head);
   1.413 -				return(1);
   1.414 -			}
   1.415 -		}
   1.416 -	}
   1.417 -	free_rdata_list(head); /*clean up*/
   1.418 -	LM_DBG("FAIL\n");
   1.419 -
   1.420 -    /* must not have found the record */
   1.421 -    return(-8);
   1.422 -}
   1.423 -
   1.424 -
   1.425 -
   1.426 -/* 
   1.427 - * Add parameter to URI.
   1.428 - */
   1.429 -int add_uri_param(str *uri, str *param, str *new_uri)
   1.430 -{
   1.431 -	struct sip_uri puri;
   1.432 -	char *at;
   1.433 -
   1.434 -	if (parse_uri(uri->s, uri->len, &puri) < 0) {
   1.435 -		return 0;
   1.436 -	}
   1.437 -
   1.438 -	/* if current uri has no headers, pad param to the end of uri */
   1.439 -	if (puri.headers.len == 0) {
   1.440 -		memcpy(uri->s + uri->len, param->s, param->len);
   1.441 -		uri->len = uri->len + param->len;
   1.442 -		new_uri->len = 0;
   1.443 -		return 1;
   1.444 -	}
   1.445 -
   1.446 -	/* otherwise take the long path and create new_uri */
   1.447 -	at = new_uri->s;
   1.448 -	switch (puri.type) {
   1.449 -	case SIP_URI_T:
   1.450 -	    memcpy(at, "sip:", 4);
   1.451 -	    at = at + 4;
   1.452 -	    break;
   1.453 -	case SIPS_URI_T:
   1.454 -	    memcpy(at, "sips:", 5);
   1.455 -	    at = at + 5;
   1.456 -	    break;
   1.457 -	case TEL_URI_T:
   1.458 -	    memcpy(at, "tel:", 4);
   1.459 -	    at = at + 4;
   1.460 -	    break;
   1.461 -	case TELS_URI_T:
   1.462 -	    memcpy(at, "tels:", 5);
   1.463 -	    at = at + 5;
   1.464 -	    break;
   1.465 -	default:
   1.466 -	    LM_ERR("Unknown URI scheme <%d>\n", puri.type);
   1.467 -	    return 0;
   1.468 -	}
   1.469 -	if (puri.user.len) {
   1.470 -		memcpy(at, puri.user.s, puri.user.len);
   1.471 -		at = at + puri.user.len;
   1.472 -		if (puri.passwd.len) {
   1.473 -			*at = ':';
   1.474 -			at = at + 1;
   1.475 -			memcpy(at, puri.passwd.s, puri.passwd.len);
   1.476 -			at = at + puri.passwd.len;
   1.477 -		};
   1.478 -		*at = '@';
   1.479 -		at = at + 1;
   1.480 -	}
   1.481 -	memcpy(at, puri.host.s, puri.host.len);
   1.482 -	at = at + puri.host.len;
   1.483 -	if (puri.port.len) {
   1.484 -		*at = ':';
   1.485 -		at = at + 1;
   1.486 -		memcpy(at, puri.port.s, puri.port.len);
   1.487 -		at = at + puri.port.len;
   1.488 -	}
   1.489 -	if (puri.params.len) {
   1.490 -		*at = ';';
   1.491 -		at = at + 1;
   1.492 -		memcpy(at, puri.params.s, puri.params.len);
   1.493 -		at = at + puri.params.len;
   1.494 -	}
   1.495 -	memcpy(at, param->s, param->len);
   1.496 -	at = at + param->len;
   1.497 -	*at = '?';
   1.498 -	at = at + 1;
   1.499 -	memcpy(at, puri.headers.s, puri.headers.len);
   1.500 -	at = at + puri.headers.len;
   1.501 -	new_uri->len = at - new_uri->s;
   1.502 -	return 1;
   1.503 -}
   1.504 -
   1.505 -/*
   1.506 - * Tests if one result record is "greater" that the other.  Non-NAPTR records
   1.507 - * greater that NAPTR record.  An invalid NAPTR record is greater than a 
   1.508 - * valid one.  Valid NAPTR records are compared based on their
   1.509 - * (order,preference).
   1.510 - */
   1.511 -static inline int naptr_greater(struct rdata* a, struct rdata* b)
   1.512 -{
   1.513 -	struct naptr_rdata *na, *nb;
   1.514 -
   1.515 -	if (a->type != T_NAPTR) return 1;
   1.516 -	if (b->type != T_NAPTR) return 0;
   1.517 -
   1.518 -	na = (struct naptr_rdata*)a->rdata;
   1.519 -	if (na == 0) return 1;
   1.520 -
   1.521 -	nb = (struct naptr_rdata*)b->rdata;
   1.522 -	if (nb == 0) return 0;
   1.523 -	
   1.524 -	return (((na->order) << 16) + na->pref) >
   1.525 -		(((nb->order) << 16) + nb->pref);
   1.526 -}
   1.527 -	
   1.528 -	
   1.529 -/*
   1.530 - * Bubble sorts result record list according to naptr (order,preference).
   1.531 - */
   1.532 -static inline void naptr_sort(struct rdata** head)
   1.533 -{
   1.534 -	struct rdata *p, *q, *r, *s, *temp, *start;
   1.535 -
   1.536 -        /* r precedes p and s points to the node up to which comparisons
   1.537 -         are to be made */ 
   1.538 -
   1.539 -	s = NULL;
   1.540 -	start = *head;
   1.541 -	while ( s != start -> next ) { 
   1.542 -		r = p = start ; 
   1.543 -		q = p -> next ;
   1.544 -		while ( p != s ) { 
   1.545 -			if ( naptr_greater(p, q) ) { 
   1.546 -				if ( p == start ) { 
   1.547 -					temp = q -> next ; 
   1.548 -					q -> next = p ; 
   1.549 -					p -> next = temp ;
   1.550 -					start = q ; 
   1.551 -					r = q ; 
   1.552 -				} else {
   1.553 -					temp = q -> next ; 
   1.554 -					q -> next = p ; 
   1.555 -					p -> next = temp ;
   1.556 -					r -> next = q ; 
   1.557 -					r = q ; 
   1.558 -				} 
   1.559 -			} else {
   1.560 -				r = p ; 
   1.561 -				p = p -> next ; 
   1.562 -			} 
   1.563 -			q = p -> next ; 
   1.564 -			if ( q == s ) s = p ; 
   1.565 -		}
   1.566 -	}
   1.567 -	*head = start;
   1.568 -}	
   1.569 -	
   1.570 -
   1.571 -/*
   1.572 - * Makes enum query on name.  On success, rewrites user part and 
   1.573 - * replaces Request-URI.
   1.574 - */
   1.575 -int do_query(struct sip_msg* _msg, char *user, char *name, str *service) {
   1.576 -
   1.577 -    char uri[MAX_URI_SIZE];
   1.578 -    char new_uri[MAX_URI_SIZE];
   1.579 -    unsigned int priority, curr_prio, first;
   1.580 -    qvalue_t q;
   1.581 -    struct rdata* head;
   1.582 -    struct rdata* l;
   1.583 -    struct naptr_rdata* naptr;
   1.584 -    str pattern, replacement, result, new_result;
   1.585 -
   1.586 -    head = get_record(name, T_NAPTR);
   1.587 -    
   1.588 -    if (head == 0) {
   1.589 -	LM_DBG("No NAPTR record found for %s.\n", name);
   1.590 -	return -1;
   1.591 -    }
   1.592 -    
   1.593 -    naptr_sort(&head);
   1.594 -
   1.595 -    q = MAX_Q - 10;
   1.596 -    curr_prio = 0;
   1.597 -    first = 1;
   1.598 -
   1.599 -    for (l = head; l; l = l->next) {
   1.600 -
   1.601 -	if (l->type != T_NAPTR) continue; /*should never happen*/
   1.602 -	naptr = (struct naptr_rdata*)l->rdata;
   1.603 -	if (naptr == 0) {
   1.604 -	    LM_ERR("Null rdata in DNS response\n");
   1.605 -	    continue;
   1.606 -	}
   1.607 -
   1.608 -	LM_DBG("ENUM query on %s: order %u, pref %u, flen %u, flags '%.*s', "
   1.609 -	       "slen %u, services '%.*s', rlen %u, regexp '%.*s'\n",
   1.610 -	       name, naptr->order, naptr->pref,
   1.611 -	    naptr->flags_len, (int)(naptr->flags_len), ZSW(naptr->flags),
   1.612 -	    naptr->services_len,
   1.613 -	    (int)(naptr->services_len), ZSW(naptr->services), naptr->regexp_len,
   1.614 -	    (int)(naptr->regexp_len), ZSW(naptr->regexp));
   1.615 -	
   1.616 -	if (sip_match(naptr, service) == 0) continue;
   1.617 -	
   1.618 -	if (parse_naptr_regexp(&(naptr->regexp[0]), naptr->regexp_len,
   1.619 -			       &pattern, &replacement) < 0) {
   1.620 -	    LM_ERR("Parsing of NAPTR regexp failed\n");
   1.621 -	    continue;
   1.622 -	}
   1.623 -	result.s = &(uri[0]);
   1.624 -	result.len = MAX_URI_SIZE;
   1.625 -	/* Avoid making copies of pattern and replacement */
   1.626 -	pattern.s[pattern.len] = (char)0;
   1.627 -	replacement.s[replacement.len] = (char)0;
   1.628 -	if (reg_replace(pattern.s, replacement.s, user, &result) < 0) {
   1.629 -	    pattern.s[pattern.len] = '!';
   1.630 -	    replacement.s[replacement.len] = '!';
   1.631 -	    LM_ERR("Regexp replace failed\n");
   1.632 -	    continue;
   1.633 -	}
   1.634 -	LM_DBG("Resulted in replacement: '%.*s'\n", result.len, ZSW(result.s));
   1.635 -	pattern.s[pattern.len] = '!';
   1.636 -	replacement.s[replacement.len] = '!';
   1.637 -	
   1.638 -	if (param.len > 0) {
   1.639 -	    if (result.len + param.len > MAX_URI_SIZE - 1) {
   1.640 -		LM_ERR("URI is too long\n");
   1.641 -		continue;
   1.642 -	    }
   1.643 -	    new_result.s = &(new_uri[0]);
   1.644 -	    new_result.len = MAX_URI_SIZE;
   1.645 -	    if (add_uri_param(&result, &param, &new_result) == 0) {
   1.646 -		LM_ERR("Parsing of URI <%.*s> failed\n",
   1.647 -		       result.len, result.s);
   1.648 -		continue;
   1.649 -	    }
   1.650 -	    if (new_result.len > 0) {
   1.651 -		result = new_result;
   1.652 -	    }
   1.653 -	}
   1.654 -	
   1.655 -	if (first) {
   1.656 -	    if (set_ruri(_msg, &result) == -1) {
   1.657 -		goto done;
   1.658 -	    }
   1.659 -	    set_ruri_q(q);
   1.660 -	    first = 0;
   1.661 -	    curr_prio = ((naptr->order) << 16) + naptr->pref;
   1.662 -	} else {
   1.663 -	    priority = ((naptr->order) << 16) + naptr->pref;
   1.664 -	    if (priority > curr_prio) {
   1.665 -		q = q - 10;
   1.666 -		curr_prio = priority;
   1.667 -	    }
   1.668 -	    if (append_branch(_msg, &result, 0, 0, q, 0, 0) == -1) {
   1.669 -		goto done;
   1.670 -	    }
   1.671 -	}
   1.672 -    }
   1.673 -
   1.674 -done:
   1.675 -    free_rdata_list(head);
   1.676 -    return first ? -1 : 1;
   1.677 -}
   1.678 -
   1.679 -	
   1.680 -/*
   1.681 - * Call enum_query_2 with module parameter suffix and default service.
   1.682 - */
   1.683 -int enum_query_0(struct sip_msg* _msg, char* _str1, char* _str2)
   1.684 -{
   1.685 -	return enum_query_2(_msg, (char *)(&suffix), (char *)(&service));
   1.686 -}
   1.687 -
   1.688 -
   1.689 -/*
   1.690 - * Call enum_query_2 with given suffix and default service.
   1.691 - */
   1.692 -int enum_query_1(struct sip_msg* _msg, char* _suffix, char* _str2)
   1.693 -{
   1.694 -	return enum_query_2(_msg, _suffix, (char *)(&service));
   1.695 -}
   1.696 -
   1.697 -
   1.698 -/*
   1.699 - * See documentation in README file.
   1.700 - */
   1.701 -int enum_query_2(struct sip_msg* _msg, char* _suffix, char* _service)
   1.702 -{
   1.703 -	char *user_s;
   1.704 -	int user_len, i, j;
   1.705 -	char name[MAX_DOMAIN_SIZE];
   1.706 -	char string[17];
   1.707 -
   1.708 -	str *suffix, *service;
   1.709 -
   1.710 -	suffix = (str*)_suffix;
   1.711 -	service = (str*)_service;
   1.712 -
   1.713 -	if (parse_sip_msg_uri(_msg) < 0) {
   1.714 -		LM_ERR("Parsing of R-URI failed\n");
   1.715 -		return -1;
   1.716 -	}
   1.717 -
   1.718 -	if (is_e164(&(_msg->parsed_uri.user)) == -1) {
   1.719 -		LM_ERR("R-URI user is not an E164 number\n");
   1.720 -		return -1;
   1.721 -	}
   1.722 -
   1.723 -	user_s = _msg->parsed_uri.user.s;
   1.724 -	user_len = _msg->parsed_uri.user.len;
   1.725 -
   1.726 -	memcpy(&(string[0]), user_s, user_len);
   1.727 -	string[user_len] = (char)0;
   1.728 -
   1.729 -	j = 0;
   1.730 -	for (i = user_len - 1; i > 0; i--) {
   1.731 -		name[j] = user_s[i];
   1.732 -		name[j + 1] = '.';
   1.733 -		j = j + 2;
   1.734 -	}
   1.735 -
   1.736 -	memcpy(name + j, suffix->s, suffix->len + 1);
   1.737 -
   1.738 -	return do_query(_msg, string, name, service);
   1.739 -}
   1.740 -
   1.741 -
   1.742 -/*
   1.743 - * Call isn_query_2 with module parameter suffix and default service.
   1.744 - */
   1.745 -int isn_query_0(struct sip_msg* _msg, char* _str1, char* _str2)
   1.746 -{
   1.747 -	return isn_query_2(_msg, (char *)(&isnsuffix), (char *)(&service));
   1.748 -}
   1.749 -
   1.750 -
   1.751 -/*
   1.752 - * Call isn_query_2 with given suffix and default service.
   1.753 - */
   1.754 -int isn_query_1(struct sip_msg* _msg, char* _suffix, char* _str2)
   1.755 -{
   1.756 -	return isn_query_2(_msg, _suffix, (char *)(&service));
   1.757 -}
   1.758 -
   1.759 -
   1.760 -/*
   1.761 - * See documentation in README file.
   1.762 - */
   1.763 -int isn_query_2(struct sip_msg* _msg, char* _suffix, char* _service)
   1.764 -{
   1.765 -	char *user_s = NULL;
   1.766 -	int user_len, i, j;
   1.767 -	char name[MAX_DOMAIN_SIZE] = {0};
   1.768 -	char string[17] = {0};
   1.769 -	char szItad[17] = {0};
   1.770 -	size_t nItlen = 0;
   1.771 -
   1.772 -	str *suffix, *service;
   1.773 -
   1.774 -	suffix = (str*)_suffix;
   1.775 -	service = (str*)_service;
   1.776 -
   1.777 -	if (parse_sip_msg_uri(_msg) < 0) {
   1.778 -		LM_ERR("Parsing of R-URI failed\n");
   1.779 -		return -1;
   1.780 -	}
   1.781 -
   1.782 -	user_s = _msg->parsed_uri.user.s;
   1.783 -	user_len = _msg->parsed_uri.user.len;
   1.784 -
   1.785 -	memcpy(&(string[0]), user_s, user_len);
   1.786 -	string[user_len] = (char)0;
   1.787 -
   1.788 -	/* Do primitive test for correct ISN format, */
   1.789 -	/* and set szItad to the ISN ITAD (RFC 3872/2871). */
   1.790 -	/* Correct ISN format guessed from freenum.org and IANA */
   1.791 -	/* doc http://www.iana.org/assignments/trip-parameters/ */
   1.792 -	{
   1.793 -		char *pAster = strchr(string, '*');
   1.794 -		if (pAster && (nItlen = strspn(pAster + sizeof(char), "0123456789")))
   1.795 -			strncpy(szItad, pAster + sizeof(char), nItlen);
   1.796 -		else {
   1.797 -			LM_ERR("R-URI user does not contain a valid ISN\n");
   1.798 -			return -1;
   1.799 -		}
   1.800 -	}
   1.801 -
   1.802 -	/* Ammend the original ENUM E.164 string logic to process */
   1.803 -	/* ISN numbers instead, which include a nonreversed ITAD. */
   1.804 -	i = user_len - nItlen - sizeof(char); /* Ex: *1212 */
   1.805 -	j = 0;
   1.806 -	while (i--) {
   1.807 -		name[j] = user_s[i];
   1.808 -		name[j + 1] = '.';
   1.809 -		j = j + 2;
   1.810 -	}
   1.811 -
   1.812 -	strcat(name + j, szItad);  /* Copy the unreversed ITAD, */
   1.813 -	name[j + nItlen] = '.';    /* and append a trailing dot. */
   1.814 -	memcpy(name + j + nItlen + sizeof(char), suffix->s, suffix->len + 1);
   1.815 -
   1.816 -	return do_query(_msg, string, name, service);
   1.817 -}
   1.818 -
   1.819 -
   1.820 -/*********** INFRASTRUCTURE ENUM ***************/
   1.821 -
   1.822 -/*
   1.823 - * Call enum_query_2 with default suffix and service.
   1.824 - */
   1.825 -int i_enum_query_0(struct sip_msg* _msg, char* _suffix, char* _service)
   1.826 -{
   1.827 -	return i_enum_query_2(_msg, (char *)(&i_suffix), (char *)(&service));
   1.828 -}
   1.829 -
   1.830 -/*
   1.831 - * Call enum_query_2 with given suffix and default service.
   1.832 - */
   1.833 -int i_enum_query_1(struct sip_msg* _msg, char* _suffix, char* _service)
   1.834 -{
   1.835 -	return i_enum_query_2(_msg, _suffix, (char *)(&service));
   1.836 -}
   1.837 -
   1.838 -
   1.839 -int i_enum_query_2(struct sip_msg* _msg, char* _suffix, char* _service)
   1.840 -{
   1.841 -	char *user_s;
   1.842 -	int user_len, i, j;
   1.843 -	char name[MAX_DOMAIN_SIZE];
   1.844 -	char apex[MAX_COMPONENT_SIZE + 1];
   1.845 -	char separator[MAX_COMPONENT_SIZE + 1];
   1.846 -	int sdl = 0;    /* subdomain location: infrastructure enum offset */
   1.847 -	int cc_len;
   1.848 -	struct rdata* head;
   1.849 -
   1.850 -	char string[17];
   1.851 -
   1.852 -	str *suffix, *service;
   1.853 -
   1.854 -	suffix = (str*)_suffix;
   1.855 -	service = (str*)_service;
   1.856 -
   1.857 -	if (parse_sip_msg_uri(_msg) < 0) {
   1.858 -		LM_ERR("Parsing of R-URI failed\n");
   1.859 -		return -1;
   1.860 -	}
   1.861 -
   1.862 -	if (is_e164(&(_msg->parsed_uri.user)) == -1) {
   1.863 -		LM_ERR("R-URI user is not an E164 number\n");
   1.864 -		return -1;
   1.865 -	}
   1.866 -
   1.867 -	user_s = _msg->parsed_uri.user.s;
   1.868 -	user_len = _msg->parsed_uri.user.len;
   1.869 -
   1.870 -	/* make sure we don't run out of space in strings */
   1.871 -	if (( 2*user_len + MAX_COMPONENT_SIZE + MAX_COMPONENT_SIZE + 4) > MAX_DOMAIN_SIZE) {
   1.872 -		LM_ERR("Strings too long\n");
   1.873 -		return -1;
   1.874 -	}
   1.875 -	if ( i_branchlabel.len > MAX_COMPONENT_SIZE ) {
   1.876 -		LM_ERR("i_branchlabel too long\n");
   1.877 -		return -1;
   1.878 -	}
   1.879 -	if ( suffix->len > MAX_COMPONENT_SIZE ) {
   1.880 -		LM_ERR("Suffix too long\n");
   1.881 -		return -1;
   1.882 -	}
   1.883 -
   1.884 -
   1.885 -	memcpy(&(string[0]), user_s, user_len);
   1.886 -	string[user_len] = (char)0;
   1.887 -
   1.888 -	/* Set up parameters as for user-enum */
   1.889 -	memcpy(apex,  suffix->s , suffix->len);
   1.890 -	apex[suffix->len] = (char)0;
   1.891 -	sdl = 0;		/* where to insert i-enum separator */
   1.892 -	separator[0] = 0;	/* don't insert anything */
   1.893 -
   1.894 -	cc_len = cclen(string + 1);
   1.895 -
   1.896 -	if (!strncasecmp(i_bl_alg.s,"ebl",i_bl_alg.len)) {
   1.897 -		sdl = cc_len; /* default */
   1.898 -
   1.899 -		j = 0;
   1.900 -		memcpy(name, i_branchlabel.s, i_branchlabel.len);
   1.901 -		j += i_branchlabel.len;
   1.902 -		name[j++] = '.';
   1.903 -
   1.904 -		for (i = cc_len ; i > 0; i--) {
   1.905 -			name[j++] = user_s[i];
   1.906 -			name[j++] = '.';
   1.907 -		}
   1.908 -		memcpy(name + j, suffix->s, suffix->len + 1);
   1.909 -
   1.910 -		LM_DBG("Looking for EBL record for %s.\n", name); 
   1.911 -		head = get_record(name, T_EBL);
   1.912 -		if (head == 0) {
   1.913 -			LM_DBG("No EBL found for %s. Defaulting to user ENUM.\n",name);
   1.914 -		} else {
   1.915 -		    	struct ebl_rdata* ebl;
   1.916 -			ebl = (struct ebl_rdata *) head->rdata;
   1.917 -
   1.918 -			LM_DBG("EBL record for %s is %d / %.*s / %.*s.\n",
   1.919 -			       name, ebl->position, (int)ebl->separator_len,
   1.920 -			       ebl->separator,(int)ebl->apex_len, ebl->apex);
   1.921 -
   1.922 -			if ((ebl->apex_len > MAX_COMPONENT_SIZE) || (ebl->separator_len > MAX_COMPONENT_SIZE)) {
   1.923 -				LM_ERR("EBL strings too long\n"); 
   1.924 -				return -1;
   1.925 -			}
   1.926 -
   1.927 -			if (ebl->position > 15)  {
   1.928 -				LM_ERR("EBL position too large (%d)\n",
   1.929 -				       ebl->position); 
   1.930 -				return -1;
   1.931 -			}
   1.932 -
   1.933 -			sdl = ebl->position;
   1.934 -
   1.935 -			memcpy(separator, ebl->separator, ebl->separator_len);
   1.936 -			separator[ebl->separator_len] = 0;
   1.937 -
   1.938 -			memcpy(apex, ebl->apex, ebl->apex_len);
   1.939 -			apex[ebl->apex_len] = 0;
   1.940 -			free_rdata_list(head);
   1.941 -		}
   1.942 -	} else if (!strncasecmp(i_bl_alg.s,"txt",i_bl_alg.len)) {
   1.943 -		sdl = cc_len; /* default */
   1.944 -		memcpy(separator, i_branchlabel.s, i_branchlabel.len);
   1.945 -		separator[i_branchlabel.len] = 0;
   1.946 -		/* no change to apex */
   1.947 -
   1.948 -		j = 0;
   1.949 -		memcpy(name, i_branchlabel.s, i_branchlabel.len);
   1.950 -		j += i_branchlabel.len;
   1.951 -		name[j++] = '.';
   1.952 -
   1.953 -		for (i = cc_len ; i > 0; i--) {
   1.954 -			name[j++] = user_s[i];
   1.955 -			name[j++] = '.';
   1.956 -		}
   1.957 -		memcpy(name + j, suffix->s, suffix->len + 1);
   1.958 -
   1.959 -		head = get_record(name, T_TXT);
   1.960 -		if (head == 0) {
   1.961 -			LM_DBG("TXT found for %s. Defaulting to %d\n",
   1.962 -			       name, cc_len);
   1.963 -		} else {
   1.964 -			sdl = atoi(((struct txt_rdata*)head->rdata)->txt);
   1.965 -			LM_DBG("TXT record for %s is %d.\n", name, sdl);
   1.966 -
   1.967 -			if ((sdl < 0) || (sdl > 10)) {
   1.968 -				LM_ERR("Sdl %d out of bounds. Set back to cc_len.\n", sdl);
   1.969 -				sdl = cc_len;
   1.970 -			}
   1.971 -			free_rdata_list(head);
   1.972 -		}
   1.973 -	} else {	/* defaults to CC */
   1.974 -		sdl = cc_len;
   1.975 -		memcpy(separator, i_branchlabel.s, i_branchlabel.len);
   1.976 -		separator[i_branchlabel.len] = 0;
   1.977 -		/* no change to apex */
   1.978 -	}
   1.979 -
   1.980 -	j = 0;
   1.981 -	sdl++; /* to avoid comparing i to (sdl+1) */
   1.982 -	for (i = user_len - 1; i > 0; i--) {
   1.983 -		name[j] = user_s[i];
   1.984 -		name[j + 1] = '.';
   1.985 -		j = j + 2;
   1.986 -		if (separator[0] && (i == sdl)) { /* insert the I-ENUM separator here? */
   1.987 -			strcpy(name + j, separator);  /* we've checked string sizes. */
   1.988 -			j += strlen(separator);
   1.989 -			name[j++] = '.';
   1.990 -		}
   1.991 -	}
   1.992 -
   1.993 -	memcpy(name + j, apex, strlen(apex)+1);
   1.994 -
   1.995 -	return do_query(_msg, string, name, service);
   1.996 -}
   1.997 -
   1.998 -
   1.999 -
  1.1000 -/******************* FQUERY *******************/
  1.1001 -
  1.1002 -
  1.1003 -/*
  1.1004 - * Call enum_pv_query_3 with pv arg, module parameter suffix,
  1.1005 - * and default service.
  1.1006 - */
  1.1007 -int enum_pv_query_1(struct sip_msg* _msg, char* _sp)
  1.1008 -{
  1.1009 -    return enum_pv_query_3(_msg, _sp, (char *)(&suffix), (char *)(&service));
  1.1010 -}
  1.1011 -
  1.1012 -/*
  1.1013 - * Call enum_pv_query_3 with pv and suffix args and default service.
  1.1014 - */
  1.1015 -int enum_pv_query_2(struct sip_msg* _msg, char* _sp, char* _suffix)
  1.1016 -{
  1.1017 -    return enum_pv_query_3(_msg, _sp, _suffix, (char *)(&service));
  1.1018 -}
  1.1019 -
  1.1020 -/*
  1.1021 - * See documentation in README file.
  1.1022 - */
  1.1023 -
  1.1024 -int enum_pv_query_3(struct sip_msg* _msg, char* _sp, char* _suffix,
  1.1025 -		    char* _service)
  1.1026 -{
  1.1027 -	char *user_s;
  1.1028 -	int user_len, i, j, first;
  1.1029 -	char name[MAX_DOMAIN_SIZE];
  1.1030 -	char uri[MAX_URI_SIZE];
  1.1031 -	char new_uri[MAX_URI_SIZE];
  1.1032 -	unsigned int priority, curr_prio;
  1.1033 -	qvalue_t q;
  1.1034 -	char tostring[17];
  1.1035 -	struct rdata* head;
  1.1036 -	struct rdata* l;
  1.1037 -	struct naptr_rdata* naptr;
  1.1038 -	str pattern, replacement, result, new_result;
  1.1039 -	str *suffix, *service;
  1.1040 -	char string[17];
  1.1041 -	pv_spec_t *sp;
  1.1042 -	pv_value_t pv_val;
  1.1043 -
  1.1044 -	sp = (pv_spec_t *)_sp;
  1.1045 -	suffix = (str*)_suffix;
  1.1046 -	service = (str*)_service;
  1.1047 -
  1.1048 -	/*
  1.1049 -	 *  Get R-URI user to tostring
  1.1050 -	 */
  1.1051 -	if (parse_sip_msg_uri(_msg) < 0) {
  1.1052 -		LM_ERR("R-URI parsing failed\n");
  1.1053 -		return -1;
  1.1054 -	}
  1.1055 -
  1.1056 -	if (is_e164(&(_msg->parsed_uri.user)) == -1) {
  1.1057 -		LM_ERR("R-URI user is not an E164 number\n");
  1.1058 -		return -1;
  1.1059 -	}
  1.1060 -
  1.1061 -	user_s = _msg->parsed_uri.user.s;
  1.1062 -	user_len = _msg->parsed_uri.user.len;
  1.1063 -
  1.1064 -	memcpy(&(tostring[0]), user_s, user_len);
  1.1065 -	tostring[user_len] = (char)0;
  1.1066 -
  1.1067 -	/*
  1.1068 -	 * Get E.164 number from pseudo variable
  1.1069 -         */
  1.1070 -	if (sp && (pv_get_spec_value(_msg, sp, &pv_val) == 0)) {
  1.1071 -	    if (pv_val.flags & PV_VAL_STR) {
  1.1072 -		if (pv_val.rs.len == 0 || pv_val.rs.s == NULL) {
  1.1073 -		    LM_DBG("Missing E.164 number\n");
  1.1074 -		    return -1;
  1.1075 -		}
  1.1076 -	    } else {
  1.1077 -		LM_DBG("Pseudo variable value is not string\n");
  1.1078 -		return -1;
  1.1079 -	}
  1.1080 -	} else {
  1.1081 -	    LM_DBG("Cannot get pseudo variable value\n");
  1.1082 -	    return -1;
  1.1083 -	}
  1.1084 -	if (is_e164(&(pv_val.rs)) == -1) {
  1.1085 -	    LM_ERR("pseudo variable does not contain an E164 number\n");
  1.1086 -	    return -1;
  1.1087 -	}
  1.1088 -
  1.1089 -	user_s = pv_val.rs.s;
  1.1090 -	user_len = pv_val.rs.len;
  1.1091 -
  1.1092 -	memcpy(&(string[0]), user_s, user_len);
  1.1093 -	string[user_len] = (char)0;
  1.1094 -
  1.1095 -	j = 0;
  1.1096 -	for (i = user_len - 1; i > 0; i--) {
  1.1097 -		name[j] = user_s[i];
  1.1098 -		name[j + 1] = '.';
  1.1099 -		j = j + 2;
  1.1100 -	}
  1.1101 -
  1.1102 -	memcpy(name + j, suffix->s, suffix->len + 1);
  1.1103 -
  1.1104 -	head = get_record(name, T_NAPTR);
  1.1105 -
  1.1106 -	if (head == 0) {
  1.1107 -		LM_DBG("No NAPTR record found for %s.\n", name);
  1.1108 -		return -1;
  1.1109 -	}
  1.1110 -
  1.1111 -	naptr_sort(&head);
  1.1112 -
  1.1113 -	q = MAX_Q - 10;
  1.1114 -	curr_prio = 0;
  1.1115 -	first = 1;
  1.1116 -
  1.1117 -	for (l = head; l; l = l->next) {
  1.1118 -
  1.1119 -		if (l->type != T_NAPTR) continue; /*should never happen*/
  1.1120 -		naptr = (struct naptr_rdata*)l->rdata;
  1.1121 -		if (naptr == 0) {
  1.1122 -			LM_ERR("Null rdata in DNS response\n");
  1.1123 -			continue;
  1.1124 -		}
  1.1125 -
  1.1126 -		LM_DBG("ENUM query on %s: order %u, pref %u, flen %u, flags "
  1.1127 -		       "'%.*s', slen %u, services '%.*s', rlen %u, "
  1.1128 -		       "regexp '%.*s'\n",
  1.1129 -		       name, naptr->order, naptr->pref,
  1.1130 -		    naptr->flags_len, (int)(naptr->flags_len), ZSW(naptr->flags),
  1.1131 -		    naptr->services_len,
  1.1132 -		    (int)(naptr->services_len), ZSW(naptr->services), naptr->regexp_len,
  1.1133 -		    (int)(naptr->regexp_len), ZSW(naptr->regexp));
  1.1134 -
  1.1135 -		if (sip_match(naptr, service) == 0) continue;
  1.1136 -
  1.1137 -		if (parse_naptr_regexp(&(naptr->regexp[0]), naptr->regexp_len,
  1.1138 -				       &pattern, &replacement) < 0) {
  1.1139 -			LM_ERR("Parsing of NAPTR regexp failed\n");
  1.1140 -			continue;
  1.1141 -		}
  1.1142 -		result.s = &(uri[0]);
  1.1143 -		result.len = MAX_URI_SIZE;
  1.1144 -		/* Avoid making copies of pattern and replacement */
  1.1145 -		pattern.s[pattern.len] = (char)0;
  1.1146 -		replacement.s[replacement.len] = (char)0;
  1.1147 -		if (reg_replace(pattern.s, replacement.s, &(tostring[0]),
  1.1148 -				&result) < 0) {
  1.1149 -			pattern.s[pattern.len] = '!';
  1.1150 -			replacement.s[replacement.len] = '!';
  1.1151 -			LM_ERR("Regexp replace failed\n");
  1.1152 -			continue;
  1.1153 -		}
  1.1154 -		LM_DBG("Resulted in replacement: '%.*s'\n",
  1.1155 -		       result.len, ZSW(result.s));
  1.1156 -		pattern.s[pattern.len] = '!';
  1.1157 -		replacement.s[replacement.len] = '!';
  1.1158 -		
  1.1159 -		if (param.len > 0) {
  1.1160 -			if (result.len + param.len > MAX_URI_SIZE - 1) {
  1.1161 -				LM_ERR("URI is too long\n");
  1.1162 -				continue;
  1.1163 -			}
  1.1164 -			new_result.s = &(new_uri[0]);
  1.1165 -			new_result.len = MAX_URI_SIZE;
  1.1166 -			if (add_uri_param(&result, &param, &new_result) == 0) {
  1.1167 -				LM_ERR("Parsing of URI <%.*s> failed\n",
  1.1168 -				       result.len, result.s);
  1.1169 -				continue;
  1.1170 -			}
  1.1171 -			if (new_result.len > 0) {
  1.1172 -				result = new_result;
  1.1173 -			}
  1.1174 -		}
  1.1175 -
  1.1176 -		if (first) {
  1.1177 -			if (set_ruri(_msg, &result) == -1) {
  1.1178 -				goto done;
  1.1179 -			}
  1.1180 -			set_ruri_q(q);
  1.1181 -			first = 0;
  1.1182 -			curr_prio = ((naptr->order) << 16) + naptr->pref;
  1.1183 -		} else {
  1.1184 -			priority = ((naptr->order) << 16) + naptr->pref;
  1.1185 -			if (priority > curr_prio) {
  1.1186 -				q = q - 10;
  1.1187 -				curr_prio = priority;
  1.1188 -			}
  1.1189 -			if (append_branch(_msg, &result, 0, 0, q, 0, 0) == -1) {
  1.1190 -				goto done;
  1.1191 -			}
  1.1192 -		}
  1.1193 -	}
  1.1194 -
  1.1195 -done:
  1.1196 -	free_rdata_list(head);
  1.1197 -	return first ? -1 : 1;
  1.1198 -}
  1.1199 -

mercurial