Ejemplo n.º 1
0
int th_add_hdr_cookie(sip_msg_t *msg)
{
	struct lump* anchor;
	str h;

	h.len = th_cookie_name.len + 2 + th_cookie_value.len + 1 + CRLF_LEN;
	h.s = (char*)pkg_malloc(h.len+1);
	if(h.s == 0)
	{
		LM_ERR("no more pkg\n");
		return -1;
	}
	anchor = anchor_lump(msg, msg->unparsed - msg->buf, 0, 0);
	if(anchor == 0)
	{
		LM_ERR("can't get anchor\n");
		pkg_free(h.s);
		return -1;
	}
	memcpy(h.s, th_cookie_name.s, th_cookie_name.len);
	memcpy(h.s+th_cookie_name.len, ": ", 2);
	memcpy(h.s+th_cookie_name.len+2, th_cookie_value.s, th_cookie_value.len);
	memcpy(h.s+th_cookie_name.len+2+th_cookie_value.len+1, CRLF, CRLF_LEN);
	h.s[h.len-1-CRLF_LEN] = 'h';
	h.s[h.len] = '\0';
	if (insert_new_lump_before(anchor, h.s, h.len, 0) == 0)
	{
		LM_ERR("can't insert lump\n");
		pkg_free(h.s);
		return -1;
	}
	LM_DBG("+++++++++++++ added cookie header [%s]\n", h.s);
	return 0;
}
Ejemplo n.º 2
0
int _test_insert_to_reply( struct sip_msg *msg, char *str )
{
    struct lump* anchor;
    char *buf;
    int len;

    len=strlen( str );
    buf=pkg_malloc( len );
    if (!buf) {
        LOG(L_ERR, "_test_insert_to_reply: no mem\n");
        return 0;
    }
    memcpy( buf, str, len );

    anchor = anchor_lump(msg, msg->headers->name.s - msg->buf, 0 , 0);
    if (anchor == NULL) {
        LOG(L_ERR, "_test_insert_to_reply: anchor_lump failed\n");
        return 0;
    }
    if (insert_new_lump_before(anchor,buf, len, 0)==0) {
        LOG(L_ERR, "_test_insert_to_reply: inser_new_lump failed\n");
        return 0;
    }
    return 1;
}
Ejemplo n.º 3
0
static int lua_sr_hdr_insert (lua_State *L)
{
	struct lump* anchor;
	struct hdr_field *hf;
	char *txt;
	int len;
	char *hdr;
	sr_lua_env_t *env_L;

	env_L = sr_lua_env_get();

	txt = (char*)lua_tostring(L, -1);
	if(txt==NULL || env_L->msg==NULL)
		return 0;

	LM_DBG("insert hf: %s\n", txt);
	hf = env_L->msg->headers;
	len = strlen(txt);
	hdr = (char*)pkg_malloc(len);
	if(hdr==NULL)
	{
		LM_ERR("no pkg memory left\n");
		return 0;
	}
	memcpy(hdr, txt, len);
	anchor = anchor_lump(env_L->msg,
				hf->name.s + hf->len - env_L->msg->buf, 0, 0);
	if(insert_new_lump_before(anchor, hdr, len, 0) == 0)
	{
		LM_ERR("can't insert lump\n");
		pkg_free(hdr);
		return 0;
	}
	return 0;
}
Ejemplo n.º 4
0
/**
 * Given some header text, append it to the passed in message.
 *
 * @param msg The message to append the header text to.
 * @param header The header text to append.
 *
 * @return 0 on success, non-zero on failure.
 */
static int append_header(struct sip_msg *msg, const char *header)
{
	struct lump* anchor = NULL;
	char *s = NULL;
	int len = 0;

	LM_DBG("Appending header: %s", header);

	if (parse_headers(msg, HDR_EOH_F, 0) == -1) {
		LM_ERR("failed to parse headers in message.\n");
		return(1);
	}

	if ((anchor = anchor_lump(msg, msg->unparsed - msg->buf, 0)) == 0) {
		LM_ERR("failed to get anchor to append header\n");
		return(1);
	}
	len = strlen(header);
	if ((s = (char *)pkg_malloc(len)) == 0) {
		LM_ERR("No more pkg memory. (size requested = %d)\n", len);
		return(1);
	}
	memcpy(s, header, len);
	if (insert_new_lump_before(anchor, s, len, 0) == 0) {
		LM_ERR("failed to insert lump\n");
		pkg_free(s);
		return(1);
	}
	LM_DBG("Done appending header successfully.\n");
	return(0);
}
Ejemplo n.º 5
0
static int insert_header_lump(struct sip_msg* msg, char* msg_position, int lump_before, str* hname, str *val) {
	struct lump* anchor;
	char *s;
	int len;

	anchor = anchor_lump(msg, msg_position - msg->buf, 0, 0);
	if (anchor == 0) {
		LOG(L_ERR, "ERROR: textops: insert_header_lump(): Can't get anchor\n");
		return -1;
	}

	len=hname->len+2+val->len+2;

	s = (char*)pkg_malloc(len);
	if (!s) {
		LOG(L_ERR, "ERROR: textops: insert_header_lump(): not enough memory\n");
		return -1;
	}

	memcpy(s, hname->s, hname->len);
	s[hname->len] = ':';
	s[hname->len+1] = ' ';
	memcpy(s+hname->len+2, val->s, val->len);
	s[hname->len+2+val->len] = '\r';
	s[hname->len+2+val->len+1] = '\n';

	if ( (lump_before?insert_new_lump_before(anchor, s, len, 0):insert_new_lump_after(anchor, s, len, 0)) == 0) {
		LOG(L_ERR, "ERROR: textops: insert_header_lump(): Can't insert lump\n");
		pkg_free(s);
		return -1;
	}
	return 1;
}
Ejemplo n.º 6
0
/**
 *	Inserts the Route header for marking, before first header.
 * - the marking will be in a header like below
 * - if the "as" parameter is empty: \code Route: <[iscmark]> \endcode
 * - else: \code Route: <sip:[email protected];lr>, <[iscmark]> \endcode
 * 			 
 *
 *	@param msg - SIP mesage to mark
 *	@param as - SIP addres of the application server to forward to
 *	@param iscmark - the mark to write
 *	@returns 1 on success, else 0
 */
