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
00049
00050
00051 #include "defs.h"
00052
00053 #ifdef EXTRA_DEBUG
00054 #include <assert.h>
00055 #endif
00056 #include "../../comp_defs.h"
00057 #include "../../hash_func.h"
00058 #include "../../globals.h"
00059 #include "t_funcs.h"
00060 #include "../../dprint.h"
00061 #include "../../config.h"
00062 #include "../../parser/parser_f.h"
00063 #include "../../ut.h"
00064 #include "../../parser/msg_parser.h"
00065 #include "../../parser/contact/parse_contact.h"
00066 #include "lw_parser.h"
00067 #include "t_msgbuilder.h"
00068 #include "uac.h"
00069 #ifdef USE_DNS_FAILOVER
00070 #include "../../dns_cache.h"
00071 #include "../../cfg_core.h"
00072 #endif
00073
00074
00075 #define memapp(_d,_s,_len) \
00076 do{\
00077 memcpy((_d),(_s),(_len));\
00078 (_d) += (_len);\
00079 }while(0)
00080
00081 #define append_mem_block(_d,_s,_len) \
00082 do{\
00083 memcpy((_d),(_s),(_len));\
00084 (_d) += (_len);\
00085 }while(0)
00086
00087 #define append_str(_p,_str) \
00088 do{ \
00089 memcpy((_p), (_str).s, (_str).len); \
00090 (_p)+=(_str).len; \
00091 } while(0)
00092
00093
00094
00095
00096
00097 char *build_local(struct cell *Trans,unsigned int branch,
00098 unsigned int *len, char *method, int method_len, str *to)
00099 {
00100 char *cancel_buf, *p, *via;
00101 unsigned int via_len;
00102 struct hdr_field *hdr;
00103 char branch_buf[MAX_BRANCH_PARAM_LEN];
00104 int branch_len;
00105 str branch_str;
00106 str via_id;
00107 struct hostport hp;
00108
00109
00110 via_id.s=0;
00111 via_id.len=0;
00112
00113
00114 *len=SIP_VERSION_LEN + method_len + 2 + CRLF_LEN;
00115 *len+=Trans->uac[branch].uri.len;
00116
00117
00118 if (!t_calc_branch(Trans, branch,
00119 branch_buf, &branch_len ))
00120 goto error;
00121 branch_str.s=branch_buf;
00122 branch_str.len=branch_len;
00123 set_hostport(&hp, (is_local(Trans))?0:(Trans->uas.request));
00124 #ifdef USE_TCP
00125 if (!is_local(Trans) && ((Trans->uas.request->rcv.proto==PROTO_TCP)
00126 #ifdef USE_TLS
00127 || (Trans->uas.request->rcv.proto==PROTO_TLS)
00128 #endif
00129 )){
00130 if ((via_id.s=id_builder(Trans->uas.request,
00131 (unsigned int*)&via_id.len))==0){
00132 LOG(L_ERR, "ERROR: build_local: id builder failed\n");
00133
00134 }
00135 }
00136 #endif
00137 via=via_builder(&via_len, &Trans->uac[branch].request.dst,
00138 &branch_str, via_id.s?&via_id:0 , &hp );
00139
00140
00141 if (via_id.s){
00142 pkg_free(via_id.s);
00143 via_id.s=0;
00144 via_id.len=0;
00145 }
00146
00147 if (!via)
00148 {
00149 LOG(L_ERR, "ERROR: build_local: "
00150 "no via header got from builder\n");
00151 goto error;
00152 }
00153 *len+= via_len;
00154
00155 *len+=Trans->from.len+Trans->callid.len+to->len+
00156 +Trans->cseq_n.len+1+method_len+CRLF_LEN;
00157
00158
00159
00160 if (!is_local(Trans)) {
00161 for ( hdr=Trans->uas.request->headers ; hdr ; hdr=hdr->next )
00162 if (hdr->type==HDR_ROUTE_T)
00163 *len+=hdr->len;
00164 }
00165
00166
00167 if (server_signature) {
00168 *len += USER_AGENT_LEN + CRLF_LEN;
00169 }
00170
00171 *len+=CONTENT_LENGTH_LEN+1 + CRLF_LEN + CRLF_LEN;
00172
00173 cancel_buf=shm_malloc( *len+1 );
00174 if (!cancel_buf)
00175 {
00176 LOG(L_ERR, "ERROR: build_local: cannot allocate memory\n");
00177 goto error01;
00178 }
00179 p = cancel_buf;
00180
00181 append_mem_block( p, method, method_len );
00182 append_mem_block( p, " ", 1 );
00183 append_str( p, Trans->uac[branch].uri );
00184 append_mem_block( p, " " SIP_VERSION CRLF, 1+SIP_VERSION_LEN+CRLF_LEN );
00185
00186
00187 append_mem_block(p,via,via_len);
00188
00189
00190 append_str( p, Trans->from );
00191 append_str( p, Trans->callid );
00192 append_str( p, *to );
00193
00194 append_str( p, Trans->cseq_n );
00195 append_mem_block( p, " ", 1 );
00196 append_mem_block( p, method, method_len );
00197 append_mem_block( p, CRLF, CRLF_LEN );
00198
00199 if (!is_local(Trans)) {
00200 for ( hdr=Trans->uas.request->headers ; hdr ; hdr=hdr->next )
00201 if(hdr->type==HDR_ROUTE_T) {
00202 append_mem_block(p, hdr->name.s, hdr->len );
00203 }
00204 }
00205
00206
00207 if (server_signature) {
00208 append_mem_block(p,USER_AGENT CRLF, USER_AGENT_LEN+CRLF_LEN );
00209 }
00210
00211 append_mem_block(p, CONTENT_LENGTH "0" CRLF CRLF ,
00212 CONTENT_LENGTH_LEN+1 + CRLF_LEN + CRLF_LEN);
00213 *p=0;
00214
00215 pkg_free(via);
00216 return cancel_buf;
00217 error01:
00218 pkg_free(via);
00219 error:
00220 return NULL;
00221 }
00222
00223
00224
00225
00226
00227
00228
00229 char *build_local_reparse(struct cell *Trans,unsigned int branch,
00230 unsigned int *len, char *method, int method_len, str *to)
00231 {
00232 char *invite_buf, *invite_buf_end;
00233 char *cancel_buf;
00234 char *s, *s1, *d;
00235 short invite_len;
00236 enum _hdr_types_t hf_type;
00237 int first_via, to_len;
00238
00239 invite_buf = Trans->uac[branch].request.buffer;
00240 invite_len = Trans->uac[branch].request.buffer_len;
00241
00242 if (!invite_buf || !invite_len) {
00243 LOG(L_ERR, "ERROR: build_local_reparse: INVITE is missing\n");
00244 goto error;
00245 }
00246 if ((*invite_buf != 'I') && (*invite_buf != 'i')) {
00247 LOG(L_ERR, "ERROR: build_local_reparse: trying to call build_local_reparse() for a non-INVITE request?\n");
00248 goto error;
00249 }
00250 invite_buf_end = invite_buf + invite_len;
00251 s = invite_buf;
00252
00253
00254
00255
00256
00257 to_len = to ? to->len : 0;
00258 cancel_buf = shm_malloc(sizeof(char)*(invite_len + to_len));
00259 if (!cancel_buf)
00260 {
00261 LOG(L_ERR, "ERROR: build_local_reparse: cannot allocate shared memory\n");
00262 goto error;
00263 }
00264 d = cancel_buf;
00265
00266
00267 append_mem_block(d, method, method_len);
00268 *d = ' ';
00269 d++;
00270
00271 s += 7;
00272 s1 = s;
00273 s = eat_line(s, invite_buf_end - s);
00274 append_mem_block(d, s1, s - s1);
00275
00276
00277
00278 first_via = 1;
00279 while (s < invite_buf_end) {
00280 s1 = s;
00281 if ((*s == '\n') || (*s == '\r')) {
00282
00283 hf_type = HDR_EOH_T;
00284 } else {
00285
00286 s = lw_get_hf_name(s, invite_buf_end,
00287 &hf_type);
00288 }
00289
00290 switch(hf_type) {
00291 case HDR_CSEQ_T:
00292
00293 while ((s < invite_buf_end)
00294 && ((*s == ':') || (*s == ' ') || (*s == '\t') || ((*s >= '0') && (*s <= '9')))
00295 ) s++;
00296 append_mem_block(d, s1, s - s1);
00297 append_mem_block(d, method, method_len);
00298 append_mem_block(d, CRLF, CRLF_LEN);
00299 s = lw_next_line(s, invite_buf_end);
00300 break;
00301
00302 case HDR_VIA_T:
00303 s = lw_next_line(s, invite_buf_end);
00304 if (first_via) {
00305
00306 append_mem_block(d, s1, s - s1);
00307 first_via = 0;
00308 }
00309 break;
00310
00311 case HDR_TO_T:
00312 if (to_len == 0) {
00313
00314 s = lw_next_line(s, invite_buf_end);
00315 append_mem_block(d, s1, s - s1);
00316 } else {
00317
00318 append_mem_block(d, to->s, to->len);
00319
00320 s = lw_next_line(s, invite_buf_end);
00321 }
00322 break;
00323
00324 case HDR_FROM_T:
00325 case HDR_CALLID_T:
00326 case HDR_ROUTE_T:
00327 case HDR_MAXFORWARDS_T:
00328
00329 s = lw_next_line(s, invite_buf_end);
00330 append_mem_block(d, s1, s - s1);
00331 break;
00332
00333 case HDR_REQUIRE_T:
00334 case HDR_PROXYREQUIRE_T:
00335
00336 s = lw_next_line(s, invite_buf_end);
00337 break;
00338
00339 case HDR_CONTENTLENGTH_T:
00340
00341 append_mem_block(d, s1, s - s1);
00342 append_mem_block(d, ": 0" CRLF, 3 + CRLF_LEN);
00343
00344 s = lw_next_line(s, invite_buf_end);
00345 break;
00346
00347 case HDR_EOH_T:
00348
00349 append_mem_block(d, CRLF, CRLF_LEN);
00350 *len = d - cancel_buf;
00351
00352 return cancel_buf;
00353
00354 default:
00355 s = lw_next_line(s, invite_buf_end);
00356
00357 if (cfg_get(tm, tm_cfg, ac_extra_hdrs).len
00358 && (s1 + cfg_get(tm, tm_cfg, ac_extra_hdrs).len < invite_buf_end)
00359 && (strncasecmp(s1,
00360 cfg_get(tm, tm_cfg, ac_extra_hdrs).s,
00361 cfg_get(tm, tm_cfg, ac_extra_hdrs).len) == 0)
00362 ) {
00363 append_mem_block(d, s1, s - s1);
00364 }
00365 break;
00366 }
00367 }
00368
00369
00370 LOG(L_ERR, "ERROR: build_local_reparse: HDR_EOH_T was not found\n");
00371
00372 shm_free(cancel_buf);
00373 error:
00374 LOG(L_ERR, "ERROR: build_local_reparse: cannot build %.*s request\n", method_len, method);
00375 return NULL;
00376
00377 }
00378
00379
00380 typedef struct rte {
00381 rr_t* ptr;
00382
00383
00384 int free_rr;
00385 struct rte* next;
00386 } rte_t;
00387
00388
00389 static inline void free_rte_list(struct rte* list)
00390 {
00391 struct rte* ptr;
00392
00393 while(list) {
00394 ptr = list;
00395 list = list->next;
00396 if (ptr->free_rr)
00397 free_rr(&ptr->ptr);
00398 pkg_free(ptr);
00399 }
00400 }
00401
00402
00403 static inline int calc_routeset_len(struct rte* list, str* contact)
00404 {
00405 struct rte* ptr;
00406 int ret;
00407
00408 if (list || contact) {
00409 ret = ROUTE_PREFIX_LEN + CRLF_LEN;
00410 } else {
00411 return 0;
00412 }
00413
00414 ptr = list;
00415 while(ptr) {
00416 if (ptr != list) {
00417 ret += ROUTE_SEPARATOR_LEN;
00418 }
00419 ret += ptr->ptr->len;
00420 ptr = ptr->next;
00421 }
00422
00423 if (contact) {
00424 if (list) ret += ROUTE_SEPARATOR_LEN;
00425 ret += 2 + contact->len;
00426 }
00427
00428 return ret;
00429 }
00430
00431
00432
00433
00434
00435 static inline char* print_rs(char* p, struct rte* list, str* contact)
00436 {
00437 struct rte* ptr;
00438
00439 if (list || contact) {
00440 memapp(p, ROUTE_PREFIX, ROUTE_PREFIX_LEN);
00441 } else {
00442 return p;
00443 }
00444
00445 ptr = list;
00446 while(ptr) {
00447 if (ptr != list) {
00448 memapp(p, ROUTE_SEPARATOR, ROUTE_SEPARATOR_LEN);
00449 }
00450
00451 memapp(p, ptr->ptr->nameaddr.name.s, ptr->ptr->len);
00452 ptr = ptr->next;
00453 }
00454
00455 if (contact) {
00456 if (list) memapp(p, ROUTE_SEPARATOR, ROUTE_SEPARATOR_LEN);
00457 *p++ = '<';
00458 append_str(p, *contact);
00459 *p++ = '>';
00460 }
00461
00462 memapp(p, CRLF, CRLF_LEN);
00463 return p;
00464 }
00465
00466
00467
00468
00469
00470
00471 static inline int get_contact_uri(struct sip_msg* msg, str* uri)
00472 {
00473 contact_t* c;
00474
00475 uri->len = 0;
00476 if (!msg->contact) return 1;
00477
00478 if (parse_contact(msg->contact) < 0) {
00479 LOG(L_ERR, "get_contact_uri: Error while parsing Contact body\n");
00480 return -1;
00481 }
00482
00483 c = ((contact_body_t*)msg->contact->parsed)->contacts;
00484
00485 if (!c) {
00486 LOG(L_ERR, "get_contact_uri: Empty body or * contact\n");
00487 return -2;
00488 }
00489
00490 *uri = c->uri;
00491 return 0;
00492 }
00493
00500 static inline int get_uac_rs(sip_msg_t *msg, int is_req, struct rte **rtset)
00501 {
00502 struct hdr_field* ptr;
00503 rr_t *p, *new_p;
00504 struct rte *t, *head, *old_head;
00505
00506 head = 0;
00507 for (ptr = is_req ? msg->route : msg->record_route; ptr; ptr = ptr->next) {
00508 switch (ptr->type) {
00509 case HDR_RECORDROUTE_T:
00510 if (is_req)
00511 continue;
00512 break;
00513 case HDR_ROUTE_T:
00514 if (! is_req)
00515 continue;
00516 break;
00517 default:
00518 continue;
00519 }
00520 if (parse_rr(ptr) < 0) {
00521 ERR("failed to parse Record-/Route HF (%d).\n", ptr->type);
00522 goto err;
00523 }
00524
00525 p = (rr_t*)ptr->parsed;
00526 while(p) {
00527 if (! (t = (struct rte*)pkg_malloc(sizeof(struct rte)))) {
00528 ERR("out of pkg mem (asked for: %zd).\n", sizeof(struct rte));
00529 goto err;
00530 }
00531 if (is_req) {
00532
00533
00534 if (duplicate_rr(&new_p, p) < 0) {
00535 pkg_free(t);
00536 ERR("failed to duplicate RR");
00537 goto err;
00538 }
00539 t->ptr = new_p;
00540 } else {
00541 t->ptr = p;
00542 }
00543 t->free_rr = is_req;
00544 t->next = head;
00545 head = t;
00546 p = p->next;
00547 }
00548 }
00549
00550 if (is_req) {
00551
00552
00553 old_head = head;
00554 head = 0;
00555 while (old_head) {
00556 t = old_head;
00557 old_head = old_head->next;
00558 t->next = head;
00559 head = t;
00560 }
00561 }
00562
00563 *rtset = head;
00564 return 0;
00565 err:
00566 free_rte_list(head);
00567 return -1;
00568 }
00569
00570
00571 static inline unsigned short uri2port(const struct sip_uri *puri)
00572 {
00573 if (puri->port.s) {
00574 return puri->port_no;
00575 } else switch (puri->type) {
00576 case SIP_URI_T:
00577 case TEL_URI_T:
00578 if (puri->transport_val.len == sizeof("TLS") - 1) {
00579 unsigned trans;
00580 trans = puri->transport_val.s[0] | 0x20; trans <<= 8;
00581 trans |= puri->transport_val.s[1] | 0x20; trans <<= 8;
00582 trans |= puri->transport_val.s[2] | 0x20;
00583 if (trans == 0x746C73)
00584 return SIPS_PORT;
00585 }
00586 return SIP_PORT;
00587 case SIPS_URI_T:
00588 case TELS_URI_T:
00589 return SIPS_PORT;
00590 default:
00591 BUG("unexpected URI type %d.\n", puri->type);
00592 }
00593 return 0;
00594 }
00595
00607 static unsigned long nhop_type(sip_msg_t *orig_inv, rte_t *rtset,
00608 const struct dest_info *dst_inv, str *contact)
00609 {
00610 struct sip_uri puri, topr_uri, lastr_uri, inv_ruri, cont_uri;
00611 struct ip_addr *uri_ia;
00612 union sockaddr_union uri_sau;
00613 unsigned int uri_port, dst_port, inv_port, cont_port, lastr_port;
00614 rte_t *last_r;
00615 #ifdef TM_LOC_ACK_DO_REV_DNS
00616 struct ip_addr ia;
00617 struct hostent *he;
00618 char **alias;
00619 #endif
00620
00621 #define PARSE_URI(_str_, _uri_) \
00622 do { \
00623 \
00624 if (parse_uri((_str_)->s, \
00625 (_str_)->len, _uri_) < 0) { \
00626 ERR("failed to parse route body '%.*s'.\n", STR_FMT(_str_)); \
00627 return 0; \
00628 } \
00629 } while (0)
00630
00631 #define HAS_LR(_rte_) \
00632 ({ \
00633 PARSE_URI(&(_rte_)->ptr->nameaddr.uri, &puri); \
00634 puri.lr.s; \
00635 })
00636
00637 #define URI_PORT(_puri_, _port) \
00638 do { \
00639 if (! (_port = uri2port(_puri_))) \
00640 return 0; \
00641 } while (0)
00642
00643
00644
00645
00646 DEBUG("checking lack of ';lr' in 1st route.\n");
00647 if (! HAS_LR(rtset))
00648 return F_RB_NH_STRICT;
00649 topr_uri = puri;
00650
00651
00652 DEBUG("checking presence of ';lr' in last route.\n");
00653 for (last_r = rtset; last_r->next; last_r = last_r->next)
00654
00655 ;
00656 if (HAS_LR(last_r))
00657 return F_RB_NH_LOOSE;
00658
00659
00660
00661 DEBUG("checking INVITE's destination against its first route.\n");
00662 URI_PORT(&topr_uri, uri_port);
00663 if (! (dst_port = su_getport((void *)&dst_inv->to)))
00664 return 0;
00665 if (dst_port != uri_port)
00666 return F_RB_NH_STRICT;
00667
00668 if ((uri_ia = str2ip(&topr_uri.host))
00669 #ifdef USE_IPV6
00670 || (uri_ia = str2ip6(&topr_uri.host))
00671 #endif
00672 ) {
00673
00674 if (init_su(&uri_sau, uri_ia, uri_port) < 0)
00675 return 0;
00676 if (su_cmp(&uri_sau, (void *)&dst_inv->to))
00677
00678 return F_RB_NH_LOOSE;
00679 else
00680
00681 return F_RB_NH_STRICT;
00682 } else {
00683
00684 INFO("Failed to decode string '%.*s' in route set element as IP "
00685 "address. Trying name resolution.\n",STR_FMT(&topr_uri.host));
00686
00687
00688 #ifdef TM_LOC_ACK_DO_REV_DNS
00689 ia.af = 0;
00690 su2ip_addr(&ia, (void *)&dst_inv->to);
00691 if (! ia.af)
00692 return 0;
00693 if ((he = rev_resolvehost(&ia))) {
00694 if ((strlen(he->h_name) == topr_uri.host.len) &&
00695 (memcmp(he->h_name, topr_uri.host.s,
00696 topr_uri.host.len) == 0))
00697 return F_RB_NH_LOOSE;
00698 for (alias = he->h_aliases; *alias; alias ++)
00699 if ((strlen(*alias) == topr_uri.host.len) &&
00700 (memcmp(*alias, topr_uri.host.s,
00701 topr_uri.host.len) == 0))
00702 return F_RB_NH_LOOSE;
00703 return F_RB_NH_STRICT;
00704 } else {
00705 INFO("failed to resolve address '%s' to a name.\n",
00706 ip_addr2a(&ia));
00707 }
00708 #endif
00709 }
00710
00711 WARN("failed to establish with certainty the type of next hop; trying an"
00712 " educated guess.\n");
00713
00714
00715
00716 DEBUG("checking remote target against INVITE's RURI.\n");
00717 PARSE_URI(contact, &cont_uri);
00718 PARSE_URI(GET_RURI(orig_inv), &inv_ruri);
00719 URI_PORT(&cont_uri, cont_port);
00720 URI_PORT(&inv_ruri, inv_port);
00721 if ((cont_port == inv_port) && (cont_uri.host.len == inv_ruri.host.len) &&
00722 (memcmp(cont_uri.host.s, inv_ruri.host.s, cont_uri.host.len) == 0))
00723 return F_RB_NH_LOOSE;
00724
00725
00726
00727
00728 DEBUG("checking remote target against INVITE's last route.\n");
00729 PARSE_URI(&last_r->ptr->nameaddr.uri, &lastr_uri);
00730 URI_PORT(&lastr_uri, lastr_port);
00731 if ((cont_port == lastr_port) &&
00732 (cont_uri.host.len == lastr_uri.host.len) &&
00733 (memcmp(cont_uri.host.s, lastr_uri.host.s,
00734 lastr_uri.host.len) == 0))
00735 return F_RB_NH_STRICT;
00736
00737 WARN("failed to establish the type of next hop; assuming loose router.\n");
00738 return F_RB_NH_LOOSE;
00739
00740 #undef PARSE_URI
00741 #undef HAS_LR
00742 #undef URI_PORT
00743 }
00744
00761 static int eval_uac_routing(sip_msg_t *rpl, const struct retr_buf *inv_rb,
00762 str* contact, struct rte **list, str *ruri, str *next_hop)
00763 {
00764 sip_msg_t orig_inv, *sipmsg;
00765 rte_t *t, *prev_t, *rtset = NULL;
00766 int is_req;
00767 struct sip_uri puri;
00768 static size_t chklen;
00769 int ret = -1;
00770
00771
00772 memset(&orig_inv, 0, sizeof(struct sip_msg));
00773 orig_inv.buf = inv_rb->buffer;
00774 orig_inv.len = inv_rb->buffer_len;
00775 DEBUG("reparsing retransmission buffer of original INVITE:\n%.*s\n",
00776 orig_inv.len, orig_inv.buf);
00777 if (parse_msg(orig_inv.buf, orig_inv.len, &orig_inv) != 0) {
00778 ERR("failed to parse retr buffer (weird!): \n%.*s\n", orig_inv.len,
00779 orig_inv.buf);
00780 return -1;
00781 }
00782
00783
00784 if ((parse_headers(&orig_inv, HDR_TO_F, 0) < 0) || (! orig_inv.to)) {
00785
00786 BUG("failed to parse INVITE retr. buffer and/or extract 'To' HF:"
00787 "\n%.*s\n", orig_inv.len, orig_inv.buf);
00788 goto end;
00789 }
00790 if (((struct to_body *)orig_inv.to->parsed)->tag_value.len) {
00791 DEBUG("building ACK for in-dialog INVITE (using RS in orig. INV.)\n");
00792 if (parse_headers(&orig_inv, HDR_EOH_F, 0) < 0) {
00793 BUG("failed to parse INVITE retr. buffer to EOH:"
00794 "\n%.*s\n", orig_inv.len, orig_inv.buf);
00795 goto end;
00796 }
00797 sipmsg = &orig_inv;
00798 is_req = 1;
00799 } else {
00800 DEBUG("building ACK for out-of-dialog INVITE (using RS in RR set).\n");
00801 sipmsg = rpl;
00802 is_req = 0;
00803 }
00804
00805
00806 if (get_uac_rs(sipmsg, is_req, &rtset) < 0) {
00807 ERR("failed to extract route set.\n");
00808 goto end;
00809 }
00810
00811 if (! rtset) {
00812 *ruri = *contact;
00813 *next_hop = *contact;
00814 } else if (! is_req) {
00815 if (parse_uri(rtset->ptr->nameaddr.uri.s, rtset->ptr->nameaddr.uri.len,
00816 &puri) < 0) {
00817 ERR("failed to parse first route in set.\n");
00818 goto end;
00819 }
00820
00821 if (puri.lr.s) {
00822 *ruri = *contact;
00823 *next_hop = rtset->ptr->nameaddr.uri;
00824 } else {
00825 *ruri = rtset->ptr->nameaddr.uri;
00826 *next_hop = *ruri;
00827
00828 t = rtset;
00829 rtset = rtset->next;
00830 pkg_free(t);
00831 }
00832 } else {
00833 unsigned long route_flags = inv_rb->flags;
00834 DEBUG("UAC rb flags: 0x%x.\n", (unsigned int)route_flags);
00835 eval_flags:
00836 switch (route_flags & (F_RB_NH_LOOSE|F_RB_NH_STRICT)) {
00837 case 0:
00838 WARN("calculate_hooks() not called when built the local UAC of "
00839 "in-dialog request, or called with empty route set.\n");
00840
00841
00842 if ((route_flags = nhop_type(&orig_inv, rtset, &inv_rb->dst,
00843 contact))) {
00844 DEBUG("original request's next hop type evaluated to: 0x%x.\n",
00845 (unsigned int)route_flags);
00846 goto eval_flags;
00847 } else {
00848 ERR("failed to establish what kind of router the next "
00849 "hop is.\n");
00850 goto end;
00851 }
00852 break;
00853 case F_RB_NH_LOOSE:
00854 *ruri = *contact;
00855 *next_hop = rtset->ptr->nameaddr.uri;
00856 break;
00857 case F_RB_NH_STRICT:
00858
00859
00860
00861 for (t = rtset, prev_t = t; t->next; prev_t = t, t = t->next)
00862 ;
00863 if ((t->ptr->len == contact->len) &&
00864 (memcmp(t->ptr->nameaddr.name.s, contact->s,
00865 contact->len) == 0)){
00866
00867
00868
00869 } else {
00870
00871 free_rte_list(t);
00872
00873
00874
00875 chklen = sizeof(struct rte) + sizeof(rr_t);
00876 if (! (t = (struct rte *)pkg_malloc(chklen))) {
00877 ERR("out of pkg memory (%zd required)\n", chklen);
00878 goto end;
00879 }
00880
00881 memset(t, 0, chklen);
00882 ((rr_t *)&t[1])->nameaddr.name = *contact;
00883 ((rr_t *)&t[1])->len = contact->len;
00884
00885 if (prev_t == rtset)
00886
00887 rtset = t;
00888 else
00889 prev_t->next = t;
00890 }
00891
00892 *ruri = *GET_RURI(&orig_inv);
00893 *next_hop = *ruri;
00894 break;
00895 default:
00896
00897 BUG("next hop of original request marked as both loose and strict"
00898 " router (buffer: %.*s).\n", inv_rb->buffer_len,
00899 inv_rb->buffer);
00900 #ifdef EXTRA_DEBUG
00901 abort();
00902 #else
00903 goto end;
00904 #endif
00905 }
00906 }
00907
00908 *list = rtset;
00909
00910 ret = 0;
00911 end:
00912 free_sip_msg(&orig_inv);
00913 if (ret < 0)
00914 free_rte_list(rtset);
00915 return ret;
00916 }
00917
00918
00919
00920
00921
00922
00923
00924 char *build_dlg_ack(struct sip_msg* rpl, struct cell *Trans,
00925 unsigned int branch, str *hdrs, str *body,
00926 unsigned int *len, struct dest_info* dst)
00927 {
00928 char *req_buf, *p, *via;
00929 unsigned int via_len;
00930 char branch_buf[MAX_BRANCH_PARAM_LEN];
00931 int branch_len;
00932 str branch_str;
00933 struct hostport hp;
00934 struct rte* list;
00935 str contact, ruri, *cont;
00936 str next_hop;
00937 str body_len;
00938 str _to, *to = &_to;
00939 #ifdef USE_DNS_FAILOVER
00940 struct dns_srv_handle dns_h;
00941 #endif
00942 #ifdef WITH_AS_SUPPORT
00943
00944
00945
00946
00947
00948
00949
00950
00951
00952
00953
00954
00955 unsigned offset = *len;
00956 #endif
00957
00958 if (parse_headers(rpl, HDR_EOH_F, 0) == -1 || !rpl->to) {
00959 ERR("Error while parsing headers.\n");
00960 return 0;
00961 } else {
00962 _to.s = rpl->to->name.s;
00963 _to.len = rpl->to->len;
00964 }
00965
00966 if (get_contact_uri(rpl, &contact) < 0) {
00967 return 0;
00968 }
00969
00970 if (eval_uac_routing(rpl, &Trans->uac[branch].request, &contact,
00971 &list, &ruri, &next_hop) < 0) {
00972 ERR("failed to evaluate routing elements.\n");
00973 return 0;
00974 }
00975 DEBUG("ACK RURI: `%.*s', NH: `%.*s'.\n", STR_FMT(&ruri),
00976 STR_FMT(&next_hop));
00977
00978 if ((contact.s != ruri.s) || (contact.len != ruri.len)) {
00979
00980
00981
00982
00983
00984 cont = &contact;
00985 } else {
00986
00987 cont = 0;
00988 }
00989
00990
00991 *len = SIP_VERSION_LEN + ACK_LEN + 2 + CRLF_LEN;
00992 *len += ruri.len;
00993
00994
00995
00996 #ifdef USE_DNS_FAILOVER
00997 if (cfg_get(core, core_cfg, use_dns_failover)){
00998 dns_srv_handle_init(&dns_h);
00999 if ((uri2dst(&dns_h , dst, rpl, &next_hop, PROTO_NONE)==0) ||
01000 (dst->send_sock==0)){
01001 dns_srv_handle_put(&dns_h);
01002 LOG(L_ERR, "build_dlg_ack: no socket found\n");
01003 goto error;
01004 }
01005 dns_srv_handle_put(&dns_h);
01006 }else{
01007 if ((uri2dst(0 , dst, rpl, &next_hop, PROTO_NONE)==0) ||
01008 (dst->send_sock==0)){
01009 LOG(L_ERR, "build_dlg_ack: no socket found\n");
01010 goto error;
01011 }
01012 }
01013 #else
01014 if ( (uri2dst( dst, rpl, &next_hop, PROTO_NONE)==0) ||
01015 (dst->send_sock==0)){
01016 LOG(L_ERR, "build_dlg_ack: no socket found\n");
01017 goto error;
01018 }
01019 #endif
01020
01021 if (!t_calc_branch(Trans, branch, branch_buf, &branch_len)) goto error;
01022 branch_str.s = branch_buf;
01023 branch_str.len = branch_len;
01024 set_hostport(&hp, 0);
01025 via = via_builder(&via_len, dst, &branch_str, 0, &hp);
01026 if (!via) {
01027 LOG(L_ERR, "build_dlg_ack: No via header got from builder\n");
01028 goto error;
01029 }
01030 *len+= via_len;
01031
01032
01033 *len += Trans->from.len + Trans->callid.len + to->len + Trans->cseq_n.len + 1 + ACK_LEN + CRLF_LEN;
01034
01035
01036
01037 *len += calc_routeset_len(list, cont);
01038
01039
01040 if (server_signature) *len += USER_AGENT_LEN + CRLF_LEN;
01041
01042 if (hdrs)
01043 *len += hdrs->len;
01044
01045 if (body) {
01046 body_len.s = int2str(body->len, &body_len.len);
01047 *len += body->len;
01048 } else {
01049 body_len.len = 0;
01050 body_len.s = NULL;
01051 *len += 1;
01052 }
01053
01054 *len += CONTENT_LENGTH_LEN + body_len.len + CRLF_LEN + CRLF_LEN;
01055
01056 #if WITH_AS_SUPPORT
01057 req_buf = shm_malloc(offset + *len + 1);
01058 req_buf += offset;
01059 #else
01060 req_buf = shm_malloc(*len + 1);
01061 #endif
01062 if (!req_buf) {
01063 ERR("Cannot allocate memory (%u+1)\n", *len);
01064 goto error01;
01065 }
01066 p = req_buf;
01067
01068 append_mem_block( p, ACK, ACK_LEN );
01069 append_mem_block( p, " ", 1 );
01070 append_str(p, ruri);
01071 append_mem_block( p, " " SIP_VERSION CRLF, 1 + SIP_VERSION_LEN + CRLF_LEN);
01072
01073
01074 append_mem_block(p, via, via_len);
01075
01076
01077 append_str(p, Trans->from);
01078 append_str(p, Trans->callid);
01079 append_str(p, *to);
01080
01081 append_str(p, Trans->cseq_n);
01082 append_mem_block( p, " ", 1 );
01083 append_mem_block( p, ACK, ACK_LEN);
01084 append_mem_block(p, CRLF, CRLF_LEN);
01085
01086
01087 p = print_rs(p, list, cont);
01088
01089
01090 if (server_signature) {
01091 append_mem_block(p, USER_AGENT CRLF, USER_AGENT_LEN + CRLF_LEN);
01092 }
01093
01094
01095 if (hdrs)
01096 append_mem_block(p, hdrs->s, hdrs->len);
01097
01098
01099 if (body) {
01100 append_mem_block(p, CONTENT_LENGTH, CONTENT_LENGTH_LEN);
01101 append_mem_block(p, body_len.s, body_len.len);
01102 append_mem_block(p, CRLF CRLF, CRLF_LEN +
01103 CRLF_LEN);
01104 append_mem_block(p, body->s, body->len);
01105 } else {
01106 append_mem_block(p, CONTENT_LENGTH "0" CRLF CRLF,
01107 CONTENT_LENGTH_LEN + 1 + CRLF_LEN + CRLF_LEN);
01108 }
01109
01110
01111 *p = 0;
01112
01113 pkg_free(via);
01114 free_rte_list(list);
01115 return req_buf;
01116
01117 error01:
01118 pkg_free(via);
01119 error:
01120 free_rte_list(list);
01121 return 0;
01122 }
01123
01124
01125
01126
01127
01128 static inline int print_content_length(str* dest, str* body)
01129 {
01130 static char content_length[10];
01131 int len;
01132 int b_len;
01133 char* tmp;
01134
01135
01136 b_len=body?body->len:0;
01137 tmp = int2str(b_len, &len);
01138 if (len >= sizeof(content_length)) {
01139 LOG(L_ERR, "ERROR: print_content_length: content_len too big\n");
01140 dest->s = 0;
01141 dest->len = 0;
01142 return -1;
01143 }
01144 memcpy(content_length, tmp, len);
01145 dest->s = content_length;
01146 dest->len = len;
01147 return 0;
01148 }
01149
01150
01151
01152
01153
01154 static inline int print_cseq_num(str* _s, dlg_t* _d)
01155 {
01156 static char cseq[INT2STR_MAX_LEN];
01157 char* tmp;
01158 int len;
01159
01160 tmp = int2str(_d->loc_seq.value, &len);
01161 if (len > sizeof(cseq)) {
01162 LOG(L_ERR, "print_cseq_num: cseq too big\n");
01163 return -1;
01164 }
01165
01166 memcpy(cseq, tmp, len);
01167 _s->s = cseq;
01168 _s->len = len;
01169 return 0;
01170 }
01171
01172
01173
01174
01175
01176 static inline int assemble_via(str* dest, struct cell* t,
01177 struct dest_info* dst, int branch)
01178 {
01179 static char branch_buf[MAX_BRANCH_PARAM_LEN];
01180 char* via;
01181 int len;
01182 unsigned int via_len;
01183 str branch_str;
01184 struct hostport hp;
01185
01186 if (!t_calc_branch(t, branch, branch_buf, &len)) {
01187 LOG(L_ERR, "ERROR: assemble_via: branch calculation failed\n");
01188 return -1;
01189 }
01190
01191 branch_str.s = branch_buf;
01192 branch_str.len = len;
01193
01194 #ifdef XL_DEBUG
01195 printf("!!!proto: %d\n", sock->proto);
01196 #endif
01197
01198 set_hostport(&hp, 0);
01199 via = via_builder(&via_len, dst, &branch_str, 0, &hp);
01200 if (!via) {
01201 LOG(L_ERR, "assemble_via: via building failed\n");
01202 return -2;
01203 }
01204
01205 dest->s = via;
01206 dest->len = via_len;
01207 return 0;
01208 }
01209
01210
01211
01212
01213
01214 static inline char* print_request_uri(char* w, str* method, dlg_t* dialog, struct cell* t, int branch)
01215 {
01216 memapp(w, method->s, method->len);
01217 memapp(w, " ", 1);
01218
01219 t->uac[branch].uri.s = w;
01220 t->uac[branch].uri.len = dialog->hooks.request_uri->len;
01221
01222 memapp(w, dialog->hooks.request_uri->s, dialog->hooks.request_uri->len);
01223 memapp(w, " " SIP_VERSION CRLF, 1 + SIP_VERSION_LEN + CRLF_LEN);
01224
01225 return w;
01226 }
01227
01228
01229
01230
01231
01232 static inline char* print_to(char* w, dlg_t* dialog, struct cell* t)
01233 {
01234 t->to.s = w;
01235 t->to.len = TO_LEN + dialog->rem_uri.len + CRLF_LEN;
01236
01237 memapp(w, TO, TO_LEN);
01238 memapp(w, dialog->rem_uri.s, dialog->rem_uri.len);
01239
01240 if (dialog->id.rem_tag.len) {
01241 t->to.len += TOTAG_LEN + dialog->id.rem_tag.len ;
01242 memapp(w, TOTAG, TOTAG_LEN);
01243 memapp(w, dialog->id.rem_tag.s, dialog->id.rem_tag.len);
01244 }
01245
01246 memapp(w, CRLF, CRLF_LEN);
01247 return w;
01248 }
01249
01250
01251
01252
01253
01254 static inline char* print_from(char* w, dlg_t* dialog, struct cell* t)
01255 {
01256 t->from.s = w;
01257 t->from.len = FROM_LEN + dialog->loc_uri.len + CRLF_LEN;
01258
01259 memapp(w, FROM, FROM_LEN);
01260 memapp(w, dialog->loc_uri.s, dialog->loc_uri.len);
01261
01262 if (dialog->id.loc_tag.len) {
01263 t->from.len += FROMTAG_LEN + dialog->id.loc_tag.len;
01264 memapp(w, FROMTAG, FROMTAG_LEN);
01265 memapp(w, dialog->id.loc_tag.s, dialog->id.loc_tag.len);
01266 }
01267
01268 memapp(w, CRLF, CRLF_LEN);
01269 return w;
01270 }
01271
01272
01273
01274
01275
01276 char* print_cseq_mini(char* target, str* cseq, str* method) {
01277 memapp(target, CSEQ, CSEQ_LEN);
01278 memapp(target, cseq->s, cseq->len);
01279 memapp(target, " ", 1);
01280 memapp(target, method->s, method->len);
01281 return target;
01282 }
01283
01284 static inline char* print_cseq(char* w, str* cseq, str* method, struct cell* t)
01285 {
01286 t->cseq_n.s = w;
01287
01288
01289 t->cseq_n.len = CSEQ_LEN + cseq->len;
01290 w = print_cseq_mini(w, cseq, method);
01291 return w;
01292 }
01293
01294
01295
01296
01297
01298
01299 char* print_callid_mini(char* target, str callid) {
01300 memapp(target, CALLID, CALLID_LEN);
01301 memapp(target, callid.s, callid.len);
01302 memapp(target, CRLF, CRLF_LEN);
01303 return target;
01304 }
01305
01306 static inline char* print_callid(char* w, dlg_t* dialog, struct cell* t)
01307 {
01308
01309 memapp(w, CRLF, CRLF_LEN);
01310 t->callid.s = w;
01311 t->callid.len = CALLID_LEN + dialog->id.call_id.len + CRLF_LEN;
01312
01313 w = print_callid_mini(w, dialog->id.call_id);
01314 return w;
01315 }
01316
01317
01318
01319
01320
01321 char* build_uac_req(str* method, str* headers, str* body, dlg_t* dialog, int branch,
01322 struct cell *t, int* len, struct dest_info* dst)
01323 {
01324 char* buf, *w;
01325 str content_length, cseq, via;
01326
01327 if (!method || !dialog) {
01328 LOG(L_ERR, "build_uac_req(): Invalid parameter value\n");
01329 return 0;
01330 }
01331 if (print_content_length(&content_length, body) < 0) {
01332 LOG(L_ERR, "build_uac_req(): Error while printing content-length\n");
01333 return 0;
01334 }
01335 if (print_cseq_num(&cseq, dialog) < 0) {
01336 LOG(L_ERR, "build_uac_req(): Error while printing CSeq number\n");
01337 return 0;
01338 }
01339 *len = method->len + 1 + dialog->hooks.request_uri->len + 1 + SIP_VERSION_LEN + CRLF_LEN;
01340
01341 if (assemble_via(&via, t, dst, branch) < 0) {
01342 LOG(L_ERR, "build_uac_req(): Error while assembling Via\n");
01343 return 0;
01344 }
01345 *len += via.len;
01346
01347 *len += TO_LEN + dialog->rem_uri.len
01348 + (dialog->id.rem_tag.len ? (TOTAG_LEN + dialog->id.rem_tag.len) : 0) + CRLF_LEN;
01349 *len += FROM_LEN + dialog->loc_uri.len
01350 + (dialog->id.loc_tag.len ? (FROMTAG_LEN + dialog->id.loc_tag.len) : 0) + CRLF_LEN;
01351 *len += CALLID_LEN + dialog->id.call_id.len + CRLF_LEN;
01352 *len += CSEQ_LEN + cseq.len + 1 + method->len + CRLF_LEN;
01353 *len += calculate_routeset_length(dialog);
01354 *len += CONTENT_LENGTH_LEN + content_length.len + CRLF_LEN;
01355
01356 *len += (server_signature ? (USER_AGENT_LEN + CRLF_LEN) : 0);
01357 *len += (headers ? headers->len : 0);
01358 *len += (body ? body->len : 0);
01359 *len += CRLF_LEN;
01360
01361 buf = shm_malloc(*len + 1);
01362 if (!buf) {
01363 LOG(L_ERR, "build_uac_req(): no shmem\n");
01364 goto error;
01365 }
01366
01367 w = buf;
01368
01369 w = print_request_uri(w, method, dialog, t, branch);
01370 memapp(w, via.s, via.len);
01371 w = print_to(w, dialog, t);
01372 w = print_from(w, dialog, t);
01373 w = print_cseq(w, &cseq, method, t);
01374 w = print_callid(w, dialog, t);
01375 w = print_routeset(w, dialog);
01376
01377
01378 memapp(w, CONTENT_LENGTH, CONTENT_LENGTH_LEN);
01379 memapp(w, content_length.s, content_length.len);
01380 memapp(w, CRLF, CRLF_LEN);
01381
01382
01383 if (server_signature) memapp(w, USER_AGENT CRLF, USER_AGENT_LEN + CRLF_LEN);
01384 if (headers) memapp(w, headers->s, headers->len);
01385 memapp(w, CRLF, CRLF_LEN);
01386 if (body) memapp(w, body->s, body->len);
01387
01388 #ifdef EXTRA_DEBUG
01389 assert(w-buf == *len);
01390 #endif
01391
01392 pkg_free(via.s);
01393 return buf;
01394
01395 error:
01396 pkg_free(via.s);
01397 return 0;
01398 }
01399
01400
01401 int t_calc_branch(struct cell *t,
01402 int b, char *branch, int *branch_len)
01403 {
01404 return syn_branch ?
01405 branch_builder( t->hash_index,
01406 t->label, 0,
01407 b, branch, branch_len )
01408 : branch_builder( t->hash_index,
01409 0, t->md5,
01410 b, branch, branch_len );
01411 }
01412