MT#62181 use std::string for string building

Automatic memory management and less error prone as it avoids manual
pointer manipulations.

No functional change.

Change-Id: Id35f4e4dc8918436589001db4acdf55ff9c60e5f
mr26.1.1
Richard Fuchs 1 year ago
parent d67fe1617d
commit 578def7a5a

@ -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);

@ -33,50 +33,45 @@
#include <assert.h>
#include <stdlib.h>
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;
}

@ -34,33 +34,16 @@
#include "cstring.h"
#include "parse_common.h"
struct sip_msg;
#include <string>
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);

@ -31,63 +31,14 @@
#include "msg_hdrs.h"
int copy_hdrs_len(const list<sip_header*>& hdrs)
{
int ret = 0;
list<sip_header*>::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<sip_header*>& hdrs)
{
int ret = 0;
list<sip_header*>::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<sip_header*>& hdrs)
{
int ret = 0;
list<sip_header*>::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<sip_header*>& hdrs)
void copy_hdrs_wr(string& c, const list<sip_header*>& hdrs)
{
list<sip_header*>::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<sip_header*>& hdrs)
void copy_hdrs_wr_no_via(string& c, const list<sip_header*>& hdrs)
{
list<sip_header*>::const_iterator it = hdrs.begin();
for(;it != hdrs.end(); ++it) {
@ -99,7 +50,7 @@ void copy_hdrs_wr_no_via(char** c, const list<sip_header*>& hdrs)
}
}
void copy_hdrs_wr_no_via_contact(char** c, const list<sip_header*>& hdrs)
void copy_hdrs_wr_no_via_contact(string& c, const list<sip_header*>& hdrs)
{
list<sip_header*>::const_iterator it = hdrs.begin();
for(;it != hdrs.end(); ++it){

@ -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 <string>
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<trsp.len; i++) {
if(trsp.s[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 <list>
using std::list;
int copy_hdrs_len(const list<sip_header*>& hdrs);
int copy_hdrs_len_no_via_contact(const list<sip_header*>& hdrs);
void copy_hdrs_wr(char** c, const list<sip_header*>& hdrs);
void copy_hdrs_wr_no_via(char** c, const list<sip_header*>& hdrs);
void copy_hdrs_wr_no_via_contact(char** c, const list<sip_header*>& hdrs);
void copy_hdrs_wr(string& c, const list<sip_header*>& hdrs);
void copy_hdrs_wr_no_via(string& c, const list<sip_header*>& hdrs);
void copy_hdrs_wr_no_via_contact(string& c, const list<sip_header*>& hdrs);
#endif

@ -43,7 +43,7 @@
#include <memory>
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),

@ -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);

@ -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));

@ -30,11 +30,12 @@
#ifndef _sip_trans_h
#define _sip_trans_h
#include "cstring.h"
#include "wheeltimer.h"
#include <sys/socket.h>
#include <string>
using std::string;
#include <list>
using std::list;
#include <memory>
@ -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<string> retr_buf;
/** Destination for retransmissions */
sockaddr_storage retr_addr;

@ -66,6 +66,9 @@
#include <algorithm>
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/* "=<port number>" */;
}
}
@ -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>();
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<sip_header*>::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<size_t>(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<size_t>(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<sip_header*>::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<sip_header*>::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);

Loading…
Cancel
Save