inline int isc_mark_write_route(struct sip_msg *msg, str *as, str *iscmark) {
	struct hdr_field *first;
	struct lump* anchor;
	str route;

	parse_headers(msg, HDR_EOH_F, 0);
	first = msg->headers;
	if (as && as->len) {
		route.s = pkg_malloc(21+as->len+iscmark->len);
		sprintf(route.s, "Route: <%.*s;lr>, <%.*s>\r\n", as->len, as->s,
				iscmark->len, iscmark->s);
	} else {
		route.s = pkg_malloc(18+iscmark->len);
		sprintf(route.s, "Route: <%.*s>\r\n", iscmark->len, iscmark->s);
	}

	route.len = strlen(route.s);
	LM_DBG("isc_mark_write_route: <%.*s>\n", route.len, route.s);

	anchor = anchor_lump(msg, first->name.s - msg->buf, 0, HDR_ROUTE_T);
	if (anchor == NULL) {
		LM_ERR("isc_mark_write_route: anchor_lump failed\n");
		return 0;
	}

	if (!insert_new_lump_before(anchor, route.s, route.len, HDR_ROUTE_T)) {
		LM_ERR("isc_mark_write_route: error creating lump for header_mark\n");
	}
	return 1;
}
Ejemplo n.º 7
0
static inline int add_diversion_helper(struct sip_msg* msg, str* s)
{
	char *ptr;
	int is_ref;

	struct lump* anchor = 0;

	if (!msg->diversion && parse_headers(msg, HDR_DIVERSION_F, 0) == -1) {
		LM_ERR("header parsing failed\n");
		return -1;
	}
	
	if (msg->diversion) {
		     /* Insert just before the topmost Diversion header */
		ptr = msg->diversion->name.s;
	} else {
		     /* Insert at the end */
		ptr = msg->unparsed;
	}

	anchor = anchor_lump2(msg, ptr - msg->buf, 0, 0, &is_ref);
	if (!anchor) {
		LM_ERR("can't get anchor\n");
		return -2;
	}
	
	if (!insert_new_lump_before(anchor, s->s, s->len, 0)) {
		LM_ERR("can't insert lump\n");
		return -3;
	}

	return 0;
}
Ejemplo n.º 8
0
static int ki_add_sock_hdr(sip_msg_t* msg, str *hdr_name)
{
	struct socket_info* si;
	struct lump* anchor;
	str hdr;
	char *p;

	if(hdr_name==NULL || hdr_name->s==NULL || hdr_name->len<=0) {
		LM_ERR("invalid header name parameter\n");
		return -1;
	}
	si = msg->rcv.bind_address;

	if (parse_headers( msg, HDR_EOH_F, 0) == -1) {
		LM_ERR("failed to parse message\n");
		goto error;
	}

	anchor = anchor_lump( msg, msg->unparsed-msg->buf, 0, 0);
	if (anchor==0) {
		LM_ERR("can't get anchor\n");
		goto error;
	}

	hdr.len = hdr_name->len + 2 + si->sock_str.len + CRLF_LEN;
	if ( (hdr.s=(char*)pkg_malloc(hdr.len))==0 ) {
		LM_ERR("no more pkg mem\n");
		goto error;
	}

	p = hdr.s;
	memcpy( p, hdr_name->s, hdr_name->len);
	p += hdr_name->len;
	*(p++) = ':';
	*(p++) = ' ';

	memcpy( p, si->sock_str.s, si->sock_str.len);
	p += si->sock_str.len;

	memcpy( p, CRLF, CRLF_LEN);
	p += CRLF_LEN;

	if ( p-hdr.s!=hdr.len ) {
		LM_CRIT("buffer overflow (%d!=%d)\n", (int)(long)(p-hdr.s),hdr.len);
		goto error1;
	}

	if (insert_new_lump_before( anchor, hdr.s, hdr.len, 0) == 0) {
		LM_ERR("can't insert lump\n");
		goto error1;
	}

	return 1;
error1:
	pkg_free(hdr.s);
error:
	return -1;
}
Ejemplo n.º 9
0
/**
 * Adds a received parameter to the first via with the source IP of the message.
 * @param req - the SIP request
 * @param str1 - not used
 * @param str2 - not used
 * @returns true if ok, false if not or error
 */
