00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00035 #include <string.h>
00036 #include "../../ut.h"
00037 #include "../../dset.h"
00038 #include "../../str.h"
00039 #include "../../xavp.h"
00040 #include "../../config.h"
00041 #include "../../action.h"
00042 #include "../../mod_fix.h"
00043 #include "../../parser/parse_rr.h"
00044 #include "../usrloc/usrloc.h"
00045 #include "common.h"
00046 #include "regtime.h"
00047 #include "reg_mod.h"
00048 #include "lookup.h"
00049 #include "config.h"
00050
00051 #define allowed_method(_msg, _c) \
00052 ( !method_filtering || ((_msg)->REQ_METHOD)&((_c)->methods) )
00053
00054
00058 int reg_cmp_instances(str *i1, str *i2)
00059 {
00060 str inst1;
00061 str inst2;
00062
00063 if(i1==NULL || i2==NULL || i1->len<=0 || i2->len<=0)
00064 return -1;
00065
00066 inst1 = *i1;
00067 inst2 = *i2;
00068 if(inst1.len>2 && inst1.s[0]=='<' && inst1.s[inst1.len-1]=='>')
00069 {
00070 inst1.s++;
00071 inst1.len -=2;
00072 }
00073 if(inst2.len>2 && inst2.s[0]=='<' && inst2.s[inst2.len-1]=='>')
00074 {
00075 inst2.s++;
00076 inst2.len -=2;
00077 }
00078 if(inst1.len>0 && inst1.len==inst2.len
00079 && memcmp(inst1.s, inst2.s, inst2.len)==0)
00080 return 0;
00081 return -1;
00082 }
00083
00090 int lookup(struct sip_msg* _m, udomain_t* _d, str* _uri)
00091 {
00092 urecord_t* r;
00093 str aor, uri;
00094 sip_uri_t puri;
00095 ucontact_t* ptr = 0;
00096 int res;
00097 int ret;
00098 str path_dst;
00099 flag_t old_bflags;
00100 int i;
00101 str inst = {0};
00102 unsigned int ahash = 0;
00103 sr_xavp_t *xavp=NULL;
00104 sr_xavp_t *list=NULL;
00105 str xname = {"ruid", 4};
00106 sr_xval_t xval;
00107
00108 ret = -1;
00109
00110 if (_m->new_uri.s) uri = _m->new_uri;
00111 else uri = _m->first_line.u.request.uri;
00112
00113 if (extract_aor((_uri)?_uri:&uri, &aor, &puri) < 0) {
00114 LM_ERR("failed to extract address of record\n");
00115 return -3;
00116 }
00117
00118 if(puri.gr.s!=NULL)
00119 {
00120 if(puri.gr_val.len>0) {
00121
00122 inst = puri.gr_val;
00123 LM_DBG("looking up pub gruu [%.*s]\n", inst.len, inst.s);
00124 } else {
00125
00126 ahash = 0;
00127 inst = puri.user;
00128 for(i=inst.len-1; i>=0; i--)
00129 {
00130 if(inst.s[i]==REG_GRUU_SEP)
00131 break;
00132 ahash <<= 4;
00133 if(inst.s[i] >='0' && inst.s[i] <='9') ahash+=inst.s[i] -'0';
00134 else if (inst.s[i] >='a' && inst.s[i] <='f') ahash+=inst.s[i] -'a'+10;
00135 else if (inst.s[i] >='A' && inst.s[i] <='F') ahash+=inst.s[i] -'A'+10;
00136 else {
00137 LM_ERR("failed to extract temp gruu - invalid hash\n");
00138 return -3;
00139 }
00140 }
00141 if(i<0) {
00142 LM_ERR("failed to extract temp gruu - invalid format\n");
00143 return -3;
00144 }
00145 inst.len = i;
00146 LM_DBG("looking up temp gruu [%u / %.*s]\n", ahash, inst.len, inst.s);
00147 }
00148 }
00149
00150 get_act_time();
00151
00152 if(puri.gr.s==NULL || puri.gr_val.len>0)
00153 {
00154
00155 ul.lock_udomain(_d, &aor);
00156 res = ul.get_urecord(_d, &aor, &r);
00157 if (res > 0) {
00158 LM_DBG("'%.*s' Not found in usrloc\n", aor.len, ZSW(aor.s));
00159 ul.unlock_udomain(_d, &aor);
00160 return -1;
00161 }
00162
00163 ptr = r->contacts;
00164 ret = -1;
00165
00166 while (ptr) {
00167 if(VALID_CONTACT(ptr,act_time)) {
00168 if(allowed_method(_m,ptr)) {
00169
00170 if(inst.len>0) {
00171 if(reg_cmp_instances(&inst, &ptr->instance)==0)
00172 {
00173
00174 LM_DBG("contact for [%.*s] found by pub gruu [%.*s]\n",
00175 aor.len, ZSW(aor.s), inst.len, inst.s);
00176 break;
00177 }
00178 } else {
00179
00180 LM_DBG("contact for [%.*s] found by address\n",
00181 aor.len, ZSW(aor.s));
00182 break;
00183 }
00184 } else {
00185 LM_DBG("contact for [%.*s] cannot handle the SIP method\n",
00186 aor.len, ZSW(aor.s));
00187 ret = -2;
00188 }
00189 }
00190 ptr = ptr->next;
00191 }
00192 if (ptr==0) {
00193
00194 LM_DBG("'%.*s' has no valid contact in usrloc\n", aor.len, ZSW(aor.s));
00195 goto done;
00196 }
00197 } else {
00198
00199 res = ul.get_urecord_by_ruid(_d, ahash, &inst, &r, &ptr);
00200 if(res<0) {
00201 LM_DBG("temp gruu '%.*s' not found in usrloc\n", aor.len, ZSW(aor.s));
00202 return -1;
00203 }
00204 aor = *ptr->aor;
00205
00206 if( (ptr) && !(VALID_CONTACT(ptr,act_time)
00207 && (ret=-2) && allowed_method(_m,ptr)))
00208 goto done;
00209 LM_DBG("contact for [%.*s] found by temp gruu [%.*s / %u]\n",
00210 aor.len, ZSW(aor.s), inst.len, inst.s, ahash);
00211 }
00212
00213 ret = 1;
00214 if (ptr) {
00215 if (rewrite_uri(_m, &ptr->c) < 0) {
00216 LM_ERR("unable to rewrite Request-URI\n");
00217 ret = -3;
00218 goto done;
00219 }
00220
00221
00222 reset_dst_uri(_m);
00223
00224
00225 if(reg_xavp_rcd.s!=NULL)
00226 {
00227 list = xavp_get(®_xavp_rcd, NULL);
00228 xavp = list;
00229 memset(&xval, 0, sizeof(sr_xval_t));
00230 xval.type = SR_XTYPE_STR;
00231 xval.v.s = ptr->ruid;
00232 xavp_add_value(&xname, &xval, &xavp);
00233 if(list==NULL)
00234 {
00235
00236 xval.type = SR_XTYPE_XAVP;
00237 xval.v.xavp = xavp;
00238 xavp_add_value(®_xavp_rcd, &xval, NULL);
00239 }
00240 }
00241
00242
00243
00244 if (ptr->path.s && ptr->path.len) {
00245 if (get_path_dst_uri(&ptr->path, &path_dst) < 0) {
00246 LM_ERR("failed to get dst_uri for Path\n");
00247 ret = -3;
00248 goto done;
00249 }
00250 if (set_path_vector(_m, &ptr->path) < 0) {
00251 LM_ERR("failed to set path vector\n");
00252 ret = -3;
00253 goto done;
00254 }
00255 if (set_dst_uri(_m, &path_dst) < 0) {
00256 LM_ERR("failed to set dst_uri of Path\n");
00257 ret = -3;
00258 goto done;
00259 }
00260 } else if (ptr->received.s && ptr->received.len) {
00261 if (set_dst_uri(_m, &ptr->received) < 0) {
00262 ret = -3;
00263 goto done;
00264 }
00265 }
00266
00267 set_ruri_q(ptr->q);
00268
00269 old_bflags = 0;
00270 getbflagsval(0, &old_bflags);
00271 setbflagsval(0, old_bflags|ptr->cflags);
00272
00273 if (ptr->sock)
00274 set_force_socket(_m, ptr->sock);
00275
00276 ptr = ptr->next;
00277 }
00278
00279
00280 if(inst.len>0) goto done;
00281
00282
00283 if (!cfg_get(registrar, registrar_cfg, append_branches)) goto done;
00284
00285 for( ; ptr ; ptr = ptr->next ) {
00286 if (VALID_CONTACT(ptr, act_time) && allowed_method(_m, ptr)) {
00287 path_dst.len = 0;
00288 if(ptr->path.s && ptr->path.len
00289 && get_path_dst_uri(&ptr->path, &path_dst) < 0) {
00290 LM_ERR("failed to get dst_uri for Path\n");
00291 continue;
00292 }
00293
00294
00295
00296 if (km_append_branch(_m,&ptr->c,path_dst.len?&path_dst:&ptr->received,
00297 &ptr->path, ptr->q, ptr->cflags, ptr->sock) == -1) {
00298 LM_ERR("failed to append a branch\n");
00299
00300 continue;
00301 }
00302 }
00303 }
00304
00305 done:
00306 ul.release_urecord(r);
00307 ul.unlock_udomain(_d, &aor);
00308 return ret;
00309 }
00310
00311
00317 int registered(struct sip_msg* _m, udomain_t* _d, str* _uri)
00318 {
00319 str uri, aor;
00320 urecord_t* r;
00321 ucontact_t* ptr;
00322 int res;
00323 int_str match_callid=(int_str)0;
00324
00325 if(_uri!=NULL)
00326 {
00327 uri = *_uri;
00328 } else {
00329 if (_m->new_uri.s) uri = _m->new_uri;
00330 else uri = _m->first_line.u.request.uri;
00331 }
00332
00333 if (extract_aor(&uri, &aor, NULL) < 0) {
00334 LM_ERR("failed to extract address of record\n");
00335 return -1;
00336 }
00337
00338 ul.lock_udomain(_d, &aor);
00339 res = ul.get_urecord(_d, &aor, &r);
00340
00341 if (res < 0) {
00342 ul.unlock_udomain(_d, &aor);
00343 LM_ERR("failed to query usrloc\n");
00344 return -1;
00345 }
00346
00347 if (res == 0) {
00348
00349 if (reg_callid_avp_name.n) {
00350 struct usr_avp *avp =
00351 search_first_avp( reg_callid_avp_type, reg_callid_avp_name, &match_callid, 0);
00352 if (!(avp && is_avp_str_val(avp)))
00353 match_callid.n = 0;
00354 match_callid.s.s = NULL;
00355 } else {
00356 match_callid.n = 0;
00357 match_callid.s.s = NULL;
00358 }
00359
00360 for (ptr = r->contacts; ptr; ptr = ptr->next) {
00361 if(!VALID_CONTACT(ptr, act_time)) continue;
00362 if (match_callid.s.s &&
00363 memcmp(match_callid.s.s,ptr->callid.s,match_callid.s.len))
00364 continue;
00365 ul.release_urecord(r);
00366 ul.unlock_udomain(_d, &aor);
00367 LM_DBG("'%.*s' found in usrloc\n", aor.len, ZSW(aor.s));
00368 return 1;
00369 }
00370 }
00371
00372 ul.unlock_udomain(_d, &aor);
00373 LM_DBG("'%.*s' not found in usrloc\n", aor.len, ZSW(aor.s));
00374 return -1;
00375 }