Beispiel #1
0
static struct chan *chan_create(struct chanlist *cl, uint16_t numb,
				const struct sa *peer,
				const struct allocation *al)
{
	struct chan *chan;

	if (!cl || !peer)
		return NULL;

	chan = mem_zalloc(sizeof(*chan), destructor);
	if (!chan)
		return NULL;

	hash_append(cl->ht_numb, numb, &chan->he_numb, chan);
	hash_append(cl->ht_peer, sa_hash(peer, SA_ALL), &chan->he_peer, chan);

	chan->peer = *peer;
	chan->numb = numb;
	chan->al = al;
	chan->expires = time(NULL) + CHAN_LIFETIME;

	restund_debug("turn: allocation %p channel 0x%x %J created\n",
		      chan->al, chan->numb, &chan->peer);

	return chan;
}
Beispiel #2
0
/**
 * Add TURN Permission for a peer
 *
 * @param turnc TURN Client
 * @param peer  Peer IP-address
 * @param ph    Permission handler
 * @param arg   Handler argument
 *
 * @return 0 if success, otherwise errorcode
 */
int turnc_add_perm(struct turnc *turnc, const struct sa *peer,
		   turnc_perm_h *ph, void *arg)
{
	struct perm *perm;
	int err;

	if (!turnc || !peer)
		return EINVAL;

	if (perm_find(turnc, peer))
		return 0;

	perm = mem_zalloc(sizeof(*perm), destructor);
	if (!perm)
		return ENOMEM;

	hash_append(turnc->perms, sa_hash(peer, SA_ADDR), &perm->he, perm);
	tmr_init(&perm->tmr);
	perm->peer = *peer;
	perm->turnc = turnc;
	perm->ph = ph;
	perm->arg = arg;

	err = createperm_request(perm, true);
	if (err)
		mem_deref(perm);

	return err;
}
int  sip_keepalive_udp(struct sip_keepalive *ka, struct sip *sip,
		       struct udp_sock *us, const struct sa *paddr,
		       uint32_t interval)
{
	struct sip_udpconn *uc;

	if (!ka || !sip || !us || !paddr)
		return EINVAL;

	uc = udpconn_find(sip, us, paddr);
	if (!uc) {
		uc = mem_zalloc(sizeof(*uc), destructor);
		if (!uc)
			return ENOMEM;

		hash_append(sip->ht_udpconn, sa_hash(paddr, SA_ALL),
			    &uc->he, uc);

		uc->paddr = *paddr;
		uc->stun  = mem_ref(sip->stun);
		uc->us    = mem_ref(us);
		uc->ka_interval = interval ? interval : UDP_KEEPALIVE_INTVAL;

		/* learn mapped address immediately */
		tmr_start(&uc->tmr_ka, 0, udpconn_keepalive_handler, uc);
	}

	list_append(&uc->kal, &ka->le, ka);

	return 0;
}
Beispiel #4
0
void one_add(struct tcuplinks *ups, struct uplink*up)
{
    int hash;
    struct uplink *nup;
    nup = mem_alloc(sizeof(struct uplink), uplink_de);
    if(!nup) return;

    memcpy(nup, up, sizeof(struct uplink));
    memset(nup, 0, sizeof(struct le));
    mem_ref((void*)nup->uri.p);

    hash = hash_joaat_ci(up->uri.p, up->uri.l);

    void *found;
    found = hash_lookup(ups->data_c, hash, apply_find, NULL);

    hash_append(ups->uris_c, hash, &nup->le, nup);

    if (ups->up_h == NULL) {
        return;
    }

    if(found) {
	      ups->up_h(up, 2, ups->up_arg);
    } else {
	      ups->up_h(up, 1, ups->up_arg);
    }

}
Beispiel #5
0
/**
 * Add a contact
 *
 * @param contacts Contacts container
 * @param contactp Pointer to allocated contact (optional)
 * @param addr     Contact in SIP address format
 *
 * @return 0 if success, otherwise errorcode
 */
int contact_add(struct contacts *contacts,
		struct contact **contactp, const struct pl *addr)
{
	struct contact *c;
	struct pl pl;
	int err;

	if (!contacts)
		return EINVAL;

	c = mem_zalloc(sizeof(*c), destructor);
	if (!c)
		return ENOMEM;

	err = pl_strdup(&c->buf, addr);
	if (err)
		goto out;

	pl_set_str(&pl, c->buf);

	err = sip_addr_decode(&c->addr, &pl);
	if (err) {
		warning("contact: decode error '%r'\n", addr);
		goto out;
	}

	if (0 == msg_param_decode(&c->addr.params, "access", &pl)) {

		if (0 == pl_strcasecmp(&pl, "block")) {
			c->access = ACCESS_BLOCK;
		}
		else if (0 == pl_strcasecmp(&pl, "allow")) {
			c->access = ACCESS_ALLOW;
		}
		else {
			warning("contact: unknown 'access=%r' for '%r'\n",
				&pl, addr);
			err = EINVAL;
			goto out;
		}
	}
	else
		c->access = ACCESS_UNKNOWN;

	c->status = PRESENCE_UNKNOWN;

	list_append(&contacts->cl, &c->le, c);
	hash_append(contacts->cht, hash_joaat_pl(&c->addr.auri), &c->he, c);

 out:
	if (err)
		mem_deref(c);
	else if (contactp)
		*contactp = c;

	return err;
}
Beispiel #6
0
bool LedgerProposal::checkSign (std::string const& signature) const
{
    auto const valid = mPublicKey.verifyNodePublic(
        getSigningHash(), signature, ECDSA::not_strict);

    HashStream h;
    hash_append(h);
    assert(valid == (publicKey_.verify(
        Slice(h.data(), h.size()),
            makeSlice(signature), false)));

    return valid;
}
Beispiel #7
0
int device_connect(struct device **devp, const char *device,
		   struct auplay_st *auplay, struct ausrc_st *ausrc)
{
	struct device *dev;
	int err = 0;

