obsolete/registrar/lookup.c
d23bed8f
 /*
  * $Id$
  *
  * Lookup contacts in usrloc
ed346bcc
  *
95072403
  * Copyright (C) 2001-2003 FhG Fokus
ed346bcc
  *
  * This file is part of ser, a free SIP server.
  *
  * ser is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation; either version 2 of the License, or
  * (at your option) any later version
  *
  * For a license to use the ser software under conditions
  * other than those described here, or to purchase support for this
  * software, please contact iptel.org by e-mail at the following addresses:
  *    info@iptel.org
  *
  * ser is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License 
  * along with this program; if not, write to the Free Software 
9e1ff448
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
6328454b
  *
  * History:
  * ---------
067c3d5a
  * 2005-08-01 fix: "received=" is used also for the branches (andrei)
  * 2005-04-22 added received_to_uri option support (andrei)
6328454b
  * 2003-03-12 added support for zombie state (nils)
dbbd32ac
  * 2005-02-25 lookup() forces the socket stored in USRLOC (bogdan)
d23bed8f
  */
 
ed346bcc
 
d23bed8f
 #include <string.h>
e60b65ed
 #include "../../ut.h"
 #include "../../dset.h"
 #include "../../str.h"
 #include "../../config.h"
 #include "../../action.h"
 #include "../usrloc/usrloc.h"
067c3d5a
 #include "../../error.h"
d60a6b25
 #include "../../id.h"
c29222b1
 #include "../../sr_module.h"
d23bed8f
 #include "common.h"
 #include "regtime.h"
 #include "reg_mod.h"
fdac2b59
 #include "lookup.h"
602242f3
 #include "../../usr_avp.h"
d23bed8f
 
 
067c3d5a
 
 /* new_uri= uri "; received=" received
  * returns 0 on success, < 0 on error (out of memory)
  * new_uri.s is pkg_malloc'ed (so you must pkg_free it when you are done
  *  with it)
  */
 static inline int add_received(str* new_uri, str* uri, str* received)
 {
 	/* copy received into an uri param */
 	new_uri->len=uri->len+RECEIVED_LEN+1+received->len+1;
 	new_uri->s=pkg_malloc(new_uri->len+1);
 	if (new_uri->s==0){
 		LOG(L_ERR, "ERROR: add_received(): out of memory\n");
 		return -1;
 	}
 	memcpy(new_uri->s, uri->s, uri->len);
 	memcpy(new_uri->s+uri->len, RECEIVED, RECEIVED_LEN);
 	new_uri->s[uri->len+RECEIVED_LEN]='"';
 	memcpy(new_uri->s+uri->len+RECEIVED_LEN+1, received->s, received->len);
 	new_uri->s[new_uri->len-1]='"';
 	new_uri->s[new_uri->len]=0; /* for debugging */
 	return 0;
 }
 
 	
 