int P_add_via_received(struct sip_msg *msg,char *str1, char *str2)
{
	struct via_body *via;
	struct via_param *vp;
	str received={0,0};
	struct ip_addr *src_ip;
	char *src_ip_ch;
	int len;
	struct lump* anchor,*l;
	char *x;
	
	/* first add a received parameter */
	via = msg->via1;
	
	/* if we already have a received header, SER will take care of it and put the right value */	
	if (via->received) goto delete_others;
	
	x = via->port_str.s+via->port_str.len;
	if (!x) x= via->host.s+via->host.len;
	anchor = anchor_lump(msg, x-msg->buf, 0 , 0 );
	if (anchor == NULL) {
		LOG(L_ERR, "ERR:"M_NAME":P_add_via_received(): anchor_lump failed\n");
		return 0;
	}
	
	src_ip = &(msg->rcv.src_ip);
	src_ip_ch = ip_addr2a(src_ip);
	len = strlen(src_ip_ch);
	received.len = s_received.len+len;	
	received.s = pkg_malloc(received.len);
	
	if (!received.s){
		LOG(L_ERR, "ERR:"M_NAME":P_add_via_received(): allocating %d bytes\n",received.len);
		return CSCF_RETURN_ERROR;
	}
	memcpy(received.s,s_received.s,s_received.len);
	memcpy(received.s+s_received.len,src_ip_ch,len);
	
	if (!(l=insert_new_lump_before(anchor, received.s,received.len,0))){
		LOG(L_ERR, "ERR:"M_NAME":P_add_via_received(): error creating lump for received parameter\n" );
		return CSCF_RETURN_ERROR;
	}	
	
	/* then remove the old received params*/
delete_others:	
	for(vp = via->param_lst; vp; vp = vp->next)
		if (vp->name.len == s_received2.len &&
			strncasecmp(vp->name.s,s_received2.s,s_received2.len)==0){
				LOG(L_ERR, "ERR:"M_NAME":P_add_via_received(): Found old received parameter!! This might indicate an attack.\n" );
				if (!del_lump(msg,vp->start-msg->buf-1,vp->size+1,0)){
					LOG(L_ERR,"ERR:"M_NAME":P_add_via_received(): Error deleting old received parameter from first via\n");
					return CSCF_RETURN_ERROR;		
				}		
			}	
	return CSCF_RETURN_TRUE;
}
Ejemplo n.º 10
0
int add_maxfwd_header( struct sip_msg* msg , unsigned int val )
{
	unsigned int  len;
	char          *buf;
	struct lump*  anchor;

	/* double check just to be sure */
	if ( msg->maxforwards )
	{
		LOG( L_ERR , "ERROR: add_maxfwd_header :"
			" MAX_FORWARDS header already exists (%p) !\n",msg->maxforwards);
		goto error;
	}

	/* constructing the header */
	len = 14 /*"MAX-FORWARDS: "*/+ CRLF_LEN + 3/*val max on 3 digits*/;

	buf = (char*)pkg_malloc( len );
	if (!buf) {
		LOG(L_ERR, "ERROR : add_maxfwd_header : "
		  "No memory left\n");
		return -1;
	}
	memcpy( buf , "Max-Forwards: ", 14 );
	len = 14 ;
	len += btostr( buf+len , val );
	memcpy( buf+len , CRLF , CRLF_LEN );
	len +=CRLF_LEN;

	/*inserts the header at the begining of the message*/
	anchor = anchor_lump(msg, msg->headers->name.s - msg->buf, 0 , 0);
	if (anchor == 0) {
		LOG(L_ERR, "ERROR: add_maxfwd_header :"
		   " Error, can't get anchor\n");
		goto error1;
	}

	if (insert_new_lump_before(anchor, buf, len, 0) == 0) {
		LOG(L_ERR, "ERROR: add_maxfwd_header : "
		    "Error, can't insert MAX-FORWARDS\n");
		goto error1;
	}

	return 1;

error1:
	pkg_free( buf );
error:
	return -1;
}
Ejemplo n.º 11
0
int tps_add_headers(sip_msg_t *msg, str *hname, str *hbody, int hpos)
{
	struct lump* anchor;
	str hs;

	if(hname==NULL || hname->len<=0 || hbody==NULL || hbody->len<=0)
		return 0;

	parse_headers(msg, HDR_EOH_F, 0);
	if(hpos == 0) { /* append */
		/* after last header */
		anchor = anchor_lump(msg, msg->unparsed - msg->buf, 0, 0);
	} else { /* insert */
		/* before first header */
		anchor = anchor_lump(msg, msg->headers->name.s - msg->buf, 0, 0);
	}

	if(anchor == 0) {
		LM_ERR("can't get anchor\n");
		return -1;
	}

	hs.len = hname->len + 2 + hbody->len;
	hs.s  = (char*)pkg_malloc(hs.len + 3);
	if (hs.s==NULL) {
		LM_ERR("no pkg memory left (%.*s - %d)\n",
				hname->len, hname->s, hs.len);
		return -1;
	}
	memcpy(hs.s, hname->s, hname->len);
	hs.s[hname->len] = ':';
	hs.s[hname->len+1] = ' ';
	memcpy(hs.s + hname->len + 2, hbody->s, hbody->len);

	/* add end of header if not present */
	if(hs.s[hname->len + 2 + hbody->len]!='\n') {
		hs.s[hname->len + 2 + hbody->len] = '\r';
		hs.s[hname->len + 2 + hbody->len+1] = '\n';
		hs.len += 2;
	}

	if (insert_new_lump_before(anchor, hs.s, hs.len, 0) == 0) {
		LM_ERR("can't insert lump\n");
		pkg_free(hs.s);
		return -1;
	}

	return 0;
}
Ejemplo n.º 12
0
static inline int apply_urihdr_changes( struct sip_msg *req,
													str *uri, str *hdr)
{
	struct lump* anchor;

	/* add the uri - move it to branch directly FIXME (bogdan)*/
	if (req->new_uri.s)
	{
		pkg_free(req->new_uri.s);
		req->new_uri.len=0;
	}
	req->parsed_uri_ok=0;
	req->new_uri.s = (char*)pkg_malloc(uri->len+1);
	if (req->new_uri.s==0)
	{
		LM_ERR("no more pkg\n");
		goto error;
	}
	memcpy( req->new_uri.s, uri->s, uri->len);
	req->new_uri.s[uri->len]=0;
	req->new_uri.len=uri->len;
	ruri_mark_new();

	/* add the header */
	if (parse_headers(req, HDR_EOH_F, 0) == -1)
	{
		LM_ERR("failed to parse message\n");
		goto error;
	}

	anchor = anchor_lump(req, req->unparsed - req->buf, 0, 0);
	if (anchor==0)
	{
		LM_ERR("failed to get anchor\n");
		goto error;
	}

	if (insert_new_lump_before(anchor, hdr->s, hdr->len, 0) == 0)
	{
		LM_ERR("faield to insert lump\n");
		goto error;
	}

	return 0;
error:
	pkg_free( hdr->s );
	return -1;
}
Ejemplo n.º 13
0
/*!
 * \brief Set Request-URI as last Route header of a SIP
 *
 * Set Request-URI as last Route header of a SIP message,
 * this is necessary when forwarding to a strict router.
 * Allocates memory for message lump in private memory.
 * \param _m SIP message
 * \return negative on failure, 0 on success
 */
static inline int save_ruri(struct sip_msg* _m)
{
    struct lump* anchor;
    char *s;
    int len;

    /* We must parse the whole message header here, because
     * the Request-URI must be saved in last Route HF in the message
     */
    if (parse_headers(_m, HDR_EOH_F, 0) == -1) {
        LM_ERR("failed to parse message\n");
        return -1;
    }

    /* Create an anchor */
    anchor = anchor_lump(_m, _m->unparsed - _m->buf, 0, 0);
    if (anchor == 0) {
        LM_ERR("failed to get anchor\n");
        return -2;
    }

    /* Create buffer for new lump */
    len = RR_ROUTE_PREFIX_LEN + _m->first_line.u.request.uri.len
          + ROUTE_SUFFIX_LEN;
    s = (char*)pkg_malloc(len);
    if (!s) {
        LM_ERR("No memory pkg left\n");
        return -3;
    }

    /* Create new header field */
    memcpy(s, RR_ROUTE_PREFIX, RR_ROUTE_PREFIX_LEN);
    memcpy(s + RR_ROUTE_PREFIX_LEN, _m->first_line.u.request.uri.s,
           _m->first_line.u.request.uri.len);
    memcpy(s + RR_ROUTE_PREFIX_LEN + _m->first_line.u.request.uri.len,
           ROUTE_SUFFIX, ROUTE_SUFFIX_LEN);

    LM_DBG("New header: '%.*s'\n", len, ZSW(s));

    /* Insert it */
    if (insert_new_lump_before(anchor, s, len, 0) == 0) {
        pkg_free(s);
        LM_ERR("failed to insert lump\n");
        return -4;
    }

    return 0;
}
Ejemplo n.º 14
0
static int sr_mono_hdr_append (MonoString *hv)
{
	struct lump* anchor;
	struct hdr_field *hf;
	char *hdr;
	str txt = {0};
	sr_mono_env_t *env_M;

	env_M = sr_mono_env_get();
	txt.s = mono_string_to_utf8(hv);

	if(txt.s==NULL || env_M->msg==NULL)
		goto error;

	txt.len = strlen(txt.s);

	LM_DBG("append hf: %s\n", txt.s);
	if (parse_headers(env_M->msg, HDR_EOH_F, 0) == -1)
	{
		LM_ERR("error while parsing message\n");
		goto error;
	}

	hf = env_M->msg->last_header;
	hdr = (char*)pkg_malloc(txt.len+1);
	if(hdr==NULL)
	{
		PKG_MEM_ERROR;
		goto error;
	}
	memcpy(hdr, txt.s, txt.len);
	hdr[txt.len] = '\0';
	anchor = anchor_lump(env_M->msg,
				hf->name.s + hf->len - env_M->msg->buf, 0, 0);
	if(insert_new_lump_before(anchor, hdr, txt.len, 0) == 0)
	{
		LM_ERR("can't insert lump\n");
		pkg_free(hdr);
		goto error;
	}
	mono_free(txt.s);
	return 0;

error:
	if(txt.s!=NULL)
		mono_free(txt.s);
	return -1;
}
Ejemplo n.º 15
0
static int lua_sr_hdr_append (lua_State *L)
{
	struct lump* anchor;
	struct hdr_field *hf;
	char *txt;
	int len;
	char *hdr;
	sr_lua_env_t *env_L;

	env_L = sr_lua_env_get();

	txt = (char*)lua_tostring(L, -1);
	if(txt==NULL || env_L->msg==NULL)
		return 0;

	LM_DBG("append hf: %s\n", txt);
	if (parse_headers(env_L->msg, HDR_EOH_F, 0) == -1)
	{
		LM_ERR("error while parsing message\n");
		return 0;
	}

	hf = env_L->msg->last_header;
	len = strlen(txt);
	hdr = (char*)pkg_malloc(len);
	if(hdr==NULL)
	{
		LM_ERR("no pkg memory left\n");
		return 0;
	}
	memcpy(hdr, txt, len);
	anchor = anchor_lump(env_L->msg,
				hf->name.s + hf->len - env_L->msg->buf, 0, 0);
	if(anchor==NULL)
	{
		LM_ERR("unable to get the anchor\n");
		pkg_free(hdr);
		return 0;
	}
	if(insert_new_lump_before(anchor, hdr, len, 0) == 0)
	{
		LM_ERR("can't insert lump\n");
		pkg_free(hdr);
		return 0;
	}
	return 0;
}
Ejemplo n.º 16
0
/**
 * Adds a header to the message as the first one in the message
 * @param msg - the message to add a header to
 * @param content - the str containing the new header
 * @returns 1 on succes, 0 on failure
 */