	if (!devp)
		return EINVAL;
	if (!str_isset(device))
		return ENODEV;

	dev = find_device(device);
	if (dev) {
		*devp = mem_ref(dev);
	}
	else {
		dev = mem_zalloc(sizeof(*dev), destructor);
		if (!dev)
			return ENOMEM;

		str_ncpy(dev->name, device, sizeof(dev->name));

		hash_append(ht_device, hash_joaat_str(device), &dev->le, dev);

		*devp = dev;

		debug("aubridge: created device '%s'\n", device);
	}

	if (auplay)
		dev->auplay = auplay;
	if (ausrc)
		dev->ausrc = ausrc;

	/* wait until we have both SRC+PLAY */
	if (dev->ausrc && dev->auplay && !dev->run) {

		dev->run = true;
		err = pthread_create(&dev->thread, NULL, device_thread, dev);
		if (err) {
			dev->run = false;
		}
	}

	return err;
}
Beispiel #8
0
int sip_ctrans_request(struct sip_ctrans **ctp, struct sip *sip,
		       enum sip_transp tp, const struct sa *dst, char *met,
		       char *branch, struct mbuf *mb,
		       sip_resp_h *resph, void *arg)
{
	struct sip_ctrans *ct;
	int err;

	if (!sip || !dst || !met || !branch || !mb)
		return EINVAL;

	ct = mem_zalloc(sizeof(*ct), destructor);
	if (!ct)
		return ENOMEM;

	hash_append(sip->ht_ctrans, hash_joaat_str(branch), &ct->he, ct);

	ct->invite = !strcmp(met, "INVITE");
	ct->branch = mem_ref(branch);
	ct->met    = mem_ref(met);
	ct->mb     = mem_ref(mb);
	ct->dst    = *dst;
	ct->tp     = tp;
	ct->sip    = sip;
	ct->state  = ct->invite ? CALLING : TRYING;
	ct->resph  = resph ? resph : dummy_handler;
	ct->arg    = arg;

	err = sip_transp_send(&ct->qent, sip, NULL, tp, dst, mb,
			      transport_handler, ct);
	if (err)
		goto out;

	tmr_start(&ct->tmr, 64 * SIP_T1, tmr_handler, ct);

	if (!sip_transp_reliable(ct->tp))
		tmr_start(&ct->tmre, SIP_T1, retransmit_handler, ct);

 out:
	if (err)
		mem_deref(ct);
	else if (ctp)
		*ctp = ct;

	return err;
}
Beispiel #9
0
void http_header(struct request *request, char* hname, char* val)
{
    enum http_hdr_id id;
    struct http_hdr *hdr;
    char *tmp;

    hdr = mem_zalloc(sizeof(struct http_hdr), hdr_destruct2);
    re_sdprintf(&tmp, "%s", hname);
    pl_set_str(&hdr->name, tmp);

    re_sdprintf(&tmp, "%s", val);
    pl_set_str(&hdr->val, tmp);

    id = (enum http_hdr_id)hash_joaat_ci(hdr->name.p, hdr->name.l);
    id &= 0xFFF;

    hash_append(request->hdrht, id, &hdr->he, hdr);
}
Beispiel #10
0
static void tcp_connect_handler(const struct sa *paddr, void *arg)
{
	struct sip_transport *transp = arg;
	struct sip_conn *conn;
	int err;

	conn = mem_zalloc(sizeof(*conn), conn_destructor);
	if (!conn) {
		err = ENOMEM;
		goto out;
	}

	hash_append(transp->sip->ht_conn, sa_hash(paddr, SA_ALL),
		    &conn->he, conn);

	conn->paddr = *paddr;
	conn->sip   = transp->sip;

	err = tcp_accept(&conn->tc, transp->sock, tcp_estab_handler,
			 tcp_recv_handler, tcp_close_handler, conn);
	if (err)
		goto out;

	err = tcp_conn_local_get(conn->tc, &conn->laddr);
	if (err)
		goto out;

#ifdef USE_TLS
	if (transp->tls) {
		err = tls_start_tcp(&conn->sc, transp->tls, conn->tc, 0);
		if (err)
			goto out;
	}
#endif

	tmr_start(&conn->tmr, TCP_ACCEPT_TIMEOUT * 1000,
		  conn_tmr_handler, conn);

 out:
	if (err) {
		tcp_reject(transp->sock);
		mem_deref(conn);
	}
}
Beispiel #11
0
static void dname_append(struct hash *ht_dname, const char *name, size_t pos)
{
	struct dname *dn;

	if (!ht_dname || pos > OFFSET_MASK || !*name)
		return;

	dn = mem_zalloc(sizeof(*dn), destructor);
	if (!dn)
		return;

	if (str_dup(&dn->name, name)) {
		mem_deref(dn);
		return;
	}

	hash_append(ht_dname, hash_joaat_str_ci(name), &dn->he, dn);
	dn->pos = pos;
}
Beispiel #12
0
core::stringc CHashMD5::quickHash(core::stringc str)
{
	hash_start();
	hash_append((u8*)str.c_str(), str.size());
	u8 digest[16];
	hash_finish(digest, 16);
	c8 retstr[33];
	memset(retstr, 0, 33);
	c8* temp = retstr;
	for(int i = 0; i < 16; i++)
	{
		if((digest[i] & 0xff) > 0xf){
			sprintf(temp, "%x", (digest[i] & 0xff));
		}else{
			sprintf(temp, "0%x", (digest[i] & 0xff));
		}
		temp += 2;
	}
	core::stringc ret(retstr);
	return ret;
};
Beispiel #13
0
int vidbridge_disp_alloc(struct vidisp_st **stp, const struct vidisp *vd,
                         struct vidisp_prm *prm, const char *dev,
                         vidisp_resize_h *resizeh, void *arg)
{
    struct vidisp_st *st;
    int err = 0;
    (void)prm;
    (void)resizeh;
    (void)arg;

    if (!stp || !vd || !dev)
        return EINVAL;

    st = mem_zalloc(sizeof(*st), destructor);
    if (!st)
        return ENOMEM;

    st->vd = vd;

    err = str_dup(&st->device, dev);
    if (err)
        goto out;

    /* find the vidsrc with the same device-name */
    st->vidsrc = vidbridge_src_find(dev);
    if (st->vidsrc) {
        st->vidsrc->vidisp = st;
    }

    hash_append(ht_disp, hash_joaat_str(dev), &st->le, st);

out:
    if (err)
        mem_deref(st);
    else
        *stp = st;

    return err;
}
Beispiel #14
0
void hdr_add(struct request *req, enum http_hdr_id id, struct pl *name, struct pl *val)
{
    struct http_hdr *hdr;
    switch(id) {
    case HTTP_CONTENT_LENGTH:
        req->clen = pl_u32(val);
        break;
    case HTTP_WWW_AUTH:
        req->www_auth.l = val->l;
        req->www_auth.p = val->p;
        break;
    default:
        ;;
    }

    hdr = mem_zalloc(sizeof(struct http_hdr), hdr_destruct);
    hdr->name.l = name->l;
    hdr->name.p = name->p;
    hdr->val.l = val->l;
    hdr->val.p = val->p;

    hash_append(req->hdrht, id, &hdr->he, hdr);
}
Beispiel #15
0
static struct tls_conn *conn_alloc(struct tls_sock *ts, const struct sa *peer)
{
	struct tls_conn *tc;

