int th_prepare_msg(sip_msg_t *msg) { if (parse_msg(msg->buf, msg->len, msg)!=0) { LM_DBG("outbuf buffer parsing failed!"); return 1; } if(msg->first_line.type==SIP_REQUEST) { if(!IS_SIP(msg)) { LM_DBG("non sip request message\n"); return 1; } } else if(msg->first_line.type!=SIP_REPLY) { LM_DBG("non sip message\n"); return 1; } if (parse_headers(msg, HDR_EOH_F, 0)==-1) { LM_DBG("parsing headers failed [[%.*s]]\n", msg->len, msg->buf); return 2; } /* force 2nd via parsing here - it helps checking it later */ if (parse_headers(msg, HDR_VIA2_F, 0)==-1 || (msg->via2==0) || (msg->via2->error!=PARSE_OK)) { LM_DBG("no second via in this message \n"); } if(parse_from_header(msg)<0) { LM_ERR("cannot parse FROM header\n"); return 3; } if(parse_to_header(msg)<0 || msg->to==NULL) { LM_ERR("cannot parse TO header\n"); return 3; } if(get_to(msg)==NULL) { LM_ERR("cannot get TO header\n"); return 3; } if(msg->via1==NULL || msg->callid==NULL) { LM_ERR("mandatory headers missing - via1: %p callid: %p\n", msg->via1, msg->callid); return 4; } return 0; }
int uac_reg_tmdlg(dlg_t *tmdlg, sip_msg_t *rpl) { if(tmdlg==NULL || rpl==NULL) return -1; if (parse_headers(rpl, HDR_EOH_F, 0) < 0) { LM_ERR("error while parsing all headers in the reply\n"); return -1; } if(parse_to_header(rpl)<0 || parse_from_header(rpl)<0) { LM_ERR("error while parsing From/To headers in the reply\n"); return -1; } memset(tmdlg, 0, sizeof(dlg_t)); str2int(&(get_cseq(rpl)->number), &tmdlg->loc_seq.value); tmdlg->loc_seq.is_set = 1; tmdlg->id.call_id = rpl->callid->body; trim(&tmdlg->id.call_id); if (get_from(rpl)->tag_value.len) { tmdlg->id.loc_tag = get_from(rpl)->tag_value; } #if 0 if (get_to(rpl)->tag_value.len) { tmdlg->id.rem_tag = get_to(rpl)->tag_value; } #endif tmdlg->loc_uri = get_from(rpl)->uri; tmdlg->rem_uri = get_to(rpl)->uri; tmdlg->state= DLG_CONFIRMED; return 0; }
sip_uri_t *parse_to_uri(sip_msg_t* const msg) { to_body_t *tb = NULL; if(msg==NULL) return NULL; if(parse_to_header(msg)<0) { LM_ERR("cannot parse TO header\n"); return NULL; } if(msg->to==NULL || get_to(msg)==NULL) return NULL; tb = get_to(msg); if(tb->parsed_uri.user.s!=NULL || tb->parsed_uri.host.s!=NULL) return &tb->parsed_uri; if (parse_uri(tb->uri.s, tb->uri.len , &tb->parsed_uri)<0) { LM_ERR("failed to parse To uri\n"); memset(&tb->parsed_uri, 0, sizeof(struct sip_uri)); return NULL; } return &tb->parsed_uri; }
static int sip_trace_prepare(sip_msg_t *msg) { if(parse_from_header(msg)==-1 || msg->from==NULL || get_from(msg)==NULL) { LM_ERR("cannot parse FROM header\n"); goto error; } if(parse_to_header(msg)==-1 || msg->to==NULL || get_to(msg)==NULL) { LM_ERR("cannot parse To header\n"); goto error; } if(parse_headers(msg, HDR_CALLID_F, 0)!=0 || msg->callid==NULL || msg->callid->body.s==NULL) { LM_ERR("cannot parse call-id\n"); goto error; } if(msg->cseq==NULL && ((parse_headers(msg, HDR_CSEQ_F, 0)==-1) || (msg->cseq==NULL))) { LM_ERR("cannot parse cseq\n"); goto error; } return 0; error: return -1; }
static int dlg_cseq_prepare_msg(sip_msg_t *msg) { LM_DBG("prepare msg for cseq update operations\n"); if(msg->first_line.type==SIP_REQUEST) { if(!IS_SIP(msg)) { LM_DBG("non sip request message\n"); return 1; } } else if(msg->first_line.type==SIP_REPLY) { if(!IS_SIP_REPLY(msg)) { LM_DBG("non sip reply message\n"); return 1; } } else { LM_DBG("non sip message\n"); return 1; } if((!msg->cseq && (parse_headers(msg,HDR_CSEQ_F,0)<0 || !msg->cseq)) || !msg->cseq->parsed){ LM_DBG("parsing cseq header failed\n"); return 2; } if(msg->first_line.type==SIP_REPLY) { /* reply to local transaction -- nothing to do */ if (parse_headers(msg, HDR_VIA2_F, 0)==-1 || (msg->via2==0) || (msg->via2->error!=PARSE_OK)) { if(get_cseq(msg)->method_id != METHOD_CANCEL) { LM_DBG("no second via in this message \n"); return 3; } } } if(parse_from_header(msg)<0) { LM_ERR("cannot parse FROM header\n"); return 3; } if(parse_to_header(msg)<0 || msg->to==NULL) { LM_ERR("cannot parse TO header\n"); return 3; } if(get_to(msg)==NULL) { LM_ERR("cannot get TO header\n"); return 3; } return 0; }
int dlg_cseq_prepare_msg(sip_msg_t *msg) { if (parse_msg(msg->buf, msg->len, msg)!=0) { LM_DBG("outbuf buffer parsing failed!"); return 1; } if(msg->first_line.type==SIP_REQUEST) { if(!IS_SIP(msg)) { LM_DBG("non sip request message\n"); return 1; } } else if(msg->first_line.type!=SIP_REPLY) { LM_DBG("non sip message\n"); return 1; } if (parse_headers(msg, HDR_CSEQ_F, 0)==-1) { LM_DBG("parsing cseq header failed\n"); return 2; } if(msg->first_line.type==SIP_REPLY) { /* reply to local transaction -- nothing to do */ if (parse_headers(msg, HDR_VIA2_F, 0)==-1 || (msg->via2==0) || (msg->via2->error!=PARSE_OK)) { LM_DBG("no second via in this message \n"); return 3; } } if(parse_from_header(msg)<0) { LM_ERR("cannot parse FROM header\n"); return 3; } if(parse_to_header(msg)<0 || msg->to==NULL) { LM_ERR("cannot parse TO header\n"); return 3; } if(get_to(msg)==NULL) { LM_ERR("cannot get TO header\n"); return 3; } return 0; }
int dlg_th_callid_pre_parse(struct sip_msg *msg,int want_from) { #ifdef CHANGEABLE_DEBUG_LEVEL int prev_dbg_level; #endif #ifdef CHANGEABLE_DEBUG_LEVEL prev_dbg_level = *debug; *debug = L_ALERT; #endif if (parse_msg(msg->buf,msg->len,msg)!=0) { LM_ERR("Invalid SIP msg\n"); goto error; } if (parse_headers(msg,HDR_EOH_F,0)<0) { LM_ERR("Failed to parse SIP headers\n"); goto error; } if (msg->cseq==NULL || get_cseq(msg)==NULL) { LM_ERR("Failed to parse CSEQ header\n"); goto error; } if((get_cseq(msg)->method_id)&MSG_SKIP_BITMASK) { LM_DBG("Skipping %d for DLG callid topo hiding\n",get_cseq(msg)->method_id); goto error; } if (parse_to_header(msg)<0 || msg->to==NULL || get_to(msg)==NULL) { LM_ERR("cannot parse TO header\n"); goto error; } if (parse_from_header(msg)<0 || msg->from==NULL || get_from(msg)==NULL) { LM_ERR("cannot parse TO header\n"); goto error; } #ifdef CHANGEABLE_DEBUG_LEVEL *debug = prev_dbg_level; #endif return 0; error: #ifdef CHANGEABLE_DEBUG_LEVEL *debug = prev_dbg_level; #endif return -1; }
int registered4(struct sip_msg* _m, udomain_t* _d, str* _uri, int match_flag, int match_action_flag) { str uri, aor; urecord_t* r; ucontact_t* ptr; int res; str match_callid = {0,0}; str match_received = {0,0}; str match_contact = {0,0}; sr_xavp_t *vavp = NULL; if(_uri!=NULL) { uri = *_uri; } else { if(IS_SIP_REPLY(_m)) { if (parse_to_header(_m) < 0) { LM_ERR("failed to prepare the message\n"); return -1; } uri = get_to(_m)->uri; } else { if (_m->new_uri.s) uri = _m->new_uri; else uri = _m->first_line.u.request.uri; } } if (extract_aor(&uri, &aor, NULL) < 0) { LM_ERR("failed to extract address of record\n"); return -1; } ul.lock_udomain(_d, &aor); res = ul.get_urecord(_d, &aor, &r); if (res < 0) { ul.unlock_udomain(_d, &aor); LM_ERR("failed to query usrloc\n"); return -1; } if (res == 0) { LM_DBG("searching with match flags (%d,%d)\n", match_flag, match_action_flag); if(reg_xavp_cfg.s!=NULL) { if((match_flag & 1) && (vavp = xavp_get_child_with_sval(®_xavp_cfg, &match_callid_name)) != NULL && vavp->val.v.s.len > 0) { match_callid = vavp->val.v.s; LM_DBG("matching with callid %.*s\n", match_callid.len, match_callid.s); } if((match_flag & 2) && (vavp = xavp_get_child_with_sval(®_xavp_cfg, &match_received_name)) != NULL && vavp->val.v.s.len > 0) { match_received = vavp->val.v.s; LM_DBG("matching with received %.*s\n", match_received.len, match_received.s); } if((match_flag & 4) && (vavp = xavp_get_child_with_sval(®_xavp_cfg, &match_contact_name)) != NULL && vavp->val.v.s.len > 0) { match_contact = vavp->val.v.s; LM_DBG("matching with contact %.*s\n", match_contact.len, match_contact.s); } } for (ptr = r->contacts; ptr; ptr = ptr->next) { if(!VALID_CONTACT(ptr, act_time)) continue; if (match_callid.s && /* optionally enforce tighter matching w/ Call-ID */ match_callid.len > 0 && (match_callid.len != ptr->callid.len || memcmp(match_callid.s, ptr->callid.s, match_callid.len))) continue; if (match_received.s && /* optionally enforce tighter matching w/ ip:port */ match_received.len > 0 && (match_received.len != ptr->received.len || memcmp(match_received.s, ptr->received.s, match_received.len))) continue; if (match_contact.s && /* optionally enforce tighter matching w/ Contact */ match_contact.len > 0 && (match_contact.len != ptr->c.len || memcmp(match_contact.s, ptr->c.s, match_contact.len))) continue; if(!(match_action_flag & 2)) { xavp_rcd_helper(ptr); } if((ptr->xavp!=NULL) && (match_action_flag & 1)) { sr_xavp_t *xavp = xavp_clone_level_nodata(ptr->xavp); if(xavp_add(xavp, NULL)<0) { LM_ERR("error adding xavp for %.*s after successful match\n", aor.len, ZSW(aor.s)); xavp_destroy_list(&xavp); } } ul.release_urecord(r); ul.unlock_udomain(_d, &aor); LM_DBG("'%.*s' found in usrloc\n", aor.len, ZSW(aor.s)); return 1; } } ul.unlock_udomain(_d, &aor); LM_DBG("'%.*s' not found in usrloc\n", aor.len, ZSW(aor.s)); return -1; }
static int has_to_tag(struct sip_msg* msg) { if (parse_to_header(msg) < 0) return 0; return (get_to(msg)->tag_value.len > 0) ? 1 : 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 dlg_th_post_raw(str *data) { struct sip_msg msg; struct dlg_cell *dlg; memset(&msg,0,sizeof(struct sip_msg)); msg.buf=data->s; msg.len=data->len; if (parse_msg(msg.buf,msg.len,&msg)!=0) { LM_ERR("Invalid SIP msg \n"); goto error; } if (parse_headers(&msg,HDR_EOH_F,0)<0) { LM_ERR("Failed to parse SIP headers\n"); goto error; } if (msg.cseq==NULL || get_cseq(&msg)==NULL) { LM_ERR("Failed to parse CSEQ header \n"); goto error; } if((get_cseq(&msg)->method_id)&MSG_SKIP_BITMASK) { LM_DBG("Skipping %d for DLG callid topo hiding\n",get_cseq(&msg)->method_id); goto error; } if (parse_to_header(&msg)<0 || msg.to==NULL || get_to(&msg)==NULL) { LM_ERR("cannot parse TO header\n"); goto error; } if (parse_from_header(&msg)<0 || msg.from==NULL || get_from(&msg)==NULL) { LM_ERR("cannot parse TO header\n"); goto error; } if (msg.first_line.type==SIP_REQUEST) { if (get_to(&msg)->tag_value.len>0) { /* sequential request, check if callid needs to be unmasked */ dlg = get_current_dialog(); if (dlg == NULL || (dlg->flags & DLG_FLAG_TOPH_HIDE_CALLID) == 0 ) { /* dialog module not involved or not callid topo hiding - let is pass freely */ } else { if (get_from(&msg)->tag_value.len != 0) { if (memcmp(get_from(&msg)->tag_value.s, dlg->legs[0].tag.s,dlg->legs[0].tag.len) == 0) { /* request from caller - need to encode callid */ if (dlg_th_encode_callid(&msg) < 0) { LM_ERR("Failed to mask callid for initial request \n"); goto error; } goto rebuild_req; } else { /* let request go through - was decoded on the in side */ } } else { /* no from tag in request - kinda foobar ? - let it through */ } } } else { /* initial request */ dlg = get_current_dialog(); if (dlg == NULL || (dlg->flags & DLG_FLAG_TOPH_HIDE_CALLID) == 0 ) { /* dialog module not involved or not callid topo hiding - let is pass freely */ } else { /* mask callid */ if (dlg_th_encode_callid(&msg) < 0) { LM_ERR("Failed to mask callid for initial request \n"); goto error; } goto rebuild_req; } } } else if (msg.first_line.type==SIP_REPLY) { /* we need to look at the direction */ dlg = get_current_dialog(); if (dlg == NULL || (dlg->flags & DLG_FLAG_TOPH_HIDE_CALLID) == 0 ) { /* dialog module not involved or not callid topo hiding - let is pass freely */ } else { if (get_from(&msg)->tag_value.len != 0) { if (memcmp(get_from(&msg)->tag_value.s, dlg->legs[0].tag.s,dlg->legs[0].tag.len) == 0) { /* reply going to caller - decode was done on the receiving end, let it unchanged */ } else { /* reply going to callee , need to encode callid */ if (dlg_th_encode_callid(&msg) < 0) { LM_ERR("Failed to decode callid for reply \n"); goto error; } goto rebuild_rpl; } } else { /* no from tag in reply - kinda foobar ? - let it through */ } } } free_sip_msg(&msg); return 0; rebuild_req: data->s = dlg_th_rebuild_req(&msg,&data->len); free_sip_msg(&msg); return 0; rebuild_rpl: data->s = dlg_th_rebuild_rpl(&msg,&data->len); free_sip_msg(&msg); return 0; error: free_sip_msg(&msg); return -1; }
int dlg_th_pre_raw(str *data) { struct sip_msg msg; memset(&msg,0,sizeof(struct sip_msg)); msg.buf=data->s; msg.len=data->len; if (parse_msg(msg.buf,msg.len,&msg)!=0) { LM_ERR("Invalid SIP msg \n"); goto error; } if (parse_headers(&msg,HDR_EOH_F,0)<0) { LM_ERR("Failed to parse SIP headers\n"); goto error; } if (msg.cseq==NULL || get_cseq(&msg)==NULL) { LM_ERR("Failed to parse CSEQ header \n"); goto error; } if((get_cseq(&msg)->method_id)&MSG_SKIP_BITMASK) { LM_DBG("Skipping %d for DLG callid topo hiding\n",get_cseq(&msg)->method_id); goto error; } if (parse_to_header(&msg)<0 || msg.to==NULL || get_to(&msg)==NULL) { LM_ERR("cannot parse TO header\n"); goto error; } if (msg.first_line.type==SIP_REQUEST) { if (get_to(&msg)->tag_value.len>0) { /* sequential request, check if callid needs to be unmasked */ if (dlg_th_needs_decoding(&msg)) { if (dlg_th_decode_callid(&msg) < 0) { LM_ERR("Failed to decode callid for sequential request \n"); goto error; } goto rebuild_msg; } } else { /* initial request, don't do anything callid masking will be done on the out side */ } } else if (msg.first_line.type==SIP_REPLY) { /* we might need to decode callid if mangled */ if (dlg_th_needs_decoding(&msg)) { if (dlg_th_decode_callid(&msg) < 0) { LM_ERR("Failed to decode callid for reply \n"); goto error; } goto rebuild_rpl; } else { /* encoding will be done on the out side */ } } else { /* non sip, most likely, let it through */ return 0; } free_sip_msg(&msg); return 0; rebuild_msg: data->s = dlg_th_rebuild_req(&msg,&data->len); free_sip_msg(&msg); return 0; rebuild_rpl: data->s = dlg_th_rebuild_rpl(&msg,&data->len); free_sip_msg(&msg); return 0; error: free_sip_msg(&msg); return -1; }