int cscf_add_header_first(struct sip_msg *msg, str *hdr,int type)
{
	struct hdr_field *first;
	struct lump* anchor,*l;

	first = msg->headers;
	anchor = anchor_lump(msg, first->name.s - msg->buf, 0 , 0 );

	if (anchor == NULL) {
		LM_DBG( "cscf_add_header_first: anchor_lump failed\n");
		return 0;
	}

	if (!(l=insert_new_lump_before(anchor, hdr->s,hdr->len,type))){
		LM_ERR( "cscf_add_header_first: error creating lump for header\n" );
		return 0;
	}	
	return 1;
}
Ejemplo n.º 17
0
static inline int add_diversion_helper(struct sip_msg* msg, str* s)
{
	char *ptr;

	static struct lump* anchor = 0;
	static int msg_id = 0;

	if (msg_id != msg->id) {
		msg_id = msg->id;
		anchor = 0;
	}

	if (!msg->diversion && parse_headers(msg, HDR_DIVERSION_F, 0) == -1) {
		LOG(L_ERR, "add_diversion_helper: Header parsing failed\n");
		return -1;
	}

	if (msg->diversion) {
		     /* Insert just before the topmost Diversion header */
		ptr = msg->diversion->name.s;
	} else {
		     /* Insert at the end */
		ptr = msg->unparsed;
	}

	if (!anchor) {
		anchor = anchor_lump(msg, ptr - msg->buf, 0, 0);
		if (!anchor) {
			LOG(L_ERR, "add_diversion_helper: Can't get anchor\n");
			return -2;
		}
	}

	if (!insert_new_lump_before(anchor, s->s, s->len, 0)) {
		LOG(L_ERR, "add_diversion_helper: Can't insert lump\n");
		return -3;
	}

	return 0;
}
Ejemplo n.º 18
0
int add_maxfwd_header( struct sip_msg* msg , unsigned int val )
{
	unsigned int  len;
	char          *buf;
	struct lump*  anchor;

	/* constructing the header */
	len = MF_HDR_LEN /*"MAX-FORWARDS: "*/+ CRLF_LEN + 3/*val max on 3 digits*/;

	buf = (char*)pkg_malloc( len );
	if (!buf) {
		LOG(L_ERR, "ERROR:maxfwd:add_maxfwd_header: no more pkg memory\n");
		goto error;
	}
	memcpy( buf , MF_HDR, MF_HDR_LEN );
	len = MF_HDR_LEN ;
	len += btostr( buf+len , val );
	memcpy( buf+len , CRLF , CRLF_LEN );
	len +=CRLF_LEN;

	/*inserts the header at the beginning of the message*/
	anchor = anchor_lump(msg, msg->headers->name.s - msg->buf, 0 , 0);
	if (anchor == 0) {
		LOG(L_ERR, "ERROR:maxfwd:add_maxfwd_header: failed to get anchor\n");
		goto error1;
	}

	if (insert_new_lump_before(anchor, buf, len, 0) == 0) {
		LOG(L_ERR, "ERROR:maxfwd:add_maxfwd_header: failed to insert "
			"MAX-FORWARDS lump\n");
		goto error1;
	}

	return 1;

error1:
	pkg_free( buf );
error:
	return -1;
}
Ejemplo n.º 19
0
static int append_hf_helper(struct sip_msg* msg, str *str1, str *str2)
{
	struct lump* anchor;
	char *s;
	int len;

	if (parse_headers(msg, HDR_EOH_F, 0) == -1) {
		LOG(L_ERR, "append_hf(): Error while parsing message\n");
		return -1;
	}

	anchor = anchor_lump(msg, msg->unparsed - msg->buf, 0, 0);
	if (anchor == 0) {
		LOG(L_ERR, "append_hf(): Can't get anchor\n");
		return -1;
	}

	len=str1->len;
	if (str2) len+= str2->len + REQ_LINE(msg).uri.len;

	s = (char*)pkg_malloc(len);
	if (!s) {
		LOG(L_ERR, "append_hf(): No memory left\n");
		return -1;
	}

	memcpy(s, str1->s, str1->len);
	if (str2) {
		memcpy(s+str1->len, REQ_LINE(msg).uri.s, REQ_LINE(msg).uri.len);
		memcpy(s+str1->len+REQ_LINE(msg).uri.len, str2->s, str2->len );
	}

	if (insert_new_lump_before(anchor, s, len, 0) == 0) {
		LOG(L_ERR, "append_hf(): Can't insert lump\n");
		pkg_free(s);
		return -1;
	}
	return 1;
}
Ejemplo n.º 20
0
/* 
 * Append header to SIP message
 * param msg SIP message
 * param header Header to be appended
 * return 0 success, -1 failure
 */
static int ospAppendHeader(
    struct sip_msg* msg, 
    str* header)
{
    char* s;
    struct lump* anchor;
    
    if((msg == 0) || (header == 0) || (header->s == 0) || (header->len <= 0)) {
        LM_ERR("bad parameters for appending header\n");
        return -1;
    }

    if (parse_headers(msg, HDR_EOH_F, 0) == -1) {
        LM_ERR("failed to parse message\n");
        return -1;
    }

    anchor = anchor_lump(msg, msg->unparsed - msg->buf, 0, 0);
    if (anchor == 0) {
        LM_ERR("failed to get anchor\n");
        return -1;
    }

    s = (char*)pkg_malloc(header->len);
    if (s == 0) {
        LM_ERR("no pkg memory\n");
        return -1;
    }

    memcpy(s, header->s, header->len);

    if (insert_new_lump_before(anchor, s, header->len, 0) == 0) {
        LM_ERR("failed to insert lump\n");
        pkg_free(s);
        return -1;
    }
    
    return 0;
}
Ejemplo n.º 21
0
/*
 * Copy of append_hf_helper from textops.
 */