	tc = mem_zalloc(sizeof(*tc), conn_destructor);
	if (!tc)
		return NULL;

	tc->ssl = SSL_new(ts->tls->ctx);
	if (!tc->ssl)
		goto error;

	tc->sbio_in = BIO_new(BIO_s_mem());
	if (!tc->sbio_in)
		goto error;

	tc->sbio_out = BIO_new(&bio_udp_send);
	if (!tc->sbio_out) {
		BIO_free(tc->sbio_in);
		goto error;
	}
	tc->sbio_out->ptr = tc;

	SSL_set_bio(tc->ssl, tc->sbio_in, tc->sbio_out);

	tmr_init(&tc->tmr);

	tc->peer = *peer;
	tc->ts   = ts;

	hash_append(ts->ht_conn, sa_hash(peer, SA_ALL), &tc->he, tc);

	return tc;

 error:
	return mem_deref(tc);
}
Beispiel #16
0
static int tcpconn_alloc(struct tcpconn **tcpp, struct dnsc *dnsc,
			 const struct sa *srv)
{
	struct tcpconn *tc;
	int err = ENOMEM;

	if (!tcpp || !dnsc || !srv)
		return EINVAL;

	tc = mem_zalloc(sizeof(struct tcpconn), tcpconn_destructor);
	if (!tc)
		goto out;

	hash_append(dnsc->ht_tcpconn, sa_hash(srv, SA_ALL), &tc->le, tc);
	tc->srv = *srv;
	tc->dnsc = dnsc;

	tc->mb = mbuf_alloc(1500);
	if (!tc->mb)
		goto out;

	err = tcp_connect(&tc->conn, srv, tcp_estab_handler,
			  tcp_recv_handler, tcp_close_handler, tc);
	if (err)
		goto out;

	tmr_start(&tc->tmr, tc->dnsc->conf.conn_timeout,
		  tcpconn_timeout_handler, tc);
 out:
	if (err)
		mem_deref(tc);
	else
		*tcpp = tc;

	return err;
}
Beispiel #17
0
static int conn_send(struct sip_connqent **qentp, struct sip *sip, bool secure,
		     const struct sa *dst, struct mbuf *mb,
		     sip_transp_h *transph, void *arg)
{
	struct sip_conn *conn, *new_conn = NULL;
	struct sip_connqent *qent;
	int err = 0;

	conn = conn_find(sip, dst, secure);
	if (conn) {
		if (!conn->established)
			goto enqueue;

		return tcp_send(conn->tc, mb);
	}

	new_conn = conn = mem_zalloc(sizeof(*conn), conn_destructor);
	if (!conn)
		return ENOMEM;

	hash_append(sip->ht_conn, sa_hash(dst, SA_ALL), &conn->he, conn);
	conn->paddr = *dst;
	conn->sip   = sip;

	err = tcp_connect(&conn->tc, dst, tcp_estab_handler, tcp_recv_handler,
			  tcp_close_handler, conn);
	if (err)
		goto out;

	err = tcp_conn_local_get(conn->tc, &conn->laddr);
	if (err)
		goto out;

#ifdef USE_TLS
	if (secure) {
		const struct sip_transport *transp;

		transp = transp_find(sip, SIP_TRANSP_TLS, sa_af(dst), dst);
		if (!transp || !transp->tls) {
			err = EPROTONOSUPPORT;
			goto out;
		}

		err = tls_start_tcp(&conn->sc, transp->tls, conn->tc, 0);
		if (err)
			goto out;
	}
#endif

	tmr_start(&conn->tmr, TCP_IDLE_TIMEOUT * 1000, conn_tmr_handler, conn);

 enqueue:
	qent = mem_zalloc(sizeof(*qent), qent_destructor);
	if (!qent) {
		err = ENOMEM;
		goto out;

	}

	list_append(&conn->ql, &qent->le, qent);
	qent->mb = mem_ref(mb);
	qent->transph = transph ? transph : internal_transport_handler;
	qent->arg = arg;

	if (qentp) {
		qent->qentp = qentp;
		*qentp = qent;
	}

 out:
	if (err)
		mem_deref(new_conn);

	return err;
}
Beispiel #18
0
int sipevent_accept(struct sipnot **notp, struct sipevent_sock *sock,
		    const struct sip_msg *msg, struct sip_dialog *dlg,
		    const struct sipevent_event *event,
		    uint16_t scode, const char *reason, uint32_t expires_min,
		    uint32_t expires_dfl, uint32_t expires_max,
		    const char *cuser, const char *ctype,
		    sip_auth_h *authh, void *aarg, bool aref,
		    sipnot_close_h *closeh, void *arg, const char *fmt, ...)
{
	struct sipnot *not;
	uint32_t expires;
	int err;

	if (!notp || !sock || !msg || !scode || !reason || !expires_dfl ||
	    !expires_max || !cuser || !ctype || expires_dfl < expires_min)
		return EINVAL;

	not = mem_zalloc(sizeof(*not), destructor);
	if (!not)
		return ENOMEM;

	if (!pl_strcmp(&msg->met, "REFER")) {

		err = str_dup(&not->event, "refer");
		if (err)
			goto out;

		err = re_sdprintf(&not->id, "%u", msg->cseq.num);
		if (err)
			goto out;
	}
	else {
		if (!event) {
			err = EINVAL;
			goto out;
		}

		err = pl_strdup(&not->event, &event->event);
		if (err)
			goto out;

		if (pl_isset(&event->id)) {

			err = pl_strdup(&not->id, &event->id);
			if (err)
				goto out;
		}
	}

	if (dlg) {
		not->dlg = mem_ref(dlg);
	}
	else {
		err = sip_dialog_accept(&not->dlg, msg);
		if (err)
			goto out;
	}

	hash_append(sock->ht_not,
		    hash_joaat_str(sip_dialog_callid(not->dlg)),
		    &not->he, not);

	err = sip_auth_alloc(&not->auth, authh, aarg, aref);
	if (err)
		goto out;

	err = str_dup(&not->cuser, cuser);
	if (err)
		goto out;

	err = str_dup(&not->ctype, ctype);
	if (err)
		goto out;

	if (fmt) {
		va_list ap;

		va_start(ap, fmt);
		err = re_vsdprintf(&not->hdrs, fmt, ap);
		va_end(ap);
		if (err)
			goto out;
	}

	not->expires_min = expires_min;
	not->expires_dfl = expires_dfl;
	not->expires_max = expires_max;
	not->substate = SIPEVENT_PENDING;
	not->sock   = mem_ref(sock);
	not->sip    = mem_ref(sock->sip);
	not->closeh = closeh ? closeh : internal_close_handler;
	not->arg    = arg;

	if (pl_isset(&msg->expires))
		expires = pl_u32(&msg->expires);
	else
		expires = not->expires_dfl;

	sipnot_refresh(not, expires);

	err = sipnot_reply(not, msg, scode, reason);
	if (err)
		goto out;

	not->subscribed = true;

 out:
	if (err)
		mem_deref(not);
	else
		*notp = not;

	return err;
}
Beispiel #19
0
    void run() override
    {
        // used to verify set insertion (hashing required)
        std::unordered_set<test96, hardened_hash<>> uset;

        Blob raw { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 };
        BEAST_EXPECT(test96::bytes == raw.size());

        test96 u { raw };
        uset.insert(u);
        BEAST_EXPECT(raw.size() == u.size());
        BEAST_EXPECT(to_string(u) == "0102030405060708090A0B0C");
        BEAST_EXPECT(*u.data() == 1);
        BEAST_EXPECT(u.signum() == 1);
        BEAST_EXPECT(!!u);
        BEAST_EXPECT(!u.isZero());
        BEAST_EXPECT(u.isNonZero());
        unsigned char t = 0;
        for (auto& d : u)
        {
            BEAST_EXPECT(d == ++t);
        }

        // Test hash_append by "hashing" with a no-op hasher (h)
        // and then extracting the bytes that were written during hashing
        // back into another base_uint (w) for comparison with the original
        nonhash<96> h;
        hash_append(h, u);
        test96 w {std::vector<std::uint8_t>(h.data_.begin(), h.data_.end())};
        BEAST_EXPECT(w == u);

        test96 v { ~u };
        uset.insert(v);
        BEAST_EXPECT(to_string(v) == "FEFDFCFBFAF9F8F7F6F5F4F3");
        BEAST_EXPECT(*v.data() == 0xfe);
        BEAST_EXPECT(v.signum() == 1);
        BEAST_EXPECT(!!v);
        BEAST_EXPECT(!v.isZero());
        BEAST_EXPECT(v.isNonZero());
        t = 0xff;
        for (auto& d : v)
        {
            BEAST_EXPECT(d == --t);
        }

        BEAST_EXPECT(compare(u, v) < 0);
        BEAST_EXPECT(compare(v, u) > 0);

        v = u;
        BEAST_EXPECT(v == u);

        test96 z { beast::zero };
        uset.insert(z);
        BEAST_EXPECT(to_string(z) == "000000000000000000000000");
        BEAST_EXPECT(*z.data() == 0);
        BEAST_EXPECT(*z.begin() == 0);
        BEAST_EXPECT(*std::prev(z.end(), 1) == 0);
        BEAST_EXPECT(z.signum() == 0);
        BEAST_EXPECT(!z);
        BEAST_EXPECT(z.isZero());
        BEAST_EXPECT(!z.isNonZero());
        for (auto& d : z)
        {
            BEAST_EXPECT(d == 0);
        }

        test96 n { z };
        n++;
        BEAST_EXPECT(n == test96(1));
        n--;
        BEAST_EXPECT(n == beast::zero);
        BEAST_EXPECT(n == z);
        n--;
        BEAST_EXPECT(to_string(n) == "FFFFFFFFFFFFFFFFFFFFFFFF");
        n = beast::zero;
        BEAST_EXPECT(n == z);

        test96 zp1 { z };
        zp1++;
        test96 zm1 { z };
        zm1--;
        test96 x { zm1 ^ zp1 };
        uset.insert(x);
        BEAST_EXPECTS(to_string(x) == "FFFFFFFFFFFFFFFFFFFFFFFE", to_string(x));

        BEAST_EXPECT(uset.size() == 4);

        // SetHex tests...
        test96 fromHex;
        BEAST_EXPECT(fromHex.SetHexExact(to_string(u)));
        BEAST_EXPECT(fromHex == u);
        fromHex = z;

        // fails with extra char
        BEAST_EXPECT(! fromHex.SetHexExact("A" + to_string(u)));
        fromHex = z;

        // fails with extra char at end
        BEAST_EXPECT(! fromHex.SetHexExact(to_string(u) + "A"));
        // NOTE: the value fromHex is actually correctly parsed
        // in this case, but that is an implementation detail and
        // not guaranteed, thus we don't check the value here.
        fromHex = z;

        BEAST_EXPECT(fromHex.SetHex(to_string(u)));
        BEAST_EXPECT(fromHex == u);
        fromHex = z;

        // leading space/0x allowed if not strict
        BEAST_EXPECT(fromHex.SetHex("  0x" + to_string(u)));
        BEAST_EXPECT(fromHex == u);
        fromHex = z;

        // other leading chars also allowed (ignored)
        BEAST_EXPECT(fromHex.SetHex("FEFEFE" + to_string(u)));
        BEAST_EXPECT(fromHex == u);
        fromHex = z;

        // invalid hex chars should fail (0 replaced with Z here)
        BEAST_EXPECT(! fromHex.SetHex(
            boost::algorithm::replace_all_copy(to_string(u), "0", "Z")));
        fromHex = z;

        BEAST_EXPECT(fromHex.SetHex(to_string(u), true));
        BEAST_EXPECT(fromHex == u);
        fromHex = z;

        // strict mode fails with leading chars
        BEAST_EXPECT(! fromHex.SetHex("  0x" + to_string(u), true));
        fromHex = z;

        // SetHex ignores extra leading hexits, so the parsed value
        // is still correct for the following case (strict or non-strict)
        BEAST_EXPECT(fromHex.SetHex("DEAD" + to_string(u), true ));
        BEAST_EXPECT(fromHex == u);
        fromHex = z;

        BEAST_EXPECT(fromHex.SetHex("DEAD" + to_string(u), false ));
        BEAST_EXPECT(fromHex == u);
        fromHex = z;
    }
