lookup.c

Go to the documentation of this file.
00001 /*
00002  * $Id: lookup.c 5143 2008-10-30 16:01:29Z henningw $
00003  *
00004  * Lookup contacts in usrloc
00005  *
00006  * Copyright (C) 2001-2003 FhG Fokus
00007  *
00008  * This file is part of Kamailio, a free SIP server.
00009  *
00010  * Kamailio is free software; you can redistribute it and/or modify
00011  * it under the terms of the GNU General Public License as published by
00012  * the Free Software Foundation; either version 2 of the License, or
00013  * (at your option) any later version
00014  *
00015  * Kamailio is distributed in the hope that it will be useful,
00016  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00017  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00018  * GNU General Public License for more details.
00019  *
00020  * You should have received a copy of the GNU General Public License 
00021  * along with this program; if not, write to the Free Software 
00022  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00023  *
00024  * History:
00025  * ---------
00026  * 2003-03-12 added support for zombie state (nils)
00027  */
00028 /*!
00029  * \file
00030  * \brief SIP registrar module - lookup contacts in usrloc
00031  * \ingroup registrar  
00032  */  
00033 
00034 
00035 #include <string.h>
00036 #include "../../ut.h"
00037 #include "../../dset.h"
00038 #include "../../str.h"
00039 #include "../../config.h"
00040 #include "../../action.h"
00041 #include "../../parser/parse_rr.h"
00042 #include "../usrloc/usrloc.h"
00043 #include "common.h"
00044 #include "regtime.h"
00045 #include "reg_mod.h"
00046 #include "lookup.h"
00047 
00048 
00049 #define allowed_method(_msg, _c) \
00050    ( !method_filtering || ((_msg)->REQ_METHOD)&((_c)->methods) )
00051 
00052 
00053 /*! \brief
00054  * Lookup contact in the database and rewrite Request-URI
00055  * \return: -1 : not found
00056  *          -2 : found but method not allowed
00057  *          -3 : error
00058  */
00059 int lookup(struct sip_msg* _m, char* _t, char* _s)
00060 {
00061    urecord_t* r;
00062    str aor, uri;
00063    ucontact_t* ptr;
00064    int res;
00065    int ret;
00066    str path_dst;
00067 
00068    if (_m->new_uri.s) uri = _m->new_uri;
00069    else uri = _m->first_line.u.request.uri;
00070    
00071    if (extract_aor(&uri, &aor) < 0) {
00072       LM_ERR("failed to extract address of record\n");
00073       return -3;
00074    }
00075    
00076    get_act_time();
00077 
00078    ul.lock_udomain((udomain_t*)_t, &aor);
00079    res = ul.get_urecord((udomain_t*)_t, &aor, &r);
00080    if (res > 0) {
00081       LM_DBG("'%.*s' Not found in usrloc\n", aor.len, ZSW(aor.s));
00082       ul.unlock_udomain((udomain_t*)_t, &aor);
00083       return -1;
00084    }
00085 
00086    ptr = r->contacts;
00087    ret = -1;
00088    /* look first for an un-expired and suported contact */
00089    while ( (ptr) &&
00090    !(VALID_CONTACT(ptr,act_time) && (ret=-2) && allowed_method(_m,ptr)))
00091       ptr = ptr->next;
00092    if (ptr==0) {
00093       /* nothing found */
00094       goto done;
00095    }
00096 
00097    ret = 1;
00098    if (ptr) {
00099       if (rewrite_uri(_m, &ptr->c) < 0) {
00100          LM_ERR("unable to rewrite Request-URI\n");
00101          ret = -3;
00102          goto done;
00103       }
00104 
00105       /* If a Path is present, use first path-uri in favour of
00106        * received-uri because in that case the last hop towards the uac
00107        * has to handle NAT. - agranig */
00108       if (ptr->path.s && ptr->path.len) {
00109          if (get_path_dst_uri(&ptr->path, &path_dst) < 0) {
00110             LM_ERR("failed to get dst_uri for Path\n");
00111             ret = -3;
00112             goto done;
00113          }
00114          if (set_path_vector(_m, &ptr->path) < 0) {
00115             LM_ERR("failed to set path vector\n");
00116             ret = -3;
00117             goto done;
00118          }
00119          if (set_dst_uri(_m, &path_dst) < 0) {
00120             LM_ERR("failed to set dst_uri of Path\n");
00121             ret = -3;
00122             goto done;
00123          }
00124       } else if (ptr->received.s && ptr->received.len) {
00125          if (set_dst_uri(_m, &ptr->received) < 0) {
00126             ret = -3;
00127             goto done;
00128          }
00129       }
00130 
00131       set_ruri_q(ptr->q);
00132 
00133       setbflag( 0, ptr->cflags);
00134 
00135       if (ptr->sock)
00136          _m->force_send_socket = ptr->sock;
00137 
00138       ptr = ptr->next;
00139    }
00140 
00141    /* Append branches if enabled */
00142    if (!append_branches) goto done;
00143 
00144    for( ; ptr ; ptr = ptr->next ) {
00145       if (VALID_CONTACT(ptr, act_time) && allowed_method(_m, ptr)) {
00146          path_dst.len = 0;
00147          if(ptr->path.s && ptr->path.len 
00148          && get_path_dst_uri(&ptr->path, &path_dst) < 0) {
00149             LM_ERR("failed to get dst_uri for Path\n");
00150             continue;
00151          }
00152 
00153          /* The same as for the first contact applies for branches 
00154           * regarding path vs. received. */
00155          if (append_branch(_m,&ptr->c,path_dst.len?&path_dst:&ptr->received,
00156          &ptr->path, ptr->q, ptr->cflags, ptr->sock) == -1) {
00157             LM_ERR("failed to append a branch\n");
00158             /* Also give a chance to the next branches*/
00159             continue;
00160          }
00161       }
00162    }
00163 
00164 done:
00165    ul.release_urecord(r);
00166    ul.unlock_udomain((udomain_t*)_t, &aor);
00167    return ret;
00168 }
00169 
00170 
00171 /*! \brief the is_registered() function
00172  * Return true if the AOR in the Request-URI is registered,
00173  * it is similar to lookup but registered neither rewrites
00174  * the Request-URI nor appends branches
00175  */
00176 int registered(struct sip_msg* _m, char* _t, char* _s)
00177 {
00178    str uri, aor;
00179    urecord_t* r;
00180    ucontact_t* ptr;
00181    int res;
00182 
00183    if (_m->new_uri.s) uri = _m->new_uri;
00184    else uri = _m->first_line.u.request.uri;
00185    
00186    if (extract_aor(&uri, &aor) < 0) {
00187       LM_ERR("failed to extract address of record\n");
00188       return -1;
00189    }
00190    
00191    ul.lock_udomain((udomain_t*)_t, &aor);
00192    res = ul.get_urecord((udomain_t*)_t, &aor, &r);
00193 
00194    if (res < 0) {
00195       ul.unlock_udomain((udomain_t*)_t, &aor);
00196       LM_ERR("failed to query usrloc\n");
00197       return -1;
00198    }
00199 
00200    if (res == 0) {
00201       
00202       int_str match_callid;
00203       if (reg_callid_avp_name.n) {
00204          struct usr_avp *avp =
00205             search_first_avp( reg_callid_avp_type, reg_callid_avp_name, &match_callid, 0);
00206          if (!(avp && is_avp_str_val(avp)))
00207             match_callid=(int_str)0;
00208       }
00209 
00210       for (ptr = r->contacts; ptr; ptr = ptr->next) {
00211          if(!VALID_CONTACT(ptr, act_time)) continue;
00212          if (match_callid.s.s && /* optionally enforce tighter matching w/ Call-ID */
00213             memcmp(match_callid.s.s,ptr->callid.s,match_callid.s.len))
00214             continue;
00215          ul.release_urecord(r);
00216          ul.unlock_udomain((udomain_t*)_t, &aor);
00217          LM_DBG("'%.*s' found in usrloc\n", aor.len, ZSW(aor.s));
00218          return 1;
00219       }
00220    }
00221 
00222    ul.unlock_udomain((udomain_t*)_t, &aor);
00223    LM_DBG("'%.*s' not found in usrloc\n", aor.len, ZSW(aor.s));
00224    return -1;
00225 }

Generated on Wed May 23 18:00:28 2012 for Kamailio - The Open Source SIP Server by  doxygen 1.5.6