d23bed8f
 /*
  * Lookup contact in the database and rewrite Request-URI
  */
 int lookup(struct sip_msg* _m, char* _t, char* _s)
 {
 	urecord_t* r;
d60a6b25
 	str uid;
d23bed8f
 	ucontact_t* ptr;
 	int res;
716ffc0a
 	unsigned int nat;
067c3d5a
 	str new_uri; 	
716ffc0a
 
 	nat = 0;
d23bed8f
 	
d60a6b25
 	if (get_to_uid(&uid, _m) < 0) return -1;
 
d23bed8f
 	get_act_time();
 
aab4e8a6
 	ul.lock_udomain((udomain_t*)_t);
d60a6b25
 	res = ul.get_urecord((udomain_t*)_t, &uid, &r);
d23bed8f
 	if (res < 0) {
 		LOG(L_ERR, "lookup(): Error while querying usrloc\n");
aab4e8a6
 		ul.unlock_udomain((udomain_t*)_t);
1b985a7d
 		return -2;
d23bed8f
 	}
 	
 	if (res > 0) {
d60a6b25
 		DBG("lookup(): '%.*s' Not found in usrloc\n", uid.len, ZSW(uid.s));
aab4e8a6
 		ul.unlock_udomain((udomain_t*)_t);
1b985a7d
 		return -3;
d23bed8f
 	}
 
 	ptr = r->contacts;
8b516bb8
 	while ((ptr) && !VALID_CONTACT(ptr, act_time))
6328454b
 		ptr = ptr->next;
d23bed8f
 	
544b4716
 	if (ptr) {
a57782d7
 		if (ptr->received.s && ptr->received.len) {
067c3d5a
 			if (received_to_uri){
 				if (add_received(&new_uri, &ptr->c, &ptr->received)<0){
 					LOG(L_ERR, "ERROR: lookup(): out of memory\n");
 					return -4;
 				}
 			/* replace the msg uri */
 			if (_m->new_uri.s)      pkg_free(_m->new_uri.s);
 			_m->new_uri=new_uri;
 			_m->parsed_uri_ok=0;
039b182e
 			ruri_mark_new();
067c3d5a
 			goto skip_rewrite_uri;
 			}else if (set_dst_uri(_m, &ptr->received) < 0) {
71b46822
 				ul.unlock_udomain((udomain_t*)_t);
 				return -4;
 			}
 		}
602242f3
 		
067c3d5a
 		if (rewrite_uri(_m, &ptr->c) < 0) {
 			LOG(L_ERR, "lookup(): Unable to rewrite Request-URI\n");
 			ul.unlock_udomain((udomain_t*)_t);
 			return -4;
 		}
71b46822
 
dbbd32ac
 		if (ptr->sock) {
6054da62
 			set_force_socket(_m, ptr->sock);
dbbd32ac
 		}
 
067c3d5a
 skip_rewrite_uri:
 
feb92a23
 		set_ruri_q(ptr->q);
 
716ffc0a
 		nat |= ptr->flags & FL_NAT;
544b4716
 		ptr = ptr->next;
 	} else {
 		     /* All contacts expired */
aab4e8a6
 		ul.unlock_udomain((udomain_t*)_t);
1b985a7d
 		return -5;
d23bed8f
 	}
 	
 	     /* Append branches if enabled */
 	if (!append_branches) goto skip;
 
 	while(ptr) {
8b516bb8
 		if (VALID_CONTACT(ptr, act_time)) {
067c3d5a
 			if (received_to_uri && ptr->received.s && ptr->received.len){
 				if (add_received(&new_uri, &ptr->c, &ptr->received)<0){
 					LOG(L_ERR, "ERROR: lookup(): branch: out of memory\n");
 					goto cont; /* try to continue */
 				}
181561c7
 				if (append_branch(_m, &new_uri, 0, 0, ptr->q,
 						  0, 0, 0, 0) == -1) {
067c3d5a
 					LOG(L_ERR, "lookup(): Error while appending a branch\n");
 					pkg_free(new_uri.s);
 					if (ser_error==E_TOO_MANY_BRANCHES) goto skip;
 					else goto cont; /* try to continue, maybe we have an
 							                   oversized contact */
 				}
 				pkg_free(new_uri.s); /* append_branch doesn't free it */
 			}else{
181561c7
 				if (append_branch(_m, &ptr->c, &ptr->received,
 						  0 /* path */,
 						  ptr->q, 0 /* brflags*/,
 						  ptr->sock, 0, 0) == -1) {
067c3d5a
 					LOG(L_ERR, "lookup(): Error while appending a branch\n");
 					goto skip; /* Return OK here so the function succeeds */
 				}
 			}
fdac2b59
 			
 			nat |= ptr->flags & FL_NAT; 
d23bed8f
 		} 
067c3d5a
 cont:
fdac2b59
 		ptr = ptr->next; 
d23bed8f
 	}
 	
  skip:
aab4e8a6
 	ul.unlock_udomain((udomain_t*)_t);
1577e24b
 	if (nat) setflag(_m, load_nat_flag);
d23bed8f
 	return 1;
 }