Beispiel #20
0
static inline int hdr_add(struct sip_msg *msg, const struct pl *name,
			  enum sip_hdrid id, const char *p, ssize_t l,
			  bool atomic, bool line)
{
	struct sip_hdr *hdr;
	int err = 0;

	hdr = mem_zalloc(sizeof(*hdr), hdr_destructor);
	if (!hdr)
		return ENOMEM;

	hdr->name  = *name;
	hdr->val.p = p;
	hdr->val.l = MAX(l, 0);
	hdr->id    = id;

	switch (id) {

	case SIP_HDR_VIA:
	case SIP_HDR_ROUTE:
		if (!atomic)
			break;

		hash_append(msg->hdrht, id, &hdr->he, mem_ref(hdr));
		list_append(&msg->hdrl, &hdr->le, mem_ref(hdr));
		break;

	default:
		if (atomic)
			hash_append(msg->hdrht, id, &hdr->he, mem_ref(hdr));
		if (line)
			list_append(&msg->hdrl, &hdr->le, mem_ref(hdr));
		break;
	}

	/* parse common headers */
	switch (id) {

	case SIP_HDR_VIA:
		if (!atomic || pl_isset(&msg->via.sentby))
			break;

		err = sip_via_decode(&msg->via, &hdr->val);
		break;

	case SIP_HDR_TO:
		err = sip_addr_decode((struct sip_addr *)&msg->to, &hdr->val);
		if (err)
			break;

		(void)msg_param_decode(&msg->to.params, "tag", &msg->to.tag);
		msg->to.val = hdr->val;
		break;

	case SIP_HDR_FROM:
		err = sip_addr_decode((struct sip_addr *)&msg->from,
				      &hdr->val);
		if (err)
			break;

		(void)msg_param_decode(&msg->from.params, "tag",
				       &msg->from.tag);
		msg->from.val = hdr->val;
		break;

	case SIP_HDR_CALL_ID:
		msg->callid = hdr->val;
		break;

	case SIP_HDR_CSEQ:
		err = sip_cseq_decode(&msg->cseq, &hdr->val);
		break;

	case SIP_HDR_MAX_FORWARDS:
		msg->maxfwd = hdr->val;
		break;

	case SIP_HDR_CONTENT_TYPE:
		err = msg_ctype_decode(&msg->ctyp, &hdr->val);
		break;

	case SIP_HDR_CONTENT_LENGTH:
		msg->clen = hdr->val;
		break;

	case SIP_HDR_EXPIRES:
		msg->expires = hdr->val;
		break;

	default:
		/* re_printf("%r = %u\n", &hdr->name, id); */
		break;
	}

	mem_deref(hdr);

	return err;
}
Beispiel #21
0
/**
 * Connect to a remote SIP useragent
 *
 * @param sessp     Pointer to allocated SIP Session
 * @param sock      SIP Session socket
 * @param to_uri    To SIP uri
 * @param from_name From display name
 * @param from_uri  From SIP uri
 * @param cuser     Contact username or URI
 * @param routev    Outbound route vector
 * @param routec    Outbound route vector count
 * @param ctype     Session content-type
 * @param desc      Content description (e.g. SDP)
 * @param authh     SIP Authentication handler
 * @param aarg      Authentication handler argument
 * @param aref      True to mem_ref() aarg
 * @param offerh    Session offer handler
 * @param answerh   Session answer handler
 * @param progrh    Session progress handler
 * @param estabh    Session established handler
 * @param infoh     Session info handler
 * @param referh    Session refer handler
 * @param closeh    Session close handler
 * @param arg       Handler argument
 * @param fmt       Formatted strings with extra SIP Headers
 *
 * @return 0 if success, otherwise errorcode
 */
