static int normalize_uri(char **out, const char *uri, const struct uri *luri) { struct uri uri2; struct pl pl; int err; if (!out || !uri || !luri) return EINVAL; pl_set_str(&pl, uri); if (0 == uri_decode(&uri2, &pl)) { err = str_dup(out, uri); } else { uri2 = *luri; uri2.user = pl; uri2.password = pl_null; uri2.params = pl_null; err = re_sdprintf(out, "%H", uri_encode, &uri2); } return err; }
void tcsipcall_key(struct tcsipcall*call) { re_sdprintf(&call->ckey, "%d@%r->%r", call->tv.tv_sec, call->cdir ? &call->local->auri: &call->remote->auri, call->cdir ? &call->remote->auri : &call->local->auri ); }
/** Foundation is a hash of IP address and candidate type */ static int compute_foundation(struct cand *cand) { uint32_t v; v = sa_hash(&cand->addr, SA_ADDR); v ^= cand->type; return re_sdprintf(&cand->foundation, "%08x", v); }
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); }
int icem_rcand_add_prflx(struct cand **rcp, struct icem *icem, uint8_t compid, uint32_t prio, const struct sa *addr) { struct cand *rcand; int err; if (!icem || !addr) return EINVAL; rcand = mem_zalloc(sizeof(*rcand), cand_destructor); if (!rcand) return ENOMEM; list_append(&icem->rcandl, &rcand->le, rcand); rcand->type = CAND_TYPE_PRFLX; rcand->compid = compid; rcand->prio = prio; rcand->addr = *addr; err = re_sdprintf(&rcand->foundation, "%08x", rand_u32()); if (err) goto out; icecomp_printf(icem_comp_find(icem, compid), "added PeerReflexive remote candidate" " with priority %u (%J)\n", prio, addr); out: if (err) mem_deref(rcand); else if (rcp) *rcp = rcand; return err; }
/** * Allocate a SIP User-Agent * * @param uap Pointer to allocated User-Agent object * @param aor SIP Address-of-Record (AOR) * * @return 0 if success, otherwise errorcode */ int ua_alloc(struct ua **uap, const char *aor) { struct ua *ua; int err; if (!aor) return EINVAL; ua = mem_zalloc(sizeof(*ua), ua_destructor); if (!ua) return ENOMEM; MAGIC_INIT(ua); list_init(&ua->calls); #if HAVE_INET6 ua->af = uag.prefer_ipv6 ? AF_INET6 : AF_INET; #else ua->af = AF_INET; #endif /* Decode SIP address */ err = account_alloc(&ua->acc, aor); if (err) goto out; /* generate a unique contact-user, this is needed to route incoming requests when using multiple useragents */ err = re_sdprintf(&ua->cuser, "%r-%p", &ua->acc->luri.user, ua); if (err) goto out; if (ua->acc->sipnat) { ua_printf(ua, "Using sipnat: `%s'\n", ua->acc->sipnat); } if (ua->acc->mnat) { ua_printf(ua, "Using medianat `%s'\n", ua->acc->mnat->id); if (0 == str_casecmp(ua->acc->mnat->id, "ice")) add_extension(ua, "ice"); } if (ua->acc->menc) { ua_printf(ua, "Using media encryption `%s'\n", ua->acc->menc->id); } /* Register clients */ if (str_isset(uag.cfg->uuid)) add_extension(ua, "gruu"); if (0 == str_casecmp(ua->acc->sipnat, "outbound")) { size_t i; add_extension(ua, "path"); add_extension(ua, "outbound"); if (!str_isset(uag.cfg->uuid)) { warning("ua: outbound requires valid UUID!\n"); err = ENOSYS; goto out; } for (i=0; i<ARRAY_SIZE(ua->acc->outbound); i++) { if (ua->acc->outbound[i] && ua->acc->regint) { err = reg_add(&ua->regl, ua, (int)i+1); if (err) break; } } } else if (ua->acc->regint) { err = reg_add(&ua->regl, ua, 0); } if (err) goto out; list_append(&uag.ual, &ua->le, ua); if (ua->acc->regint) { err = ua_register(ua); } if (!uag_current()) uag_current_set(ua); out: if (err) mem_deref(ua); else if (uap) { *uap = ua; ua->uap = uap; } return err; }
int sdp_format_add(struct sdp_format **fmtp, struct sdp_media *m, bool prepend, const char *id, const char *name, uint32_t srate, uint8_t ch, sdp_fmtp_cmp_h *cmph, void *data, bool ref, const char *params, ...) { struct sdp_format *fmt; int err; if (!m) return EINVAL; if (!id && (m->dynpt > RTP_DYNPT_END)) return ERANGE; fmt = mem_zalloc(sizeof(*fmt), destructor); if (!fmt) return ENOMEM; if (prepend) list_prepend(&m->lfmtl, &fmt->le, fmt); else list_append(&m->lfmtl, &fmt->le, fmt); if (id) err = str_dup(&fmt->id, id); else err = re_sdprintf(&fmt->id, "%i", m->dynpt++); if (err) goto out; if (name) { err = str_dup(&fmt->name, name); if (err) goto out; } if (params) { va_list ap; va_start(ap, params); err = re_vsdprintf(&fmt->params, params, ap); va_end(ap); if (err) goto out; } fmt->pt = atoi(fmt->id); fmt->srate = srate; fmt->ch = ch; fmt->cmph = cmph; fmt->data = ref ? mem_ref(data) : data; fmt->ref = ref; fmt->sup = true; out: if (err) mem_deref(fmt); else if (fmtp) *fmtp = fmt; 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; }