static inline int append_rpid_helper(struct sip_msg* _m, str *_s)
{
	struct lump* anchor;

	if (parse_headers(_m, HDR_EOH_F, 0) == -1) {
		LM_ERR("failed to parse message\n");
		return -1;
	}

	anchor = anchor_lump(_m, _m->unparsed - _m->buf, 0);
	if (!anchor) {
		LM_ERR("can't get anchor\n");
		return -2;
	}

	if (!insert_new_lump_before(anchor, _s->s, _s->len, 0)) {
		LM_ERR("can't insert lump\n");
		return -3;
	}

	return 0;
}
Ejemplo n.º 22
0
static int insert_value_lump(struct sip_msg* msg, struct hdr_field* hf, char* msg_position, int lump_before, str *val) {
	struct lump* anchor;
	char *s;
	int len;

	anchor = anchor_lump(msg, msg_position - msg->buf, 0, 0);
	if (anchor == 0) {
		LOG(L_ERR, "ERROR: textops: insert_value_lump(): Can't get anchor\n");
		return -1;
	}

	len=val->len+1;

	s = (char*)pkg_malloc(len);
	if (!s) {
		LOG(L_ERR, "ERROR: textops: insert_value_lump(): not enough memory\n");
		return -1;
	}

	if (!hf) {
		memcpy(s, val->s, val->len);
		len--;
	}
	else if (msg_position == hf->body.s+hf->body.len) {
		s[0] = ',';
		memcpy(s+1, val->s, val->len);
	}
	else {
		memcpy(s, val->s, val->len);
		s[val->len] = ',';
	}
	if ( (lump_before?insert_new_lump_before(anchor, s, len, 0):insert_new_lump_after(anchor, s, len, 0)) == 0) {
		LOG(L_ERR, "ERROR: textops: insert_value_lump(): Can't insert lump\n");
		pkg_free(s);
		return -1;
	}
	return 1;
}
Ejemplo n.º 23
0
static inline struct lump *insert_rr_param_lump(struct lump *before,
						char *s, int l)
{
	struct lump *rrp_l;
	char *s1;

	/* duplicate data in pkg mem */
	s1 = (char*)pkg_malloc(l);
	if (s1==0) {
		LM_ERR("no more pkg mem (%d)\n",l);
		return 0;
	}
	memcpy( s1, s, l);

	/* add lump */
	rrp_l = insert_new_lump_before( before, s1, l, 0);
	if (rrp_l==0) {
		LM_ERR("failed to add before lump\n");
		pkg_free(s1);
		return 0;
	}
	return rrp_l;
}
Ejemplo n.º 24
0
static int assign_hf_do_lumping(struct sip_msg* msg,struct hdr_field* hf, struct hname_data* hname, str* value, int upd_del_fl, str* lump_upd, str* lump_del, char delim) {
	int len, i;
	char *s;
	struct lump* anchor;

	if (upd_del_fl) {
		len = value?lump_upd->len:lump_del->len;
		if (len > 0) {
			if (!del_lump(msg, (value?lump_upd->s:lump_del->s)-msg->buf, len, 0)) {
				LOG(L_ERR, "ERROR: textops: assign_hf_do_lumping: not enough memory\n");
				return -1;
			}
		}
		if (value && value->len) {
			anchor = anchor_lump(msg, lump_upd->s - msg->buf, 0, 0);
			if (anchor == 0) {
				LOG(L_ERR, "ERROR: textops: assign_hf_do_lumping: Can't get anchor\n");
				return -1;
			}

			len = 1+value->len;
			s = pkg_malloc(len);
			if (!s) {
				LOG(L_ERR, "ERROR: textops: assign_hf_do_lumping: not enough memory\n");
				return -1;
			}
			s[0]='=';
			memcpy(s+1, value->s, value->len);
			if ( (insert_new_lump_before(anchor, s, len, 0)) == 0) {
				LOG(L_ERR, "ERROR: textops: assign_hf_do_lumping: Can't insert lump\n");
				pkg_free(s);
				return -1;
			}
		}
	}
	else {
		if (!value) return -1;

		anchor = anchor_lump(msg, lump_del->s - msg->buf, 0, 0);
		if (anchor == 0) {
			LOG(L_ERR, "ERROR: textops: assign_hf_do_lumping: Can't get anchor\n");
			return -1;
		}

		len = 1+hname->param.len+(value->len?value->len+1:0);
		s = pkg_malloc(len);
		if (!s) {
			LOG(L_ERR, "ERROR: textops: assign_hf_do_lumping: not enough memory\n");
			return -1;
		}
		if (delim) {
			s[0] = delim;
			i = 1;
		}
		else {
			i = 0;
			len--;
		}
		memcpy(s+i, hname->param.s, hname->param.len);
		if (value->len) {
			s[hname->param.len+i]='=';
			memcpy(s+i+hname->param.len+1, value->s, value->len);
		}

		if ( (insert_new_lump_before(anchor, s, len, 0)) == 0) {
			LOG(L_ERR, "ERROR: textops: assign_hf_do_lumping: Can't insert lump\n");
			pkg_free(s);
			return -1;
		}
	}
	return 1;
}
Ejemplo n.º 25
0
int rtjson_prepare_branch(sip_msg_t *msg, srjson_doc_t *jdoc, srjson_t *nj)
{
	srjson_t *rj = NULL;
	srjson_t *tj = NULL;
	srjson_t *vj = NULL;
	str xdsp = {0};
	str xuri = {0};
	str xhdr = {0};
	unsigned int fr = 0;
	unsigned int fr_inv = 0;
	struct lump *anchor = NULL;
	char *s;


	if(tmb.set_fr!=NULL) {
		rj = srjson_GetObjectItem(jdoc, nj, "fr_timer");
		if(rj!=NULL && rj->type==srjson_Number && SRJSON_GET_UINT(rj)!=0) {
			fr = SRJSON_GET_UINT(rj);
		}
		rj = srjson_GetObjectItem(jdoc, nj, "fr_inv_timer");
		if(rj!=NULL && rj->type==srjson_Number && SRJSON_GET_UINT(rj)!=0) {
			fr_inv = SRJSON_GET_UINT(rj);
		}
		if(fr || fr_inv) tmb.set_fr(msg, fr_inv, fr);
	}
	rj = srjson_GetObjectItem(jdoc, nj, "headers");
	if(rj==NULL || rj->type!=srjson_Object || rj->child==NULL) {
		LM_DBG("no header operations - done\n");
		return 0;
	}

	tj = srjson_GetObjectItem(jdoc, rj, "extra");
	if(tj!=NULL && tj->type==srjson_String && tj->valuestring!=0) {
		xhdr.s =  tj->valuestring;
		xhdr.len = strlen(xhdr.s);
	}

	if(xhdr.len>4) {
		LM_DBG("appending extra headers: [%.*s]\n", xhdr.len, xhdr.s);
		anchor = anchor_lump(msg, msg->unparsed - msg->buf, 0, 0);
		if(anchor == 0) {
			LM_ERR("can't get anchor\n");
			return -1;
		}
		s = pkg_malloc(xhdr.len+1);
		if(s==NULL) {
			LM_ERR("no more pkg\n");
			return -1;
		}
		strncpy(s, xhdr.s, xhdr.len);
		s[xhdr.len] = '\0';
		if (insert_new_lump_before(anchor, s, xhdr.len, 0) == 0) {
			LM_ERR("can't insert lump\n");
			pkg_free(s);
			return -1;
		}
	}

	if(uacb.replace_from!=NULL) {
		tj = srjson_GetObjectItem(jdoc, rj, "from");
		if(tj!=NULL && tj->type==srjson_Object && rj->child!=NULL) {
			vj = srjson_GetObjectItem(jdoc, tj, "display");
			if(vj!=NULL && vj->type==srjson_String && vj->valuestring!=0) {
				xdsp.s =  vj->valuestring;
				xdsp.len = strlen(xdsp.s);
			}
			vj = srjson_GetObjectItem(jdoc, tj, "uri");
			if(vj!=NULL && vj->type==srjson_String && vj->valuestring!=0) {
				xuri.s =  vj->valuestring;
				xuri.len = strlen(xuri.s);
			}
			if(xdsp.len>0 || xuri.len>0) {
				uacb.replace_from(msg, &xdsp, &xuri);
			}
		}
	}

	if(uacb.replace_to!=NULL) {
		tj = srjson_GetObjectItem(jdoc, rj, "to");
		if(tj!=NULL && tj->type==srjson_Object && rj->child!=NULL) {
			vj = srjson_GetObjectItem(jdoc, tj, "display");
			if(vj!=NULL && vj->type==srjson_String && vj->valuestring!=0) {
				xdsp.s =  vj->valuestring;
				xdsp.len = strlen(xdsp.s);
			}
			vj = srjson_GetObjectItem(jdoc, tj, "uri");
			if(vj!=NULL && vj->type==srjson_String && vj->valuestring!=0) {
				xuri.s =  vj->valuestring;
				xuri.len = strlen(xuri.s);
			}
			if(xdsp.len>0 || xuri.len>0) {
				uacb.replace_to(msg, &xdsp, &xuri);
			}
		}
	}

	return 0;
}
Ejemplo n.º 26
0
/*! \brief
 * build a Record-Route header field
 */
