Beispiel #1
0
Datei: op.c Projekt: accre/lstore
gop_op_generic_t *ibp_version_gop(ibp_context_t *ic, ibp_depot_t *depot, char *buffer, int buffer_size, int timeout)
{
    ibp_op_t *op = new_ibp_op(ic);
    if (op == NULL) return(NULL);

    char hoststr[MAX_HOST_SIZE];
    char pchoststr[MAX_HOST_SIZE];
    ibp_op_version_t *cmd = &(op->ops.ver_op);

    ibppc_form_host(op->ic, pchoststr, sizeof(pchoststr), depot->host, depot->rid);
    set_hostport(hoststr, sizeof(hoststr), pchoststr, depot->port, &(op->ic->cc[IBP_STATUS]));

    init_ibp_base_op(op, "depot_version", timeout, op->ic->other_new_command, strdup(hoststr),
                     op->ic->other_new_command, IBP_STATUS, IBP_ST_VERSION);

    cmd->depot = depot;
    cmd->buffer = buffer;
    cmd->buffer_size = buffer_size;

    gop_op_generic_t *gop = ibp_get_gop(op);
    gop->op->cmd.send_command = depot_version_command;
    gop->op->cmd.send_phase = NULL;
    gop->op->cmd.recv_phase = depot_version_recv;

    return(ibp_get_gop(op));
}
Beispiel #2
0
Datei: op.c Projekt: accre/lstore
gop_op_generic_t *ibp_query_resources_gop(ibp_context_t *ic, ibp_depot_t *depot, ibp_ridlist_t *rlist, int timeout)
{
    ibp_op_t *op = new_ibp_op(ic);
    if (op == NULL) return(NULL);
    
    char hoststr[MAX_HOST_SIZE];
    char pchoststr[MAX_HOST_SIZE];
    ibp_op_rid_inq_t *cmd = &(op->ops.rid_op);

    ibppc_form_host(op->ic, pchoststr, sizeof(pchoststr), depot->host, depot->rid);
    set_hostport(hoststr, sizeof(hoststr), pchoststr, depot->port, &(op->ic->cc[IBP_STATUS]));

    init_ibp_base_op(op, "query_resources", timeout, op->ic->other_new_command, strdup(hoststr),
                        op->ic->other_new_command, IBP_STATUS, IBP_ST_RES);

    cmd->depot = depot;
    cmd->rlist = rlist;

    gop_op_generic_t *gop = ibp_get_gop(op);
    gop->op->cmd.send_command = query_res_command;
    gop->op->cmd.send_phase = NULL;
    gop->op->cmd.recv_phase = query_res_recv;
    
    return(ibp_get_gop(op));
}
Beispiel #3
0
Datei: op.c Projekt: accre/lstore
gop_op_generic_t *ibp_depot_inq_gop(ibp_context_t *ic, ibp_depot_t *depot, char *password, ibp_depotinfo_t *di, int timeout)
{
    ibp_op_t *op = new_ibp_op(ic);
    if (op == NULL) return(NULL);

    char hoststr[MAX_HOST_SIZE];
    char pchost[MAX_HOST_SIZE];
    ibp_op_depot_inq_t *cmd = &(op->ops.depot_inq_op);

    ibppc_form_host(op->ic, pchost, sizeof(pchost), depot->host, depot->rid);
    set_hostport(hoststr, sizeof(hoststr), pchost, depot->port, &(op->ic->cc[IBP_STATUS]));

    init_ibp_base_op(op, "depot_inq", timeout, op->ic->other_new_command, strdup(hoststr),
                     op->ic->other_new_command, IBP_STATUS, IBP_ST_INQ);

    cmd->depot = depot;
    cmd->password = password;
    cmd->di = di;

    gop_op_generic_t *gop = ibp_get_gop(op);
    gop->op->cmd.send_command = depot_inq_command;
    gop->op->cmd.send_phase = NULL;
    gop->op->cmd.recv_phase = depot_inq_recv;

    return(ibp_get_gop(op));
}
Beispiel #4
0
/*
 * Create Via header
 */
static inline int assemble_via(str* dest, struct cell* t,
								struct dest_info* dst, int branch)
{
	static char branch_buf[MAX_BRANCH_PARAM_LEN];
	char* via;
	int len;
	unsigned int via_len;
	str branch_str;
	struct hostport hp;

	if (!t_calc_branch(t, branch, branch_buf, &len)) {
		LM_ERR("branch calculation failed\n");
		return -1;
	}

	branch_str.s = branch_buf;
	branch_str.len = len;

#ifdef XL_DEBUG
	printf("!!!proto: %d\n", sock->proto);
#endif

	set_hostport(&hp, 0);
	via = via_builder(&via_len, NULL, dst, &branch_str, 0, &hp);
	if (!via) {
		LM_ERR("via building failed\n");
		return -2;
	}

