/*! \brief * build a Record-Route header field */ static inline int build_rr(struct lump* _l, struct lump* _l2, str* user, str *tag, str *params, struct lump *lp, int _inbound) { char* prefix, *suffix, *term, *r2; int suffix_len, prefix_len; char *p; prefix_len = RR_PREFIX_LEN + (user->len ? (user->len + 1) : 0); suffix_len = RR_LR_LEN + (params?params->len:0) + ((tag && tag->len) ? (RR_FROMTAG_LEN + tag->len) : 0); prefix = pkg_malloc(prefix_len); suffix = pkg_malloc(suffix_len); term = pkg_malloc(RR_TERM_LEN); r2 = pkg_malloc(RR_R2_LEN); if (!prefix || !suffix || !term || !r2) { LM_ERR("No more pkg memory\n"); if (suffix) pkg_free(suffix); if (prefix) pkg_free(prefix); if (term) pkg_free(term); if (r2) pkg_free(r2); return -3; } memcpy(prefix, RR_PREFIX, RR_PREFIX_LEN); if (user->len) { memcpy(prefix + RR_PREFIX_LEN, user->s, user->len); #ifdef ENABLE_USER_CHECK /* don't add the ignored user into a RR */ if(i_user.len && i_user.len == user->len && !strncmp(i_user.s, user->s, i_user.len)) { if(prefix[RR_PREFIX_LEN]=='x') prefix[RR_PREFIX_LEN]='y'; else prefix[RR_PREFIX_LEN]='x'; } #endif prefix[RR_PREFIX_LEN + user->len] = '@'; } p = suffix; memcpy( p, RR_LR, RR_LR_LEN); p += RR_LR_LEN; if (tag && tag->len) { memcpy(p, RR_FROMTAG, RR_FROMTAG_LEN); p += RR_FROMTAG_LEN; memcpy(p, tag->s, tag->len); p += tag->len; } if (params && params->len) { memcpy(p, params->s, params->len); p += params->len; } memcpy(term, RR_TERM, RR_TERM_LEN); memcpy(r2, RR_R2, RR_R2_LEN); if (!(_l = insert_new_lump_after(_l, prefix, prefix_len, 0))) goto lump_err; prefix = 0; _l = insert_subst_lump_after(_l, _inbound?SUBST_RCV_ALL:SUBST_SND_ALL, 0); if (_l ==0 ) goto lump_err; if (enable_double_rr) { if (!(_l = insert_cond_lump_after(_l, COND_IF_DIFF_REALMS, 0))) goto lump_err; if (!(_l = insert_new_lump_after(_l, r2, RR_R2_LEN, 0))) goto lump_err; r2 = 0; } else { pkg_free(r2); r2 = 0; } _l2 = insert_new_lump_before(_l2, suffix, suffix_len, 0); if (_l2 == 0) goto lump_err; suffix = 0; if ( lp ) { /* link the pending buffered params and go at the end of the list */ for ( _l2->before = lp ; _l2 && _l2->before ; _l2=_l2->before); } if (!(_l2 = insert_new_lump_before(_l2, term, RR_TERM_LEN, 0))) goto lump_err; term = 0; return 0; lump_err: LM_ERR("failed to insert lumps\n"); if (prefix) pkg_free(prefix); if (suffix) pkg_free(suffix); if (r2) pkg_free(r2); if (term) pkg_free(term); return -4; }
static inline int build_advertised_rr(struct lump* _l, struct lump* _l2, str *_data, str* user, str *tag, int _inbound, int _sips) { char *p; char *hdr, *trans, *r2, *suffix, *term; int hdr_len, suffix_len; char *rr_prefix; int rr_prefix_len; if(_sips==0) { rr_prefix = RR_PREFIX_SIP; rr_prefix_len = RR_PREFIX_SIP_LEN; } else { rr_prefix = RR_PREFIX_SIPS; rr_prefix_len = RR_PREFIX_SIPS_LEN; } hdr_len = rr_prefix_len; if (user && user->len) hdr_len += user->len + 1; /* @ */ hdr_len += _data->len; suffix_len = 0; if (tag && tag->len) { suffix_len += RR_FROMTAG_LEN + tag->len; } if (enable_full_lr) { suffix_len += RR_LR_FULL_LEN; } else { suffix_len += RR_LR_LEN; } hdr = pkg_malloc(hdr_len); trans = pkg_malloc(RR_TRANS_LEN); suffix = pkg_malloc(suffix_len); r2 = pkg_malloc(RR_R2_LEN); term = pkg_malloc(RR_TERM_LEN); if (!hdr || !trans || !suffix || !term || !r2) { LM_ERR("no pkg memory left\n"); if (hdr) pkg_free(hdr); if (trans) pkg_free(trans); if (suffix) pkg_free(suffix); if (r2) pkg_free(r2); if (term) pkg_free(term); return -1; } p = hdr; memcpy(p, rr_prefix, rr_prefix_len); p += rr_prefix_len; if (user && user->len) { memcpy(p, user->s, user->len); p += user->len; *p = '@'; p++; } memcpy(p, _data->s, _data->len); p = suffix; if (tag && tag->len) { memcpy(p, RR_FROMTAG, RR_FROMTAG_LEN); p += RR_FROMTAG_LEN; memcpy(p, tag->s, tag->len); p += tag->len; } if (enable_full_lr) { memcpy(p, RR_LR_FULL, RR_LR_FULL_LEN); p += RR_LR_FULL_LEN; } else { memcpy(p, RR_LR, RR_LR_LEN); p += RR_LR_LEN; } memcpy(trans, RR_TRANS, RR_TRANS_LEN); memcpy(term, RR_TERM, RR_TERM_LEN); memcpy(r2, RR_R2, RR_R2_LEN); if (!(_l = insert_new_lump_after(_l, hdr, hdr_len, 0))) { LM_ERR("failed to insert new lump\n"); goto lump_err; } hdr = NULL; if (!(_l = insert_cond_lump_after(_l, (enable_double_rr == 2) ? COND_TRUE : COND_IF_DIFF_PROTO, 0))) goto lump_err; if (!(_l = insert_new_lump_after(_l, trans, RR_TRANS_LEN, 0))) goto lump_err; if (!(_l = insert_subst_lump_after(_l, _inbound?SUBST_RCV_PROTO:SUBST_SND_PROTO, 0))) goto lump_err; if (enable_double_rr) { if (!(_l = insert_cond_lump_after(_l, (enable_double_rr == 2) ? COND_TRUE : COND_IF_DIFF_REALMS, 0))) goto lump_err; if (!(_l = insert_new_lump_after(_l, r2, RR_R2_LEN, 0))) goto lump_err; r2 = 0; } else { pkg_free(r2); r2 = 0; } if (!(_l2 = insert_new_lump_before(_l2, suffix, suffix_len, HDR_RECORDROUTE_T))) goto lump_err; suffix = NULL; if (rr_param_buf.len) { if (!(_l2 = insert_rr_param_lump(_l2, rr_param_buf.s, rr_param_buf.len))) goto lump_err; } if (!(_l2 = insert_new_lump_before(_l2, term, RR_TERM_LEN, 0))) goto lump_err; return 1; lump_err: if (hdr) pkg_free(hdr); if (trans) pkg_free(trans); if (suffix) pkg_free(suffix); if (term) pkg_free(term); if (r2) pkg_free(r2); return -7; }
int dlg_replace_contact(struct sip_msg* msg, struct dlg_cell* dlg) { struct lump* lump, *crt, *prev_crt =0, *a, *foo; int offset; int len,n; char *prefix=NULL,*suffix=NULL,*p,*p_init,*ct_username=NULL; int prefix_len,suffix_len,ct_username_len=0; struct sip_uri ctu; str contact; if(!msg->contact) { if(parse_headers(msg, HDR_CONTACT_F, 0)< 0) { LM_ERR("Failed to parse headers\n"); return -1; } if(!msg->contact) return 0; } prefix_len = 5; /* <sip: */ if (dlg->flags & DLG_FLAG_TOPH_KEEP_USER) { if ( parse_contact(msg->contact)<0 || ((contact_body_t *)msg->contact->parsed)->contacts==NULL || ((contact_body_t *)msg->contact->parsed)->contacts->next!=NULL ) { LM_ERR("bad Contact HDR\n"); } else { contact = ((contact_body_t *)msg->contact->parsed)->contacts->uri; if(parse_uri(contact.s, contact.len, &ctu) < 0) { LM_ERR("Bad Contact URI\n"); } else { ct_username = ctu.user.s; ct_username_len = ctu.user.len; LM_DBG("Trying to propagate username [%.*s]\n",ct_username_len, ct_username); if (ct_username_len > 0) prefix_len += 1 + /* @ */ + ct_username_len; } } } prefix = pkg_malloc(prefix_len); if (!prefix) { LM_ERR("no more pkg\n"); goto error; } suffix_len = RR_DLG_PARAM_SIZE+1; /* > */ suffix = pkg_malloc(suffix_len); if (!suffix) { LM_ERR("no more pkg\n"); goto error; } memcpy(prefix,"<sip:",prefix_len); if (dlg->flags & DLG_FLAG_TOPH_KEEP_USER && ct_username_len > 0) { memcpy(prefix+5,ct_username,ct_username_len); prefix[prefix_len-1] = '@'; } p_init = p = suffix; *p++ = ';'; memcpy(p,rr_param.s,rr_param.len); p+=rr_param.len; *p++ = '='; n = RR_DLG_PARAM_SIZE - (p-p_init); if (int2reverse_hex( &p, &n, dlg->h_entry)==-1) return -1; *(p++) = DLG_SEPARATOR; n = RR_DLG_PARAM_SIZE - (p-p_init); if (int2reverse_hex( &p, &n, dlg->h_id)==-1) return -1; *p++ = '>'; suffix_len = p - p_init; offset = msg->contact->body.s - msg->buf; len = msg->contact->body.len; for (crt = msg->add_rm;crt;) { if (crt->type == HDR_CONTACT_T && crt->op == LUMP_DEL && crt->u.offset >= offset && crt->u.offset <= offset + len) { lump = crt; crt = crt->next; a=lump->before; while(a) { LM_DBG("before [%p], op=%d\n", a, a->op); if(a->op == LUMP_ADD) LM_DBG("value= %.*s\n", a->len, a->u.value); foo=a; a=a->before; if (!(foo->flags&(LUMPFLAG_DUPED|LUMPFLAG_SHMEM))) free_lump(foo); if (!(foo->flags&LUMPFLAG_SHMEM)) pkg_free(foo); } a=lump->after; while(a) { LM_DBG("after [%p], op=%d\n", a, a->op); if(a->op == LUMP_ADD) LM_DBG("value= %.*s\n", a->len, a->u.value); foo=a; a=a->after; if (!(foo->flags&(LUMPFLAG_DUPED|LUMPFLAG_SHMEM))) free_lump(foo); if (!(foo->flags&LUMPFLAG_SHMEM)) pkg_free(foo); } if(lump == msg->add_rm) msg->add_rm = lump->next; else prev_crt->next = lump->next; if (!(lump->flags&(LUMPFLAG_DUPED|LUMPFLAG_SHMEM))) free_lump(lump); if (!(lump->flags&LUMPFLAG_SHMEM)) pkg_free(lump); continue; } prev_crt = crt; crt= crt->next; } if ((lump = del_lump(msg, msg->contact->body.s - msg->buf, msg->contact->body.len,HDR_CONTACT_T)) == 0) { LM_ERR("del_lump failed\n"); goto error; } if ((lump = insert_new_lump_after(lump,prefix,prefix_len,HDR_CONTACT_T)) == 0) { LM_ERR("failed inserting '<sip:'\n"); goto error; } /* make sure we do not free this string in case of a further error */ prefix = NULL; if ((lump = insert_subst_lump_after(lump, SUBST_SND_ALL, HDR_CONTACT_T)) == 0) { LM_ERR("failed inserting SUBST_SND buf\n"); goto error; } if ((lump = insert_new_lump_after(lump,suffix,suffix_len,HDR_CONTACT_T)) == 0) { LM_ERR("failed inserting '<sip:'\n"); goto error; } return 0; error: if (prefix) pkg_free(prefix); if (suffix) pkg_free(suffix); return -1; }
/*! * \brief Build a Record-Route header field * * Build a Record-Route header field, allocates new private memory for this. * \param _l first lump * \param _l2 second lump * \param user user parameter * \param tag tag parameter * \param params parameter * \param _inbound inbound request * \return 0 on success, negative on failure */ static inline int build_rr(struct lump* _l, struct lump* _l2, str* user, str *tag, str *params, int _inbound, int _sips) { char* prefix, *suffix, *term, *r2; int suffix_len, prefix_len; char *p; char *rr_prefix; int rr_prefix_len; if(_sips==0) { rr_prefix = RR_PREFIX_SIP; rr_prefix_len = RR_PREFIX_SIP_LEN; } else { rr_prefix = RR_PREFIX_SIPS; rr_prefix_len = RR_PREFIX_SIPS_LEN; } prefix_len = rr_prefix_len + (user->len ? (user->len + 1) : 0); if (enable_full_lr) { suffix_len = RR_LR_FULL_LEN + (params?params->len:0) + ((tag && tag->len) ? (RR_FROMTAG_LEN + tag->len) : 0); } else { suffix_len = RR_LR_LEN + (params?params->len:0) + ((tag && tag->len) ? (RR_FROMTAG_LEN + tag->len) : 0); } prefix = pkg_malloc(prefix_len); suffix = pkg_malloc(suffix_len); term = pkg_malloc(RR_TERM_LEN); r2 = pkg_malloc(RR_R2_LEN); if (!prefix || !suffix || !term || !r2) { LM_ERR("No more pkg memory\n"); if (suffix) pkg_free(suffix); if (prefix) pkg_free(prefix); if (term) pkg_free(term); if (r2) pkg_free(r2); return -3; } memcpy(prefix, rr_prefix, rr_prefix_len); if (user->len) { memcpy(prefix + rr_prefix_len, user->s, user->len); #ifdef ENABLE_USER_CHECK /* don't add the ignored user into a RR */ if(i_user.len && i_user.len == user->len && !strncmp(i_user.s, user->s, i_user.len)) { if(prefix[rr_prefix_len]=='x') prefix[rr_prefix_len]='y'; else prefix[rr_prefix_len]='x'; } #endif prefix[rr_prefix_len + user->len] = '@'; } p = suffix; if (enable_full_lr) { memcpy( p, RR_LR_FULL, RR_LR_FULL_LEN); p += RR_LR_FULL_LEN; } else { memcpy( p, RR_LR, RR_LR_LEN); p += RR_LR_LEN; } if (tag && tag->len) { memcpy(p, RR_FROMTAG, RR_FROMTAG_LEN); p += RR_FROMTAG_LEN; memcpy(p, tag->s, tag->len); p += tag->len; } if (params && params->len) { memcpy(p, params->s, params->len); p += params->len; } memcpy(term, RR_TERM, RR_TERM_LEN); memcpy(r2, RR_R2, RR_R2_LEN); if (!(_l = insert_new_lump_after(_l, prefix, prefix_len, 0))) goto lump_err; prefix = 0; _l = insert_subst_lump_after(_l, _inbound?SUBST_RCV_ALL:SUBST_SND_ALL, 0); if (_l ==0 ) goto lump_err; if (enable_double_rr) { if (!(_l = insert_cond_lump_after(_l, (enable_double_rr == 2) ? COND_TRUE : COND_IF_DIFF_REALMS, 0))) goto lump_err; if (!(_l = insert_new_lump_after(_l, r2, RR_R2_LEN, 0))) goto lump_err; r2 = 0; } else { pkg_free(r2); r2 = 0; } _l2 = insert_new_lump_before(_l2, suffix, suffix_len, HDR_RECORDROUTE_T); if (_l2 == 0) goto lump_err; if (rr_param_buf.len) { _l2 = insert_rr_param_lump(_l2, rr_param_buf.s, rr_param_buf.len); if (_l2 == 0) goto lump_err; } suffix = 0; if (!(_l2 = insert_new_lump_before(_l2, term, RR_TERM_LEN, 0))) goto lump_err; term = 0; return 0; lump_err: LM_ERR("failed to insert lumps\n"); if (prefix) pkg_free(prefix); if (suffix) pkg_free(suffix); if (r2) pkg_free(r2); if (term) pkg_free(term); return -4; }
int dlg_replace_contact(struct sip_msg* msg, struct dlg_cell* dlg) { // str local_contact; struct lump* lump, *crt, *prev_crt =0, *a, *foo; int offset; int len,n; char *prefix=NULL,*suffix=NULL,*p,*p_init; int prefix_len,suffix_len; if(!msg->contact) { if(parse_headers(msg, HDR_CONTACT_F, 0)< 0) { LM_ERR("Failed to parse headers\n"); return -1; } if(!msg->contact) return 0; } prefix_len = 5; /* <sip: */ prefix = pkg_malloc(prefix_len); if (!prefix) { LM_ERR("no more pkg\n"); goto error; } suffix_len = RR_DLG_PARAM_SIZE+1; /* > */ suffix = pkg_malloc(suffix_len); if (!suffix) { LM_ERR("no more pkg\n"); goto error; } memcpy(prefix,"<sip:",prefix_len); p_init = p = suffix; *p++ = ';'; memcpy(p,"did",3); p+=3; *p++ = '='; n = RR_DLG_PARAM_SIZE - (p-p_init); if (int2reverse_hex( &p, &n, dlg->h_entry)==-1) return -1; *(p++) = DLG_SEPARATOR; n = RR_DLG_PARAM_SIZE - (p-p_init); if (int2reverse_hex( &p, &n, dlg->h_id)==-1) return -1; *p++ = '>'; suffix_len = p - p_init; offset = msg->contact->body.s - msg->buf; len = msg->contact->body.len; for (crt = msg->add_rm;crt;) { if (crt->type == HDR_CONTACT_T && crt->op == LUMP_DEL && crt->u.offset >= offset && crt->u.offset <= offset + len) { lump = crt; crt = crt->next; a=lump->before; while(a) { LM_DBG("before [%p], op=%d\n", a, a->op); if(a->op == LUMP_ADD) LM_DBG("value= %.*s\n", a->len, a->u.value); foo=a; a=a->before; if (!(foo->flags&(LUMPFLAG_DUPED|LUMPFLAG_SHMEM))) free_lump(foo); if (!(foo->flags&LUMPFLAG_SHMEM)) pkg_free(foo); } a=lump->after; while(a) { LM_DBG("after [%p], op=%d\n", a, a->op); if(a->op == LUMP_ADD) LM_DBG("value= %.*s\n", a->len, a->u.value); foo=a; a=a->after; if (!(foo->flags&(LUMPFLAG_DUPED|LUMPFLAG_SHMEM))) free_lump(foo); if (!(foo->flags&LUMPFLAG_SHMEM)) pkg_free(foo); } if(lump == msg->add_rm) msg->add_rm = lump->next; else prev_crt->next = lump->next; if (!(lump->flags&(LUMPFLAG_DUPED|LUMPFLAG_SHMEM))) free_lump(lump); if (!(lump->flags&LUMPFLAG_SHMEM)) pkg_free(lump); continue; } prev_crt = crt; crt= crt->next; } if ((lump = del_lump(msg, msg->contact->body.s - msg->buf, msg->contact->body.len,HDR_CONTACT_T)) == 0) { LM_ERR("del_lump failed \n"); goto error; } if ((lump = insert_new_lump_after(lump,prefix,prefix_len,HDR_CONTACT_T)) == 0) { LM_ERR("failed inserting '<sip:'\n"); goto error; } if ((lump = insert_subst_lump_after(lump, SUBST_SND_ALL, HDR_CONTACT_T)) == 0) { LM_ERR("failed inserting SUBST_SND buf\n"); goto error; } if ((lump = insert_new_lump_after(lump,suffix,suffix_len,HDR_CONTACT_T)) == 0) { LM_ERR("failed inserting '<sip:'\n"); goto error; } // LM_DBG("Replaced contact with [%.*s]\n", local_contact.len, local_contact.s); return 0; error: if (prefix) pkg_free(prefix); if (suffix) pkg_free(suffix); return -1; }