diff --git a/core/SipCtrlInterface.cpp b/core/SipCtrlInterface.cpp index fa861e52..5dc1c314 100644 --- a/core/SipCtrlInterface.cpp +++ b/core/SipCtrlInterface.cpp @@ -753,7 +753,7 @@ void SipCtrlInterface::handle_reply_timeout(AmSipTimeoutEvent::EvType evt, break; case AmSipTimeoutEvent::noPRACK: { - sip_msg msg(tr->retr_buf, tr->retr_len); + sip_msg msg(tr->retr_buf->c_str(), tr->retr_buf->length()); char* err_msg=0; int err = parse_sip_msg(&msg, err_msg); diff --git a/core/sip/msg_fline.cpp b/core/sip/msg_fline.cpp index 0ac50f0c..46d611ee 100644 --- a/core/sip/msg_fline.cpp +++ b/core/sip/msg_fline.cpp @@ -33,50 +33,45 @@ #include #include -inline void status_code_wr(char** c, int code) +inline void status_code_wr(string& c, int code) { div_t d = div(code, 100); - *((*c)++) = d.quot + '0'; + c += d.quot + '0'; d = div(d.rem, 10); - *((*c)++) = d.quot + '0'; - *((*c)++) = d.rem + '0'; + c += d.quot + '0'; + c += d.rem + '0'; } -void status_line_wr(char** c, int status_code, +void status_line_wr(string& c, int status_code, const cstring& reason) { - memcpy(*c,"SIP/2.0 ",8); - *c += 8; - + c += "SIP/2.0 "; + status_code_wr(c,status_code); - *((*c)++) = SP; + c += SP; - memcpy(*c,reason.s,reason.len); - *c += reason.len; + c += c2stlstr(reason); - *((*c)++) = CR; - *((*c)++) = LF; + c += CR; + c += LF; } -void request_line_wr(char** c, +void request_line_wr(string& c, const cstring& method, const cstring& ruri) { - memcpy(*c,method.s,method.len); - *c += method.len; - - *((*c)++) = SP; - - memcpy(*c,ruri.s,ruri.len); - *c += ruri.len; - - memcpy(*c," SIP/2.0",8); - *c += 8; - - *((*c)++) = CR; - *((*c)++) = LF; + c += c2stlstr(method); + + c += SP; + + c += c2stlstr(ruri); + + c += " SIP/2.0"; + + c += CR; + c += LF; } diff --git a/core/sip/msg_fline.h b/core/sip/msg_fline.h index c0f1b98e..d1444ad7 100644 --- a/core/sip/msg_fline.h +++ b/core/sip/msg_fline.h @@ -34,33 +34,16 @@ #include "cstring.h" #include "parse_common.h" -struct sip_msg; +#include +using std::string; -// -// Request-line builder -// -inline int request_line_len(const cstring& method, - const cstring& ruri) -{ - return method.len + ruri.len + SIPVER_len - + 4; // 2*SP + CRLF -} +struct sip_msg; -void request_line_wr(char** c, +void request_line_wr(string& c, const cstring& method, const cstring& ruri); -// -// Status-line builder -// -inline int status_line_len(const cstring& reason) -{ - return SIPVER_len + 3/*status code*/ - + reason.len - + 4; // 2*SP + CRLF -} - -void status_line_wr(char** c, int status_code, +void status_line_wr(string& c, int status_code, const cstring& reason); diff --git a/core/sip/msg_hdrs.cpp b/core/sip/msg_hdrs.cpp index ef182f8b..8dc957e1 100644 --- a/core/sip/msg_hdrs.cpp +++ b/core/sip/msg_hdrs.cpp @@ -31,63 +31,14 @@ #include "msg_hdrs.h" -int copy_hdrs_len(const list& hdrs) -{ - int ret = 0; - - list::const_iterator it = hdrs.begin(); - for(;it != hdrs.end(); ++it){ - ret += copy_hdr_len(*it); - } - - return ret; -} - -int copy_hdrs_len_no_via(const list& hdrs) -{ - int ret = 0; - - list::const_iterator it = hdrs.begin(); - for(;it != hdrs.end(); ++it){ - - if((*it)->type == sip_header::H_VIA) - continue; - - ret += copy_hdr_len(*it); - } - - return ret; -} - -int copy_hdrs_len_no_via_contact(const list& hdrs) -{ - int ret = 0; - - list::const_iterator it = hdrs.begin(); - for(;it != hdrs.end(); ++it){ - - switch((*it)->type) { - case sip_header::H_VIA: - case sip_header::H_CONTACT: - continue; - - default: - ret += copy_hdr_len(*it); - break; - } - } - - return ret; -} - -void copy_hdrs_wr(char** c, const list& hdrs) +void copy_hdrs_wr(string& c, const list& hdrs) { list::const_iterator it = hdrs.begin(); for(;it != hdrs.end(); ++it) copy_hdr_wr(c,*it); } -void copy_hdrs_wr_no_via(char** c, const list& hdrs) +void copy_hdrs_wr_no_via(string& c, const list& hdrs) { list::const_iterator it = hdrs.begin(); for(;it != hdrs.end(); ++it) { @@ -99,7 +50,7 @@ void copy_hdrs_wr_no_via(char** c, const list& hdrs) } } -void copy_hdrs_wr_no_via_contact(char** c, const list& hdrs) +void copy_hdrs_wr_no_via_contact(string& c, const list& hdrs) { list::const_iterator it = hdrs.begin(); for(;it != hdrs.end(); ++it){ diff --git a/core/sip/msg_hdrs.h b/core/sip/msg_hdrs.h index 9de2d958..0032db0f 100644 --- a/core/sip/msg_hdrs.h +++ b/core/sip/msg_hdrs.h @@ -34,156 +34,99 @@ #include "parse_common.h" #include "parse_via.h" -inline int copy_hdr_len(sip_header* hdr) -{ - return hdr->name.len + hdr->value.len - + 4/* ': ' + CRLF */; -} +#include +using std::string; -inline void copy_hdr_wr(char** c, const sip_header* hdr) +inline void copy_hdr_wr(string& c, const sip_header* hdr) { - memcpy(*c,hdr->name.s,hdr->name.len); - *c += hdr->name.len; - - *((*c)++) = ':'; - *((*c)++) = SP; - - memcpy(*c,hdr->value.s,hdr->value.len); - *c += hdr->value.len; - - *((*c)++) = CR; - *((*c)++) = LF; -} + c += c2stlstr(hdr->name); -inline int contact_len(const cstring& contact) -{ - return 11/*'Contact: ' + CRLF*/ - + contact.len; -} + c += ':'; + c += SP; -inline void contact_wr(char** c,const cstring& contact) -{ - memcpy(*c,"Contact: ",9); - *c += 9/*'Contact: '*/; - - memcpy(*c,contact.s,contact.len); - *c += contact.len; - - *((*c)++) = CR; - *((*c)++) = LF; + c += c2stlstr(hdr->value); + + c += CR; + c += LF; } -inline int via_len(const cstring& trsp, const cstring& addr, - const cstring& branch, bool rport) +inline void contact_wr(string& c,const cstring& contact) { - return 16/* 'Via: SIP/2.0/' + SP + CRLF */ - + trsp.len - + addr.len - + 8 + MAGIC_BRANCH_LEN/*';branch=' + MAGIC_BRANCH_COOKIE*/ - + branch.len - + (rport ? 6/*;rport*/ : 0 ); + c += "Contact: "; + + c += c2stlstr(contact); + + c += CR; + c += LF; } -inline void via_wr(char** c, const cstring& trsp, const cstring& addr, +inline void via_wr(string& c, const cstring& trsp, const cstring& addr, const cstring& branch, bool rport) { - memcpy(*c,"Via: SIP/2.0/",13); - *c += 13/*'Via: SIP/2.0/'*/; + c += "Via: SIP/2.0/"; for(unsigned int i=0; i= 'a' && trsp.s[i] <= 'z') - *((*c)++) = trsp.s[i] - 'a' + 'A'; + c += trsp.s[i] - 'a' + 'A'; } - - *((*c)++) = SP; - memcpy(*c,addr.s,addr.len); - *c += addr.len; + c += SP; + + c += c2stlstr(addr); - memcpy(*c,";branch=" MAGIC_BRANCH_COOKIE,8+MAGIC_BRANCH_LEN); - *c += 8+MAGIC_BRANCH_LEN; + c += ";branch=" MAGIC_BRANCH_COOKIE; + + c += c2stlstr(branch); - memcpy(*c,branch.s,branch.len); - *c += branch.len; - if(rport){ - memcpy(*c,";rport",6); - *c += 6; + c += ";rport"; } - *((*c)++) = CR; - *((*c)++) = LF; + c += CR; + c += LF; } -inline int cseq_len(const cstring& num, const cstring& method) +inline void cseq_wr(string& c, const cstring& num, const cstring& method) { - return 9/*'CSeq: ' + SP + CRLF*/ - + num.len + method.len; -} + c += "CSeq: "; -inline void cseq_wr(char** c, const cstring& num, const cstring& method) -{ - memcpy(*c,"CSeq: ",6); - *c += 6/*'CSeq: '*/; + c += c2stlstr(num); - memcpy(*c,num.s,num.len); - *c += num.len; + c += SP; - *((*c)++) = SP; - - memcpy(*c,method.s,method.len); - *c += method.len; - - *((*c)++) = CR; - *((*c)++) = LF; -} + c += c2stlstr(method); -inline int content_length_len(const cstring& len) -{ - return 18/*'Content-Length: ' + CRLF*/ - + len.len; + c += CR; + c += LF; } -inline void content_length_wr(char** c, const cstring& len) +inline void content_length_wr(string& c, const cstring& len) { - memcpy(*c,"Content-Length: ",16); - *c += 16/*'Content-Length: '*/; + c += "Content-Length: "; - memcpy(*c,len.s,len.len); - *c += len.len; + c += c2stlstr(len); - *((*c)++) = CR; - *((*c)++) = LF; + c += CR; + c += LF; } -inline int content_type_len(const cstring& len) +inline void content_type_wr(string& c, const cstring& len) { - return 16/*'Content-Type: ' + CRLF*/ - + len.len; -} + c += "Content-Type: "; -inline void content_type_wr(char** c, const cstring& len) -{ - memcpy(*c,"Content-Type: ",14); - *c += 14/*'Content-Type: '*/; + c += c2stlstr(len); - memcpy(*c,len.s,len.len); - *c += len.len; - - *((*c)++) = CR; - *((*c)++) = LF; + c += CR; + c += LF; } #include using std::list; -int copy_hdrs_len(const list& hdrs); -int copy_hdrs_len_no_via_contact(const list& hdrs); - -void copy_hdrs_wr(char** c, const list& hdrs); -void copy_hdrs_wr_no_via(char** c, const list& hdrs); -void copy_hdrs_wr_no_via_contact(char** c, const list& hdrs); +void copy_hdrs_wr(string& c, const list& hdrs); +void copy_hdrs_wr_no_via(string& c, const list& hdrs); +void copy_hdrs_wr_no_via_contact(string& c, const list& hdrs); #endif diff --git a/core/sip/sip_parser.cpp b/core/sip/sip_parser.cpp index 44f7290c..a0b681b4 100644 --- a/core/sip/sip_parser.cpp +++ b/core/sip/sip_parser.cpp @@ -43,7 +43,7 @@ #include using std::unique_ptr; -sip_msg::sip_msg(const char* msg_buf, int msg_len) +sip_msg::sip_msg(const char* msg_buf, size_t msg_len) : hdrs(), to(NULL), from(NULL), diff --git a/core/sip/sip_parser.h b/core/sip/sip_parser.h index 54ea7e7a..7bd147ae 100644 --- a/core/sip/sip_parser.h +++ b/core/sip/sip_parser.h @@ -139,7 +139,7 @@ struct sip_msg sockaddr_storage remote_ip; sip_msg(); - sip_msg(const char* msg_buf, int msg_len); + sip_msg(const char* msg_buf, size_t msg_len); ~sip_msg(); void copy_msg_buf(const char* msg_buf, int msg_len); diff --git a/core/sip/sip_trans.cpp b/core/sip/sip_trans.cpp index 8f7eb3b8..35e55fa9 100644 --- a/core/sip/sip_trans.cpp +++ b/core/sip/sip_trans.cpp @@ -76,7 +76,6 @@ sip_trans::sip_trans() last_rseq(0), targets(NULL), retr_buf(NULL), - retr_len(0), retr_addr{}, retr_socket(NULL), logger(NULL), @@ -89,7 +88,6 @@ sip_trans::~sip_trans() reset_all_timers(); delete msg; delete targets; - delete [] retr_buf; } /** @@ -97,13 +95,13 @@ sip_trans::~sip_trans() */ void sip_trans::retransmit() { - if(!retr_buf || !retr_len){ + if (!retr_buf) { // there is nothing to re-transmit yet!!! return; } assert(retr_socket); - int send_err = retr_socket->send(&retr_addr,retr_buf,retr_len,flags); + int send_err = retr_socket->send(&retr_addr, retr_buf->c_str(), retr_buf->size(), flags); if(send_err < 0){ ERROR("Error from transport layer\n"); } @@ -111,7 +109,7 @@ void sip_trans::retransmit() if(logger) { sockaddr_storage src_ip; retr_socket->copy_addr_to(&src_ip); - logger->log(retr_buf,retr_len, + logger->log(retr_buf->c_str(), retr_buf->length(), &src_ip,&retr_addr, msg->u.request->method_str, reply_status); @@ -277,7 +275,7 @@ void sip_trans::dump() const DBG("type=%s (0x%x); msg=%p; to_tag=%s;" " reply_status=%i; state=%s (%i); retr_buf=%p; timers [%s,%s,%s]\n", type_str(), type, msg, to_tag.c_str(), - reply_status,state_str(),state,retr_buf, + reply_status, state_str(), state, retr_buf.get(), timers[0]==NULL?"none":timer_name(timers[0]->type), timers[1]==NULL?"none":timer_name(timers[1]->type), timers[2]==NULL?"none":timer_name(timers[2]->type)); diff --git a/core/sip/sip_trans.h b/core/sip/sip_trans.h index 8823fc7f..0eda26b9 100644 --- a/core/sip/sip_trans.h +++ b/core/sip/sip_trans.h @@ -30,11 +30,12 @@ #ifndef _sip_trans_h #define _sip_trans_h -#include "cstring.h" #include "wheeltimer.h" #include +#include +using std::string; #include using std::list; #include @@ -143,10 +144,7 @@ class sip_trans * - UAC transaction: ACK * - UAS transaction: last reply */ - char* retr_buf; - - /** Length of the retransmission buffer */ - int retr_len; + shared_ptr retr_buf; /** Destination for retransmissions */ sockaddr_storage retr_addr; diff --git a/core/sip/trans_layer.cpp b/core/sip/trans_layer.cpp index 627d04be..ec760338 100644 --- a/core/sip/trans_layer.cpp +++ b/core/sip/trans_layer.cpp @@ -66,6 +66,9 @@ #include +using std::make_shared; +using std::string_view; + bool trans_layer::accept_fr_without_totag = false; unsigned int trans_layer::default_bl_ttl = DEFAULT_BL_TTL; @@ -280,7 +283,6 @@ int trans_layer::send_reply(sip_msg& msg, const trans_ticket& tt, } bool have_to_tag = false; - int reply_len = status_line_len(msg.u.reply->reason); // add 'received' should be added // check if first Via has rport parameter @@ -288,20 +290,15 @@ int trans_layer::send_reply(sip_msg& msg, const trans_ticket& tt, assert(req.via1); assert(req.via_p1); - unsigned int new_via1_len = copy_hdr_len(req.via1); string remote_ip_str = get_addr_str(&req.remote_ip); bool append_received = !(req.via_p1->host == remote_ip_str.c_str()); - if(append_received) { - new_via1_len += 10/*;received=*/ + remote_ip_str.length(); - } // needed if rport parameter was present but empty string remote_port_str; if(req.via_p1->has_rport) { if(!req.via_p1->rport.len){ remote_port_str = int2str(ntohs(((sockaddr_in*)&req.remote_ip)->sin_port)); - new_via1_len += remote_port_str.length() + 1/* "=" */; } } @@ -316,23 +313,10 @@ int trans_layer::send_reply(sip_msg& msg, const trans_ticket& tt, assert((*it)); switch((*it)->type){ - case sip_header::H_VIA: - // if first via, take the possibly modified one - if((*it) == req.via1) - reply_len += new_via1_len; - else - reply_len += copy_hdr_len(*it); - break; - case sip_header::H_TO: if (!(*it)->p) break; // ignore if not parsed if (!to_tag.empty()) { - if(! ((sip_from_to*)(*it)->p)->tag.len ) { - - reply_len += 5/* ';tag=' */ - + to_tag.length(); - } - else { + if (((sip_from_to*)(*it)->p)->tag.len) { // To-tag present in request... have_to_tag = true; // ... save it: @@ -345,14 +329,6 @@ int trans_layer::send_reply(sip_msg& msg, const trans_ticket& tt, // (necessary to match pre-RFC3261 non-200 ACKs) t->to_tag.clear(); } - reply_len += copy_hdr_len(*it); - break; - - case sip_header::H_FROM: - case sip_header::H_CALL_ID: - case sip_header::H_CSEQ: - case sip_header::H_RECORD_ROUTE: - reply_len += copy_hdr_len(*it); break; case sip_header::H_REQUIRE: @@ -389,26 +365,12 @@ int trans_layer::send_reply(sip_msg& msg, const trans_ticket& tt, } } - reply_len += copy_hdrs_len(msg.hdrs); - string c_len = int2str((unsigned int) msg.body.length()); - reply_len += content_length_len((char*)c_len.c_str()); - if(msg.body.length()){ - - reply_len += msg.body.length(); - } - - reply_len += 2/*CRLF*/; - - // Allocate buffer for the reply - // - char* reply_buf = new char[reply_len]; - char* c = reply_buf; + auto reply_buf = make_shared(); + string& reply_str = *reply_buf; // for convenience - DBG("reply_len = %i\n",reply_len); - - status_line_wr(&c,reply_code,msg.u.reply->reason); + status_line_wr(reply_str, reply_code, msg.u.reply->reason); for(list::iterator it = req.hdrs.begin(); it != req.hdrs.end(); ++it) { @@ -424,86 +386,72 @@ int trans_layer::send_reply(sip_msg& msg, const trans_ticket& tt, unsigned int len; - memcpy(c,(*it)->name.s,(*it)->name.len); - c += (*it)->name.len; - - *(c++) = ':'; - *(c++) = SP; - + reply_str += c2stlstr((*it)->name); + + reply_str += ':'; + reply_str += SP; + if(req.via_p1->has_rport && !req.via_p1->rport.len){ // copy everything from the beginning up to the "rport" param: len = (req.via_p1->rport.s + req.via_p1->rport.len) - req.via1->value.s; - memcpy(c,req.via1->value.s,len); - c += len; + reply_str += string_view(req.via1->value.s, len); // add '=' - *(c++) = '='; + reply_str += '='; // add the remote port - memcpy(c,remote_port_str.c_str(),remote_port_str.length()); - c += remote_port_str.length(); + reply_str += remote_port_str; //copy up to the end of the first Via parm len = req.via_p1->eop - (req.via_p1->rport.s + req.via_p1->rport.len); - memcpy(c,req.via_p1->rport.s + req.via_p1->rport.len, len); - c += len; + reply_str += string_view(req.via_p1->rport.s + req.via_p1->rport.len, len); } else { //copy up to the end of the first Via parm len = req.via_p1->eop - req.via1->value.s; - memcpy(c,req.via1->value.s,len); - c += len; + reply_str += string_view(req.via1->value.s, len); } if(append_received) { - - memcpy(c,";received=",10); - c += 10; - - memcpy(c,remote_ip_str.c_str(),remote_ip_str.length()); - c += remote_ip_str.length(); + reply_str += ";received="; + reply_str += remote_ip_str; } //copy the rest of the first Via header len = req.via1->value.s + req.via1->value.len - req.via_p1->eop; - memcpy(c,req.via_p1->eop,len); - c += len; + reply_str += string_view(req.via_p1->eop, len); - *(c++) = CR; - *(c++) = LF; + reply_str += CR; + reply_str += LF; } else { - copy_hdr_wr(&c,*it); + copy_hdr_wr(reply_str, *it); } break; case sip_header::H_TO: if (!(*it)->p) break; // ignore if not parsed - if (to_tag.empty() || have_to_tag){ - copy_hdr_wr(&c,*it); + if (to_tag.empty() || have_to_tag) { + copy_hdr_wr(reply_str, *it); } else { - memcpy(c,(*it)->name.s,(*it)->name.len); - c += (*it)->name.len; + reply_str += c2stlstr((*it)->name); - *(c++) = ':'; - *(c++) = SP; + reply_str += ':'; + reply_str += SP; - memcpy(c,(*it)->value.s,(*it)->value.len); - c += (*it)->value.len; + reply_str += c2stlstr((*it)->value); - memcpy(c,";tag=",5); - c += 5; + reply_str += ";tag="; t->to_tag = to_tag; - memcpy(c, to_tag.c_str(), to_tag.length()); - c += to_tag.length(); + reply_str += to_tag; - *(c++) = CR; - *(c++) = LF; + reply_str += CR; + reply_str += LF; } break; @@ -511,20 +459,20 @@ int trans_layer::send_reply(sip_msg& msg, const trans_ticket& tt, case sip_header::H_CALL_ID: case sip_header::H_CSEQ: case sip_header::H_RECORD_ROUTE: - copy_hdr_wr(&c,*it); + copy_hdr_wr(reply_str, *it); break; } } - copy_hdrs_wr(&c,msg.hdrs); - content_length_wr(&c,(char*)c_len.c_str()); + copy_hdrs_wr(reply_str, msg.hdrs); + content_length_wr(reply_str, (char*)c_len.c_str()); - *c++ = CR; - *c++ = LF; + reply_str += CR; + reply_str += LF; - if(msg.body.length()){ - memcpy(c, msg.body.c_str(), msg.body.length()); - } + reply_str += msg.body; + + DBG("reply_len = %zu\n", reply_str.length()); int err = -1; @@ -535,7 +483,6 @@ int trans_layer::send_reply(sip_msg& msg, const trans_ticket& tt, if(!local_socket) { ERROR("request to be replied has no transport socket set\n"); - delete [] reply_buf; goto end; } @@ -548,7 +495,6 @@ int trans_layer::send_reply(sip_msg& msg, const trans_ticket& tt, if (resolver::instance()->str2ip(via_host.c_str(), &remote_ip, (address_type)(IPv4 | IPv6)) != 1) { ERROR("Invalid via_host '%s'\n", via_host.c_str()); - delete [] reply_buf; goto end; } } @@ -580,17 +526,15 @@ int trans_layer::send_reply(sip_msg& msg, const trans_ticket& tt, DBG("Sending to %s:%i <%.*s...>\n", get_addr_str(&remote_ip).c_str(), ntohs(((sockaddr_in*)&remote_ip)->sin_port), - 50 /* preview - instead of p_msg->len */,reply_buf); + (int) std::min(50, reply_str.length()) /* preview - instead of p_msg->len */, reply_str.c_str()); //TODO: pass send-flags down to here - err = local_socket->send(&remote_ip,reply_buf,reply_len,0); + err = local_socket->send(&remote_ip, reply_str.c_str(), reply_str.length(), 0); if(err < 0){ ERROR("could not send to %s:%i <%.*s...>\n", get_addr_str(&remote_ip).c_str(), ntohs(((sockaddr_in*)&remote_ip)->sin_port), - 50 /* preview - instead of p_msg->len */,reply_buf); - - delete [] reply_buf; + (int) std::min(50, reply_str.length()) /* preview - instead of p_msg->len */, reply_str.c_str()); if(!local_socket->is_reliable()) { // set timer to capture retransmissions @@ -606,21 +550,14 @@ int trans_layer::send_reply(sip_msg& msg, const trans_ticket& tt, stats.inc_sent_replies(); - if (t->retr_buf) { - // delete old retry-buffer - // before overwriting it - delete [] t->retr_buf; - } - t->retr_buf = reply_buf; - t->retr_len = reply_len; memcpy(&t->retr_addr,&remote_ip,sizeof(sockaddr_storage)); t->retr_socket = local_socket; if(logger) { sockaddr_storage src_ip; local_socket->copy_addr_to(&src_ip); - logger->log(reply_buf,reply_len,&src_ip,&remote_ip, + logger->log(reply_str.c_str(), reply_str.length(), &src_ip, &remote_ip, req.u.request->method_str,reply_code); if(!t->logger){ @@ -689,7 +626,6 @@ int trans_layer::send_sl_reply(sip_msg* req, int reply_code, assert(req); bool have_to_tag = false; - int reply_len = status_line_len(reason); for(list::iterator it = req->hdrs.begin(); it != req->hdrs.end(); ++it) { @@ -699,44 +635,19 @@ int trans_layer::send_sl_reply(sip_msg* req, int reply_code, case sip_header::H_TO: - if((!(*it)->p) || (!((sip_from_to*)(*it)->p)->tag.len) ) { - - reply_len += 5/* ';tag=' */ - + SL_TOTAG_LEN; - } - else { + if ((*it)->p && ((sip_from_to*)(*it)->p)->tag.len) { // To-tag present in request have_to_tag = true; } - // fall-through-trap - case sip_header::H_FROM: - case sip_header::H_CALL_ID: - case sip_header::H_CSEQ: - case sip_header::H_VIA: - case sip_header::H_RECORD_ROUTE: - reply_len += copy_hdr_len(*it); break; } } - reply_len += hdrs.len; - string c_len = int2str(body.len); - reply_len += content_length_len((char*)c_len.c_str()); - - if(body.len){ - - reply_len += body.len; - } - reply_len += 2/*CRLF*/; - - // Allocate buffer for the reply - // - char* reply_buf = new char[reply_len]; - char* c = reply_buf; + string reply_str; - status_line_wr(&c,reply_code,reason); + status_line_wr(reply_str, reply_code,reason); for(list::iterator it = req->hdrs.begin(); it != req->hdrs.end(); ++it) { @@ -746,28 +657,24 @@ int trans_layer::send_sl_reply(sip_msg* req, int reply_code, case sip_header::H_TO: if(have_to_tag){ - copy_hdr_wr(&c,*it); + copy_hdr_wr(reply_str, *it); } else { - memcpy(c,(*it)->name.s,(*it)->name.len); - c += (*it)->name.len; - - *(c++) = ':'; - *(c++) = SP; - - memcpy(c,(*it)->value.s,(*it)->value.len); - c += (*it)->value.len; - - memcpy(c,";tag=",5); - c += 5; + reply_str += c2stlstr((*it)->name); + + reply_str += ':'; + reply_str += SP; + + reply_str += c2stlstr((*it)->value); + + reply_str += ";tag="; char to_tag[SL_TOTAG_LEN]; compute_sl_to_tag(to_tag,req); - memcpy(c,to_tag,SL_TOTAG_LEN); - c += SL_TOTAG_LEN; + reply_str += string_view(to_tag, SL_TOTAG_LEN); - *(c++) = CR; - *(c++) = LF; + reply_str += CR; + reply_str += LF; } break; @@ -776,30 +683,28 @@ int trans_layer::send_sl_reply(sip_msg* req, int reply_code, case sip_header::H_CSEQ: case sip_header::H_VIA: case sip_header::H_RECORD_ROUTE: - copy_hdr_wr(&c,*it); + copy_hdr_wr(reply_str, *it); break; } } if (hdrs.len) { - memcpy(c,hdrs.s,hdrs.len); - c += hdrs.len; + reply_str += c2stlstr(hdrs); } - content_length_wr(&c,(char*)c_len.c_str()); + content_length_wr(reply_str, (char*)c_len.c_str()); - *c++ = CR; - *c++ = LF; + reply_str += CR; + reply_str += LF; if(body.len){ - - memcpy(c,body.s,body.len); + + reply_str += c2stlstr(body); } assert(req->local_socket); - int err = req->local_socket->send(&req->remote_ip,reply_buf,reply_len,0); - delete [] reply_buf; + int err = req->local_socket->send(&req->remote_ip, reply_str.c_str(), reply_str.length(), 0); stats.inc_sent_replies(); @@ -1103,9 +1008,6 @@ static int patch_ruri_with_remote_ip(string& n_uri, sip_msg* msg) static int generate_and_parse_new_msg(sip_msg* msg, sip_msg*& p_msg) { - int request_len = request_line_len(msg->u.request->method_str, - msg->u.request->ruri_str); - char branch_buf[BRANCH_BUF_LEN]; compute_branch(branch_buf,msg->callid->value,msg->cseq->value); cstring branch(branch_buf,BRANCH_BUF_LEN); @@ -1129,58 +1031,35 @@ static int generate_and_parse_new_msg(sip_msg* msg, sip_msg*& p_msg) patch_contact_transport(n_contacts.back(),trsp,*contact_buf_it); } - // add 'rport' parameter defaultwise? yes, for now - request_len += via_len(trsp,stl2cstr(via),branch,true); - - request_len += copy_hdrs_len(msg->vias); - request_len += copy_hdrs_len_no_via_contact(msg->hdrs); - request_len += copy_hdrs_len(n_contacts); - string content_len = int2str(msg->body.length()); - request_len += content_length_len(stl2cstr(content_len)); - request_len += 2/* CRLF end-of-headers*/; - - if (msg->body.length()) { - request_len += msg->body.length(); - } - // Allocate new message p_msg = new sip_msg(); - char* buf = new char[request_len+1]; + string& buf = p_msg->buf; // for convenience // generate it - char* c = buf; - request_line_wr(&c,msg->u.request->method_str, + request_line_wr(buf, msg->u.request->method_str, msg->u.request->ruri_str); - via_wr(&c,trsp,stl2cstr(via),branch,true); - copy_hdrs_wr(&c,msg->vias); - copy_hdrs_wr_no_via_contact(&c,msg->hdrs); + via_wr(buf, trsp, stl2cstr(via), branch, true); + copy_hdrs_wr(buf, msg->vias); + copy_hdrs_wr_no_via_contact(buf, msg->hdrs); - copy_hdrs_wr(&c,n_contacts); + copy_hdrs_wr(buf, n_contacts); free_headers(n_contacts); - content_length_wr(&c,stl2cstr(content_len)); + content_length_wr(buf, content_len.c_str()); - *c++ = CR; - *c++ = LF; + buf += CR; + buf += LF; - if (msg->body.length()) { - memcpy(c, msg->body.c_str(), msg->body.length()); - - c += msg->body.length(); - } - *c++ = '\0'; - - p_msg->buf = string(buf, request_len); - delete[] buf; + buf += msg->body; // and parse it char* err_msg=0; - if(parse_sip_msg(p_msg,err_msg)){ + if(parse_sip_msg(p_msg, err_msg)){ ERROR("Parser failed on generated request\n"); - ERROR("Message was: <%s>\n", p_msg->buf.c_str()); + ERROR("Message was: <%s>\n", buf.c_str()); delete p_msg; p_msg = NULL; return MALFORMED_SIP_MSG; @@ -1353,8 +1232,8 @@ int trans_layer::send_request(sip_msg* msg, trans_ticket* tt, if(tt->_t && (method == sip_request::ACK)) { // in case of ACK, p_msg gets deleted in update_uac_request - msg_buffer = tt->_t->retr_buf; - msg_len = tt->_t->retr_len; + msg_buffer = tt->_t->retr_buf->c_str(); + msg_len = tt->_t->retr_buf->length(); } /* p_msg could have been freed already by update_uac_request() */ else if (p_msg) { @@ -1462,56 +1341,34 @@ int trans_layer::cancel(trans_ticket* tt, const string& dialog_id, cstring cancel_str("CANCEL"); cstring zero("0"); - int request_len = request_line_len(cancel_str, - req->u.request->ruri_str); - - request_len += copy_hdr_len(req->via1); - - request_len += copy_hdr_len(req->to) - + copy_hdr_len(req->from) - + copy_hdr_len(req->callid) - + cseq_len(get_cseq(req)->num_str,cancel_str) - + copy_hdrs_len(req->route) - + copy_hdrs_len(req->contacts); - - request_len += hdrs.len; - request_len += content_length_len(zero); - request_len += 2/* CRLF end-of-headers*/; - // Allocate new message sip_msg* p_msg = new sip_msg(); - char* buf = new char[request_len+1]; + string& buf = p_msg->buf; // for convenience // generate it - char* c = buf; - request_line_wr(&c,cancel_str, + request_line_wr(buf, cancel_str, req->u.request->ruri_str); - copy_hdr_wr(&c,req->via1); - copy_hdr_wr(&c,req->to); - copy_hdr_wr(&c,req->from); - copy_hdr_wr(&c,req->callid); - cseq_wr(&c,get_cseq(req)->num_str,cancel_str); - copy_hdrs_wr(&c,req->route); - copy_hdrs_wr(&c,req->contacts); - - if (hdrs.len) { - memcpy(c,hdrs.s,hdrs.len); - c += hdrs.len; - } + copy_hdr_wr(buf, req->via1); + copy_hdr_wr(buf, req->to); + copy_hdr_wr(buf, req->from); + copy_hdr_wr(buf, req->callid); + cseq_wr(buf, get_cseq(req)->num_str,cancel_str); + copy_hdrs_wr(buf, req->route); + copy_hdrs_wr(buf, req->contacts); - content_length_wr(&c,zero); + buf += c2stlstr(hdrs); - *c++ = CR; - *c++ = LF; + content_length_wr(buf, zero); - p_msg->buf = string(buf, request_len); + buf += CR; + buf += LF; // and parse it char* err_msg=0; if(parse_sip_msg(p_msg,err_msg)){ ERROR("Parser failed on generated request\n"); - ERROR("Message was: <%s>\n", p_msg->buf.c_str()); + ERROR("Message was: <%s>\n", buf.c_str()); delete p_msg; bucket->unlock(); return MALFORMED_SIP_MSG; @@ -2067,13 +1924,10 @@ int trans_layer::update_uac_request(trans_bucket* bucket, sip_trans*& t, } DBG("update_uac_request(200 ACK, t=%p)\n", t); // clear old retransmission buffer - delete [] t->retr_buf; - - // transfer the message buffer + // and + // transfer the message buffer // to the transaction (incl. ownership) - t->retr_buf = new char[msg->buf.length() + 1]; - memcpy(t->retr_buf, msg->buf.c_str(), msg->buf.length() + 1); - t->retr_len = msg->buf.length(); + t->retr_buf.reset(new string(std::move(msg->buf))); msg->buf.clear(); // copy destination address @@ -2257,51 +2111,36 @@ int trans_layer::update_uas_request(trans_bucket* bucket, sip_trans* t, sip_msg* void trans_layer::send_non_200_ack(sip_msg* reply, sip_trans* t) { sip_msg* inv = t->msg; - - cstring method("ACK",3); - int ack_len = request_line_len(method,inv->u.request->ruri_str); - - ack_len += copy_hdr_len(inv->via1) - + copy_hdr_len(inv->from) - + copy_hdr_len(reply->to) - + copy_hdr_len(inv->callid); - - ack_len += cseq_len(get_cseq(inv)->num_str,method); - if(!inv->route.empty()) - ack_len += copy_hdrs_len(inv->route); + static constexpr string method("ACK"); cstring content_len("0"); - ack_len += content_length_len(content_len); - ack_len += 2/* EoH CRLF */; - - char* ack_buf = new char [ack_len]; - char* c = ack_buf; + string ack_buf; - request_line_wr(&c,method,inv->u.request->ruri_str); - - copy_hdr_wr(&c,inv->via1); + request_line_wr(ack_buf, stl2cstr(method), inv->u.request->ruri_str); - copy_hdr_wr(&c,inv->from); - copy_hdr_wr(&c,reply->to); - copy_hdr_wr(&c,inv->callid); - - cseq_wr(&c,get_cseq(inv)->num_str,method); + copy_hdr_wr(ack_buf, inv->via1); + + copy_hdr_wr(ack_buf, inv->from); + copy_hdr_wr(ack_buf, reply->to); + copy_hdr_wr(ack_buf, inv->callid); + + cseq_wr(ack_buf, get_cseq(inv)->num_str, stl2cstr(method)); if(!inv->route.empty()) - copy_hdrs_wr(&c,inv->route); + copy_hdrs_wr(ack_buf, inv->route); - content_length_wr(&c,content_len); - - *c++ = CR; - *c++ = LF; + content_length_wr(ack_buf, "0"); + + ack_buf += CR; + ack_buf += LF; DBG("About to send ACK\n"); assert(inv->local_socket); - int send_err = inv->local_socket->send(&inv->remote_ip,ack_buf, - ack_len,t->flags); + int send_err = inv->local_socket->send(&inv->remote_ip, ack_buf.c_str(), + ack_buf.length(), t->flags); if(send_err < 0){ ERROR("Error from transport layer\n"); } @@ -2310,11 +2149,8 @@ void trans_layer::send_non_200_ack(sip_msg* reply, sip_trans* t) if(t->logger) { sockaddr_storage src_ip; inv->local_socket->copy_addr_to(&src_ip); - t->logger->log(ack_buf,ack_len,&src_ip,&inv->remote_ip,method); + t->logger->log(ack_buf.c_str(), ack_buf.length(), &src_ip, &inv->remote_ip, stl2cstr(method)); } - - delete[] ack_buf; - } void trans_layer::timer_expired(trans_timer* t, trans_bucket* bucket, @@ -2424,7 +2260,7 @@ void trans_layer::timer_expired(trans_timer* t, trans_bucket* bucket, switch(tr->state) { case TS_PROCEEDING_REL: // missing PRACK for rel-1xx - assert(tr->retr_len); + assert(tr->retr_buf); tr->clear_timer(type); // stop retransmissions //signal timeout to UA ua->handle_reply_timeout(AmSipTimeoutEvent::noPRACK, tr, bucket);