26cc655c
 
 
 /*
  * Return true if the AOR in the Request-URI is registered,
  * it is similar to lookup but registered neither rewrites
  * the Request-URI nor appends branches
  */
 int registered(struct sip_msg* _m, char* _t, char* _s)
 {
d60a6b25
 	str uid;
26cc655c
 	urecord_t* r;
9a5e106b
         ucontact_t* ptr;
26cc655c
 	int res;
 
d60a6b25
 	if (get_to_uid(&uid, _m) < 0) return -1;
 
26cc655c
 	ul.lock_udomain((udomain_t*)_t);
d60a6b25
 	res = ul.get_urecord((udomain_t*)_t, &uid, &r);
26cc655c
 
 	if (res < 0) {
48a44673
 		ul.unlock_udomain((udomain_t*)_t);
26cc655c
 		LOG(L_ERR, "registered(): Error while querying usrloc\n");
 		return -1;
 	}
9a5e106b
 
 	if (res == 0) {
 		ptr = r->contacts;
 		while (ptr && !VALID_CONTACT(ptr, act_time)) {
 			ptr = ptr->next;
 		}
 
 		if (ptr) {
48a44673
 			ul.unlock_udomain((udomain_t*)_t);
d60a6b25
 			DBG("registered(): '%.*s' found in usrloc\n", uid.len, ZSW(uid.s));
9a5e106b
 			return 1;
 		}
 	}
 
48a44673
 	ul.unlock_udomain((udomain_t*)_t);
d60a6b25
 	DBG("registered(): '%.*s' not found in usrloc\n", uid.len, ZSW(uid.s));
9a5e106b
 	return -1;
26cc655c
 }
