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