	dest->s = via;
	dest->len = via_len;
	return 0;
}
Beispiel #5
0
Datei: op.c Projekt: accre/lstore
gop_op_generic_t *ibp_merge_alloc_gop(ibp_context_t *ic, ibp_cap_t *mcap, ibp_cap_t *ccap, int timeout)
{
    ibp_op_t *op = new_ibp_op(ic);
    char hoststr[MAX_HOST_SIZE];
    char host[MAX_HOST_SIZE];
    char chost[MAX_HOST_SIZE];
    ibp_op_merge_alloc_t *cmd;
    int port, cport;

    log_printf(15, "set_ibp_merge_op: start. ic=%p\n", op->ic);

    init_ibp_base_op(op, "rename", timeout, op->ic->other_new_command, NULL, 1, IBP_RENAME, IBP_NOP);

    cmd = &(op->ops.merge_op);

    parse_cap(op->ic, mcap, host, &port, cmd->mkey, cmd->mtypekey);
    set_hostport(hoststr, sizeof(hoststr), host, port, &(op->ic->cc[IBP_MERGE_ALLOCATE]));
    op->dop.cmd.hostport = strdup(hoststr);

    parse_cap(op->ic, ccap, chost, &cport, cmd->ckey, cmd->ctypekey);

    gop_op_generic_t *gop = ibp_get_gop(op);
    gop->op->cmd.send_command = merge_command;
    gop->op->cmd.send_phase = NULL;
    gop->op->cmd.recv_phase = status_get_recv;

    return(ibp_get_gop(op));
}
Beispiel #6
0
Datei: op.c Projekt: accre/lstore
gop_op_generic_t *ibp_truncate_gop(ibp_context_t *ic, ibp_cap_t *cap, ibp_off_t size, int timeout)
{
    ibp_op_t *op = new_ibp_op(ic);
    char hoststr[MAX_HOST_SIZE];
    int port;
    char host[MAX_HOST_SIZE];
    ibp_op_modify_alloc_t *cmd;

    init_ibp_base_op(op, "truncate_alloc", timeout, op->ic->other_new_command, NULL, 1, IBP_MANAGE, IBP_CHNG);

    cmd = &(op->ops.mod_alloc_op);

    parse_cap(op->ic, cap, host, &port, cmd->key, cmd->typekey);
    set_hostport(hoststr, sizeof(hoststr), host, port, &(op->ic->cc[IBP_MANAGE]));
    op->dop.cmd.hostport = strdup(hoststr);

    cmd->cap = cap;
    cmd->size = size;

    gop_op_generic_t *gop = ibp_get_gop(op);
    gop->op->cmd.send_command = truncate_command;
    gop->op->cmd.send_phase = NULL;
    gop->op->cmd.recv_phase = status_get_recv;

    return(ibp_get_gop(op));
}
Beispiel #7
0
ne_session *ne_session_create(const char *scheme,
			      const char *hostname, unsigned int port)
{
    ne_session *sess = ne_calloc(sizeof *sess);

    NE_DEBUG(NE_DBG_HTTP, "HTTP session to %s://%s:%d begins.\n",
	     scheme, hostname, port);

    strcpy(sess->error, "Unknown error.");

    /* use SSL if scheme is https */
    sess->use_ssl = !strcmp(scheme, "https");
    
    /* set the hostname/port */
    set_hostinfo(&sess->server, hostname, port);
    set_hostport(&sess->server, sess->use_ssl?443:80);

#ifdef NE_HAVE_SSL
    if (sess->use_ssl) {
        sess->ssl_context = ne_ssl_context_create(0);
        sess->flags[NE_SESSFLAG_SSLv2] = 1;
    }
#endif

    sess->scheme = ne_strdup(scheme);

    /* Set flags which default to on: */
    sess->flags[NE_SESSFLAG_PERSIST] = 1;

    return sess;
}
Beispiel #8
0
Datei: op.c Projekt: accre/lstore
gop_op_generic_t *ibp_proxy_probe_gop(ibp_context_t *ic, ibp_cap_t *cap, ibp_proxy_capstatus_t *probe, int timeout)
{
    ibp_op_t *op = new_ibp_op(ic);
    char hoststr[MAX_HOST_SIZE];
    int port;
    char host[MAX_HOST_SIZE];
    ibp_op_probe_t *cmd;

    init_ibp_base_op(op, "proxy_probe", timeout, op->ic->other_new_command, NULL, 1, IBP_PROXY_MANAGE, IBP_PROBE);

    cmd = &(op->ops.probe_op);

    parse_cap(op->ic, cap, host, &port, cmd->key, cmd->typekey);
    set_hostport(hoststr, sizeof(hoststr), host, port, &(op->ic->cc[IBP_PROXY_MANAGE]));
    op->dop.cmd.hostport = strdup(hoststr);

    cmd->cap = cap;
    cmd->proxy_probe = probe;

    gop_op_generic_t *gop = ibp_get_gop(op);
    gop->op->cmd.send_command = proxy_probe_command;
    gop->op->cmd.send_phase = NULL;
    gop->op->cmd.recv_phase = proxy_probe_recv;

    return(ibp_get_gop(op));
}
Beispiel #9
0
Datei: op.c Projekt: accre/lstore
gop_op_generic_t *ibp_alloc_gop(ibp_context_t *ic, ibp_capset_t *caps, ibp_off_t size, ibp_depot_t *depot, ibp_attributes_t *attr,
                               int disk_cs_type, ibp_off_t disk_blocksize, int timeout)
{
    ibp_op_t *op = new_ibp_op(ic);

    char hoststr[MAX_HOST_SIZE];
    char pchost[MAX_HOST_SIZE];
    ibp_op_alloc_t *cmd;

    ibppc_form_host(op->ic, pchost, sizeof(pchost), depot->host, depot->rid);
    set_hostport(hoststr, sizeof(hoststr), pchost, depot->port, &(op->ic->cc[IBP_ALLOCATE]));

    init_ibp_base_op(op, "alloc", timeout, op->ic->other_new_command, strdup(hoststr), 1, IBP_ALLOCATE, IBP_NOP);

    cmd = &(op->ops.alloc_op);
    cmd->caps = caps;
    cmd->depot = depot;
    cmd->attr = attr;

    cmd->duration = cmd->attr->duration - time(NULL);  //** This is in sec NOT APR time
    if (cmd->duration < 0) cmd->duration = cmd->attr->duration;

    cmd->size = size;
    cmd->disk_chksum_type = disk_cs_type;
    cmd->disk_blocksize = disk_blocksize;

    gop_op_generic_t *gop = ibp_get_gop(op);
    gop->op->cmd.send_command = allocate_command;
    gop->op->cmd.send_phase = NULL;
    gop->op->cmd.recv_phase = allocate_recv;
    
    return(ibp_get_gop(op));
}
Beispiel #10
0
Datei: op.c Projekt: accre/lstore
gop_op_generic_t *ibp_validate_chksum_gop(ibp_context_t *ic, ibp_cap_t *mcap, int correct_errors, int *n_bad_blocks,
        int timeout)
{
    ibp_op_t *op = new_ibp_op(ic);
    char hoststr[MAX_HOST_SIZE];
    char host[MAX_HOST_SIZE];
    ibp_op_validate_chksum_t *cmd;
    int port;

    init_ibp_base_op(op, "validate_chksum", timeout, op->ic->other_new_command, NULL, 1, IBP_VALIDATE_CHKSUM, IBP_NOP);
    gop_op_generic_t *gop = ibp_get_gop(op);

    cmd = &(op->ops.validate_op);

    parse_cap(op->ic, mcap, host, &port, cmd->key, cmd->typekey);
    set_hostport(hoststr, sizeof(hoststr), host, port, &(op->ic->cc[IBP_VALIDATE_CHKSUM]));
    op->dop.cmd.hostport = strdup(hoststr);

    cmd = &(op->ops.validate_op);
    cmd->correct_errors = correct_errors;
    cmd->n_bad_blocks = n_bad_blocks;

    gop->op->cmd.send_command = validate_chksum_command;
    gop->op->cmd.send_phase = NULL;
    gop->op->cmd.recv_phase = validate_chksum_recv;

    return(ibp_get_gop(op));
}
Beispiel #11
0
Datei: op.c Projekt: accre/lstore
gop_op_generic_t *ibp_copy_gop(ibp_context_t *ic, int mode, int ns_type,
                              char *path, ibp_cap_t *srccap, ibp_cap_t *destcap,
                              ibp_off_t src_offset, ibp_off_t dest_offset,
                              ibp_off_t size, int src_timeout,
                              int dest_timeout, int dest_client_timeout)
{
    ibp_op_t *op = new_ibp_op(ic);
    if (op == NULL) return(NULL);
    
    char hoststr[MAX_HOST_SIZE];
    int port;
    char host[MAX_HOST_SIZE];
    ibp_op_copy_t *cmd;

    init_ibp_base_op(op, "copy", src_timeout, op->ic->rw_new_command + size, NULL, size, IBP_SEND, IBP_NOP);

    cmd = &(op->ops.copy_op);

    parse_cap(op->ic, srccap, host, &port, cmd->src_key, cmd->src_typekey);
    set_hostport(hoststr, sizeof(hoststr), host, port, &(op->ic->cc[IBP_SEND]));
    op->dop.cmd.hostport = strdup(hoststr);

    cmd->ibp_command = mode;
    if (ns_type == NS_TYPE_PHOEBUS) {
        cmd->ctype = IBP_PHOEBUS;
        cmd->path = path;
        if (cmd->path == NULL) cmd->path = "auto";  //** If NULL default to auto
    } else {    //** All other ns types don't use the path
        cmd->ctype = IBP_TCP;
        cmd->path = "\0";
    }

    //** Want chksumming so tweak the command
    if (tbx_ns_chksum_is_valid(&(op->ncs)) == 1) {
        if (cmd->ibp_command == IBP_PUSH) {
            cmd->ibp_command = IBP_PUSH_CHKSUM;
        } else {
            cmd->ibp_command = IBP_PULL_CHKSUM;
        }
    }

    cmd->srccap = srccap;
    cmd->destcap = destcap;
    cmd->len = size;
    cmd->src_offset = src_offset;
    cmd->dest_offset = dest_offset;
    cmd->dest_timeout = dest_timeout;
    cmd->dest_client_timeout = dest_client_timeout;

    gop_op_generic_t *gop = ibp_get_gop(op);
    gop->op->cmd.send_command = pushpull_command;
    gop->op->cmd.send_phase = NULL;
    gop->op->cmd.recv_phase = copy_recv;

    return(ibp_get_gop(op));
}
Beispiel #12
0
Datei: op.c Projekt: accre/lstore
void set_ibp_rw_gop(ibp_op_t *op, int rw_type, ibp_cap_t *cap, ibp_off_t offset, tbx_tbuf_t *buffer, ibp_off_t bpos, ibp_off_t len, int timeout)
{
    char hoststr[MAX_HOST_SIZE];
    int port;
    char host[MAX_HOST_SIZE];
    ibp_op_rw_t *cmd;
    ibp_rw_buf_t *rwbuf;

    cmd = &(op->ops.rw_op);

    init_ibp_base_op(op, "rw", timeout, op->ic->rw_new_command + len, NULL, len, rw_type, IBP_NOP);
    gop_op_generic_t *gop = ibp_get_gop(op);


    parse_cap(op->ic, cap, host, &port, cmd->key, cmd->typekey);
    set_hostport(hoststr, sizeof(hoststr), host, port, &(op->ic->cc[rw_type]));
    op->dop.cmd.hostport = strdup(hoststr);

    cmd->cap = cap;
    cmd->size = len; //** This is the total size

    rwbuf = &(cmd->buf_single);
    cmd->bs_ptr = rwbuf;
    cmd->rwbuf = &(cmd->bs_ptr);
    cmd->n_ops = 1;
    cmd->n_tbx_iovec_total = 1;
    cmd->rw_mode = rw_type;

    rwbuf->iovec = &(rwbuf->iovec_single);

    rwbuf->n_iovec = 1;
    rwbuf->iovec->offset = offset;
    rwbuf->iovec->len = len;
    rwbuf->buffer = buffer;
    rwbuf->boff = bpos;
    rwbuf->size = len;

    if (rw_type == IBP_WRITE) {
        gop->op->cmd.send_command = write_command;
        gop->op->cmd.send_phase = write_send;
        gop->op->cmd.recv_phase = write_recv;
        gop->op->cmd.on_submit = ibp_rw_submit_coalesce;
        gop->op->cmd.before_exec = ibp_rw_coalesce;
    } else {
        gop->op->cmd.send_command = read_command;
        gop->op->cmd.send_phase = NULL;
        gop->op->cmd.recv_phase = read_recv;
        gop->op->cmd.on_submit = ibp_rw_submit_coalesce;
        gop->op->cmd.before_exec = ibp_rw_coalesce;
    }

    op->ncs = op->ic->ncs;  //** Copy the default network chksum
}
Beispiel #13
0
ne_session *ne_session_create(const char *scheme,
			      const char *hostname, unsigned int port)
{
    ne_session *sess = ne_calloc(sizeof *sess);

    NE_DEBUG(NE_DBG_HTTP, "HTTP session to %s://%s:%d begins.\n",
	     scheme, hostname, port);

    strcpy(sess->error, "Unknown error.");

    /* use SSL if scheme is https */
    sess->use_ssl = !strcmp(scheme, "https");
    
    /* set the hostname/port */
    set_hostinfo(&sess->server, PROXY_NONE, hostname, port);
    set_hostport(&sess->server, sess->use_ssl?443:80);

#ifdef NE_HAVE_SSL
    if (sess->use_ssl) {
        ne_inet_addr *ia;

        sess->ssl_context = ne_ssl_context_create(0);
        sess->flags[NE_SESSFLAG_SSLv2] = 1;
        
        /* If the hostname parses as an IP address, don't
         * enable SNI by default. */
        ia = ne_iaddr_parse(hostname, ne_iaddr_ipv4);
        if (ia == NULL)
            ia = ne_iaddr_parse(hostname, ne_iaddr_ipv6);

        if (ia) {
            ne_iaddr_free(ia);
        } 
        else {
            sess->flags[NE_SESSFLAG_TLS_SNI] = 1;
        }
        NE_DEBUG(NE_DBG_SSL, "ssl: SNI %s by default.\n",
                 sess->flags[NE_SESSFLAG_TLS_SNI] ?
                 "enabled" : "disabled");
    }
#endif

    sess->scheme = ne_strdup(scheme);

    /* Set flags which default to on: */
    sess->flags[NE_SESSFLAG_PERSIST] = 1;

    return sess;
}
Beispiel #14
0
Datei: op.c Projekt: accre/lstore
char *change_hostport_cc(char *old_hostport, ibp_connect_context_t *cc)
{
    char host[MAX_HOST_SIZE], new_hostport[MAX_HOST_SIZE];
    char *hp2 = strdup(old_hostport);
    char *bstate;
    int fin, port;

    strncpy(host, tbx_stk_string_token(hp2, HP_HOSTPORT_SEPARATOR, &bstate, &fin), sizeof(host)-1);
    host[sizeof(host)-1] = '\0';
    port = atoi(bstate);

    set_hostport(new_hostport, sizeof(new_hostport), host, port, cc);

    free(hp2);
    return(strdup(new_hostport));
}
Beispiel #15
0
Datei: op.c Projekt: accre/lstore
void set_ibp_generic_modify_count_op(int command, ibp_op_t *op, ibp_cap_t *cap, ibp_cap_t *mcap, int mode, int captype, int timeout)
{
    char hoststr[MAX_HOST_SIZE];
    int port;
    char host[MAX_HOST_SIZE];
    ibp_op_probe_t *cmd;

    if ((command != IBP_MANAGE) && (command != IBP_PROXY_MANAGE)) {
        log_printf(0, "set_ibp_generic_modify_count_op: Invalid command! should be IBP_MANAGE or IBP_PROXY_MANAGE.  Got %d\n", command);
        return;
    }
    if ((mode != IBP_INCR) && (mode != IBP_DECR)) {
        log_printf(0, "ibp_modify_count_gop: Invalid mode! should be IBP_INCR or IBP_DECR\n");
        return;
    }
    if ((captype != IBP_WRITECAP) && (captype != IBP_READCAP)) {
        log_printf(0, "ibp_modify_count_gop: Invalid captype! should be IBP_READCAP or IBP_WRITECAP\n");
        return;
    }

    init_ibp_base_op(op, "modify_count", timeout, op->ic->other_new_command, NULL, 1, command, mode);

    cmd = &(op->ops.probe_op);

    parse_cap(op->ic, cap, host, &port, cmd->key, cmd->typekey);
    set_hostport(hoststr, sizeof(hoststr), host, port, &(op->ic->cc[command]));
    op->dop.cmd.hostport = strdup(hoststr);

    if (command == IBP_PROXY_MANAGE) parse_cap(op->ic, mcap, host, &port, cmd->mkey, cmd->mtypekey);

    cmd->cmd = command;
    cmd->cap = cap;
    cmd->mode = mode;
    cmd->captype = captype;

    gop_op_generic_t *gop = ibp_get_gop(op);
    gop->op->cmd.send_command = modify_count_command;
    if (command == IBP_PROXY_MANAGE) gop->op->cmd.send_command = proxy_modify_count_command;
    gop->op->cmd.send_phase = NULL;
    gop->op->cmd.recv_phase = status_get_recv;
}
Beispiel #16
0
Datei: op.c Projekt: accre/lstore
gop_op_generic_t *ibp_proxy_alloc_gop(ibp_context_t *ic, ibp_capset_t *caps, ibp_cap_t *mcap, ibp_off_t offset, ibp_off_t size,
                                     int duration, int timeout)
{
    ibp_op_t *op = new_ibp_op(ic);
    char hoststr[MAX_HOST_SIZE];
    char host[MAX_HOST_SIZE];
    ibp_op_alloc_t *cmd;
    int port;

    log_printf(15, "set_ibp_proxy_alloc_gop: start. ic=%p\n", op->ic);

    init_ibp_base_op(op, "rename", timeout, op->ic->other_new_command, NULL, 1, IBP_PROXY_ALLOCATE, IBP_NOP);

    cmd = &(op->ops.alloc_op);

    parse_cap(op->ic, mcap, host, &port, cmd->key, cmd->typekey);
    set_hostport(hoststr, sizeof(hoststr), host, port, &(op->ic->cc[IBP_PROXY_ALLOCATE]));
    op->dop.cmd.hostport = strdup(hoststr);

    cmd->offset = offset;
    cmd->size = size;
    if (duration == 0) {
        cmd->duration = 0;
    } else {
        cmd->duration = duration - time(NULL); //** This is in sec NOT APR time
    }


    cmd->caps = caps;

    gop_op_generic_t *gop = ibp_get_gop(op);
    gop->op->cmd.send_command = proxy_allocate_command;
    gop->op->cmd.send_phase = NULL;
    gop->op->cmd.recv_phase = allocate_recv;

    return(ibp_get_gop(op));
}
Beispiel #17
0
Datei: op.c Projekt: accre/lstore
gop_op_generic_t *ibp_split_alloc_gop(ibp_context_t *ic, ibp_cap_t *mcap, ibp_capset_t *caps, ibp_off_t size,
                                     ibp_attributes_t *attr, int disk_cs_type, ibp_off_t disk_blocksize, int timeout)
{
    ibp_op_t *op = new_ibp_op(ic);

    char hoststr[MAX_HOST_SIZE];
    char host[MAX_HOST_SIZE];
    ibp_op_alloc_t *cmd;
    int port;

    init_ibp_base_op(op, "split_allocate", timeout, op->ic->other_new_command, NULL, 1, IBP_SPLIT_ALLOCATE, IBP_NOP);

    cmd = &(op->ops.alloc_op);

    parse_cap(op->ic, mcap, host, &port, cmd->key, cmd->typekey);
    set_hostport(hoststr, sizeof(hoststr), host, port, &(op->ic->cc[IBP_SPLIT_ALLOCATE]));
    op->dop.cmd.hostport = strdup(hoststr);

    cmd = &(op->ops.alloc_op);
    cmd->caps = caps;
    cmd->attr = attr;

    cmd->duration = cmd->attr->duration - time(NULL);  //** This is in sec NOT APR time
    if (cmd->duration < 0) cmd->duration = cmd->attr->duration;

    cmd->size = size;
    cmd->disk_chksum_type = disk_cs_type;
    cmd->disk_blocksize = disk_blocksize;

    gop_op_generic_t *gop = ibp_get_gop(op);
    gop->op->cmd.send_command = split_allocate_command;
    gop->op->cmd.send_phase = NULL;
    gop->op->cmd.recv_phase = allocate_recv;

    return(ibp_get_gop(op));
}
Beispiel #18
0
Datei: op.c Projekt: accre/lstore
gop_op_generic_t *ibp_context_chksum_get_gop(ibp_context_t *ic, ibp_cap_t *mcap,
        int chksum_info_only, int *cs_type, int *cs_size, ibp_off_t *blocksize,
        ibp_off_t *nblocks, ibp_off_t *nbytes, char *buffer, ibp_off_t bufsize,
        int timeout)
{
    ibp_op_t *op = new_ibp_op(ic);
    
    char hoststr[MAX_HOST_SIZE];
    char host[MAX_HOST_SIZE];
    ibp_op_get_chksum_t *cmd;
    int port;

    init_ibp_base_op(op, "get_chksum", timeout, op->ic->other_new_command, NULL, 1, IBP_VALIDATE_CHKSUM, IBP_NOP);
    gop_op_generic_t *gop = ibp_get_gop(op);

    cmd = &(op->ops.get_chksum_op);

    parse_cap(op->ic, mcap, host, &port, cmd->key, cmd->typekey);
    set_hostport(hoststr, sizeof(hoststr), host, port, &(op->ic->cc[IBP_VALIDATE_CHKSUM]));
    op->dop.cmd.hostport = strdup(hoststr);

    cmd->cap = mcap;
    cmd = &(op->ops.get_chksum_op);
    cmd->chksum_info_only = chksum_info_only;
    cmd->cs_type = cs_type;
    cmd->cs_size = cs_size;
    cmd->blocksize = blocksize;
    cmd->nblocks = nblocks;
    cmd->n_chksumbytes = nbytes;

    gop->op->cmd.send_command = get_chksum_command;
    gop->op->cmd.send_phase = NULL;
    gop->op->cmd.recv_phase = get_chksum_recv;

    return(ibp_get_gop(op));
}
Beispiel #19
0
/*
 * The function creates an ACK to 200 OK. Route set will be created
 * and parsed and the dst parameter will contain the destination to which
 * the request should be send. The function is used by tm when it
 * generates local ACK to 200 OK (on behalf of applications using uac)
 */