static inline int build_rr(struct lump* _l, struct lump* _l2, str* user,
						str *tag, str *params, struct lump *lp, int _inbound)
{
	char* prefix, *suffix, *term, *r2;
	int suffix_len, prefix_len;
	char *p;

	prefix_len = RR_PREFIX_LEN + (user->len ? (user->len + 1) : 0);
	suffix_len = RR_LR_LEN + (params?params->len:0) +
			((tag && tag->len) ? (RR_FROMTAG_LEN + tag->len) : 0);

	prefix = pkg_malloc(prefix_len);
	suffix = pkg_malloc(suffix_len);
	term = pkg_malloc(RR_TERM_LEN);
	r2 = pkg_malloc(RR_R2_LEN);

	if (!prefix || !suffix || !term || !r2) {
		LM_ERR("No more pkg memory\n");
		if (suffix) pkg_free(suffix);
		if (prefix) pkg_free(prefix);
		if (term) pkg_free(term);
		if (r2) pkg_free(r2);
		return -3;
	}

	memcpy(prefix, RR_PREFIX, RR_PREFIX_LEN);
	if (user->len) {
		memcpy(prefix + RR_PREFIX_LEN, user->s, user->len);
#ifdef ENABLE_USER_CHECK
		/* don't add the ignored user into a RR */
		if(i_user.len && i_user.len == user->len &&
				!strncmp(i_user.s, user->s, i_user.len))
		{
			if(prefix[RR_PREFIX_LEN]=='x')
				prefix[RR_PREFIX_LEN]='y';
			else
				prefix[RR_PREFIX_LEN]='x';
		}
#endif
		prefix[RR_PREFIX_LEN + user->len] = '@';
	}

	p = suffix;
	memcpy( p, RR_LR, RR_LR_LEN);
	p += RR_LR_LEN;

	if (tag && tag->len) {
		memcpy(p, RR_FROMTAG, RR_FROMTAG_LEN);
		p += RR_FROMTAG_LEN;
		memcpy(p, tag->s, tag->len);
		p += tag->len;
	}
	if (params && params->len) {
		memcpy(p, params->s, params->len);
		p += params->len;
	}

	memcpy(term, RR_TERM, RR_TERM_LEN);
	memcpy(r2, RR_R2, RR_R2_LEN);

	if (!(_l = insert_new_lump_after(_l, prefix, prefix_len, 0)))
		goto lump_err;
	prefix = 0;
	_l = insert_subst_lump_after(_l, _inbound?SUBST_RCV_ALL:SUBST_SND_ALL, 0);
	if (_l ==0 )
		goto lump_err;
	if (enable_double_rr) {
		if (!(_l = insert_cond_lump_after(_l, COND_IF_DIFF_REALMS, 0)))
			goto lump_err;
		if (!(_l = insert_new_lump_after(_l, r2, RR_R2_LEN, 0)))
			goto lump_err;
		r2 = 0;
	} else {
		pkg_free(r2);
		r2 = 0;
	}
	_l2 = insert_new_lump_before(_l2, suffix, suffix_len, 0);
	if (_l2 == 0)
		goto lump_err;
	suffix = 0;
	if ( lp ) {
		/* link the pending buffered params and go at the end of the list */
		for ( _l2->before = lp ; _l2 && _l2->before ; _l2=_l2->before);
	}
	if (!(_l2 = insert_new_lump_before(_l2, term, RR_TERM_LEN, 0)))
		goto lump_err;
	term = 0;
	return 0;

lump_err:
	LM_ERR("failed to insert lumps\n");
	if (prefix) pkg_free(prefix);
	if (suffix) pkg_free(suffix);
	if (r2) pkg_free(r2);
	if (term) pkg_free(term);
	return -4;
}
Ejemplo n.º 27
0
Archivo: avp.c Proyecto: 2pac/kamailio
static int request_hf_helper(struct sip_msg* msg, str* hf, avp_ident_t* ident, struct lump* anchor, struct search_state* st, int front, int reverse, int reply)
{
    struct lump* new_anchor;
    static struct search_state state;
    avp_t* avp;
    char* s;
    str fin_val;
    int len, ret;
    int_str val;
    struct hdr_field* pos, *found = NULL;
    
    if (!anchor && !reply) {
	
	if (parse_headers(msg, HDR_EOH_F, 0) == -1) {
	    LOG(L_ERR, "ERROR: request_hf_helper: Error while parsing message\n");
	    return -1;
	}
	
	pos = msg->headers;
	while (pos && (pos->type != HDR_EOH_T)) {
	    if ((hf->len == pos->name.len)
		&& (!strncasecmp(hf->s, pos->name.s, pos->name.len))) {
		found = pos;
		if (front) {
		    break;
		}
	    }
	    pos = pos->next;
	}
	
	if (found) {
	    if (front) {
		len = found->name.s - msg->buf;
	    } else {
		len = found->name.s + found->len - msg->buf;
	    }
	} else {
	    len = msg->unparsed - msg->buf;
	}
	
	new_anchor = anchor_lump(msg, len, 0, 0);
	if (new_anchor == 0) {
	    LOG(L_ERR, "ERROR: request_hf_helper: Can't get anchor\n");
	    return -1;
	}
    } else {
	new_anchor = anchor;
    }
    
    if (!st) {
	st = &state;
	avp = search_avp(*ident, NULL, st);
	ret = -1;
    } else {
	avp = search_next_avp(st, NULL);
	ret = 1;
    }
    
    if (avp) {
	if (reverse && (request_hf_helper(msg, hf, ident, new_anchor, st, front, reverse, reply) == -1)) {
	    return -1;
	}
	
	get_avp_val(avp, &val);
	if (avp->flags & AVP_VAL_STR) {
	    fin_val = val.s;
	} else {
	    fin_val.s = int2str(val.n, &fin_val.len);
	}
	
	len = hf->len + 2 + fin_val.len + 2;
	s = (char*)pkg_malloc(len);
	if (!s) {
	    LOG(L_ERR, "ERROR: request_hf_helper: No memory left for data lump\n");
	    return -1;
	}
	
	memcpy(s, hf->s, hf->len);
	memcpy(s + hf->len, ": ", 2 );
	memcpy(s + hf->len+2, fin_val.s, fin_val.len );
	memcpy(s + hf->len + 2 + fin_val.len, CRLF, CRLF_LEN);
	
	if (reply) {
	    if (add_lump_rpl( msg, s, len, LUMP_RPL_HDR | LUMP_RPL_NODUP) == 0) {
		LOG(L_ERR, "ERROR: request_hf_helper: Can't insert RPL lump\n");
		pkg_free(s);
		return -1;
	    }
	} else {
	    if ((front && (insert_new_lump_before(new_anchor, s, len, 0) == 0))
		|| (!front && (insert_new_lump_after(new_anchor, s, len, 0) == 0))) {
		LOG(L_ERR, "ERROR: request_hf_helper: Can't insert lump\n");
		pkg_free(s);
		return -1;
	    }
	}
	if (!reverse && (request_hf_helper(msg, hf, ident, new_anchor, st, front, reverse, reply) == -1)) {
	    return -1;
	}
	return 1;
    };
    
	 /* in case of topmost call (st==NULL) return error */
	 /* otherwise it's OK, no more AVPs found */
    return ret; 
}
Ejemplo n.º 28
0
/**
 * Send the request back simulating an AS. 
 * - Inserts a Header with the contents of str2
 * - Tries to find the Route: appserver_uri, s-cscf_uri header and removes appserver_uri from it
 * - It forwards the message to s-scsf_uri, or if none found to str1
 *	@param msg - The sip message
 *	@param str1 - The uri of the SCSCF to default to if Route header is not found
 *	@param str2 - The Header to add to the message - if empty none will be added
 *	@returns	- 0 to cancel further script processing 
 */
