Example #1
0
int init_rb( struct retr_buf *rb, struct sip_msg *msg)
{
	struct socket_info* send_sock;
	struct via_body* via;
	int proto;

	via=msg->via1;
	if (!reply_to_via) {
		update_sock_struct_from_ip( &rb->dst.to, msg );
		proto=msg->rcv.proto;
	} else {
		/*init retrans buffer*/
		if (update_sock_struct_from_via( &(rb->dst.to), msg, via )==-1) {
			LOG(L_ERR, "ERROR: init_rb: cannot lookup reply dst: %.*s\n",
				via->host.len, via->host.s );
			ser_error=E_BAD_VIA;
			return 0;
		}
		proto=via->proto;
	}
	rb->dst.proto=proto;
	rb->dst.proto_reserved1=msg->rcv.proto_reserved1;
	send_sock=get_send_socket(&rb->dst.to, proto);
	if (send_sock==0) {
		LOG(L_ERR, "ERROR: init_rb: cannot fwd to af %d, proto %d "
			"no socket\n", rb->dst.to.s.sa_family, proto);
		ser_error=E_BAD_VIA;
		return 0;
	}
	rb->dst.send_sock=send_sock;
	
    return 1;
}
Example #2
0
int init_rb( struct retr_buf *rb, struct sip_msg *msg)
{
	int proto;

	update_sock_struct_from_ip( &rb->dst.to, msg );
	proto=msg->rcv.proto;
	rb->dst.proto=proto;
	rb->dst.proto_reserved1=msg->rcv.proto_reserved1;
	/* use for sending replies the incoming interface of the request -bogdan */
	rb->dst.send_sock=msg->rcv.bind_address;
	return 1;
}
Example #3
0
int init_rb( struct retr_buf *rb, struct sip_msg *msg)
{
	/*struct socket_info* send_sock;*/
	struct via_body* via;
	int proto;
	int backup_mhomed;

	/* rb. timers are init. init_t()/new_cell() */
	via=msg->via1;
	/* rb->dst is already init (0) by new_t()/build_cell() */
	if (!reply_to_via) {
		update_sock_struct_from_ip( &rb->dst.to, msg );
		proto=msg->rcv.proto;
	} else {
		/*init retrans buffer*/
		if (update_sock_struct_from_via( &(rb->dst.to), msg, via )==-1) {
			LOG(L_ERR, "ERROR: init_rb: cannot lookup reply dst: %.*s\n",
				via->host.len, via->host.s );
			ser_error=E_BAD_VIA;
			return 0;
		}
		proto=via->proto;
	}
	rb->dst.proto=proto;
	rb->dst.id=msg->rcv.proto_reserved1;
#ifdef USE_COMP
	rb->dst.comp=via->comp_no;
#endif
	/* turn off mhomed for generating replies -- they are ideally sent to where
	   request came from to make life with NATs and other beasts easier
	*/
	backup_mhomed=mhomed;
	mhomed=0;
	mhomed=backup_mhomed;
	/* use for sending replies the incoming interface of the request -bogdan */
	/*send_sock=get_send_socket(msg, &rb->dst.to, proto);
	if (send_sock==0) {
		LOG(L_ERR, "ERROR: init_rb: cannot fwd to af %d, proto %d "
			"no socket\n", rb->dst.to.s.sa_family, proto);
		ser_error=E_BAD_VIA;
		return 0;
	}*/
	rb->dst.send_sock=msg->rcv.bind_address;
	return 1;
}
Example #4
0
int sl_send_reply_helper(struct sip_msg *msg ,int code, str *text)
{
	str buf;
	union sockaddr_union to;
	char *dset;
	int dset_len;
	struct bookmark dummy_bm;
	int backup_mhomed;
	int ret;

	if ( msg->REQ_METHOD==METHOD_ACK)
		return 0;

	update_sock_struct_from_ip( &to, msg );

	/* if that is a redirection message, dump current message set to it */
	if (code>=300 && code<400) {
		dset=print_dset(msg, &dset_len);
		if (dset) {
			add_lump_rpl(msg, dset, dset_len, LUMP_RPL_HDR);
		}
	}

	/* add a to-tag if there is a To header field without it */
	if ( code>=180 &&
		(msg->to || (parse_headers(msg,HDR_TO_F, 0)!=-1 && msg->to))
		&& (get_to(msg)->tag_value.s==0 || get_to(msg)->tag_value.len==0) ) 
	{
		calc_crc_suffix( msg, tag_suffix );
		buf.s = build_res_buf_from_sip_req( code, text, &sl_tag, msg,
			(unsigned int*)&buf.len, &dummy_bm);
	} else {
		buf.s = build_res_buf_from_sip_req( code, text, 0, msg,
			(unsigned int*)&buf.len, &dummy_bm);
	}
	if (!buf.s) {
		LM_ERR("response building failed\n");
		goto error;
	}

	run_sl_callbacks( SLCB_REPLY_OUT, msg, &buf, code, text, &to );

	/* supress multhoming support when sending a reply back -- that makes sure
	   that replies will come from where requests came in; good for NATs
	   (there is no known use for mhomed for locally generated replies;
	    note: forwarded cross-interface replies do benefit of mhomed!
	*/
	backup_mhomed=mhomed;
	mhomed=0;
	/* use for sending the received interface -bogdan*/
	ret = msg_send( msg->rcv.bind_address, msg->rcv.proto, &to,
			msg->rcv.proto_reserved1, buf.s, buf.len);
	mhomed=backup_mhomed;
	pkg_free(buf.s);

	if (ret<0)
		goto error;

	*(sl_timeout) = get_ticks() + SL_RPL_WAIT_TIME;

	update_sl_reply_stat(code);

	return 1;

error:
	return -1;
}
Example #5
0
int sl_send_reply(struct sip_msg *msg , int code, char* reason)
{
	char *buf, *dset;
	unsigned int len;
	struct dest_info dst;
	struct bookmark dummy_bm;
	int backup_mhomed, ret, dset_len;


	if ( msg->first_line.u.request.method_value==METHOD_ACK)
	{
		LOG(L_WARN, "Warning: sl_send_reply: I won't send a reply for ACK!!\n");
		goto error;
	}
	init_dest_info(&dst);
	if (reply_to_via) {
		if (update_sock_struct_from_via(  &dst.to, msg, msg->via1 )==-1)
		{
			LOG(L_ERR, "ERROR: sl_send_reply: "
				"cannot lookup reply dst: %s\n",
				msg->via1->host.s );
			goto error;
		}
	} else update_sock_struct_from_ip( &dst.to, msg );

	/* if that is a redirection message, dump current message set to it */
	if (code>=300 && code<400) {
		dset=print_dset(msg, &dset_len);
		if (dset) {
			add_lump_rpl(msg, dset, dset_len, LUMP_RPL_HDR);
		}
	}

	/* add a to-tag if there is a To header field without it */
	if ( 	/* since RFC3261, we append to-tags anywhere we can, except
		 * 100 replies */
       		/* msg->first_line.u.request.method_value==METHOD_INVITE && */
		code>=180 &&
		(msg->to || (parse_headers(msg,HDR_TO_F, 0)!=-1 && msg->to))
		&& (get_to(msg)->tag_value.s==0 || get_to(msg)->tag_value.len==0) ) 
	{
		calc_crc_suffix( msg, tag_suffix );
		buf = build_res_buf_from_sip_req(code,reason,&sl_tag,msg,&len,&dummy_bm);
	} else {
		buf = build_res_buf_from_sip_req(code,reason,0,msg,&len,&dummy_bm);
	}
	if (!buf)
	{
		DBG("DEBUG: sl_send_reply: response building failed\n");
		goto error;
	}
	

	/* supress multhoming support when sending a reply back -- that makes sure
	   that replies will come from where requests came in; good for NATs
	   (there is no known use for mhomed for locally generated replies;
	    note: forwarded cross-interface replies do benefit of mhomed!
	*/
	backup_mhomed=mhomed;
	mhomed=0;
	/* use for sending the received interface -bogdan*/
	dst.proto=msg->rcv.proto;
	dst.send_sock=msg->rcv.bind_address;
	dst.id=msg->rcv.proto_reserved1;
#ifdef USE_COMP
	dst.comp=msg->via1->comp_no;
#endif
	ret = msg_send(&dst, buf, len);
	mhomed=backup_mhomed;
	pkg_free(buf);

	if (ret<0) {
		goto error;
	}
	
	*(sl_timeout) = get_ticks() + SL_RPL_WAIT_TIME;

	update_sl_stats(code);
	return 1;

error:
	update_sl_failures();
	return -1;
}
Example #6
0
/*!
 * helper function for stateless reply
 */