int sipsess_connect(struct sipsess **sessp, struct sipsess_sock *sock,
		    const char *to_uri, const char *from_name,
		    const char *from_uri, const char *cuser,
		    const char *routev[], uint32_t routec,
		    const char *ctype, struct mbuf *desc,
		    sip_auth_h *authh, void *aarg, bool aref,
		    sipsess_offer_h *offerh, sipsess_answer_h *answerh,
		    sipsess_progr_h *progrh, sipsess_estab_h *estabh,
		    sipsess_info_h *infoh, sipsess_refer_h *referh,
		    sipsess_close_h *closeh, void *arg, const char *fmt, ...)
{
	struct sipsess *sess;
	int err;

	if (!sessp || !sock || !to_uri || !from_uri || !cuser || !ctype)
		return EINVAL;

	err = sipsess_alloc(&sess, sock, cuser, ctype, desc, authh, aarg, aref,
			    offerh, answerh, progrh, estabh, infoh, referh,
			    closeh, arg);
	if (err)
		return err;

	/* Custom SIP headers */
	if (fmt) {
		va_list ap;

		sess->hdrs = mbuf_alloc(256);
		if (!sess->hdrs) {
			err = ENOMEM;
			goto out;
		}

		va_start(ap, fmt);
		err = mbuf_vprintf(sess->hdrs, fmt, ap);
		sess->hdrs->pos = 0;
		va_end(ap);

		if (err)
			goto out;
	}

	sess->owner = true;

	err = sip_dialog_alloc(&sess->dlg, to_uri, to_uri, from_name,
			       from_uri, routev, routec);
	if (err)
		goto out;

	hash_append(sock->ht_sess,
		    hash_joaat_str(sip_dialog_callid(sess->dlg)),
		    &sess->he, sess);

	err = invite(sess);
	if (err)
		goto out;

 out:
	if (err)
		mem_deref(sess);
	else
		*sessp = sess;

	return err;
}
Beispiel #22
0
/**
 * Accept an incoming SIP Session connection
 *
 * @param sessp     Pointer to allocated SIP Session
 * @param sock      SIP Session socket
 * @param msg       Incoming SIP message
 * @param scode     Response status code
 * @param reason    Response reason phrase
 * @param cuser     Contact username
 * @param ctype     Session content-type
 * @param desc      Content description (e.g. SDP)
 * @param authh     SIP Authentication handler
 * @param aarg      Authentication handler argument
 * @param aref      True to mem_ref() aarg
 * @param offerh    Session offer handler
 * @param answerh   Session answer handler
 * @param estabh    Session established handler
 * @param infoh     Session info handler
 * @param referh    Session refer handler
 * @param closeh    Session close handler
 * @param arg       Handler argument
 * @param fmt       Formatted strings with extra SIP Headers
 *
 * @return 0 if success, otherwise errorcode
 */
