static int inherit_from_default_head(ds_db_head_t *head) { unsigned int i; if (head == &default_db_head) return 0; for (i = 0; i < partition_param_count; ++i) { str *def_param = partition_params[i].getter_func(&default_db_head); str *p_param = partition_params[i].getter_func(head); if (p_param->len == 0 && def_param->len > 0) { /* Paramater not specified for function */ if (strstr(partition_params[i].name.s, "avp") && def_param->len > 0) { char *avp_end = q_memrchr(def_param->s, ')', def_param->len); if (avp_end == NULL) { LM_ERR ("wrong avp name %.*s\n", def_param->len, def_param->s); return -1; } p_param->len = def_param->len + 1 + head->partition_name.len; p_param->s = pkg_malloc(p_param->len); if (p_param->s == NULL) { LM_ERR ("no more private memory\n"); return -1; } int fix_len = avp_end - def_param->s; int rem_len = def_param->len - fix_len; memcpy(p_param->s, def_param->s, fix_len); p_param->s[fix_len] = '_'; memcpy(p_param->s + fix_len + 1, head->partition_name.s, head->partition_name.len); memcpy(p_param->s + fix_len + 1 + head->partition_name.len, def_param->s + fix_len, rem_len); } else memcpy(p_param, def_param, sizeof(str)); } } return 0; }
/* * Create a request */ char* build_uac_req(str* method, str* headers, str* body, dlg_t* dialog, int branch, struct cell *t, int* len, struct dest_info* dst) { char* buf, *w, *p; str content_length, cseq, via; unsigned int maxfwd_len; int tbracket, fbracket; str fromtag = STR_NULL; str loc_tag = STR_NULL; if (!method || !dialog) { LM_ERR("invalid parameter value\n"); return 0; } if (dialog->id.loc_tag.len<=0) { /* From Tag is mandatory in RFC3261 - generate one if not provided */ generate_fromtag(&fromtag, &dialog->id.call_id); loc_tag = dialog->id.loc_tag; dialog->id.loc_tag = fromtag; } if (print_content_length(&content_length, body) < 0) { LM_ERR("error while printing content-length\n"); return 0; } if (print_cseq_num(&cseq, dialog) < 0) { LM_ERR("error while printing CSeq number\n"); return 0; } if(headers==NULL || headers->len<15 || _strnstr(headers->s, "Max-Forwards:", headers->len)==NULL) { maxfwd_len = MAXFWD_HEADER_LEN; } else { maxfwd_len = 0; } *len = method->len + 1 + dialog->hooks.request_uri->len + 1 + SIP_VERSION_LEN + CRLF_LEN; if (assemble_via(&via, t, dst, branch) < 0) { LM_ERR("error while assembling Via\n"); return 0; } *len += via.len; if((p=q_memrchr(dialog->rem_uri.s, '>', dialog->rem_uri.len))!=NULL) { if((p==dialog->rem_uri.s + dialog->rem_uri.len - 1) || *(p+1)==';') { tbracket = 0; } else { tbracket = 1; } } else { tbracket = 1; } if((p=q_memrchr(dialog->loc_uri.s, '>', dialog->loc_uri.len))!=NULL) { if((p==dialog->loc_uri.s + dialog->loc_uri.len - 1) || *(p+1)==';') { fbracket = 0; } else { fbracket = 1; } } else { fbracket = 1; } *len += TO_LEN + dialog->rem_uri.len + (dialog->id.rem_tag.len ? (TOTAG_LEN + dialog->id.rem_tag.len) : 0) + CRLF_LEN; /* To */ if(tbracket) *len += 2; /* To-URI < > */ *len += FROM_LEN + dialog->loc_uri.len + (dialog->id.loc_tag.len ? (FROMTAG_LEN + dialog->id.loc_tag.len) : 0) + CRLF_LEN; /* From */ if(fbracket) *len += 2; /* From-URI < > */ *len += CALLID_LEN + dialog->id.call_id.len + CRLF_LEN; /* Call-ID */ *len += CSEQ_LEN + cseq.len + 1 + method->len + CRLF_LEN; /* CSeq */ *len += calculate_routeset_length(dialog); /* Route set */ *len += maxfwd_len; /* Max-forwards */ *len += CONTENT_LENGTH_LEN + content_length.len + CRLF_LEN; /* Content-Length */ *len += ((server_signature && user_agent_hdr.len>0) ? (user_agent_hdr.len + CRLF_LEN) : 0); /* Signature */ if(headers && headers->len>2) { /* Additional headers */ *len += headers->len; /* End of header if missing */ if(headers->s[headers->len - 1] != '\n') *len += CRLF_LEN; } *len += (body ? body->len : 0); /* Message body */ *len += CRLF_LEN; /* End of Header */ buf = shm_malloc(*len + 1); if (!buf) { LM_ERR("no more shared memory (%d)\n", *len); goto error; } w = buf; w = print_request_uri(w, method, dialog, t, branch); /* Request-URI */ memapp(w, via.s, via.len); /* Top-most Via */ w = print_to(w, dialog, t, tbracket); /* To */ w = print_from(w, dialog, t, fbracket); /* From */ if(fromtag.len>0) { dialog->id.loc_tag = loc_tag; } w = print_cseq(w, &cseq, method, t); /* CSeq */ w = print_callid(w, dialog, t); /* Call-ID */ w = print_routeset(w, dialog); /* Route set */ if(maxfwd_len>0) memapp(w, MAXFWD_HEADER, MAXFWD_HEADER_LEN); /* Max-forwards */ /* Content-Length */ memapp(w, CONTENT_LENGTH, CONTENT_LENGTH_LEN); memapp(w, content_length.s, content_length.len); memapp(w, CRLF, CRLF_LEN); /* Server signature */ if (server_signature && user_agent_hdr.len>0) { memapp(w, user_agent_hdr.s, user_agent_hdr.len); memapp(w, CRLF, CRLF_LEN); } if(headers && headers->len>2) { memapp(w, headers->s, headers->len); if(headers->s[headers->len - 1] != '\n') memapp(w, CRLF, CRLF_LEN); } memapp(w, CRLF, CRLF_LEN); if (body) memapp(w, body->s, body->len); #ifdef EXTRA_DEBUG assert(w-buf == *len); #endif memapp(w, "\0", 1); pkg_free(via.s); return buf; error: pkg_free(via.s); return 0; }
inline static int w_t_new_request(struct sip_msg* msg, char *p_method, char *p_ruri, char *p_from, char *p_to, char *p_body, char *p_ctx) { #define CONTENT_TYPE_HDR "Content-Type: " #define CONTENT_TYPE_HDR_LEN (sizeof(CONTENT_TYPE_HDR)-1) static dlg_t dlg; struct usr_avp **avp_list; str ruri; str method; str body; str headers; str s; int_str ctx; char *p; memset( &dlg, 0, sizeof(dlg_t)); /* evaluate the parameters */ /* method */ if ( fixup_get_svalue(msg, (gparam_p)p_method, &method)<0 ) { LM_ERR("failed to extract METHOD param\n"); return -1; } LM_DBG("setting METHOD to <%.*s>\n", method.len, method.s); /* ruri - next hop is the same as RURI */ dlg.hooks.next_hop = dlg.hooks.request_uri = &ruri; if ( fixup_get_svalue(msg, (gparam_p)p_ruri, &ruri)<0 ) { LM_ERR("failed to extract RURI param\n"); return -1; } LM_DBG("setting RURI to <%.*s>\n", dlg.hooks.next_hop->len, dlg.hooks.next_hop->s); /* FROM URI + display */ if ( fixup_get_svalue(msg, (gparam_p)p_from, &s)<0 ) { LM_ERR("failed to extract FROM param\n"); return -1; } if ( (p=q_memrchr(s.s, ' ', s.len))==NULL ) { /* no display, only FROM URI */ dlg.loc_uri = s; dlg.loc_dname.s = NULL; dlg.loc_dname.len = 0; } else { /* display + URI */ dlg.loc_uri.s = p+1; dlg.loc_uri.len = s.s+s.len - dlg.loc_uri.s; dlg.loc_dname.s = s.s; dlg.loc_dname.len = p - s.s; } LM_DBG("setting FROM to <%.*s> + <%.*s>\n", dlg.loc_dname.len, dlg.loc_dname.s, dlg.loc_uri.len, dlg.loc_uri.s); /* TO URI + display */ if ( fixup_get_svalue(msg, (gparam_p)p_to, &s)<0 ) { LM_ERR("failed to extract TO param\n"); return -1; } if ( (p=q_memrchr(s.s, ' ', s.len))==NULL ) { /* no display, only TO URI */ dlg.rem_uri = s; dlg.rem_dname.s = NULL; dlg.rem_dname.len = 0; } else { /* display + URI */ dlg.rem_uri.s = p+1; dlg.rem_uri.len = s.s+s.len - dlg.rem_uri.s; dlg.rem_dname.s = s.s; dlg.rem_dname.len = p - s.s; } LM_DBG("setting TO to <%.*s> + <%.*s>\n", dlg.rem_dname.len, dlg.rem_dname.s, dlg.rem_uri.len, dlg.rem_uri.s); /* BODY and Content-Type */ if (p_body!=NULL) { if ( fixup_get_svalue(msg, (gparam_p)p_body, &body)<0 ) { LM_ERR("failed to extract BODY param\n"); return -1; } if ( (p=q_memchr(body.s, ' ', body.len))==NULL ) { LM_ERR("Content Type not found in the beginning of body <%.*s>\n", body.len, body.s); return -1; } /* build the Content-type header */ headers.len = CONTENT_TYPE_HDR_LEN + (p-body.s) + CRLF_LEN; if ( (headers.s=(char*)pkg_malloc(headers.len))==NULL ) { LM_ERR("failed to get pkg mem (needed %d)\n",headers.len); return -1; } memcpy( headers.s, CONTENT_TYPE_HDR, CONTENT_TYPE_HDR_LEN); memcpy( headers.s+CONTENT_TYPE_HDR_LEN, body.s, p-body.s); memcpy( headers.s+CONTENT_TYPE_HDR_LEN+(p-body.s), CRLF, CRLF_LEN); /* set the body */ body.len = body.s + body.len - (p+1); body.s = p + 1; LM_DBG("setting BODY to <%.*s> <%.*s>\n", headers.len, headers.s, body.len, body.s ); } else { body.s = NULL; body.len = 0; headers.s = NULL; headers.len = 0; } /* context value */ if (p_ctx!=NULL) { if ( fixup_get_svalue(msg, (gparam_p)p_ctx, &ctx.s)<0 ) { LM_ERR("failed to extract BODY param\n"); if (p_body) pkg_free(headers.s); return -1; } LM_DBG("setting CTX AVP to <%.*s>\n", ctx.s.len, ctx.s.s); avp_list = set_avp_list( &dlg.avps ); if (!add_avp( AVP_VAL_STR, uac_ctx_avp_id, ctx)) LM_ERR("failed to add ctx AVP, ignorring...\n"); set_avp_list( avp_list ); } /* add cseq */ dlg.loc_seq.value = DEFAULT_CSEQ; dlg.loc_seq.is_set = 1; /* add callid */ generate_callid(&dlg.id.call_id); /* add FROM tag */ generate_fromtag(&dlg.id.loc_tag, &dlg.id.call_id); /* TO tag is empty as this is a initial request */ dlg.id.rem_tag.s = NULL; dlg.id.rem_tag.len = 0; /* do the actual sending now */ if ( t_uac( &method, headers.s?&headers:NULL, body.s?&body:NULL, &dlg, 0, 0, 0) <= 0 ) { LM_ERR("failed to send the request out\n"); if (headers.s) pkg_free(headers.s); if (dlg.avps) destroy_avp_list(&dlg.avps); return -1; } /* success -> do cleanup */ if (headers.s) pkg_free(headers.s); return 1; }