int isc_appserver_forward(struct sip_msg *msg,char *str1,char *str2 )
{
	struct hdr_field *last,*hdr;
	struct lump* anchor;
	str header_mark;
	rr_t *rr;

	LOG(L_DBG,"DEBUG:"M_NAME":isc_appserver_forward: Forward-back request reached\n");
	parse_headers(msg,HDR_EOH_F,0);
	last = msg->headers;
	while(last->next)
		last = last->next;

	LOG(L_INFO,"INFO:"M_NAME":isc_appserver_forward: New header: [%s]\n%.*s",str2,msg->len,msg->buf);
	
    /* Put header marking */

	if (strlen(str2)){
	
		header_mark.s = pkg_malloc(256);//36 should be enough
		sprintf(header_mark.s,"%.*s\n",strlen(str2),str2);
		header_mark.len =strlen(header_mark.s);
	
		anchor = anchor_lump(msg, last->name.s + last->len - msg->buf, 0 , 0);
		if (anchor == NULL) {
				LOG(L_ERR, "ERROR:"M_NAME":isc_appserver_forward: anchor_lump failed\n");
		}
	
		if (!insert_new_lump_before(anchor, header_mark.s,header_mark.len,0)){
				LOG( L_ERR, "ERROR:"M_NAME":isc_appserver_forward: error creting lump for header_mark\n" );
		}
		//pkg_free(header_mark.s);
	}
	LOG(L_ERR, "INFO:"M_NAME":isc_appserver_forward: Searching Route header to rewrite\n");
	/* Search for the Route */
	hdr = msg->headers;
	while(hdr){
		if (hdr->type == HDR_ROUTE_T){
			if (!hdr->parsed){
				if (parse_rr(hdr) < 0) {
					LOG(L_ERR, "ERROR:"M_NAME":isc_appserver_forward: Error while parsing Route HF\n");
					continue;
				}
			}
			rr = (rr_t*)hdr->parsed;
			while(rr){
				if (rr->nameaddr.uri.len >= ISC_MARK_USERNAME_LEN &&
					strncasecmp(rr->nameaddr.uri.s,ISC_MARK_USERNAME,ISC_MARK_USERNAME_LEN)==0)	{
						LOG(L_INFO,"DEBUG:"M_NAME":isc_appserver_forward: Found S-CSCF marking <%.*s> \n",rr->nameaddr.uri.len,rr->nameaddr.uri.s);
						/* delete the header */					
						if (!del_lump(msg, hdr->name.s - msg->buf, hdr->len, 0)) {
							LOG(L_ERR, "ERROR:"M_NAME":isc_appserver_forward: Can't remove Route HF\n");
						}  
										
						/* add the new header */
						anchor = anchor_lump(msg, msg->headers->name.s - msg->buf, 0 , 0);
						header_mark.s = pkg_malloc(256);//36 should be enough
						sprintf(header_mark.s,"Route: <%.*s>\n",rr->nameaddr.uri.len,rr->nameaddr.uri.s);
						header_mark.len =strlen(header_mark.s);	
						if (!insert_new_lump_before(anchor, header_mark.s,header_mark.len,0)){
							LOG( L_ERR, "ERROR:"M_NAME":isc_appserver_forward: error creting lump for route header\n" );
						}	
					/* send the message */
					msg->dst_uri.s = pkg_malloc(rr->nameaddr.uri.len);
					memcpy(msg->dst_uri.s,rr->nameaddr.uri.s,rr->nameaddr.uri.len);
					msg->dst_uri.len=rr->nameaddr.uri.len;
					isc_tmb.t_relay(msg,0,0);
					return 0;
				}					
				rr = rr->next;
			}			
		}
		hdr = hdr->next;
	}
	
	/* In case no suitable route header found, just fwd to the given parameter */
	msg->dst_uri.len = strlen(str1);
	msg->dst_uri.s = str1;
	isc_tmb.t_relay(msg,0,0);
	LOG(L_DBG,"DEBUG:"M_NAME":isc_appserver_forward: Mirror request finished\n");
	return 0;
}
Ejemplo n.º 29
0
/*! \brief
 * Insert manually created Record-Route header, no checks, no restrictions,
 * always adds lr parameter, only fromtag is added automatically when requested
 */