int sipsess_accept(struct sipsess **sessp, struct sipsess_sock *sock,
		   const struct sip_msg *msg, uint16_t scode,
		   const char *reason, const char *cuser, const char *ctype,
		   struct mbuf *desc,
		   sip_auth_h *authh, void *aarg, bool aref,
		   sipsess_offer_h *offerh, sipsess_answer_h *answerh,
		   sipsess_estab_h *estabh, sipsess_info_h *infoh,
		   sipsess_refer_h *referh, sipsess_close_h *closeh,
		   void *arg, const char *fmt, ...)
{
	struct sipsess *sess;
	va_list ap;
	int err;

	if (!sessp || !sock || !msg || scode < 101 || scode > 299 ||
	    !cuser || !ctype)
		return EINVAL;

	err = sipsess_alloc(&sess, sock, cuser, ctype, NULL, authh, aarg, aref,
			    offerh, answerh, NULL, estabh, infoh, referh,
			    closeh, arg);
	if (err)
		return err;

	err = sip_dialog_accept(&sess->dlg, msg);
	if (err)
		goto out;

	hash_append(sock->ht_sess,
		    hash_joaat_str(sip_dialog_callid(sess->dlg)),
		    &sess->he, sess);

	sess->msg = mem_ref((void *)msg);

	err = sip_strans_alloc(&sess->st, sess->sip, msg, cancel_handler,
			       sess);
	if (err)
		goto out;

	va_start(ap, fmt);

	if (scode >= 200)
		err = sipsess_reply_2xx(sess, msg, scode, reason, desc,
					fmt, &ap);
	else
		err = sip_treplyf(&sess->st, NULL, sess->sip,
				  msg, true, scode, reason,
				  "Contact: <sip:%s@%J%s>\r\n"
				  "%v"
				  "%s%s%s"
				  "Content-Length: %zu\r\n"
				  "\r\n"
				  "%b",
				  sess->cuser, &msg->dst,
				  sip_transp_param(msg->tp),
				  fmt, &ap,
				  desc ? "Content-Type: " : "",
				  desc ? sess->ctype : "",
				  desc ? "\r\n" : "",
				  desc ? mbuf_get_left(desc) : (size_t)0,
				  desc ? mbuf_buf(desc) : NULL,
				  desc ? mbuf_get_left(desc) : (size_t)0);

	va_end(ap);

	if (err)
		goto out;

 out:
	if (err)
		mem_deref(sess);
	else
		*sessp = sess;

	return err;
}
Beispiel #23
0
/*
 * Manage a new provider -> read information and add symbols.
 */