char *build_dlg_ack(struct sip_msg* rpl, struct cell *Trans,
					unsigned int branch, str *hdrs, str *body,
					unsigned int *len, struct dest_info* dst)
{
	char *req_buf, *p, *via;
	unsigned int via_len;
	char branch_buf[MAX_BRANCH_PARAM_LEN];
	int branch_len;
	str branch_str;
	struct hostport hp;
	struct rte* list;
	str contact, ruri, *cont;
	str next_hop;
	str body_len;
	str _to, *to = &_to;
#ifdef USE_DNS_FAILOVER
	struct dns_srv_handle dns_h;
#endif
#ifdef WITH_AS_SUPPORT
	/* With AS support, TM allows for external modules to generate building of
	 * the ACK; in this case, the ACK's retransmission buffer is built once
	 * and kept in memory (to help when retransmitted 2xx are received and ACK
	 * must be resent).
	 * Allocation of the string raw buffer that holds the ACK is piggy-backed
	 * with allocation of the retransmission buffer (since both have the same
	 * life-cycle): both the string buffer and retransm. buffer are placed
	 * into the same allocated chunk of memory (retr. buffer first, string
	 * buffer follows).In this case, the 'len' param is used as in-out
	 * parameter: 'in' to give the extra space needed by the retr. buffer,
	 * 'out' to return the lenght of the allocated string buffer.
	 */
	unsigned offset = *len;
#endif

	if (parse_headers(rpl, HDR_EOH_F, 0) == -1 || !rpl->to) {
		LM_ERR("Error while parsing headers.\n");
		return 0;
	} else {
		_to.s = rpl->to->name.s;
		_to.len = rpl->to->len;
	}

	if (get_contact_uri(rpl, &contact) < 0) {
		return 0;
	}

	if (eval_uac_routing(rpl, &Trans->uac[branch].request, &contact,
			&list, &ruri, &next_hop) < 0) {
		LM_ERR("failed to evaluate routing elements.\n");
		return 0;
	}
	LM_DBG("ACK RURI: `%.*s', NH: `%.*s'.\n", STR_FMT(&ruri),
			STR_FMT(&next_hop));

	if ((contact.s != ruri.s) || (contact.len != ruri.len)) {
		/* contact != ruri means that the next
		 * hop is a strict router, cont will be non-zero
		 * and print_routeset will append it at the end
		 * of the route set
		 */
		cont = &contact;
	} else {
		/* Next hop is a loose router, nothing to append */
		cont = 0;
	}

	/* method, separators, version: "ACK sip:[email protected] SIP/2.0" */
	*len = SIP_VERSION_LEN + ACK_LEN + 2 /* spaces */ + CRLF_LEN;
	*len += ruri.len;

	/* dst */
	switch(cfg_get(tm, tm_cfg, local_ack_mode)){
		case 1:
			/* send the local 200 ack to the same dst as the corresp. invite*/
			*dst=Trans->uac[branch].request.dst;
			break;
		case 2:
			/* send the local 200 ack to the same dst as the 200 reply source*/
			init_dst_from_rcv(dst, &rpl->rcv);
			dst->send_flags=rpl->fwd_send_flags;
			break;
		case 0:
		default:
			/* rfc conformant behaviour: use the next_hop determined from the
			 * contact and the route set */
#ifdef USE_DNS_FAILOVER
		if (cfg_get(core, core_cfg, use_dns_failover)){
			dns_srv_handle_init(&dns_h);
			if ((uri2dst(&dns_h , dst, rpl, &next_hop, PROTO_NONE)==0) ||
					(dst->send_sock==0)){
				dns_srv_handle_put(&dns_h);
				LM_ERR("no socket found\n");
				goto error;
			}
			dns_srv_handle_put(&dns_h); /* not needed any more */
		}else{
			if ((uri2dst(0 , dst, rpl, &next_hop, PROTO_NONE)==0) ||
					(dst->send_sock==0)){
				LM_ERR("no socket found\n");
				goto error;
			}
		}
#else /* USE_DNS_FAILOVER */
		if ( (uri2dst( dst, rpl, &next_hop, PROTO_NONE)==0) ||
				(dst->send_sock==0)){
			LM_ERR("no socket found\n");
			goto error;
		}
#endif /* USE_DNS_FAILOVER */
		break;
	}

	/* via */
	if (!t_calc_branch(Trans,  branch, branch_buf, &branch_len)) goto error;
	branch_str.s = branch_buf;
	branch_str.len = branch_len;
	set_hostport(&hp, 0);
	via = via_builder(&via_len, NULL, dst, &branch_str, 0, &hp);
	if (!via) {
		LM_ERR("No via header got from builder\n");
		goto error;
	}
	*len+= via_len;

	/* headers */
	*len += Trans->from.len + Trans->callid.len + to->len + Trans->cseq_n.len + 1 + ACK_LEN + CRLF_LEN;

	/* copy'n'paste Route headers */

	*len += calc_routeset_len(list, cont);

	/* User Agent */
	if (server_signature) *len += user_agent_hdr.len + CRLF_LEN;
	/* extra headers */
	if (hdrs)
		*len += hdrs->len;
	/* body */
	if (body) {
		body_len.s = int2str(body->len, &body_len.len);
		*len += body->len;
	} else {
		body_len.len = 0;
		body_len.s = NULL; /*4gcc*/
		*len += 1; /* for the (Cont-Len:) `0' */
	}
	/* Content Length, EoM */
	*len += CONTENT_LENGTH_LEN + body_len.len + CRLF_LEN + CRLF_LEN;

#if WITH_AS_SUPPORT
	req_buf = shm_malloc(offset + *len + 1);
	req_buf += offset;
#else
	req_buf = shm_malloc(*len + 1);
#endif
	if (!req_buf) {
		LM_ERR("Cannot allocate memory (%u+1)\n", *len);
		goto error01;
	}
	p = req_buf;

	append_str( p, ACK, ACK_LEN );
	append_str( p, " ", 1 );
	append_str(p, ruri.s, ruri.len);
	append_str( p, " " SIP_VERSION CRLF, 1 + SIP_VERSION_LEN + CRLF_LEN);

	/* insert our via */
	append_str(p, via, via_len);

	/*other headers*/
	append_str(p, Trans->from.s, Trans->from.len);
	append_str(p, Trans->callid.s, Trans->callid.len);
	append_str(p, to->s, to->len);

	append_str(p, Trans->cseq_n.s, Trans->cseq_n.len);
	append_str( p, " ", 1 );
	append_str( p, ACK, ACK_LEN);
	append_str(p, CRLF, CRLF_LEN);

	/* Routeset */
	p = print_rs(p, list, cont);

	/* User Agent header */
	if (server_signature) {
		append_str(p, user_agent_hdr.s, user_agent_hdr.len);
		append_str(p, CRLF, CRLF_LEN);
	}

	/* extra headers */
	if (hdrs)
		append_str(p, hdrs->s, hdrs->len);

	/* Content Length, EoH, (body) */
	if (body) {
		append_str(p, CONTENT_LENGTH, CONTENT_LENGTH_LEN);
		append_str(p, body_len.s, body_len.len);
		append_str(p, /*end crr. header*/CRLF /*EoH*/CRLF, CRLF_LEN +
				CRLF_LEN);
		append_str(p, body->s, body->len);
	} else {
		append_str(p, CONTENT_LENGTH "0" CRLF CRLF,
				CONTENT_LENGTH_LEN + 1 + CRLF_LEN + CRLF_LEN);
	}

	/* EoM */
	*p = 0;

	pkg_free(via);
	free_rte_list(list);
	return req_buf;

error01:
	pkg_free(via);
error:
	free_rte_list(list);
	return 0;
}
Beispiel #20
0
/*
 * The function creates an ACK for a local INVITE. If 200 OK, route set 
 * will be created and parsed
 */
