From 8e581a3ebe71eedb41ac7a41538e6b1b2b391744 Mon Sep 17 00:00:00 2001 From: Daniel-Constantin Mierla Date: Sun, 2 Sep 2018 12:33:17 +0200 Subject: [PATCH] core: functions to apply changes and update internal sip msg buffer --- src/core/msg_translator.c | 103 ++++++++++++++++++++++++++++++++++++++ src/core/msg_translator.h | 11 ++++ 2 files changed, 114 insertions(+) diff --git a/src/core/msg_translator.c b/src/core/msg_translator.c index f82d72c3cb7..6929b22e0fe 100644 --- a/src/core/msg_translator.c +++ b/src/core/msg_translator.c @@ -3176,3 +3176,106 @@ int build_sip_msg_from_buf(struct sip_msg *msg, char *buf, int len, return 0; } +/** + * + */ +int sip_msg_update_buffer(sip_msg_t *msg, str *obuf) +{ + sip_msg_t tmp; + + if(obuf==NULL || obuf->s==NULL || obuf->len<=0) { + LM_ERR("invalid buffer parameter\n"); + return -1; + } + + if(obuf->len >= BUF_SIZE) { + LM_ERR("new buffer is too large (%d)\n", obuf->len); + return -1; + } + /* temporary copy */ + memcpy(&tmp, msg, sizeof(sip_msg_t)); + + /* reset dst uri and path vector to avoid freeing - restored later */ + if(msg->dst_uri.s != NULL) { + msg->dst_uri.s = NULL; + msg->dst_uri.len = 0; + } + if(msg->path_vec.s != NULL) { + msg->path_vec.s = NULL; + msg->path_vec.len = 0; + } + + /* free old msg structure */ + free_sip_msg(msg); + memset(msg, 0, sizeof(sip_msg_t)); + + /* restore msg fields */ + msg->buf = tmp.buf; + msg->id = tmp.id; + msg->rcv = tmp.rcv; + msg->set_global_address = tmp.set_global_address; + msg->set_global_port = tmp.set_global_port; + msg->flags = tmp.flags; + msg->msg_flags = tmp.msg_flags; + msg->hash_index = tmp.hash_index; + msg->force_send_socket = tmp.force_send_socket; + msg->fwd_send_flags = tmp.fwd_send_flags; + msg->rpl_send_flags = tmp.rpl_send_flags; + msg->dst_uri = tmp.dst_uri; + msg->path_vec = tmp.path_vec; + + memcpy(msg->buf, obuf->s, obuf->len); + msg->len = obuf->len; + msg->buf[msg->len] = '\0'; + + /* reparse the message */ + LM_DBG("SIP message content updated - reparsing\n"); + if(parse_msg(msg->buf, msg->len, msg) != 0) { + LM_ERR("parsing new sip message failed [[%.*s]]\n", msg->len, msg->buf); + /* exit config execution - sip_msg_t structure is no longer + * valid/safe for config */ + return 0; + } + + return 1; +} + +/** + * + */ +int sip_msg_apply_changes(sip_msg_t *msg) +{ + int ret; + dest_info_t dst; + str obuf; + + if(msg->first_line.type != SIP_REPLY && get_route_type() != REQUEST_ROUTE) { + LM_ERR("invalid usage - not in request route or a reply\n"); + return -1; + } + + init_dest_info(&dst); + dst.proto = PROTO_UDP; + if(msg->first_line.type == SIP_REPLY) { + obuf.s = generate_res_buf_from_sip_res( + msg, (unsigned int *)&obuf.len, BUILD_NO_VIA1_UPDATE); + } else { + if(msg->msg_flags & FL_RR_ADDED) { + LM_ERR("cannot apply msg changes after adding record-route" + " header - it breaks conditional 2nd header\n"); + return -1; + } + obuf.s = build_req_buf_from_sip_req(msg, (unsigned int *)&obuf.len, + &dst, + BUILD_NO_PATH | BUILD_NO_LOCAL_VIA | BUILD_NO_VIA1_UPDATE); + } + if(obuf.s == NULL) { + LM_ERR("couldn't update msg buffer content\n"); + return -1; + } + ret = sip_msg_update_buffer(msg, &obuf); + /* free new buffer - copied in the static buffer from old sip_msg_t */ + pkg_free(obuf.s); + + return ret; +} diff --git a/src/core/msg_translator.h b/src/core/msg_translator.h index d95c89f5e46..b6360ce3ff3 100644 --- a/src/core/msg_translator.h +++ b/src/core/msg_translator.h @@ -180,4 +180,15 @@ void process_lumps( struct sip_msg* msg, unsigned int* orig_offs, struct dest_info* send_info, int flag); + +/** + * set the internal buffer for sip msg with obuf and reparse + */ +int sip_msg_update_buffer(sip_msg_t *msg, str *obuf); + +/** + * apply changes to sip msg buffer and reparse + */ +int sip_msg_apply_changes(sip_msg_t *msg); + #endif