602242f3
 
 /*
  * Lookup contact in the database and rewrite Request-URI,
  * and filter them by aor
  */
 int lookup2(struct sip_msg* msg, char* table, char* p2)
 {
 	urecord_t* r;
 	str uid;
 	ucontact_t* ptr;
 	int res;
 	unsigned int nat;
bbb2393f
 	str new_uri, aor;
602242f3
 
 	nat = 0;
bbb2393f
 	
 	if (get_str_fparam(&aor, msg, (fparam_t*)p2) != 0) {
 	    ERR("Unable to get the AOR value\n");
602242f3
 	    return -1;
 	}
 
 	if (get_to_uid(&uid, msg) < 0) return -1;
 	get_act_time();
 
 	ul.lock_udomain((udomain_t*)table);
 	res = ul.get_urecord((udomain_t*)table, &uid, &r);
 	if (res < 0) {
 		ERR("Error while querying usrloc\n");
 		ul.unlock_udomain((udomain_t*)table);
 		return -2;
 	}
 	
 	if (res > 0) {
 		DBG("'%.*s' Not found in usrloc\n", uid.len, ZSW(uid.s));
 		ul.unlock_udomain((udomain_t*)table);
 		return -3;
 	}
 
 	ptr = r->contacts;
a93ec3c3
 	while (ptr && (!VALID_CONTACT(ptr, act_time) || !VALID_AOR(ptr, aor)))
602242f3
 	    ptr = ptr->next;
 	
 	if (ptr) {
 	       if (ptr->received.s && ptr->received.len) {
 			if (received_to_uri){
 				if (add_received(&new_uri, &ptr->c, &ptr->received) < 0) {
 					ERR("Out of memory\n");
 					return -4;
 				}
 			/* replace the msg uri */
 			if (msg->new_uri.s) pkg_free(msg->new_uri.s);
 			msg->new_uri = new_uri;
 			msg->parsed_uri_ok = 0;
039b182e
 			ruri_mark_new();
602242f3
 			goto skip_rewrite_uri;
 			} else if (set_dst_uri(msg, &ptr->received) < 0) {
 			        ul.unlock_udomain((udomain_t*)table);
 				return -4;
 			}
 		}
 		
 		if (rewrite_uri(msg, &ptr->c) < 0) {
 			ERR("Unable to rewrite Request-URI\n");
 			ul.unlock_udomain((udomain_t*)table);
 			return -4;
 		}
 
 		if (ptr->sock) {
6054da62
 			set_force_socket(msg, ptr->sock);
602242f3
 		}
 
 skip_rewrite_uri:
 		set_ruri_q(ptr->q);
 
 		nat |= ptr->flags & FL_NAT;
 		ptr = ptr->next;
 	} else {
 		     /* All contacts expired */
 		ul.unlock_udomain((udomain_t*)table);
 		return -5;
 	}
 	
 	     /* Append branches if enabled */
 	if (!append_branches) goto skip;
 
 	while(ptr) {
 		if (VALID_CONTACT(ptr, act_time) && VALID_AOR(ptr, aor)) {
 			if (received_to_uri && ptr->received.s && ptr->received.len) {
 				if (add_received(&new_uri, &ptr->c, &ptr->received) < 0) {
 					ERR("branch: out of memory\n");
 					goto cont; /* try to continue */
 				}
181561c7
 				if (append_branch(msg, &new_uri, 0, 0, ptr->q,
 						  0, 0, 0, 0) == -1) {
602242f3
 					ERR("Error while appending a branch\n");
 					pkg_free(new_uri.s);
 					if (ser_error == E_TOO_MANY_BRANCHES) goto skip;
 					else goto cont; /* try to continue, maybe we have an
 							                   oversized contact */
 				}
 				pkg_free(new_uri.s); /* append_branch doesn't free it */
 			} else {
181561c7
 				if (append_branch(msg, &ptr->c, &ptr->received,
 						  0 /* path */,
 						  ptr->q, 0, ptr->sock,
 						  0, 0) == -1) {
602242f3
 					ERR("Error while appending a branch\n");
 					goto skip; /* Return OK here so the function succeeds */
 				}
 			}
 			
 			nat |= ptr->flags & FL_NAT; 
 		} 
 cont:
 		ptr = ptr->next; 
 	}
 	
  skip:
 	ul.unlock_udomain((udomain_t*)table);
 	if (nat) setflag(msg, load_nat_flag);
 	return 1;
 }
 
920bf6c5
 
 /*
  * Return true if the AOR in the Request-URI is registered,
  * it is similar to lookup but registered neither rewrites
  * the Request-URI nor appends branches
  */
 int registered2(struct sip_msg* _m, char* _t, char* p2)
 {
 	str uid, aor;
 	urecord_t* r;
         ucontact_t* ptr;
 	int res;
 
 	if (get_str_fparam(&aor, _m, (fparam_t*)p2) != 0) {
 	    ERR("Unable to get the AOR value\n");
 	    return -1;
 	}
 
 	if (get_to_uid(&uid, _m) < 0) return -1;
 
 	ul.lock_udomain((udomain_t*)_t);
 	res = ul.get_urecord((udomain_t*)_t, &uid, &r);
 
 	if (res < 0) {
 		ul.unlock_udomain((udomain_t*)_t);
 		LOG(L_ERR, "registered(): Error while querying usrloc\n");
 		return -1;
 	}
 
 	if (res == 0) {
 		ptr = r->contacts;
a93ec3c3
 		while (ptr && (!VALID_CONTACT(ptr, act_time) || !VALID_AOR(ptr, aor))) {
920bf6c5
 			ptr = ptr->next;
 		}
 
 		if (ptr) {
 			ul.unlock_udomain((udomain_t*)_t);
 			DBG("registered(): '%.*s' found in usrloc\n", uid.len, ZSW(uid.s));
 			return 1;
 		}
 	}
 
 	ul.unlock_udomain((udomain_t*)_t);
 	DBG("registered(): '%.*s' not found in usrloc\n", uid.len, ZSW(uid.s));
 	return -1;
 }