char *build_dlg_ack(struct sip_msg* rpl, struct cell *Trans,
							unsigned int branch, str* to, unsigned int *len)
{
	char *req_buf, *p, *via;
	unsigned int via_len;
	char branch_buf[MAX_BRANCH_PARAM_LEN];
	int branch_len;
	str branch_str;
	struct hostport hp;
	struct rte* list;
	str contact, ruri, *cont;
	struct socket_info* send_sock;
	str next_hop;


	if (rpl->first_line.u.reply.statuscode < 300 ) {
		/* build e2e ack for 2xx reply -> we need the route set */
		if (get_contact_uri(rpl, &contact) < 0) {
			return 0;
		}

		if (process_routeset(rpl, &contact, &list, &ruri, &next_hop) < 0) {
			return 0;
		}

		if ((contact.s != ruri.s) || (contact.len != ruri.len)) {
			/* contact != ruri means that the next
			 * hop is a strict router, cont will be non-zero
			 * and print_routeset will append it at the end
			 * of the route set
			 */
			cont = &contact;
		} else {
			/* Next hop is a loose router, nothing to append */
			cont = 0;
		}
	} else {
		/* build hop-by-hop ack for negative reply ->
		 * ruri is the same as in INVITE; no route set */
		ruri = Trans->uac[branch].uri;
		cont = 0;
		list = 0;
	}

	/* method, separators, version: "ACK sip:[email protected] SIP/2.0" */
	*len = SIP_VERSION_LEN + ACK_LEN + 2 /* spaces */ + CRLF_LEN;
	*len += ruri.len;

	/* use same socket as for INVITE -bogdan */
	send_sock = Trans->uac[branch].request.dst.send_sock;

	if (!t_calc_branch(Trans,  branch, branch_buf, &branch_len)) goto error;
	branch_str.s = branch_buf;
	branch_str.len = branch_len;
	set_hostport(&hp, 0);

	/* build via */
	via = via_builder(&via_len, send_sock, &branch_str, 0, 
			send_sock->proto, &hp);
	if (!via) {
		LM_ERR("no via header got from builder\n");
		goto error;
	}
	*len+= via_len;

	/*headers*/
	*len += Trans->from.len + Trans->callid.len + to->len +
		Trans->cseq_n.len + 1 + ACK_LEN + CRLF_LEN;

	/* copy'n'paste Route headers */
	*len += calc_routeset_len(list, cont);

	/* User Agent */
	if (server_signature)
		*len += user_agent_header.len + CRLF_LEN;

	/* Content Length, EoM */
	*len += CONTENT_LENGTH_LEN + 1 + CRLF_LEN + CRLF_LEN;

	req_buf = shm_malloc(*len + 1);
	if (!req_buf) {
		LM_ERR("no more share memory\n");
		goto error01;
	}
	p = req_buf;

	append_string( p, ACK " ", ACK_LEN+1 );
	append_string(p, ruri.s, ruri.len );
	append_string( p, " " SIP_VERSION CRLF, 1 + SIP_VERSION_LEN + CRLF_LEN);

	/* insert our via */
	append_string(p, via, via_len);

	/*other headers*/
	append_string(p, Trans->from.s, Trans->from.len);
	append_string(p, Trans->callid.s, Trans->callid.len);
	append_string(p, to->s, to->len);

	append_string(p, Trans->cseq_n.s, Trans->cseq_n.len);
	*(p++) = ' ';
	append_string(p, ACK CRLF, ACK_LEN+CRLF_LEN);

	/* Routeset */
	p = print_rs(p, list, cont);

	/* User Agent header, Content Length, EoM */
	if (server_signature) {
		append_string(p, user_agent_header.s, user_agent_header.len);
		append_string(p, CRLF CONTENT_LENGTH "0" CRLF CRLF,
			CRLF_LEN+CONTENT_LENGTH_LEN + 1 + CRLF_LEN + CRLF_LEN);
	} else {
		append_string(p, CONTENT_LENGTH "0" CRLF CRLF,
			CONTENT_LENGTH_LEN + 1 + CRLF_LEN + CRLF_LEN);
	}
	*p = 0;

	pkg_free(via);
	free_rte_list(list);
	return req_buf;
error01:
	pkg_free(via);
error:
	free_rte_list(list);
	return 0;
}
Beispiel #21
0
/**
 * build CANCEL from UAC side
 */
