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
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00048 #include "../../str.h"
00049 #include "../../socket_info.h"
00050 #include "../../parser/parse_allow.h"
00051 #include "../../parser/parse_methods.h"
00052 #include "../../parser/msg_parser.h"
00053 #include "../../parser/parse_to.h"
00054 #include "../../parser/parse_uri.h"
00055 #include "../../dprint.h"
00056 #include "../../trim.h"
00057 #include "../../ut.h"
00058 #include "../../qvalue.h"
00059 #include "../../dset.h"
00060 #include "../../xavp.h"
00061 #include "../../mod_fix.h"
00062 #include "../../lib/srutils/sruid.h"
00063 #include "../../lib/kcore/cmpapi.h"
00064 #include "../../lib/kcore/statistics.h"
00065 #ifdef USE_TCP
00066 #include "../../tcp_server.h"
00067 #endif
00068 #include "../usrloc/usrloc.h"
00069 #include "common.h"
00070 #include "sip_msg.h"
00071 #include "rerrno.h"
00072 #include "reply.h"
00073 #include "reg_mod.h"
00074 #include "regtime.h"
00075 #include "path.h"
00076 #include "save.h"
00077 #include "config.h"
00078
00079 static int mem_only = 0;
00080
00081 extern sruid_t _reg_sruid;
00082
00088 static inline int star(sip_msg_t *_m, udomain_t* _d, str* _a, str *_h)
00089 {
00090 urecord_t* r;
00091 ucontact_t* c;
00092
00093 ul.lock_udomain(_d, _a);
00094
00095 if (!ul.get_urecord(_d, _a, &r)) {
00096 c = r->contacts;
00097 while(c) {
00098 if (mem_only) {
00099 c->flags |= FL_MEM;
00100 } else {
00101 c->flags &= ~FL_MEM;
00102 }
00103 c = c->next;
00104 }
00105 } else {
00106 r = NULL;
00107 }
00108
00109 if (ul.delete_urecord(_d, _a, r) < 0) {
00110 LM_ERR("failed to remove record from usrloc\n");
00111
00112
00113
00114
00115
00116 rerrno = R_UL_DEL_R;
00117 if (!ul.get_urecord(_d, _a, &r)) {
00118 build_contact(_m, r->contacts, _h);
00119 ul.release_urecord(r);
00120 }
00121 ul.unlock_udomain(_d, _a);
00122 return -1;
00123 }
00124 ul.unlock_udomain(_d, _a);
00125 return 0;
00126 }
00127
00128
00131 static struct socket_info *get_sock_hdr(struct sip_msg *msg)
00132 {
00133 struct socket_info *sock;
00134 struct hdr_field *hf;
00135 str socks;
00136 str hosts;
00137 int port;
00138 int proto;
00139 char c;
00140
00141 if (parse_headers( msg, HDR_EOH_F, 0) == -1) {
00142 LM_ERR("failed to parse message\n");
00143 return 0;
00144 }
00145
00146 for (hf=msg->headers; hf; hf=hf->next) {
00147 if (cmp_hdrname_str(&hf->name, &sock_hdr_name)==0)
00148 break;
00149 }
00150
00151
00152 if (hf==0)
00153 return 0;
00154
00155 trim_len( socks.len, socks.s, hf->body );
00156 if (socks.len==0)
00157 return 0;
00158
00159
00160 c = socks.s[socks.len];
00161 socks.s[socks.len] = '\0';
00162 if (parse_phostport( socks.s, &hosts.s, &hosts.len,
00163 &port, &proto)!=0) {
00164 socks.s[socks.len] = c;
00165 LM_ERR("bad socket <%.*s> in \n",
00166 socks.len, socks.s);
00167 return 0;
00168 }
00169 socks.s[socks.len] = c;
00170 sock = grep_sock_info(&hosts,(unsigned short)port,(unsigned short)proto);
00171 if (sock==0) {
00172 LM_ERR("non-local socket <%.*s>\n", socks.len, socks.s);
00173 return 0;
00174 }
00175
00176 LM_DBG("%d:<%.*s>:%d -> p=%p\n", proto,socks.len,socks.s,port_no,sock );
00177
00178 return sock;
00179 }
00180
00181
00182
00189 static inline int no_contacts(sip_msg_t *_m, udomain_t* _d, str* _a, str* _h)
00190 {
00191 urecord_t* r;
00192 int res;
00193
00194 ul.lock_udomain(_d, _a);
00195 res = ul.get_urecord(_d, _a, &r);
00196 if (res < 0) {
00197 rerrno = R_UL_GET_R;
00198 LM_ERR("failed to retrieve record from usrloc\n");
00199 ul.unlock_udomain(_d, _a);
00200 return -1;
00201 }
00202
00203 if (res == 0) {
00204 build_contact(_m, r->contacts, _h);
00205 ul.release_urecord(r);
00206 } else {
00207 build_contact(_m, NULL, _h);
00208 }
00209 ul.unlock_udomain(_d, _a);
00210 return 0;
00211 }
00212
00213
00214
00218 static inline ucontact_info_t* pack_ci( struct sip_msg* _m, contact_t* _c,
00219 unsigned int _e, unsigned int _f)
00220 {
00221 static ucontact_info_t ci;
00222 static str no_ua = str_init("n/a");
00223 static str callid;
00224 static str path_received = {0,0};
00225 static str path;
00226 static str received = {0,0};
00227 static int received_found;
00228 static unsigned int allowed, allow_parsed;
00229 static struct sip_msg *m = 0;
00230 int_str val;
00231
00232 if (_m!=0) {
00233 memset( &ci, 0, sizeof(ucontact_info_t));
00234
00235
00236 callid = _m->callid->body;
00237 trim_trailing(&callid);
00238 if (callid.len > CALLID_MAX_SIZE) {
00239 rerrno = R_CALLID_LEN;
00240 LM_ERR("callid too long\n");
00241 goto error;
00242 }
00243 ci.callid = &callid;
00244
00245
00246 if (str2int(&get_cseq(_m)->number, (unsigned int*)&ci.cseq) < 0) {
00247 rerrno = R_INV_CSEQ;
00248 LM_ERR("failed to convert cseq number\n");
00249 goto error;
00250 }
00251
00252
00253 if (_m->flags&sock_flag) {
00254 ci.sock = get_sock_hdr(_m);
00255 if (ci.sock==0)
00256 ci.sock = _m->rcv.bind_address;
00257 } else {
00258 ci.sock = _m->rcv.bind_address;
00259 }
00260
00261
00262 if (parse_headers(_m, HDR_USERAGENT_F, 0) != -1 && _m->user_agent &&
00263 _m->user_agent->body.len>0 && _m->user_agent->body.len<UA_MAX_SIZE) {
00264 ci.user_agent = &_m->user_agent->body;
00265 } else {
00266 ci.user_agent = &no_ua;
00267 }
00268
00269
00270 if (path_enabled) {
00271 if (build_path_vector(_m, &path, &path_received) < 0) {
00272 rerrno = R_PARSE_PATH;
00273 goto error;
00274 }
00275 if (path.len && path.s) {
00276 ci.path = &path;
00277 if (path_mode != PATH_MODE_OFF) {
00278
00279 if (set_path_vector(_m, &path) < 0) {
00280 rerrno = R_PARSE_PATH;
00281 goto error;
00282 }
00283 }
00284 }
00285 }
00286
00287 ci.last_modified = act_time;
00288
00289
00290 ci.flags = _f;
00291 getbflagsval(0, &ci.cflags);
00292
00293
00294 if (path_received.len && path_received.s) {
00295 ci.cflags |= ul.nat_flag;
00296 ci.received = path_received;
00297 }
00298
00299 allow_parsed = 0;
00300 received_found = 0;
00301 m = _m;
00302 }
00303
00304 if(_c!=0) {
00305
00306 if (calc_contact_q(_c->q, &ci.q) < 0) {
00307 rerrno = R_INV_Q;
00308 LM_ERR("failed to calculate q\n");
00309 goto error;
00310 }
00311
00312
00313 ci.expires = _e;
00314
00315
00316 if (_c->methods) {
00317 if (parse_methods(&(_c->methods->body), &ci.methods) < 0) {
00318 rerrno = R_PARSE;
00319 LM_ERR("failed to parse contact methods\n");
00320 goto error;
00321 }
00322 } else {
00323
00324 if (allow_parsed == 0) {
00325 if (m && parse_allow( m ) != -1) {
00326 allowed = get_allow_methods(m);
00327 } else {
00328 allowed = ALL_METHODS;
00329 }
00330 allow_parsed = 1;
00331 }
00332 ci.methods = allowed;
00333 }
00334
00335
00336 if (ci.received.len==0) {
00337 if (_c->received) {
00338 ci.received = _c->received->body;
00339 } else {
00340 if (received_found==0) {
00341 memset(&val, 0, sizeof(int_str));
00342 if (rcv_avp_name.n!=0
00343 && search_first_avp(rcv_avp_type, rcv_avp_name, &val, 0)
00344 && val.s.len > 0) {
00345 if (val.s.len>RECEIVED_MAX_SIZE) {
00346 rerrno = R_CONTACT_LEN;
00347 LM_ERR("received too long\n");
00348 goto error;
00349 }
00350 received = val.s;
00351 } else {
00352 received.s = 0;
00353 received.len = 0;
00354 }
00355 received_found = 1;
00356 }
00357 ci.received = received;
00358 }
00359 }
00360 if(_c->instance!=NULL && _c->instance->body.len>0)
00361 ci.instance = _c->instance->body;
00362 if(_c->reg_id!=NULL && _c->reg_id->body.len>0) {
00363 if(str2int(&_c->reg_id->body, &ci.reg_id)<0)
00364 {
00365 LM_ERR("invalid reg-id value\n");
00366 goto error;
00367 }
00368 }
00369 if(sruid_next(&_reg_sruid)<0)
00370 goto error;
00371 ci.ruid = _reg_sruid.uid;
00372 }
00373
00374 return &ci;
00375 error:
00376 return 0;
00377 }
00378
00379
00380 int reg_get_crt_max_contacts(void)
00381 {
00382 int n;
00383 sr_xavp_t *ravp=NULL;
00384 sr_xavp_t *vavp=NULL;
00385 str vname = {"max_contacts", 12};
00386
00387 n = 0;
00388
00389 if(reg_xavp_cfg.s!=NULL)
00390 {
00391 ravp = xavp_get(®_xavp_cfg, NULL);
00392 if(ravp!=NULL && ravp->val.type==SR_XTYPE_XAVP)
00393 {
00394 vavp = xavp_get(&vname, ravp->val.v.xavp);
00395 if(vavp!=NULL && vavp->val.type==SR_XTYPE_INT)
00396 {
00397 n = vavp->val.v.i;
00398 LM_ERR("using max contacts value from xavp: %d\n", n);
00399 } else {
00400 ravp = NULL;
00401 }
00402 } else {
00403 ravp = NULL;
00404 }
00405 }
00406
00407 if(ravp==NULL)
00408 {
00409 n = cfg_get(registrar, registrar_cfg, max_contacts);
00410 }
00411
00412 return n;
00413 }
00414
00421 static inline int insert_contacts(struct sip_msg* _m, udomain_t* _d, str* _a)
00422 {
00423 ucontact_info_t* ci;
00424 urecord_t* r = NULL;
00425 ucontact_t* c;
00426 contact_t* _c;
00427 unsigned int flags;
00428 int num, expires;
00429 int maxc;
00430 #ifdef USE_TCP
00431 int e_max, tcp_check;
00432 struct sip_uri uri;
00433 #endif
00434 sip_uri_t *u;
00435
00436 u = parse_to_uri(_m);
00437 if(u==NULL)
00438 goto error;
00439
00440 flags = mem_only;
00441 #ifdef USE_TCP
00442 if ( (_m->flags&tcp_persistent_flag) &&
00443 (_m->rcv.proto==PROTO_TCP||_m->rcv.proto==PROTO_TLS)) {
00444 e_max = 0;
00445 tcp_check = 1;
00446 } else {
00447 e_max = tcp_check = 0;
00448 }
00449 #endif
00450 _c = get_first_contact(_m);
00451 maxc = reg_get_crt_max_contacts();
00452 for( num=0,r=0,ci=0 ; _c ; _c = get_next_contact(_c) ) {
00453
00454 calc_contact_expires(_m, _c->expires, &expires);
00455
00456 if (expires == 0)
00457 continue;
00458
00459
00460 if (maxc > 0 && num >= maxc) {
00461 LM_INFO("too many contacts (%d) for AOR <%.*s>\n",
00462 num, _a->len, _a->s);
00463 rerrno = R_TOO_MANY;
00464 goto error;
00465 }
00466 num++;
00467
00468 if (r==0) {
00469 if (ul.insert_urecord(_d, _a, &r) < 0) {
00470 rerrno = R_UL_NEW_R;
00471 LM_ERR("failed to insert new record structure\n");
00472 goto error;
00473 }
00474 }
00475
00476
00477 if ( (ci=pack_ci( (ci==0)?_m:0, _c, expires, flags))==0 ) {
00478 LM_ERR("failed to extract contact info\n");
00479 goto error;
00480 }
00481
00482
00483
00484
00485 ci->cseq++;
00486 if ( r->contacts==0
00487 || ul.get_ucontact_by_instance(r, &_c->uri, ci, &c) != 0) {
00488 ci->cseq--;
00489 if (ul.insert_ucontact( r, &_c->uri, ci, &c) < 0) {
00490 rerrno = R_UL_INS_C;
00491 LM_ERR("failed to insert contact\n");
00492 goto error;
00493 }
00494 } else {
00495 ci->cseq--;
00496 if (ul.update_ucontact( r, c, ci) < 0) {
00497 rerrno = R_UL_UPD_C;
00498 LM_ERR("failed to update contact\n");
00499 goto error;
00500 }
00501 }
00502 #ifdef USE_TCP
00503 if (tcp_check) {
00504
00505 if (parse_uri( _c->uri.s, _c->uri.len, &uri)<0) {
00506 LM_ERR("failed to parse contact <%.*s>\n",
00507 _c->uri.len, _c->uri.s);
00508 } else if (uri.proto==PROTO_TCP || uri.proto==PROTO_TLS) {
00509 if (e_max) {
00510 LM_WARN("multiple TCP contacts on single REGISTER\n");
00511 if (expires>e_max) e_max = expires;
00512 } else {
00513 e_max = expires;
00514 }
00515 }
00516 }
00517 #endif
00518 }
00519
00520 if (r) {
00521 if (r->contacts)
00522 build_contact(_m, r->contacts, &u->host);
00523 ul.release_urecord(r);
00524 } else {
00525 build_contact(_m, NULL, &u->host);
00526 }
00527
00528 #ifdef USE_TCP
00529 if ( tcp_check && e_max>0 ) {
00530 e_max -= act_time;
00531
00532
00533 }
00534 #endif
00535
00536 return 0;
00537 error:
00538 if (r)
00539 ul.delete_urecord(_d, _a, r);
00540 return -1;
00541 }
00542
00543
00544 static int test_max_contacts(struct sip_msg* _m, urecord_t* _r, contact_t* _c,
00545 ucontact_info_t *ci, int mc)
00546 {
00547 int num;
00548 int e;
00549 ucontact_t* ptr, *cont;
00550 int ret;
00551
00552 num = 0;
00553 ptr = _r->contacts;
00554 while(ptr) {
00555 if (VALID_CONTACT(ptr, act_time)) {
00556 num++;
00557 }
00558 ptr = ptr->next;
00559 }
00560 LM_DBG("%d valid contacts\n", num);
00561
00562 for( ; _c ; _c = get_next_contact(_c) ) {
00563
00564 calc_contact_expires(_m, _c->expires, &e);
00565
00566 ret = ul.get_ucontact_by_instance( _r, &_c->uri, ci, &cont);
00567 if (ret==-1) {
00568 LM_ERR("invalid cseq for aor <%.*s>\n",_r->aor.len,_r->aor.s);
00569 rerrno = R_INV_CSEQ;
00570 return -1;
00571 } else if (ret==-2) {
00572 continue;
00573 }
00574 if (ret > 0) {
00575
00576 if (e != 0) num++;
00577 } else {
00578 if (e == 0) num--;
00579 }
00580 }
00581
00582 LM_DBG("%d contacts after commit\n", num);
00583 if (num > mc) {
00584 LM_INFO("too many contacts for AOR <%.*s>\n", _r->aor.len, _r->aor.s);
00585 rerrno = R_TOO_MANY;
00586 return -1;
00587 }
00588
00589 return 0;
00590 }
00591
00592
00604 static inline int update_contacts(struct sip_msg* _m, urecord_t* _r,
00605 int _mode)
00606 {
00607 ucontact_info_t *ci;
00608 ucontact_t *c, *ptr, *ptr0;
00609 int expires, ret, updated;
00610 unsigned int flags;
00611 #ifdef USE_TCP
00612 int e_max, tcp_check;
00613 struct sip_uri uri;
00614 #endif
00615 int rc;
00616 contact_t* _c;
00617 int maxc;
00618
00619
00620 flags = mem_only;
00621
00622 rc = 0;
00623
00624 if ( (ci=pack_ci( _m, 0, 0, flags))==0 ) {
00625 LM_ERR("failed to initial pack contact info\n");
00626 goto error;
00627 }
00628
00629 if (!_mode) {
00630 maxc = reg_get_crt_max_contacts();
00631 if(maxc>0) {
00632 _c = get_first_contact(_m);
00633 if(test_max_contacts(_m, _r, _c, ci, maxc) != 0)
00634 goto error;
00635 }
00636 }
00637
00638 #ifdef USE_TCP
00639 if ( (_m->flags&tcp_persistent_flag) &&
00640 (_m->rcv.proto==PROTO_TCP||_m->rcv.proto==PROTO_TLS)) {
00641 e_max = -1;
00642 tcp_check = 1;
00643 } else {
00644 e_max = tcp_check = 0;
00645 }
00646 #endif
00647
00648 _c = get_first_contact(_m);
00649 updated=0;
00650 for( ; _c ; _c = get_next_contact(_c) ) {
00651
00652 calc_contact_expires(_m, _c->expires, &expires);
00653
00654
00655 ret = ul.get_ucontact_by_instance( _r, &_c->uri, ci, &c);
00656 if (ret==-1) {
00657 LM_ERR("invalid cseq for aor <%.*s>\n",_r->aor.len,_r->aor.s);
00658 rerrno = R_INV_CSEQ;
00659 goto error;
00660 } else if (ret==-2) {
00661 if(expires!=0 && _mode)
00662 break;
00663 continue;
00664 }
00665
00666 if ( ret > 0 ) {
00667
00668 if (expires==0)
00669 continue;
00670
00671
00672 if ( (ci=pack_ci( 0, _c, expires, 0))==0 ) {
00673 LM_ERR("failed to extract contact info\n");
00674 goto error;
00675 }
00676
00677 if (ul.insert_ucontact( _r, &_c->uri, ci, &c) < 0) {
00678 rerrno = R_UL_INS_C;
00679 LM_ERR("failed to insert contact\n");
00680 goto error;
00681 }
00682 rc = 1;
00683 if(_mode)
00684 {
00685 ptr=_r->contacts;
00686 while(ptr)
00687 {
00688 ptr0 = ptr;
00689 if(ptr!=c)
00690 ul.delete_ucontact(_r, ptr);
00691 ptr=ptr0->next;
00692 }
00693 updated=1;
00694 }
00695 } else {
00696
00697 if (expires == 0) {
00698
00699 if (mem_only) {
00700 c->flags |= FL_MEM;
00701 } else {
00702 c->flags &= ~FL_MEM;
00703 }
00704
00705 if (ul.delete_ucontact(_r, c) < 0) {
00706 rerrno = R_UL_DEL_C;
00707 LM_ERR("failed to delete contact\n");
00708 goto error;
00709 }
00710 rc = 3;
00711 } else {
00712
00713
00714 if ( (ci=pack_ci( 0, _c, expires, 0))==0 ) {
00715 LM_ERR("failed to pack contact specific info\n");
00716 goto error;
00717 }
00718
00719 if(_mode)
00720 {
00721 ptr=_r->contacts;
00722 while(ptr)
00723 {
00724 ptr0 = ptr;
00725 if(ptr!=c)
00726 ul.delete_ucontact(_r, ptr);
00727 ptr=ptr0->next;
00728 }
00729 updated=1;
00730 }
00731 if (ul.update_ucontact(_r, c, ci) < 0) {
00732 rerrno = R_UL_UPD_C;
00733 LM_ERR("failed to update contact\n");
00734 goto error;
00735 }
00736 rc = 2;
00737 }
00738 }
00739 #ifdef USE_TCP
00740 if (tcp_check) {
00741
00742 if (parse_uri( _c->uri.s, _c->uri.len, &uri)<0) {
00743 LM_ERR("failed to parse contact <%.*s>\n",
00744 _c->uri.len, _c->uri.s);
00745 } else if (uri.proto==PROTO_TCP || uri.proto==PROTO_TLS) {
00746 if (e_max>0) {
00747 LM_WARN("multiple TCP contacts on single REGISTER\n");
00748 }
00749 if (expires>e_max) e_max = expires;
00750 }
00751 }
00752 #endif
00753
00754 if(updated)
00755 break;
00756 }
00757
00758 #ifdef USE_TCP
00759 if ( tcp_check && e_max>-1 ) {
00760 if (e_max) e_max -= act_time;
00761
00762
00763 }
00764 #endif
00765
00766 return rc;
00767 error:
00768 return -1;
00769 }
00770
00771
00776 static inline int add_contacts(struct sip_msg* _m, udomain_t* _d,
00777 str* _a, int _mode)
00778 {
00779 int res;
00780 int ret;
00781 urecord_t* r;
00782 sip_uri_t *u;
00783
00784 u = parse_to_uri(_m);
00785 if(u==NULL)
00786 return -2;
00787
00788 ret = 0;
00789 ul.lock_udomain(_d, _a);
00790 res = ul.get_urecord(_d, _a, &r);
00791 if (res < 0) {
00792 rerrno = R_UL_GET_R;
00793 LM_ERR("failed to retrieve record from usrloc\n");
00794 ul.unlock_udomain(_d, _a);
00795 return -2;
00796 }
00797
00798 if (res == 0) {
00799 if ((ret=update_contacts(_m, r, _mode)) < 0) {
00800 build_contact(_m, r->contacts, &u->host);
00801 ul.release_urecord(r);
00802 ul.unlock_udomain(_d, _a);
00803 return -3;
00804 }
00805 build_contact(_m, r->contacts, &u->host);
00806 ul.release_urecord(r);
00807 } else {
00808 if (insert_contacts(_m, _d, _a) < 0) {
00809 ul.unlock_udomain(_d, _a);
00810 return -4;
00811 }
00812 ret = 1;
00813 }
00814 ul.unlock_udomain(_d, _a);
00815 return ret;
00816 }
00817
00818
00822 #define is_cflag_set(_name) (((unsigned int)_cflags)&(_name))
00823 int save(struct sip_msg* _m, udomain_t* _d, int _cflags, str *_uri)
00824 {
00825 contact_t* c;
00826 int st, mode;
00827 str aor;
00828 int ret;
00829 sip_uri_t *u;
00830
00831 u = parse_to_uri(_m);
00832 if(u==NULL)
00833 goto error;
00834
00835 rerrno = R_FINE;
00836 ret = 1;
00837
00838 if (parse_message(_m) < 0) {
00839 goto error;
00840 }
00841
00842 if (check_contacts(_m, &st) > 0) {
00843 goto error;
00844 }
00845
00846 get_act_time();
00847 c = get_first_contact(_m);
00848
00849 if (extract_aor((_uri)?_uri:&get_to(_m)->uri, &aor, NULL) < 0) {
00850 LM_ERR("failed to extract Address Of Record\n");
00851 goto error;
00852 }
00853
00854 mem_only = is_cflag_set(REG_SAVE_MEM_FL)?FL_MEM:FL_NONE;
00855
00856 if (c == 0) {
00857 if (st) {
00858 if (star(_m, (udomain_t*)_d, &aor, &u->host) < 0) goto error;
00859 else ret=3;
00860 } else {
00861 if (no_contacts(_m, (udomain_t*)_d, &aor, &u->host) < 0) goto error;
00862 else ret=4;
00863 }
00864 } else {
00865 mode = is_cflag_set(REG_SAVE_REPL_FL)?1:0;
00866 if ((ret=add_contacts(_m, (udomain_t*)_d, &aor, mode)) < 0)
00867 goto error;
00868 ret = (ret==0)?1:ret;
00869 }
00870
00871 update_stat(accepted_registrations, 1);
00872
00873
00874 if ((is_route_type(REQUEST_ROUTE)) && !is_cflag_set(REG_SAVE_NORPL_FL) && (reg_send_reply(_m) < 0))
00875 return -1;
00876
00877 return ret;
00878 error:
00879 update_stat(rejected_registrations, 1);
00880 if (is_route_type(REQUEST_ROUTE) && !is_cflag_set(REG_SAVE_NORPL_FL) )
00881 reg_send_reply(_m);
00882
00883 return 0;
00884 }
00885
00886 int unregister(struct sip_msg* _m, udomain_t* _d, str* _uri)
00887 {
00888 str aor = {0, 0};
00889 sip_uri_t *u;
00890
00891 u = parse_to_uri(_m);
00892 if(u==NULL)
00893 return -2;
00894
00895
00896 if (extract_aor(_uri, &aor, NULL) < 0) {
00897 LM_ERR("failed to extract Address Of Record\n");
00898 return -1;
00899 }
00900
00901 if (star(_m, _d, &aor, &u->host) < 0)
00902 {
00903 LM_ERR("error unregistering user [%.*s]\n", aor.len, aor.s);
00904 return -1;
00905 }
00906 return 1;
00907 }
00908