/*! \brief * Appends a new Record-Route parameter */ int add_rr_param(struct sip_msg* msg, str* rr_param) { struct lump *l; struct lump *crt; int rr_found=0; LM_DBG("adding (%.*s)\n",rr_param->len,rr_param->s); for( crt=msg->add_rm ; crt ; crt=crt->next ) { if (crt->type!=HDR_RECORDROUTE_T || crt->op!=LUMP_NOP) continue; /* found a RR-related anchor; we are looking for the * "second RR lump" (having data on "before") or for the * "buffering lump" (having also data on "before") */ if (!crt->before) continue; if (!rr_found && crt->before->op==LUMP_ADD_OPT && crt->before->u.cond==COND_FALSE ) { LM_DBG("buffering lump was found\n"); /* this is the "buffering lump" */ /* RR not done, but some RR params are already buffered -> add a before lump to the existing buffering one */ /* get the last param attached on the anchor */ for( l=crt->before->before ; l && l->before ; l=l->before); /* add the param */ if (insert_rr_param_lump( l, rr_param->s, rr_param->len)==0) { LM_ERR("failed to add buffered lump\n"); goto error; } return 0; } /* this is a "second RR lump" */ LM_DBG("second RR lump found\n"); /* RR was already done -> have to add a new lump before last param */ for (l=crt->before ; l && l->op!=LUMP_ADD ; l=l->before ); if (l==NULL) { LM_CRIT("BUG - second RR anchor has no ADD on before\n"); return -1; } if (insert_rr_param_lump( l, rr_param->s, rr_param->len)==0) { LM_ERR("failed to add lump\n"); goto error; } /* double routing enabled? */ if (!enable_double_rr) /* done */ return 0; /* continue looking for more RR headers */ rr_found = 1; } /* param already added to existing RR headers ? */ if (rr_found) return 0; /* RR not done, no other RR param added so far -> create the phony anchor and add the lump to it */ crt = anchor_lump(msg, msg->headers->name.s-msg->buf, HDR_RECORDROUTE_T); if (crt==NULL) { LM_ERR("cannot create phony lump for buffering params\n"); goto error; } l = insert_cond_lump_before( crt, COND_FALSE, 0); if (l==NULL) { LM_ERR("cannot create conditional lump for buffering params\n"); goto error; } if (insert_rr_param_lump( l, rr_param->s, rr_param->len)==0) { LM_ERR("failed to add buffered lump\n"); goto error; } return 0; error: return -1; }
/*! \brief * Insert a new Record-Route header field * And also 2nd one if it is enabled and realm changed so * the 2nd record-route header will be necessary */ int record_route(struct sip_msg* _m, str *params) { struct lump* l, *l2, *lp, *lp2, *ap; str user; struct to_body* from; str* tag; from = 0; /* Makes gcc happy */ user.len = 0; lp = lp2 = NULL; if (add_username) { if (get_username(_m, &user) < 0) { LM_ERR("failed to extract username\n"); return -1; } } if (append_fromtag) { if (parse_from_header(_m) < 0) { LM_ERR("From parsing failed\n"); return -2; } from = (struct to_body*)_m->from->parsed; tag = &from->tag_value; } else { tag = 0; } l = anchor_lump(_m, _m->headers->name.s - _m->buf, HDR_RECORDROUTE_T); l2 = anchor_lump(_m, _m->headers->name.s - _m->buf, HDR_RECORDROUTE_T); if (!l || !l2) { LM_ERR("failed to create an anchor\n"); return -3; } /* look for pending RR params */ for( lp2=NULL,lp=NULL,ap=_m->add_rm ; ap ; ap=ap->next ) { if (ap->type==HDR_RECORDROUTE_T && ap->op==LUMP_NOP && ap->before && ap->before->op==LUMP_ADD_OPT && ap->before->u.cond==COND_FALSE) { /* found our phony anchor lump */ /* jump over the anchor and conditional lumps */ lp = ap->before->before; /* unlink it */ ap->before->before = NULL; ap->type = 0; /* if double routing, make a copy of the buffered lumps for the second route hdr. */ if (enable_double_rr) lp2 = dup_lump_list(lp); break; } } if (build_rr(l, l2, &user, tag, params, lp, OUTBOUND) < 0) { LM_ERR("failed to insert inbound Record-Route\n"); return -4; } if (enable_double_rr) { l = anchor_lump(_m, _m->headers->name.s - _m->buf,HDR_RECORDROUTE_T); l2 = anchor_lump(_m, _m->headers->name.s - _m->buf, HDR_RECORDROUTE_T); if (!l || !l2) { LM_ERR("failed to create an anchor\n"); return -5; } l = insert_cond_lump_after(l, COND_IF_DIFF_REALMS, 0); l2 = insert_cond_lump_before(l2, COND_IF_DIFF_REALMS, 0); if (!l || !l2) { LM_ERR("failed to insert conditional lump\n"); return -6; } if (build_rr(l, l2, &user, tag, params, lp2, INBOUND) < 0) { LM_ERR("failed to insert outbound Record-Route\n"); return -7; } } return 0; }
int record_route_advertised_address(struct sip_msg* _m, str* _data) { str user = {NULL, 0}; str *tag = NULL; struct lump* l; struct lump* l2; int use_ob = rr_obb.use_outbound ? rr_obb.use_outbound(_m) : 0; int sips; int ret = 0; user.len = 0; user.s = 0; if (add_username) { if (get_username(_m, &user) < 0) { LM_ERR("failed to extract username\n"); return -1; } } else if (use_ob == 1) { if (rr_obb.encode_flow_token(&user, _m->rcv) != 0) { LM_ERR("encoding outbound flow-token\n"); return -1; } } else if (use_ob == 2) { if (copy_flow_token(&user, _m) != 0) { LM_ERR("copying outbound flow-token\n"); return -1; } } if (append_fromtag) { if (is_direction(_m, RR_FLOW_UPSTREAM) == 0) { if (parse_to_header(_m) < 0) { LM_ERR("To parsing failed\n"); ret = -2; goto error; } tag = &((struct to_body*)_m->to->parsed)->tag_value; } else { if (parse_from_header(_m) < 0) { LM_ERR("From parsing failed\n"); ret = -2; goto error; } tag = &((struct to_body*)_m->from->parsed)->tag_value; } } else { tag = 0; } sips = rr_is_sips(_m); if (enable_double_rr) { l = anchor_lump(_m, _m->headers->name.s - _m->buf,0,HDR_RECORDROUTE_T); l2 = anchor_lump(_m, _m->headers->name.s - _m->buf, 0, 0); if (!l || !l2) { LM_ERR("failed to create an anchor\n"); ret = -3; goto error; } l = insert_cond_lump_after(l, (enable_double_rr == 2) ? COND_TRUE : COND_IF_DIFF_PROTO, 0); l2 = insert_cond_lump_before(l2, (enable_double_rr == 2) ? COND_TRUE : COND_IF_DIFF_PROTO, 0); if (!l || !l2) { LM_ERR("failed to insert conditional lump\n"); ret = -4; goto error; } if (build_advertised_rr(l, l2, _data, &user, tag, OUTBOUND, sips) < 0) { LM_ERR("failed to insert outbound Record-Route\n"); ret = -5; goto error; } } l = anchor_lump(_m, _m->headers->name.s - _m->buf, 0, HDR_RECORDROUTE_T); l2 = anchor_lump(_m, _m->headers->name.s - _m->buf, 0, 0); if (!l || !l2) { LM_ERR("failed to create an anchor\n"); ret = -6; goto error; } if (build_advertised_rr(l, l2, _data, &user, tag, INBOUND, sips) < 0) { LM_ERR("failed to insert outbound Record-Route\n"); ret = -7; goto error; } ret = 1; error: if ((use_ob == 1) || (use_ob == 2)) if (user.s != NULL) pkg_free(user.s); return ret; }
/*! * \brief Insert a new Record-Route header field with lr parameter * * Insert a new Record-Route header field and also 2nd one if it is enabled * and the realm changed so the 2nd record-route header will be necessary. * \param _m SIP message * \param params RR parameter * \return 0 on success, negative on failure */ int record_route(struct sip_msg* _m, str *params) { struct lump* l, *l2; str user = {NULL, 0}; str* tag; int use_ob = rr_obb.use_outbound ? rr_obb.use_outbound(_m) : 0; int sips; int ret = 0; user.len = 0; if (add_username) { /* check if there is a custom user set */ if (get_custom_user(_m, &user) < 0) { if (get_username(_m, &user) < 0) { LM_ERR("failed to extract username\n"); return -1; } } } else if (use_ob == 1) { if (rr_obb.encode_flow_token(&user, _m->rcv) != 0) { LM_ERR("encoding outbound flow-token\n"); return -1; } } else if (use_ob == 2) { if (copy_flow_token(&user, _m) != 0) { LM_ERR("copying outbound flow-token\n"); return -1; } } if (append_fromtag) { if (is_direction(_m, RR_FLOW_UPSTREAM) == 0) { if (parse_to_header(_m) < 0) { LM_ERR("To parsing failed\n"); ret = -2; goto error; } tag = &((struct to_body*)_m->to->parsed)->tag_value; } else { if (parse_from_header(_m) < 0) { LM_ERR("From parsing failed\n"); ret = -2; goto error; } tag = &((struct to_body*)_m->from->parsed)->tag_value; } } else { tag = 0; } if (rr_param_buf.len && rr_param_msg!=_m->id) { /* rr_params were set for a different message -> reset buffer */ rr_param_buf.len = 0; } sips = rr_is_sips(_m); if (enable_double_rr) { l = anchor_lump(_m, _m->headers->name.s - _m->buf,0,HDR_RECORDROUTE_T); l2 = anchor_lump(_m, _m->headers->name.s - _m->buf, 0, 0); if (!l || !l2) { LM_ERR("failed to create an anchor\n"); ret = -5; goto error; } l = insert_cond_lump_after(l, (enable_double_rr == 2) ? COND_TRUE : COND_IF_DIFF_REALMS, 0); l2 = insert_cond_lump_before(l2, (enable_double_rr == 2) ? COND_TRUE : COND_IF_DIFF_REALMS, 0); if (!l || !l2) { LM_ERR("failed to insert conditional lump\n"); ret = -6; goto error; } if (build_rr(l, l2, &user, tag, params, OUTBOUND, sips) < 0) { LM_ERR("failed to insert outbound Record-Route\n"); ret = -7; goto error; } } l = anchor_lump(_m, _m->headers->name.s - _m->buf, 0, HDR_RECORDROUTE_T); l2 = anchor_lump(_m, _m->headers->name.s - _m->buf, 0, 0); if (!l || !l2) { LM_ERR("failed to create an anchor\n"); ret = -3; goto error; } if (build_rr(l, l2, &user, tag, params, INBOUND, sips) < 0) { LM_ERR("failed to insert inbound Record-Route\n"); ret = -4; goto error; } /* reset the rr_param buffer */ rr_param_buf.len = 0; ret = 0; error: if ((use_ob == 1) || (use_ob == 2)) if (user.s != NULL) pkg_free(user.s); return ret; }
int record_route_advertised_address(struct sip_msg* _m, str* _data) { str user; str *tag = NULL; struct lump* l; struct lump* l2; int use_ob = rr_obb.use_outbound ? rr_obb.use_outbound(_m) : 0; int sips; user.len = 0; user.s = 0; if (add_username) { if (get_username(_m, &user) < 0) { LM_ERR("failed to extract username\n"); return -1; } } else if (use_ob == 1) { if (rr_obb.encode_flow_token(&user, _m->rcv) != 0) { LM_ERR("encoding outbound flow-token\n"); return -1; } } else if (use_ob == 2) { if (copy_flow_token(&user, _m) != 0) { LM_ERR("copying outbound flow-token\n"); return -1; } } if (append_fromtag) { if (parse_from_header(_m) < 0) { LM_ERR("From parsing failed\n"); return -2; } tag = &((struct to_body*)_m->from->parsed)->tag_value; } sips = rr_is_sips(_m); if (enable_double_rr) { l = anchor_lump(_m, _m->headers->name.s - _m->buf,0,HDR_RECORDROUTE_T); l2 = anchor_lump(_m, _m->headers->name.s - _m->buf, 0, 0); if (!l || !l2) { LM_ERR("failed to create an anchor\n"); return -3; } l = insert_cond_lump_after(l, COND_IF_DIFF_PROTO, 0); l2 = insert_cond_lump_before(l2, COND_IF_DIFF_PROTO, 0); if (!l || !l2) { LM_ERR("failed to insert conditional lump\n"); return -4; } if (build_advertised_rr(l, l2, _data, &user, tag, OUTBOUND, sips) < 0) { LM_ERR("failed to insert outbound Record-Route\n"); return -5; } } l = anchor_lump(_m, _m->headers->name.s - _m->buf, 0, HDR_RECORDROUTE_T); l2 = anchor_lump(_m, _m->headers->name.s - _m->buf, 0, 0); if (!l || !l2) { LM_ERR("failed to create an anchor\n"); return -6; } if (build_advertised_rr(l, l2, _data, &user, tag, INBOUND, sips) < 0) { LM_ERR("failed to insert outbound Record-Route\n"); return -7; } return 1; }
/*! * \brief Insert a new Record-Route header field with lr parameter * * Insert a new Record-Route header field and also 2nd one if it is enabled * and the realm changed so the 2nd record-route header will be necessary. * \param _m SIP message * \param params RR parameter * \return 0 on success, negative on failure */ int record_route(struct sip_msg* _m, str *params) { struct lump* l, *l2; str user; struct to_body* from = NULL; str* tag; int use_ob = rr_obb.use_outbound ? rr_obb.use_outbound(_m) : 0; int sips; user.len = 0; if (add_username) { /* check if there is a custom user set */ if (get_custom_user(_m, &user) < 0) { if (get_username(_m, &user) < 0) { LM_ERR("failed to extract username\n"); return -1; } } } else if (use_ob == 1) { if (rr_obb.encode_flow_token(&user, _m->rcv) != 0) { LM_ERR("encoding outbound flow-token\n"); return -1; } } else if (use_ob == 2) { if (copy_flow_token(&user, _m) != 0) { LM_ERR("copying outbound flow-token\n"); return -1; } } if (append_fromtag) { if (parse_from_header(_m) < 0) { LM_ERR("From parsing failed\n"); return -2; } from = (struct to_body*)_m->from->parsed; tag = &from->tag_value; } else { tag = 0; } if (rr_param_buf.len && rr_param_msg!=_m->id) { /* rr_params were set for a different message -> reset buffer */ rr_param_buf.len = 0; } sips = rr_is_sips(_m); if (enable_double_rr) { l = anchor_lump(_m, _m->headers->name.s - _m->buf,0,HDR_RECORDROUTE_T); l2 = anchor_lump(_m, _m->headers->name.s - _m->buf, 0, 0); if (!l || !l2) { LM_ERR("failed to create an anchor\n"); return -5; } l = insert_cond_lump_after(l, COND_IF_DIFF_REALMS, 0); l2 = insert_cond_lump_before(l2, COND_IF_DIFF_REALMS, 0); if (!l || !l2) { LM_ERR("failed to insert conditional lump\n"); return -6; } if (build_rr(l, l2, &user, tag, params, OUTBOUND, sips) < 0) { LM_ERR("failed to insert outbound Record-Route\n"); return -7; } } l = anchor_lump(_m, _m->headers->name.s - _m->buf, 0, HDR_RECORDROUTE_T); l2 = anchor_lump(_m, _m->headers->name.s - _m->buf, 0, 0); if (!l || !l2) { LM_ERR("failed to create an anchor\n"); return -3; } if (build_rr(l, l2, &user, tag, params, INBOUND, sips) < 0) { LM_ERR("failed to insert inbound Record-Route\n"); return -4; } /* reset the rr_param buffer */ rr_param_buf.len = 0; return 0; }