char *build_uac_cancel(str *headers,str *body,struct cell *cancelledT,
		unsigned int branch, unsigned int *len, struct dest_info* dst)
{
	char *cancel_buf, *p;
	char branch_buf[MAX_BRANCH_PARAM_LEN];
	str branch_str;
	struct hostport hp;
	str content_length, via;

	LM_DBG("sing FROM=<%.*s>, TO=<%.*s>, CSEQ_N=<%.*s>\n",
		cancelledT->from.len, cancelledT->from.s, cancelledT->to.len,
		cancelledT->to.s, cancelledT->cseq_n.len, cancelledT->cseq_n.s);

	branch_str.s=branch_buf;
	if (!t_calc_branch(cancelledT,  branch, branch_str.s, &branch_str.len )){
		LM_ERR("failed to create branch !\n");
		goto error;
	}
	set_hostport(&hp,0);

	if (assemble_via(&via, cancelledT, dst, branch) < 0) {
		LM_ERR("Error while assembling Via\n");
		return 0;
	}

	/* method, separators, version  */
	*len=CANCEL_LEN + 2 /* spaces */ +SIP_VERSION_LEN + CRLF_LEN;
	*len+=cancelledT->uac[branch].uri.len;
	/*via*/
	*len+= via.len;
	/*From*/
	*len+=cancelledT->from.len;
	/*To*/
	*len+=cancelledT->to.len;
	/*CallId*/
	*len+=cancelledT->callid.len;
	/*CSeq*/
	*len+=cancelledT->cseq_n.len+1+CANCEL_LEN+CRLF_LEN;
	/* User Agent */
	if (server_signature) {
		*len += USER_AGENT_LEN + CRLF_LEN;
	}
	/* Content Length  */
	if (print_content_length(&content_length, body) < 0) {
		LM_ERR("failed to print content-length\n");
		return 0;
	}
	/* Content-Length */
	*len += (body ? (CONTENT_LENGTH_LEN + content_length.len + CRLF_LEN) : 0);
	/*Additional headers*/
	*len += (headers ? headers->len : 0);
	/*EoM*/
	*len+= CRLF_LEN;
	/* Message body */
	*len += (body ? body->len : 0);

	cancel_buf=shm_malloc( *len+1 );
	if (!cancel_buf)
	{
		LM_ERR("no more share memory\n");
		goto error01;
	}
	p = cancel_buf;

	memapp( p, CANCEL, CANCEL_LEN );

	*(p++) = ' ';
	memapp( p, cancelledT->uac[branch].uri.s,
		cancelledT->uac[branch].uri.len);
	memapp( p, " " SIP_VERSION CRLF, 1+SIP_VERSION_LEN+CRLF_LEN );

	/* insert our via */
	memapp(p,via.s,via.len);

	/*other headers*/
	memapp( p, cancelledT->from.s, cancelledT->from.len );
	memapp( p, cancelledT->callid.s, cancelledT->callid.len );
	memapp( p, cancelledT->to.s, cancelledT->to.len );

	memapp( p, cancelledT->cseq_n.s, cancelledT->cseq_n.len );
	*(p++) = ' ';
	memapp( p, CANCEL, CANCEL_LEN );
	memapp( p, CRLF, CRLF_LEN );

	/* User Agent header */
	if (server_signature) {
		memapp(p,USER_AGENT CRLF, USER_AGENT_LEN+CRLF_LEN );
	}
	/* Content Length*/
	if (body) {
		memapp(p, CONTENT_LENGTH, CONTENT_LENGTH_LEN);
		memapp(p, content_length.s, content_length.len);
		memapp(p, CRLF, CRLF_LEN);
	}
	if(headers && headers->len){
		memapp(p,headers->s,headers->len);
	}
	/*EoM*/
	memapp(p,CRLF,CRLF_LEN);
	if(body && body->len){
		memapp(p,body->s,body->len);
	}
	*p=0;
	pkg_free(via.s);
	return cancel_buf;
error01:
	pkg_free(via.s);
error:
	return NULL;
}
Beispiel #22
0
/* Build a local request based on a previous request; main
 * customers of this function are local ACK and local CANCEL
 */
