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; }
/** * 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; }
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); } }
/** * 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; }
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; }
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; }
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; }
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); }
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); } }
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; }
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; };
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; }
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); }
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); }
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; }
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; }
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(¬->event, "refer"); if (err) goto out; err = re_sdprintf(¬->id, "%u", msg->cseq.num); if (err) goto out; } else { if (!event) { err = EINVAL; goto out; } err = pl_strdup(¬->event, &event->event); if (err) goto out; if (pl_isset(&event->id)) { err = pl_strdup(¬->id, &event->id); if (err) goto out; } } if (dlg) { not->dlg = mem_ref(dlg); } else { err = sip_dialog_accept(¬->dlg, msg); if (err) goto out; } hash_append(sock->ht_not, hash_joaat_str(sip_dialog_callid(not->dlg)), ¬->he, not); err = sip_auth_alloc(¬->auth, authh, aarg, aref); if (err) goto out; err = str_dup(¬->cuser, cuser); if (err) goto out; err = str_dup(¬->ctype, ctype); if (err) goto out; if (fmt) { va_list ap; va_start(ap, fmt); err = re_vsdprintf(¬->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; }
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; }
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; }
/** * 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; }
/** * 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; }
/* * 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); }
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; }