int sl_reply_helper(struct sip_msg *msg, int code, char *reason, str *tag)
{
    str buf = {0, 0};
    str dset = {0, 0};
    struct dest_info dst;
    struct bookmark dummy_bm;
    int backup_mhomed, ret;
    str text;

    int rt, backup_rt;
    struct run_act_ctx ctx;
    struct sip_msg pmsg;

    if (msg->first_line.u.request.method_value==METHOD_ACK)
        goto error;

    init_dest_info(&dst);
    if (reply_to_via) {
        if (update_sock_struct_from_via(&dst.to, msg, msg->via1 )==-1)
        {
            LOG(L_ERR, "ERROR: sl_reply_helper: cannot lookup reply dst: %s\n",
                msg->via1->host.s);
            goto error;
        }
    } else update_sock_struct_from_ip(&dst.to, msg);

    /* if that is a redirection message, dump current message set to it */
    if (code>=300 && code<400) {
        dset.s=print_dset(msg, &dset.len);
        if (dset.s) {
            add_lump_rpl(msg, dset.s, dset.len, LUMP_RPL_HDR);
        }
    }

    text.s = reason;
    text.len = strlen(reason);

    /* add a to-tag if there is a To header field without it */
    if ( 	/* since RFC3261, we append to-tags anywhere we can, except
		 * 100 replies */
        /* msg->first_line.u.request.method_value==METHOD_INVITE && */
        code>=180 &&
        (msg->to || (parse_headers(msg,HDR_TO_F, 0)!=-1 && msg->to))
        && (get_to(msg)->tag_value.s==0 || get_to(msg)->tag_value.len==0) )
    {
        if(tag!=NULL && tag->s!=NULL) {
            buf.s = build_res_buf_from_sip_req(code, &text, tag,
                                               msg, (unsigned int*)&buf.len, &dummy_bm);
        } else {
            calc_crc_suffix( msg, tag_suffix );
            buf.s = build_res_buf_from_sip_req(code, &text, &sl_tag, msg,
                                               (unsigned int*)&buf.len, &dummy_bm);
        }
    } else {
        buf.s = build_res_buf_from_sip_req(code, &text, 0, msg,
                                           (unsigned int*)&buf.len, &dummy_bm);
    }
    if (!buf.s)
    {
        DBG("DEBUG: sl_reply_helper: response building failed\n");
        goto error;
    }

    sl_run_callbacks(SLCB_REPLY_READY, msg, code, reason, &buf, &dst);

    /* supress multhoming support when sending a reply back -- that makes sure
       that replies will come from where requests came in; good for NATs
       (there is no known use for mhomed for locally generated replies;
        note: forwarded cross-interface replies do benefit of mhomed!
    */
    backup_mhomed=mhomed;
    mhomed=0;
    /* use for sending the received interface -bogdan*/
    dst.proto=msg->rcv.proto;
    dst.send_sock=msg->rcv.bind_address;
    dst.id=msg->rcv.proto_reserved1;
#ifdef USE_COMP
    dst.comp=msg->via1->comp_no;
#endif
    dst.send_flags=msg->rpl_send_flags;
    ret = msg_send(&dst, buf.s, buf.len);
    mhomed=backup_mhomed;

    rt = route_lookup(&event_rt, "sl:local-response");
    if (unlikely(rt >= 0 && event_rt.rlist[rt] != NULL))
    {
        if (likely(build_sip_msg_from_buf(&pmsg, buf.s, buf.len,
                                          inc_msg_no()) == 0))
        {
            char *tmp = NULL;
            struct onsend_info onsnd_info;

            onsnd_info.to=&dst.to;
            onsnd_info.send_sock=dst.send_sock;
            onsnd_info.buf=buf.s;
            onsnd_info.len=buf.len;
            p_onsend=&onsnd_info;

            if (unlikely(!IS_SIP(msg)))
            {
                /* This is an HTTP reply...  So fudge in a CSeq into the parsed message
                   message structure so that $rm will work in the route */
                struct hdr_field *hf;
                struct cseq_body *cseqb;
                char *tmp2;
                int len;

                if ((hf = (struct hdr_field *) pkg_malloc(sizeof(struct hdr_field))) == NULL)
                {
                    LM_ERR("out of package memory\n");
                    goto event_route_error;
                }

                if ((cseqb = (struct cseq_body *) pkg_malloc(sizeof(struct cseq_body))) == NULL)
                {
                    LM_ERR("out of package memory\n");
                    pkg_free(hf);
                    goto event_route_error;
                }

                if ((tmp = (char *) pkg_malloc(sizeof(char) * (msg->first_line.u.request.method.len + 5))) == NULL)
                {
                    LM_ERR("out of package memory\n");
                    pkg_free(cseqb);
                    pkg_free(hf);
                    goto event_route_error;
                }

                memset(hf, 0, sizeof(struct hdr_field));
                memset(cseqb, 0, sizeof(struct cseq_body));

                len = sprintf(tmp, "0 %.*s\r\n", msg->first_line.u.request.method.len, msg->first_line.u.request.method.s);
                tmp2 = parse_cseq(tmp, &tmp[len], cseqb);

                hf->type = HDR_CSEQ_T;
                hf->body.s = tmp;
                hf->body.len = tmp2 - tmp;
                hf->parsed = cseqb;

                pmsg.parsed_flag|=HDR_CSEQ_F;
                pmsg.cseq = hf;
                if (pmsg.last_header==0) {
                    pmsg.headers=hf;
                    pmsg.last_header=hf;
                } else {
                    pmsg.last_header->next=hf;
                    pmsg.last_header=hf;
                }
            }

            backup_rt = get_route_type();
            set_route_type(LOCAL_ROUTE);
            init_run_actions_ctx(&ctx);
            run_top_route(event_rt.rlist[rt], &pmsg, 0);
            set_route_type(backup_rt);
            p_onsend=0;

            if (tmp != NULL)
                pkg_free(tmp);

event_route_error:
            free_sip_msg(&pmsg);
        }
    }

    pkg_free(buf.s);

    if (ret<0) {
        goto error;
    }

    *(sl_timeout) = get_ticks() + SL_RPL_WAIT_TIME;

    update_sl_stats(code);
    return 1;

error:
    update_sl_failures();
    return -1;
}