char *build_local(struct cell *Trans,unsigned int branch,
	unsigned int *len, char *method, int method_len, str *to
#ifdef CANCEL_REASON_SUPPORT
	, struct cancel_reason* reason
#endif /* CANCEL_REASON_SUPPORT */
	)
{
	char                *cancel_buf, *p, *via;
	unsigned int         via_len;
	struct hdr_field    *hdr;
	char branch_buf[MAX_BRANCH_PARAM_LEN];
	int branch_len;
	str branch_str;
	str via_id;
	struct hostport hp;
#ifdef CANCEL_REASON_SUPPORT
	int reason_len, code_len;
	struct hdr_field *reas1, *reas_last;
#endif /* CANCEL_REASON_SUPPORT */

	/* init */
	via_id.s=0;
	via_id.len=0;

	/* method, separators, version: "CANCEL sip:[email protected] SIP/2.0" */
	*len=SIP_VERSION_LEN + method_len + 2 /* spaces */ + CRLF_LEN;
	*len+=Trans->uac[branch].uri.len;

	/*via*/
	if (!t_calc_branch(Trans,  branch,
		branch_buf, &branch_len ))
		goto error;
	branch_str.s=branch_buf;
	branch_str.len=branch_len;
	set_hostport(&hp, (is_local(Trans))?0:(Trans->uas.request));
#ifdef USE_TCP
	if (!is_local(Trans) && ((Trans->uas.request->rcv.proto==PROTO_TCP)
#ifdef USE_TLS
				|| (Trans->uas.request->rcv.proto==PROTO_TLS)
#endif /* USE_TLS */
		)){
		if ((via_id.s=id_builder(Trans->uas.request,
									(unsigned int*)&via_id.len))==0){
			LM_ERR("id builder failed\n");
			/* try to continue without id */
		}
	}
#endif /* USE_TCP */
	via=via_builder(&via_len, NULL, &Trans->uac[branch].request.dst,
		&branch_str, via_id.s?&via_id:0 , &hp );

	/* via_id.s not needed anylonger => free it */
	if (via_id.s) {
		pkg_free(via_id.s);
		via_id.s=0;
		via_id.len=0;
	}

	if (!via) {
		LM_ERR("no via header got from builder\n");
		goto error;
	}
	*len+= via_len;
	/*headers*/
	*len+=Trans->from.len+Trans->callid.len+to->len+
		+Trans->cseq_n.len+1+method_len+CRLF_LEN+MAXFWD_HEADER_LEN;


	/* copy'n'paste Route headers */
	if (!is_local(Trans)) {
		for ( hdr=Trans->uas.request->headers ; hdr ; hdr=hdr->next )
			if (hdr->type==HDR_ROUTE_T)
				*len+=hdr->len;
	}

	/* User Agent */
	if (server_signature) {
		*len += user_agent_hdr.len + CRLF_LEN;
	}
	/* Content Length, EoM */
	*len+=CONTENT_LENGTH_LEN+1 + CRLF_LEN;
#ifdef CANCEL_REASON_SUPPORT
	reason_len = 0;
	reas1 = 0;
	reas_last = 0;
	/* compute reason size (if no reason or disabled => reason_len == 0)*/
	if (reason && reason->cause != CANCEL_REAS_UNKNOWN){
		if (likely(reason->cause > 0 &&
					cfg_get(tm, tm_cfg, local_cancel_reason))){
			/* Reason: SIP;cause=<reason->cause>[;text=<reason->u.text.s>] */
			reason_len = REASON_PREFIX_LEN + USHORT2SBUF_MAX_LEN +
				(reason->u.text.s?
					REASON_TEXT_LEN + 1 + reason->u.text.len + 1 : 0) +
				CRLF_LEN;
		} else if (likely(reason->cause == CANCEL_REAS_PACKED_HDRS &&
					!(Trans->flags & T_NO_E2E_CANCEL_REASON))) {
			reason_len = reason->u.packed_hdrs.len;
		} else if (reason->cause == CANCEL_REAS_RCVD_CANCEL &&
					reason->u.e2e_cancel &&
					!(Trans->flags & T_NO_E2E_CANCEL_REASON)) {
			/* parse the entire cancel, to get all the Reason headers */
			if(parse_headers(reason->u.e2e_cancel, HDR_EOH_F, 0)<0) {
				LM_WARN("failed to parse headers\n");
			}
			for(hdr=get_hdr(reason->u.e2e_cancel, HDR_REASON_T), reas1=hdr;
					hdr; hdr=next_sibling_hdr(hdr)) {
				/* hdr->len includes CRLF */
				reason_len += hdr->len;
				reas_last=hdr;
			}
		} else if (unlikely(reason->cause < CANCEL_REAS_MIN))
			LM_BUG("unhandled reason cause %d\n", reason->cause);
	}
	*len+= reason_len;
#endif /* CANCEL_REASON_SUPPORT */
	*len+= CRLF_LEN; /* end of msg. */

	cancel_buf=shm_malloc( *len+1 );
	if (!cancel_buf) {
		LM_ERR("cannot allocate memory\n");
		goto error01;
	}
	p = cancel_buf;

	append_str( p, method, method_len );
	append_str( p, " ", 1 );
	append_str( p, Trans->uac[branch].uri.s, Trans->uac[branch].uri.len);
	append_str( p, " " SIP_VERSION CRLF, 1+SIP_VERSION_LEN+CRLF_LEN );

	/* insert our via */
	append_str(p,via,via_len);

	/*other headers*/
	append_str( p, Trans->from.s, Trans->from.len );
	append_str( p, Trans->callid.s, Trans->callid.len );
	append_str( p, to->s, to->len );

	append_str( p, Trans->cseq_n.s, Trans->cseq_n.len );
	append_str( p, " ", 1 );
	append_str( p, method, method_len );
	append_str( p, CRLF, CRLF_LEN );
	append_str( p, MAXFWD_HEADER, MAXFWD_HEADER_LEN );

	if (!is_local(Trans))  {
		for ( hdr=Trans->uas.request->headers ; hdr ; hdr=hdr->next )
			if(hdr->type==HDR_ROUTE_T) {
				append_str(p, hdr->name.s, hdr->len );
			}
	}

	/* User Agent header */
	if (server_signature) {
		append_str(p, user_agent_hdr.s, user_agent_hdr.len );
		append_str(p, CRLF, CRLF_LEN );
	}
	/* Content Length */
	append_str(p, CONTENT_LENGTH "0" CRLF, CONTENT_LENGTH_LEN + 1 + CRLF_LEN);
#ifdef CANCEL_REASON_SUPPORT
	/* add reason if needed */
	if (reason_len) {
		if (likely(reason->cause > 0)) {
			append_str(p, REASON_PREFIX, REASON_PREFIX_LEN);
			code_len=ushort2sbuf(reason->cause, p,
									*len-(int)(p-cancel_buf));
			if (unlikely(code_len==0))
				LM_BUG("not enough space to write reason code");
			p+=code_len;
			if (reason->u.text.s){
				append_str(p, REASON_TEXT, REASON_TEXT_LEN);
				*p='"'; p++;
				append_str(p, reason->u.text.s, reason->u.text.len);
				*p='"'; p++;
			}
			append_str(p, CRLF, CRLF_LEN);
		} else if (likely(reason->cause == CANCEL_REAS_PACKED_HDRS)) {
			append_str(p, reason->u.packed_hdrs.s, reason->u.packed_hdrs.len);
		} else if (reason->cause == CANCEL_REAS_RCVD_CANCEL) {
			for(hdr=reas1; hdr; hdr=next_sibling_hdr(hdr)) {
				/* hdr->len includes CRLF */
				append_str(p, hdr->name.s, hdr->len);
				if (likely(hdr==reas_last))
					break;
			}
		}
	}
#endif /* CANCEL_REASON_SUPPORT */
	append_str(p, CRLF, CRLF_LEN); /* msg. end */
	*p=0;

	pkg_free(via);
	return cancel_buf;
error01:
	pkg_free(via);
error:
	return NULL;
}
Beispiel #23
0
/* Build a local request based on a previous request; the only
   customers of this function are local ACK and local CANCEL
 */