static guint
gdisp_insertProvider ( Kernel_T *kernel,
                       gchar    *url )
{

    TSP_provider_t            *provider      = NULL;
    Provider_T                *newProvider   = (Provider_T*)NULL;
    Symbol_T                  *symbolList    = (Symbol_T*)NULL;
    GString                   *messageString = (GString*)NULL;
    gint                       symbolCpt     = 0;
    gint                       requestStatus = 0;
    TSP_sample_symbol_info_t  *symbolInfo    = (TSP_sample_symbol_info_t*)NULL;
    const TSP_answer_sample_t *providerInfo  = (const TSP_answer_sample_t*)NULL;

    /*
     * Check the original url is not known yet.
     */
    if (gdisp_getProviderByOriginalUrl(kernel,url) != (Provider_T*)NULL) {
        return -1;
    }

    /*
     * Try to connect to the URL.
     */
    provider = TSP_consumer_connect_url(url);

    if (provider != (TSP_provider_t*)NULL) {

        /*
         * Store all available information for this provider.
         */

        /*
         * Allocate memory for this new provider.
         * Set up its status to 'FROM_SCRATCH'.
         */
        newProvider = (Provider_T*)g_malloc0(sizeof(Provider_T));
        assert(newProvider);

        newProvider->pStatus = GD_FROM_SCRATCH;


        /*
         * Now store the handle, get back the name.
         * Set up its status to 'SESSION_CLOSED'.
         * Insert it into the kernel provider list.
         */
        newProvider->pOriginalUrl = g_string_new(url);
        newProvider->pHandle      = provider;
        newProvider->pIdentity    = kernel->providerId++ % GD_MAX_PROVIDER_NUMBER;
        newProvider->pUrl         =
            g_string_new(TSP_consumer_get_connected_name(newProvider->pHandle));
        assert(newProvider->pUrl);

        newProvider->pStatus = GD_SESSION_CLOSED;

        kernel->providerList = g_list_insert_sorted(kernel->providerList,
                               (gpointer)newProvider,
                               gdisp_sortProviderByUrl);
        assert(kernel->providerList);


        /*
         * Ask the provider for a new consumer session.
         * Set up its status to 'SESSION_OPENED'.
         */
        requestStatus = TSP_consumer_request_open(newProvider->pHandle,
                        (gint)NULL,
                        (gchar**)NULL);

        if (TSP_STATUS_OK == requestStatus) {

            /*
             * Now the session is opened, get back all available information.
             * Keep the current status, since symbols are not requested here.
             */
            if (kernel->retreiveAllSymbols == TRUE) {
                requestStatus =
                    TSP_consumer_request_information(newProvider->pHandle);
            }
            else {
                requestStatus =
                    TSP_consumer_request_filtered_information(newProvider->pHandle,
                            TSP_FILTER_MINIMAL,
                            MINIMAL_STRING);
            }

            if (TSP_STATUS_OK == requestStatus) {

                /* Do not free 'providerInfo' structure */
                providerInfo = TSP_consumer_get_information(newProvider->pHandle);
                assert(providerInfo);

                newProvider->pVersionId           = providerInfo->version_id;
                newProvider->pChannelId           = providerInfo->channel_id;
                newProvider->pTimeOut             = providerInfo->provider_timeout;
                newProvider->pGroupNumber         = providerInfo->provider_group_number;
                newProvider->pBaseFrequency       = providerInfo->base_frequency;
                newProvider->pMaxPeriod           = providerInfo->max_period;
                newProvider->pMaxClientNumber     = providerInfo->max_client_number;
                newProvider->pCurrentClientNumber = providerInfo->current_client_number;
                newProvider->pSymbolNumber        = providerInfo->symbols.TSP_sample_symbol_info_list_t_len;

                /*
                 * Shall I retreive all symbols ?? It depends on the action.
                 */
                if (kernel->retreiveAllSymbols == TRUE) {

                    if (newProvider->pSymbolNumber > 0) {

                        /*
                         * Allocate symbol table.
                         */
                        newProvider->pSymbolList = (Symbol_T*)
                                                   g_malloc0(newProvider->pSymbolNumber * sizeof(Symbol_T));
                        assert(newProvider->pSymbolList);

                        /*
                         * Allocate symbol hash table for extra-boosted search.
                         */
                        newProvider->pSymbolHashTable = hash_open('.','z');
                        assert(newProvider->pSymbolHashTable);

                    }

                    /*
                     * Loop over all symbols.
                     */
                    symbolInfo = providerInfo->symbols.TSP_sample_symbol_info_list_t_val;
                    symbolList = newProvider->pSymbolList;

                    for (symbolCpt=0;
                            symbolCpt<newProvider->pSymbolNumber;
                            symbolCpt++, symbolList++, symbolInfo++) {

                        /* copy the whole structure... */
                        symbolList->sInfo = *symbolInfo;
                        symbolList->sPgi  =  symbolInfo->provider_global_index;

                        /* ... and do not forget to duplicate pointers */
                        symbolList->sInfo.name = gdisp_strDup(symbolInfo->name);

                        /* Default is : at maximum frequency without offset */
                        symbolList->sInfo.period = 1;
                        symbolList->sInfo.phase  = 0;

                        /* do not treat table */
                        if (symbolList->sInfo.dimension > 1) {
                            symbolList->sInfo.provider_global_index = -1;
                            symbolList->sPgi = -1;
                        }

                        /* initialize extrema */
                        symbolList->sMinimum = - G_MAXDOUBLE;
                        symbolList->sMaximum = + G_MAXDOUBLE;

                        /* insert symbol into hash table */
                        hash_append(newProvider->pSymbolHashTable,
                                    symbolList->sInfo.name,
                                    (void*)symbolList);

                    } /* symbolCpt */

                    /*
                     * Build PGI to symbol hash table.
                     */
                    gdisp_buildProviderPgiHashTable(newProvider,
                                                    &providerInfo->symbols);

                    /*
                     * Get symbol extended information.
                     */
                    gdisp_getSymbolExtendedInformation(newProvider,
                                                       TRUE /* forget any previous info */);

                } /* retreiveAllSymbols == TRUE */

                /*
                 * Session is now opened towards provider.
                 */
                newProvider->pStatus = GD_SESSION_OPENED;

                messageString = g_string_new((gchar*)NULL);
                g_string_sprintf(messageString,
                                 "Session opened on <%s>",
                                 newProvider->pUrl->str);
                (*kernel->outputFunc)(kernel,messageString,GD_MESSAGE);


            } /* requestStatus == TRUE (TSP_consumer_request_information) */

            else {

                messageString = g_string_new((gchar*)NULL);
                g_string_sprintf(messageString,"Cannot get back information from");
                (*kernel->outputFunc)(kernel,messageString,GD_ERROR);

                messageString = g_string_new((gchar*)NULL);
                g_string_sprintf(messageString,
                                 "<%s> provider. Session is closed.",
                                 newProvider->pUrl->str);
                (*kernel->outputFunc)(kernel,messageString,GD_ERROR);

            }

        } /* requestStatus == TRUE (TSP_consumer_request_open) */

        else {

            messageString = g_string_new((gchar*)NULL);
            g_string_sprintf(messageString,"Cannot open a session towards");
            (*kernel->outputFunc)(kernel,messageString,GD_ERROR);

            messageString = g_string_new((gchar*)NULL);
            g_string_sprintf(messageString,
                             "<%s> provider. Aborting.",
                             newProvider->pUrl->str);
            (*kernel->outputFunc)(kernel,messageString,GD_ERROR);

        }

    } /* End if available provider */

    else {

        messageString = g_string_new((gchar*)NULL);
        g_string_sprintf(messageString,
                         "No TSP provider found on host %s.",
                         url);
        (*kernel->outputFunc)(kernel,messageString,GD_ERROR);

    }

    return (provider == NULL ? -1 : 0);

}
Beispiel #24
0
static int query(struct dns_query **qp, struct dnsc *dnsc, uint8_t opcode,
		 const char *name, uint16_t type, uint16_t dnsclass,
		 const struct dnsrr *ans_rr, int proto,
		 const struct sa *srvv, const uint32_t *srvc,
		 bool aa, bool rd, dns_query_h *qh, void *arg)
{
	struct dns_query *q = NULL;
	struct dnshdr hdr;
	int err = 0;
	uint32_t i;

	if (!dnsc || !name || !srvv || !srvc || !(*srvc))
		return EINVAL;

	if (DNS_QTYPE_AXFR == type)
		proto = IPPROTO_TCP;

	q = mem_zalloc(sizeof(*q), query_destructor);
	if (!q)
		goto nmerr;

	hash_append(dnsc->ht_query, hash_joaat_str_ci(name), &q->le, q);
	tmr_init(&q->tmr);
	mbuf_init(&q->mb);

	for (i=0; i<ARRAY_SIZE(q->rrlv); i++)
		list_init(&q->rrlv[i]);

	err = str_dup(&q->name, name);
	if (err)
		goto error;

	q->srvv = srvv;
	q->srvc = srvc;
	q->id   = rand_u16();
	q->type = type;
	q->opcode = opcode;
	q->dnsclass = dnsclass;
	q->dnsc = dnsc;

	memset(&hdr, 0, sizeof(hdr));

	hdr.id = q->id;
	hdr.opcode = q->opcode;
	hdr.aa = aa;
	hdr.rd = rd;
	hdr.nq = 1;
	hdr.nans = ans_rr ? 1 : 0;

	if (proto == IPPROTO_TCP)
		q->mb.pos += 2;

	err = dns_hdr_encode(&q->mb, &hdr);
	if (err)
		goto error;

	err = dns_dname_encode(&q->mb, name, NULL, 0, false);
	if (err)
		goto error;

	err |= mbuf_write_u16(&q->mb, htons(type));
	err |= mbuf_write_u16(&q->mb, htons(dnsclass));
	if (err)
		goto error;

	if (ans_rr) {
		err = dns_rr_encode(&q->mb, ans_rr, 0, NULL, 0);
		if (err)
			goto error;
	}

	q->qh  = qh;
	q->arg = arg;

	switch (proto) {

	case IPPROTO_TCP:
		q->mb.pos = 0;
		(void)mbuf_write_u16(&q->mb, htons(q->mb.end - 2));

		err = send_tcp(q);
		if (err)
			goto error;

		tmr_start(&q->tmr, 60 * 1000, tcp_timeout_handler, q);
		break;

	case IPPROTO_UDP:
		err = send_udp(q);
		if (err)
			goto error;

		tmr_start(&q->tmr, 500, udp_timeout_handler, q);
		break;

	default:
		err = EPROTONOSUPPORT;
		goto error;
	}

	if (qp) {
		q->qp = qp;
		*qp = q;
	}

	return 0;

 nmerr:
	err = ENOMEM;
 error:
	mem_deref(q);

	return err;
}