int record_route_preset(struct sip_msg* _m, str* _data)
{
	str user;
	struct to_body* from;
	struct lump* l, *lp, *ap;
	struct lump* l2;
	char *hdr, *suffix, *p, *term;
	int hdr_len, suffix_len;

	from = 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;
		}
	}

	if (append_fromtag) {
		if (parse_from_header(_m) < 0) {
			LM_ERR("From parsing failed\n");
			return -2;
		}
		from = (struct to_body*)_m->from->parsed;
	}

	hdr_len = RR_PREFIX_LEN;
	if (user.len)
		hdr_len += user.len + 1; /* @ */
	hdr_len += _data->len;

	suffix_len = 0;
	if (append_fromtag && from->tag_value.len) {
		suffix_len += RR_FROMTAG_LEN + from->tag_value.len;
	}

	suffix_len += RR_LR_LEN;

	hdr = pkg_malloc(hdr_len);
	term = pkg_malloc(RR_TERM_LEN);
	suffix = pkg_malloc(suffix_len);
	if (!hdr || !term || !suffix) {
		LM_ERR("no pkg memory left\n");
		return -4;
	}

	/* header */
	p = hdr;
	memcpy(p, RR_PREFIX, RR_PREFIX_LEN);
	p += RR_PREFIX_LEN;

	if (user.len) {
		memcpy(p, user.s, user.len);
		p += user.len;
		*p = '@';
		p++;
	}

	memcpy(p, _data->s, _data->len);
	p += _data->len;

	/*suffix*/
	p = suffix;
	if (append_fromtag && from->tag_value.len) {
		memcpy(p, RR_FROMTAG, RR_FROMTAG_LEN);
		p += RR_FROMTAG_LEN;
		memcpy(p, from->tag_value.s, from->tag_value.len);
		p += from->tag_value.len;
	}

	memcpy(p, RR_LR, RR_LR_LEN);
	p += RR_LR_LEN;

	memcpy(term, RR_TERM, RR_TERM_LEN);

	l = anchor_lump(_m, _m->headers->name.s - _m->buf, HDR_RECORDROUTE_T);
	l2 = anchor_lump(_m, _m->headers->name.s - _m->buf, HDR_RECORDROUTE_T);
	if (!l || !l2) {
		LM_ERR("failed to create lump anchor\n");
		goto error;
	}

	if (!(l=insert_new_lump_after(l, hdr, hdr_len, 0))) {
		LM_ERR("failed to insert new lump\n");
		goto error;
	}
	hdr = NULL;

	l2 = insert_new_lump_before(l2, suffix, suffix_len, HDR_RECORDROUTE_T);
	if (l2==NULL) {
		LM_ERR("failed to insert suffix lump\n");
		goto error;
	}
	suffix = NULL;

	/* look for pending RR params */
	for( lp=NULL,ap=_m->add_rm ; ap ; ap=ap->next ) {
		if (ap->type==HDR_RECORDROUTE_T && ap->op==LUMP_NOP
		&& ap->before && ap->before->op==LUMP_ADD_OPT
		&& ap->before->u.cond==COND_FALSE) {
			/* found our phony anchor lump */
			/* jump over the anchor and conditional lumps */
			lp = ap->before->before;
			/* unlink it */
			ap->before->before = NULL;
			ap->type = 0;
			/* link the pending buffered params and go at the end of the list*/
			for ( l2->before = lp ; l2 && l2->before ; l2=l2->before);
			break;
		}
	}

	if (!(l2=insert_new_lump_before(l2, term, RR_TERM_LEN, 0))) {
		LM_ERR("failed to insert term lump");
		goto error;
	}
	term = NULL;

	return 1;
error:
	if (hdr) pkg_free(hdr);
	if (term) pkg_free(term);
	if (suffix) pkg_free(suffix);
	return -1;
}
Ejemplo n.º 30
0
/**
 * sngtc_caller_answer - attaches an SDP body to ACK requests
 */
static int sngtc_caller_answer(struct sip_msg *msg)
{
	char *p;
	str body;
	struct dlg_cell *dlg;
	struct lump *lump;
	struct sngtc_info *info;
	int len;

	LM_DBG("processing ACK\n");

	if (get_body(msg, &body) != 0 || body.len > 0) {
		LM_ERR("ACK should not contain a SDP body\n");
		return SNGTC_ERR;
	}

	dlg = dlg_binds.get_dlg();
	if (!dlg) {
		LM_ERR("failed to fetch current dialog\n");
		return SNGTC_ERR;
	}

	/* get the SDP body from the INVITE which was mangled at 200 OK */
	if (dlg_binds.fetch_dlg_value(dlg, &dlg_key_sngtc_info, &body, 0) != 0) {
		LM_ERR("failed to fetch caller sdp\n");
		return SNGTC_ERR;
	}

	info = *(struct sngtc_info **)(body.s);

	/* duplicate the SDP in pkg mem for the lumps mechanism */
	if (pkg_str_dup(&body, &info->modified_caller_sdp) != 0) {
		LM_ERR("failed to dup in pkg mem\n");
		return SNGTC_ERR;
	}

	LM_DBG("Duplicated SDP: '%.*s'\n", body.len, body.s);

	lump = anchor_lump(msg, msg->content_length->name.s - msg->buf, 0);
	if (!lump) {
		LM_ERR("failed to insert anchor lump\n");
		return SNGTC_ERR;
	}

	p = pkg_malloc(SDP_CONTENT_TYPE_LEN);
	if (!p) {
		LM_ERR("no more pkg memory\n");
		return SNGTC_ERR;
	}

	/* add the Content-Type header */

	memcpy(p, "Content-Type: application/sdp\r\n", SDP_CONTENT_TYPE_LEN);

	if (!insert_new_lump_before(lump, p, SDP_CONTENT_TYPE_LEN, 0)) {
		LM_ERR("failed to insert Content-Type lump\n");
		return SNGTC_ERR;
	}

	LM_DBG("blen: %d\n", msg->content_length->body.len);

	lump = del_lump(msg, msg->content_length->body.s - msg->buf,
	                msg->content_length->body.len, HDR_OTHER_T);
	if (!lump) {
		LM_ERR("failed to insert del lump for the content length\n");
		return SNGTC_ERR;
	}

	p = pkg_malloc(CONTENT_LEN_DIGITS);
	if (!p) {
		LM_ERR("no more pkg memory\n");
		return SNGTC_ERR;
	}

	LM_DBG("len: %d\n", body.len);

	len = sprintf(p, "%d", body.len);

	if (!insert_new_lump_after(lump, p, len, HDR_OTHER_T)) {
		LM_ERR("failed to insert Content-Length lump\n");
		return SNGTC_ERR;
	}

	lump = anchor_lump(msg, msg->len - CRLF_LEN, 0);
	if (!lump) {
		LM_ERR("failed to insert anchor lump\n");
		return SNGTC_ERR;
	}

	if (!insert_new_lump_before(lump, body.s, body.len, 0)) {
		LM_ERR("failed to insert SDP body lump\n");
		return SNGTC_ERR;
	}

	return 1;
}