char *build_local(struct cell *Trans,unsigned int branch,
	str *method, str *extra, struct sip_msg* rpl, unsigned int *len)
{
	char                *cancel_buf, *p, *via;
	unsigned int         via_len;
	struct hdr_field    *buf_hdrs;
	struct hdr_field    *hdr;
	struct sip_msg      *req;
	char branch_buf[MAX_BRANCH_PARAM_LEN];
	str branch_str;
	struct hostport hp;
	str from;
	str to;
	str cseq_n;

	req = Trans->uas.request;
	cseq_n = Trans->cseq_n;
	buf_hdrs = 0;

	if (rpl && rpl!=FAKED_REPLY) {
		/* take from and to hdrs from reply */
		to.s = rpl->to->name.s;
		to.len = rpl->to->len;
		from.s = rpl->from->name.s;
		from.len = rpl->from->len;
	} else {
		to = Trans->to;
		from = Trans->from;
		if (req && req->msg_flags&(FL_USE_UAC_FROM|FL_USE_UAC_TO)) {
			if ( extract_ftc_hdrs( Trans->uac[branch].request.buffer.s,
				Trans->uac[branch].request.buffer.len,
				(req->msg_flags&FL_USE_UAC_FROM)?&from:0 ,
				(req->msg_flags&FL_USE_UAC_TO)?&to:0 , 0 )!=0 ) {
				LM_ERR("build_local: failed to extract UAC hdrs\n");
				goto error;
			}
		}
	}

	LM_DBG("using FROM=<%.*s>, TO=<%.*s>, CSEQ_N=<%.*s>\n",
		from.len,from.s , to.len,to.s , cseq_n.len,cseq_n.s);

	/* method, separators, version  */
	*len=SIP_VERSION_LEN + method->len + 2 /* spaces */ + CRLF_LEN;
	*len+=Trans->uac[branch].uri.len;

	/*via*/
	branch_str.s=branch_buf;
	if (!t_calc_branch(Trans,  branch, branch_str.s, &branch_str.len ))
		goto error;
	set_hostport(&hp, (is_local(Trans))?0:req);
	via=via_builder(&via_len, Trans->uac[branch].request.dst.send_sock,
		&branch_str, 0, Trans->uac[branch].request.dst.proto, &hp );
	if (!via){
		LM_ERR("no via header got from builder\n");
		goto error;
	}
	*len+= via_len;
	/*headers*/
	*len+=from.len+Trans->callid.len+to.len+cseq_n.len+1+method->len+CRLF_LEN;

	/* copy'n'paste Route headers that were sent out */
	if (!is_local(Trans) &&
	( (req && req->route) || /* at least one route was received*/
	(Trans->uac[branch].path_vec.len!=0)) ) /* path was forced */
	{
		buf_hdrs = extract_parsed_hdrs(Trans->uac[branch].request.buffer.s,
			Trans->uac[branch].request.buffer.len );
		if (buf_hdrs==NULL) {
			LM_ERR("failed to reparse the request buffer\n");
			goto error01;
		}
		for ( hdr=buf_hdrs ; hdr ; hdr=hdr->next )
			if (hdr->type==HDR_ROUTE_T)
				*len+=hdr->len;
	}

	/* User Agent */
	if (server_signature) {
		*len += user_agent_header.len + CRLF_LEN;
	}
	/* Content Length, MaxFwd, EoM */
	*len+=LOCAL_MAXFWD_HEADER_LEN + CONTENT_LENGTH_LEN+1 + (extra?extra->len:0)
		+ (Trans->extra_hdrs.s?Trans->extra_hdrs.len:0) + CRLF_LEN + CRLF_LEN;

	cancel_buf=shm_malloc( *len+1 );
	if (!cancel_buf)
	{
		LM_ERR("no more share memory\n");
		goto error02;
	}
	p = cancel_buf;

	append_string( p, method->s, method->len );
	*(p++) = ' ';
	append_string( p, Trans->uac[branch].uri.s, Trans->uac[branch].uri.len);
	append_string( p, " " SIP_VERSION CRLF, 1+SIP_VERSION_LEN+CRLF_LEN );

	/* insert our via */
	append_string(p,via,via_len);

	/*other headers*/
	append_string( p, from.s, from.len );
	append_string( p, Trans->callid.s, Trans->callid.len );
	append_string( p, to.s, to.len );

	append_string( p, cseq_n.s, cseq_n.len );
	*(p++) = ' ';
	append_string( p, method->s, method->len );
	append_string( p, CRLF LOCAL_MAXFWD_HEADER,
		CRLF_LEN+LOCAL_MAXFWD_HEADER_LEN );

	/* add Route hdrs (if any) */
	for ( hdr=buf_hdrs ; hdr ; hdr=hdr->next )
		if(hdr->type==HDR_ROUTE_T) {
			append_string(p, hdr->name.s, hdr->len );
		}

	if (extra)
		append_string(p, extra->s, extra->len );

	if (Trans->extra_hdrs.s)
		append_string(p, Trans->extra_hdrs.s, Trans->extra_hdrs.len );

	/* User Agent header, Content Length, EoM */
	if (server_signature) {
		append_string(p, user_agent_header.s, user_agent_header.len);
		append_string(p, CRLF CONTENT_LENGTH "0" CRLF CRLF ,
			CRLF_LEN+CONTENT_LENGTH_LEN+1 + CRLF_LEN + CRLF_LEN);
	} else {
		append_string(p, CONTENT_LENGTH "0" CRLF CRLF ,
			CONTENT_LENGTH_LEN+1 + CRLF_LEN + CRLF_LEN);
	}
	*p=0;

	pkg_free(via);
	free_hdr_field_lst(buf_hdrs);
	return cancel_buf;
error02:
	free_hdr_field_lst(buf_hdrs);
error01:
	pkg_free(via);
error:
	return NULL;
}