2 * Copyright (C) 2001-2003 FhG Fokus
4 * This file is part of Kamailio, a free SIP server.
6 * Kamailio is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version
11 * Kamailio is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
23 * \brief Route & Record-Route module, loose routing support
28 * \defgroup rr RR :: Route & Record-Route Module
29 * This module contains record routing logic, as described in RFC 3261
30 * (see chapter 16.12 and 12.1.1 - UAS behavior).
34 #include "../../core/mem/mem.h"
35 #include "../../core/dprint.h"
36 #include "../../core/parser/parse_uri.h"
37 #include "../../core/parser/parse_from.h"
38 #include "../../core/parser/parse_rr.h"
39 #include "../../core/str.h"
40 #include "../../core/data_lump.h"
46 #define RR_PREFIX_SIP "Record-Route: <sip:"
47 #define RR_PREFIX_SIP_LEN (sizeof(RR_PREFIX_SIP)-1)
49 #define RR_PREFIX_SIPS "Record-Route: <sips:"
50 #define RR_PREFIX_SIPS_LEN (sizeof(RR_PREFIX_SIPS)-1)
53 #define RR_LR_LEN (sizeof(RR_LR)-1)
55 #define RR_LR_FULL ";lr=on"
56 #define RR_LR_FULL_LEN (sizeof(RR_LR_FULL)-1)
58 #define RR_FROMTAG ";ftag="
59 #define RR_FROMTAG_LEN (sizeof(RR_FROMTAG)-1)
61 #define RR_R2 ";r2=on"
62 #define RR_R2_LEN (sizeof(RR_R2)-1)
64 #define RR_TERM ">"CRLF
65 #define RR_TERM_LEN (sizeof(RR_TERM)-1)
67 #define INBOUND 1 /*!< Insert inbound Record-Route */
68 #define OUTBOUND 0 /*!< Insert outbound Record-Route */
70 #define RR_PARAM_BUF_SIZE 512 /*!< buffer for RR parameter */
72 extern int rr_ignore_sips;
73 extern int rr_sockname_mode;
76 * \brief RR param buffer
77 * \note used for storing RR param which are added before RR insertion
79 static char rr_param_buf_ptr[RR_PARAM_BUF_SIZE];
80 static str rr_param_buf = {rr_param_buf_ptr,0};
81 static unsigned int rr_param_msg;
83 static pv_spec_t *custom_user_avp; /*!< AVP for custom_user setting */
86 inline static int rr_is_sips(sip_msg_t *_m)
88 if(parse_sip_msg_uri(_m)<0)
90 if(_m->parsed_uri.type==SIPS_URI_T)
95 void init_custom_user(pv_spec_t *custom_user_avp_p)
97 custom_user_avp = custom_user_avp_p;
101 * \brief Return the custom_user for a record route
102 * \param req SIP message
103 * \param custom_user to be returned
104 * \return <0 for failure
106 inline static int get_custom_user(struct sip_msg *req, str *custom_user) {
109 if (custom_user_avp) {
110 if ((pv_get_spec_value(req, custom_user_avp, &pv_val) == 0)
111 && (pv_val.flags & PV_VAL_STR) && (pv_val.rs.len > 0)) {
112 custom_user->s = pv_val.rs.s;
113 custom_user->len = pv_val.rs.len;
116 LM_DBG("invalid AVP value, using default user from RURI\n");
123 * \brief Extract username from the Request URI
125 * Extract username from the Request URI. First try to look at the original
126 * Request URI and if there is no username use the new Request URI.
127 * \param _m SIP message
128 * \param _user username
129 * \return 0 on success, negative on errors
131 static inline int get_username(struct sip_msg* _m, str* _user)
135 /* first try to look at r-uri for a username */
136 if (parse_uri(_m->first_line.u.request.uri.s, _m->first_line.u.request.uri.len, &puri) < 0) {
137 LM_ERR("failed to parse R-URI\n");
141 /* no username in original uri -- hmm; maybe it is a uri
142 * with just host address and username is in a preloaded route,
143 * which is now no rewritten r-uri (assumed rewriteFromRoute
144 * was called somewhere in script's beginning)
146 if (!puri.user.len && _m->new_uri.s) {
147 if (parse_uri(_m->new_uri.s, _m->new_uri.len, &puri) < 0) {
148 LM_ERR("failed to parse new_uri\n");
153 _user->s = puri.user.s;
154 _user->len = puri.user.len;
160 * \brief Insert RR parameter lump in new allocated private memory
161 * \param before lump list
162 * \param s parameter string
163 * \param l parameter string length
164 * \return pointer to new lump on success, NULL on failure
166 static inline struct lump *insert_rr_param_lump(struct lump *before,
172 /* duplicate data in pkg mem */
173 s1 = (char*)pkg_malloc(l);
175 LM_ERR("no more pkg mem (%d)\n",l);
181 rrp_l = insert_new_lump_before( before, s1, l, HDR_RECORDROUTE_T);
183 LM_ERR("failed to add before lump\n");
192 * \brief Build a Record-Route header field
194 * Build a Record-Route header field, allocates new private memory for this.
195 * \param _l first lump
196 * \param _l2 second lump
197 * \param user user parameter
198 * \param tag tag parameter
199 * \param params parameter
200 * \param _inbound inbound request
201 * \return 0 on success, negative on failure
203 static inline int build_rr(struct lump* _l, struct lump* _l2, str* user,
204 str *tag, str *params, int _inbound, int _sips)
206 char* prefix, *suffix, *term, *r2;
207 int suffix_len, prefix_len;
214 rr_prefix = RR_PREFIX_SIP;
215 rr_prefix_len = RR_PREFIX_SIP_LEN;
217 rr_prefix = RR_PREFIX_SIPS;
218 rr_prefix_len = RR_PREFIX_SIPS_LEN;
221 prefix_len = rr_prefix_len + (user->len ? (user->len + 1) : 0);
222 if (enable_full_lr) {
223 suffix_len = RR_LR_FULL_LEN + (params?params->len:0) +
224 ((tag && tag->len) ? (RR_FROMTAG_LEN + tag->len) : 0);
226 suffix_len = RR_LR_LEN + (params?params->len:0) +
227 ((tag && tag->len) ? (RR_FROMTAG_LEN + tag->len) : 0);
230 prefix = pkg_malloc(prefix_len);
231 suffix = pkg_malloc(suffix_len);
232 term = pkg_malloc(RR_TERM_LEN);
233 r2 = pkg_malloc(RR_R2_LEN);
235 if (!prefix || !suffix || !term || !r2) {
236 LM_ERR("No more pkg memory\n");
237 if (suffix) pkg_free(suffix);
238 if (prefix) pkg_free(prefix);
239 if (term) pkg_free(term);
240 if (r2) pkg_free(r2);
244 memcpy(prefix, rr_prefix, rr_prefix_len);
246 memcpy(prefix + rr_prefix_len, user->s, user->len);
247 #ifdef ENABLE_USER_CHECK
248 /* don't add the ignored user into a RR */
249 if(i_user.len && i_user.len == user->len &&
250 !strncmp(i_user.s, user->s, i_user.len))
252 if(prefix[rr_prefix_len]=='x')
253 prefix[rr_prefix_len]='y';
255 prefix[rr_prefix_len]='x';
258 prefix[rr_prefix_len + user->len] = '@';
262 if (enable_full_lr) {
263 memcpy( p, RR_LR_FULL, RR_LR_FULL_LEN);
266 memcpy( p, RR_LR, RR_LR_LEN);
269 if (tag && tag->len) {
270 memcpy(p, RR_FROMTAG, RR_FROMTAG_LEN);
272 memcpy(p, tag->s, tag->len);
275 if (params && params->len) {
276 memcpy(p, params->s, params->len);
280 memcpy(term, RR_TERM, RR_TERM_LEN);
281 memcpy(r2, RR_R2, RR_R2_LEN);
283 if (!(_l = insert_new_lump_after(_l, prefix, prefix_len, 0)))
286 rr_lump_type = (_inbound)?
287 (rr_sockname_mode?SUBST_RCV_ALL_EX:SUBST_RCV_ALL)
288 :(rr_sockname_mode?SUBST_SND_ALL_EX:SUBST_SND_ALL);
289 _l = insert_subst_lump_after(_l, rr_lump_type, 0);
292 if (enable_double_rr) {
293 if (!(_l = insert_cond_lump_after(_l,
294 (enable_double_rr == 2) ? COND_TRUE : COND_IF_DIFF_REALMS, 0)))
296 if (!(_l = insert_new_lump_after(_l, r2, RR_R2_LEN, 0)))
303 _l2 = insert_new_lump_before(_l2, suffix, suffix_len, HDR_RECORDROUTE_T);
306 if (rr_param_buf.len) {
307 _l2 = insert_rr_param_lump(_l2, rr_param_buf.s, rr_param_buf.len);
312 if (!(_l2 = insert_new_lump_before(_l2, term, RR_TERM_LEN, 0)))
318 LM_ERR("failed to insert lumps\n");
319 if (prefix) pkg_free(prefix);
320 if (suffix) pkg_free(suffix);
321 if (r2) pkg_free(r2);
322 if (term) pkg_free(term);
327 * \brief Copy flow-token from top-Route: to a string
329 * Copy the user part of the top-Route: to a string (allocating private memory
331 * \param token where the user-part of the top-Route: will be copied to
332 * \param _m the SIP message to extract the top-Route: from
333 * \return 0 on success, negative on failure
335 static int copy_flow_token(str *token, struct sip_msg *_m)
341 || (parse_headers(_m, HDR_ROUTE_F, 0) != -1 && _m->route)) {
342 if (parse_rr(_m->route) < 0) {
343 LM_ERR("parsing Route: header body\n");
346 rt = (rr_t *) _m->route->parsed;
348 LM_ERR("empty Route:\n");
351 if (parse_uri(rt->nameaddr.uri.s, rt->nameaddr.uri.len,
353 LM_ERR("parsing Route-URI\n");
357 token->s = pkg_malloc(puri.user.len * sizeof(char));
358 if (token->s == NULL) {
359 LM_ERR("allocating memory\n");
362 memcpy(token->s, puri.user.s, puri.user.len);
363 token->len = puri.user.len;
367 LM_ERR("no Route: headers found\n");
373 * \brief Insert a new Record-Route header field with lr parameter
375 * Insert a new Record-Route header field and also 2nd one if it is enabled
376 * and the realm changed so the 2nd record-route header will be necessary.
377 * \param _m SIP message
378 * \param params RR parameter
379 * \return 0 on success, negative on failure
381 int record_route(struct sip_msg* _m, str *params)
384 str user = {NULL, 0};
386 int use_ob = rr_obb.use_outbound ? rr_obb.use_outbound(_m) : 0;
393 /* check if there is a custom user set */
394 if (get_custom_user(_m, &user) < 0) {
395 if (get_username(_m, &user) < 0) {
396 LM_ERR("failed to extract username\n");
400 } else if (use_ob == 1) {
401 if (rr_obb.encode_flow_token(&user, _m->rcv) != 0) {
402 LM_ERR("encoding outbound flow-token\n");
405 } else if (use_ob == 2) {
406 if (copy_flow_token(&user, _m) != 0) {
407 LM_ERR("copying outbound flow-token\n");
412 if (append_fromtag) {
413 if (is_direction(_m, RR_FLOW_UPSTREAM) == 0) {
414 if (parse_to_header(_m) < 0) {
415 LM_ERR("To parsing failed\n");
419 tag = &((struct to_body*)_m->to->parsed)->tag_value;
421 if (parse_from_header(_m) < 0) {
422 LM_ERR("From parsing failed\n");
426 tag = &((struct to_body*)_m->from->parsed)->tag_value;
432 if (rr_param_buf.len && rr_param_msg!=_m->id) {
433 /* rr_params were set for a different message -> reset buffer */
434 rr_param_buf.len = 0;
437 if(rr_ignore_sips==0) {
438 sips = rr_is_sips(_m);
441 if (enable_double_rr) {
442 l = anchor_lump(_m, _m->headers->name.s - _m->buf,0,HDR_RECORDROUTE_T);
443 l2 = anchor_lump(_m, _m->headers->name.s - _m->buf, 0, 0);
445 LM_ERR("failed to create an anchor\n");
449 l = insert_cond_lump_after(l,
450 (enable_double_rr == 2) ? COND_TRUE : COND_IF_DIFF_REALMS, 0);
451 l2 = insert_cond_lump_before(l2,
452 (enable_double_rr == 2) ? COND_TRUE : COND_IF_DIFF_REALMS, 0);
454 LM_ERR("failed to insert conditional lump\n");
458 if (build_rr(l, l2, &user, tag, params, OUTBOUND, sips) < 0) {
459 LM_ERR("failed to insert outbound Record-Route\n");
465 l = anchor_lump(_m, _m->headers->name.s - _m->buf, 0, HDR_RECORDROUTE_T);
466 l2 = anchor_lump(_m, _m->headers->name.s - _m->buf, 0, 0);
468 LM_ERR("failed to create an anchor\n");
473 if (build_rr(l, l2, &user, tag, params, INBOUND, sips) < 0) {
474 LM_ERR("failed to insert inbound Record-Route\n");
479 LM_DBG("inserted record route (r2: %d - plen: %d)\n", enable_double_rr,
480 (params)?params->len:0);
481 /* reset the rr_param buffer */
482 rr_param_buf.len = 0;
485 if ((use_ob == 1) || (use_ob == 2))
493 * \brief Insert manually created Record-Route header
495 * Insert manually created Record-Route header, no checks, no restrictions,
496 * always adds lr parameter, only fromtag is added automatically when requested.
497 * Allocates new private memory for this.
498 * \param _m SIP message
499 * \param _data manually created RR header
500 * \return 1 on success, negative on failure
502 int record_route_preset(struct sip_msg* _m, str* _data)
504 str user = {NULL, 0};
505 struct to_body* from = NULL;
509 int use_ob = rr_obb.use_outbound ? rr_obb.use_outbound(_m) : 0;
515 if(rr_ignore_sips==0) {
516 sips = rr_is_sips(_m);
519 rr_prefix = RR_PREFIX_SIP;
520 rr_prefix_len = RR_PREFIX_SIP_LEN;
522 rr_prefix = RR_PREFIX_SIPS;
523 rr_prefix_len = RR_PREFIX_SIPS_LEN;
527 if (get_username(_m, &user) < 0) {
528 LM_ERR("failed to extract username\n");
531 } else if (use_ob == 1) {
532 if (rr_obb.encode_flow_token(&user, _m->rcv) != 0) {
533 LM_ERR("encoding outbound flow-token\n");
536 } else if (use_ob == 2) {
537 if (copy_flow_token(&user, _m) != 0) {
538 LM_ERR("copying outbound flow-token\n");
543 if (append_fromtag) {
544 if (parse_from_header(_m) < 0 || get_from(_m)==NULL) {
545 LM_ERR("From parsing failed\n");
552 l = anchor_lump(_m, _m->headers->name.s - _m->buf, 0, HDR_RECORDROUTE_T);
554 LM_ERR("failed to create lump anchor\n");
559 hdr_len = rr_prefix_len;
561 hdr_len += user.len + 1; /* @ */
562 hdr_len += _data->len;
564 if (append_fromtag && from->tag_value.len) {
565 hdr_len += RR_FROMTAG_LEN + from->tag_value.len;
568 if (enable_full_lr) {
569 hdr_len += RR_LR_FULL_LEN;
571 hdr_len += RR_LR_LEN;
574 hdr_len += RR_TERM_LEN;
576 hdr = pkg_malloc(hdr_len);
578 LM_ERR("no pkg memory left\n");
584 memcpy(p, rr_prefix, rr_prefix_len);
588 memcpy(p, user.s, user.len);
594 memcpy(p, _data->s, _data->len);
597 if (append_fromtag && from->tag_value.len) {
598 memcpy(p, RR_FROMTAG, RR_FROMTAG_LEN);
600 memcpy(p, from->tag_value.s, from->tag_value.len);
601 p += from->tag_value.len;
604 if (enable_full_lr) {
605 memcpy(p, RR_LR_FULL, RR_LR_FULL_LEN);
608 memcpy(p, RR_LR, RR_LR_LEN);
612 memcpy(p, RR_TERM, RR_TERM_LEN);
614 if (!insert_new_lump_after(l, hdr, hdr_len, 0)) {
615 LM_ERR("failed to insert new lump\n");
620 LM_DBG("inserted preset record route\n");
623 if ((use_ob == 1) || (use_ob == 2))
630 * \brief Insert manually created Record-Route header
632 * Insert manually created Record-Route header, no checks, no restrictions,
633 * always adds lr parameter, only fromtag is added automatically when requested.
634 * Allocates new private memory for this.
635 * \param _m SIP message
636 * \param _data manually created RR header
637 * \return 1 on success, negative on failure
640 #define RR_TRANS_LEN 11
641 #define RR_TRANS ";transport="
642 static inline int build_advertised_rr(struct lump* _l, struct lump* _l2, str *_data,
643 str* user, str *tag, int _inbound, int _sips)
646 char *hdr, *trans, *r2, *suffix, *term;
647 int hdr_len, suffix_len;
652 rr_prefix = RR_PREFIX_SIP;
653 rr_prefix_len = RR_PREFIX_SIP_LEN;
655 rr_prefix = RR_PREFIX_SIPS;
656 rr_prefix_len = RR_PREFIX_SIPS_LEN;
659 hdr_len = rr_prefix_len;
660 if (user && user->len)
661 hdr_len += user->len + 1; /* @ */
662 hdr_len += _data->len;
665 if (tag && tag->len) {
666 suffix_len += RR_FROMTAG_LEN + tag->len;
669 if (enable_full_lr) {
670 suffix_len += RR_LR_FULL_LEN;
672 suffix_len += RR_LR_LEN;
675 hdr = pkg_malloc(hdr_len);
676 trans = pkg_malloc(RR_TRANS_LEN);
677 suffix = pkg_malloc(suffix_len);
678 r2 = pkg_malloc(RR_R2_LEN);
679 term = pkg_malloc(RR_TERM_LEN);
680 if (!hdr || !trans || !suffix || !term || !r2) {
681 LM_ERR("no pkg memory left\n");
682 if (hdr) pkg_free(hdr);
683 if (trans) pkg_free(trans);
684 if (suffix) pkg_free(suffix);
685 if (r2) pkg_free(r2);
686 if (term) pkg_free(term);
691 memcpy(p, rr_prefix, rr_prefix_len);
694 if (user && user->len) {
695 memcpy(p, user->s, user->len);
701 memcpy(p, _data->s, _data->len);
704 if (tag && tag->len) {
705 memcpy(p, RR_FROMTAG, RR_FROMTAG_LEN);
707 memcpy(p, tag->s, tag->len);
711 if (enable_full_lr) {
712 memcpy(p, RR_LR_FULL, RR_LR_FULL_LEN);
715 memcpy(p, RR_LR, RR_LR_LEN);
719 memcpy(trans, RR_TRANS, RR_TRANS_LEN);
720 memcpy(term, RR_TERM, RR_TERM_LEN);
721 memcpy(r2, RR_R2, RR_R2_LEN);
723 if (!(_l = insert_new_lump_after(_l, hdr, hdr_len, 0))) {
724 LM_ERR("failed to insert new lump\n");
728 if (!(_l = insert_cond_lump_after(_l,
729 (enable_double_rr == 2) ? COND_TRUE : COND_IF_DIFF_PROTO, 0)))
731 if (!(_l = insert_new_lump_after(_l, trans, RR_TRANS_LEN, 0)))
733 if (!(_l = insert_subst_lump_after(_l, _inbound?SUBST_RCV_PROTO:SUBST_SND_PROTO, 0)))
735 if (enable_double_rr) {
736 if (!(_l = insert_cond_lump_after(_l,
737 (enable_double_rr == 2) ? COND_TRUE : COND_IF_DIFF_REALMS, 0)))
739 if (!(_l = insert_new_lump_after(_l, r2, RR_R2_LEN, 0)))
746 if (!(_l2 = insert_new_lump_before(_l2, suffix, suffix_len, HDR_RECORDROUTE_T)))
749 if (rr_param_buf.len) {
750 if (!(_l2 = insert_rr_param_lump(_l2, rr_param_buf.s, rr_param_buf.len)))
753 if (!(_l2 = insert_new_lump_before(_l2, term, RR_TERM_LEN, 0)))
757 if (hdr) pkg_free(hdr);
758 if (trans) pkg_free(trans);
759 if (suffix) pkg_free(suffix);
760 if (term) pkg_free(term);
761 if (r2) pkg_free(r2);
765 int record_route_advertised_address(struct sip_msg* _m, str* _data)
767 str user = {NULL, 0};
771 int use_ob = rr_obb.use_outbound ? rr_obb.use_outbound(_m) : 0;
779 if (get_username(_m, &user) < 0) {
780 LM_ERR("failed to extract username\n");
783 } else if (use_ob == 1) {
784 if (rr_obb.encode_flow_token(&user, _m->rcv) != 0) {
785 LM_ERR("encoding outbound flow-token\n");
788 } else if (use_ob == 2) {
789 if (copy_flow_token(&user, _m) != 0) {
790 LM_ERR("copying outbound flow-token\n");
795 if (append_fromtag) {
796 if (is_direction(_m, RR_FLOW_UPSTREAM) == 0) {
797 if (parse_to_header(_m) < 0) {
798 LM_ERR("To parsing failed\n");
802 tag = &((struct to_body*)_m->to->parsed)->tag_value;
804 if (parse_from_header(_m) < 0) {
805 LM_ERR("From parsing failed\n");
809 tag = &((struct to_body*)_m->from->parsed)->tag_value;
815 if(rr_ignore_sips==0) {
816 sips = rr_is_sips(_m);
819 if (enable_double_rr) {
820 l = anchor_lump(_m, _m->headers->name.s - _m->buf,0,HDR_RECORDROUTE_T);
821 l2 = anchor_lump(_m, _m->headers->name.s - _m->buf, 0, 0);
823 LM_ERR("failed to create an anchor\n");
827 l = insert_cond_lump_after(l,
828 (enable_double_rr == 2) ? COND_TRUE : COND_IF_DIFF_PROTO, 0);
829 l2 = insert_cond_lump_before(l2,
830 (enable_double_rr == 2) ? COND_TRUE : COND_IF_DIFF_PROTO, 0);
832 LM_ERR("failed to insert conditional lump\n");
836 if (build_advertised_rr(l, l2, _data, &user, tag, OUTBOUND,
838 LM_ERR("failed to insert outbound Record-Route\n");
844 l = anchor_lump(_m, _m->headers->name.s - _m->buf, 0, HDR_RECORDROUTE_T);
845 l2 = anchor_lump(_m, _m->headers->name.s - _m->buf, 0, 0);
847 LM_ERR("failed to create an anchor\n");
852 if (build_advertised_rr(l, l2, _data, &user, tag, INBOUND, sips) < 0) {
853 LM_ERR("failed to insert outbound Record-Route\n");
857 LM_DBG("inserted advertised address record route\n");
860 if ((use_ob == 1) || (use_ob == 2))
868 * \brief Get the RR parameter lump
869 * \param root root of the lump list
870 * \return pointer to the RR parameter lump, or NULL if not found
872 static struct lump *get_rr_param_lump( struct lump** root)
874 struct lump *r, *crt, *last;
875 /* look on the "before" branch for the last added lump */
878 for( crt=*root ; crt && !last ; crt=crt->next,(*root)=crt ) {
879 /* check on before list */
880 for( r=crt->before ; r ; r=r->before ) {
881 /* we are looking for the lump that adds the
882 * suffix of the RR header */
883 if ( r->type==HDR_RECORDROUTE_T && r->op==LUMP_ADD)
892 * \brief Appends a new Record-Route parameter
893 * \param msg SIP message
894 * \param rr_param RR parameter
895 * \return 0 on success, -1 on failure
897 int add_rr_param(struct sip_msg* msg, str* rr_param)
899 struct lump *last_param;
903 last_param = get_rr_param_lump( &root );
905 /* RR was already done -> have to add a new lump before this one */
906 if (insert_rr_param_lump( last_param, rr_param->s, rr_param->len)==0) {
907 LM_ERR("failed to add lump\n");
910 /* double routing enabled? */
911 if (enable_double_rr) {
912 if (root==0 || (last_param=get_rr_param_lump(&root))==0) {
913 LM_CRIT("failed to locate double RR lump\n");
916 if (insert_rr_param_lump(last_param,rr_param->s,rr_param->len)==0){
917 LM_ERR("failed to add 2nd lump\n");
922 /* RR not done yet -> store the param in the static buffer */
923 if (rr_param_msg!=msg->id) {
924 /* it's about a different message -> reset buffer */
925 rr_param_buf.len = 0;
926 rr_param_msg = msg->id;
928 if (rr_param_buf.len+rr_param->len>RR_PARAM_BUF_SIZE) {
929 LM_ERR("maximum size of rr_param_buf exceeded\n");
932 memcpy( rr_param_buf.s+rr_param_buf.len, rr_param->s, rr_param->len);
933 rr_param_buf.len += rr_param->len;
934 LM_DBG("rr_param_buf=<%.*s>\n",rr_param_buf.len, rr_param_buf.s);