Пример #1
0
static int send_handler(enum sip_transp tp, const struct sa *src,
			const struct sa *dst, struct mbuf *mb, void *arg)
{
	struct sipreg *reg = arg;
	int err;

	(void)dst;

	if (reg->expires > 0) {
		reg->laddr = *src;
		reg->tp = tp;
	}

	err = mbuf_printf(mb, "Contact: <sip:%s@%J%s>;expires=%u%s%s",
			  reg->cuser, &reg->laddr, sip_transp_param(reg->tp),
			  reg->expires,
			  reg->params ? ";" : "",
			  reg->params ? reg->params : "");

	if (reg->regid > 0)
		err |= mbuf_printf(mb, ";reg-id=%d", reg->regid);

	err |= mbuf_printf(mb, "\r\n");

	return err;
}
Пример #2
0
static void stats_handler(struct mbuf *mb)
{
	(void)mbuf_printf(mb, "allocs_cur %u\n", turnd.allocc_cur);
	(void)mbuf_printf(mb, "allocs_tot %llu\n", turnd.allocc_tot);
	(void)mbuf_printf(mb, "bytes_tx %llu\n", turnd.bytec_tx);
	(void)mbuf_printf(mb, "bytes_rx %llu\n", turnd.bytec_rx);
	(void)mbuf_printf(mb, "bytes_tot %llu\n",
			  turnd.bytec_tx + turnd.bytec_rx);
}
Пример #3
0
void chan_status(const struct chanlist *cl, struct mbuf *mb)
{
	if (!cl || !mb)
		return;

	(void)mbuf_printf(mb, "    channels:   ");
	(void)hash_apply(cl->ht_numb, status_handler, mb);
	(void)mbuf_printf(mb, "\n");
}
Пример #4
0
static void tcp_estab_handler(void *arg)
{
    DEBUG_INFO("connection established\n");
    int ok;
    struct request * request = arg;
    struct mbuf *mb;

    char CN[256];

    if(request->secure) {
	ok = tls_verify_cert(request->ssl, CN, sizeof(CN));
	if(ok!=0)
            goto fail;

	DEBUG_INFO("https CN %s\n", CN);

	ok = strcmp(request->host, CN);
	if(ok!=0)
	    goto fail;
    }

    mb = mbuf_alloc(1024);
    mbuf_printf(mb, "%s %s HTTP/1.1\r\n", request->meth, request->path);
    mbuf_printf(mb, "Host: %s\r\n", request->host);
    write_auth(request, mb);
    mbuf_write_str(mb, "Connection: close\r\n");

    hash_apply(request->hdrht, hdr_write, mb);
    hash_flush(request->hdrht);

    if(request->post) {
        request->post->pos = 0;
        mbuf_printf(mb, "Content-Length: %d\r\n",
            mbuf_get_left(request->post));

	if(request->form)
            mbuf_printf(mb, "Content-Type: "
	        "application/x-www-form-urlencoded\r\n");
        mbuf_printf(mb, "\r\n");
        mbuf_write_mem(mb, mbuf_buf(request->post),
			   mbuf_get_left(request->post));
    } else {
        mbuf_write_str(mb, "\r\n");
    }

    mb->pos = 0;

    tcp_send(request->tcp, mb);
    mem_deref(mb);

    return;

fail:
    DEBUG_WARNING("ssl fail %p %d\n", request->app->tls, ok);
}
Пример #5
0
/**
 * Connect an outgoing call to a given SIP uri
 *
 * @param ua        User-Agent
 * @param callp     Optional pointer to allocated call object
 * @param from_uri  Optional From uri, or NULL for default AOR
 * @param uri       SIP uri to connect to
 * @param params    Optional URI parameters
 * @param vmode     Video mode
 *
 * @return 0 if success, otherwise errorcode
 */
int ua_connect(struct ua *ua, struct call **callp,
	       const char *from_uri, const char *uri,
	       const char *params, enum vidmode vmode)
{
	struct call *call = NULL;
	struct mbuf *dialbuf;
	struct pl pl;
	int err = 0;

	if (!ua || !str_isset(uri))
		return EINVAL;

	dialbuf = mbuf_alloc(64);
	if (!dialbuf)
		return ENOMEM;

	if (params)
		err |= mbuf_printf(dialbuf, "<");

	err |= uri_complete(ua, dialbuf, uri);

	if (params) {
		err |= mbuf_printf(dialbuf, ";%s", params);
	}

	/* Append any optional URI parameters */
	err |= mbuf_write_pl(dialbuf, &ua->acc->luri.params);

	if (params)
		err |= mbuf_printf(dialbuf, ">");

	if (err)
		goto out;

	err = ua_call_alloc(&call, ua, vmode, NULL, NULL, from_uri);
	if (err)
		goto out;

	pl.p = (char *)dialbuf->buf;
	pl.l = dialbuf->end;

	err = call_connect(call, &pl);

	if (err)
		mem_deref(call);
	else if (callp)
		*callp = call;

 out:
	mem_deref(dialbuf);

	return err;
}
Пример #6
0
void write_auth(struct request *req, struct mbuf *mb)
{
    int err;
    struct realm *realm;
    uint8_t digest[MD5_SIZE];
    uint64_t cnonce;

    if(!req->auth)
        return;

    realm = req->auth;
    cnonce = rand_u64();

    err = mkdigest(digest, realm, req->meth, req->path, cnonce);

    err |= mbuf_write_str(mb, "Authorization: ");

    err |= mbuf_printf(mb, "Digest username=\"%s\"", realm->user);
    err |= mbuf_printf(mb, ", realm=\"%s\"", realm->realm);
    err |= mbuf_printf(mb, ", nonce=\"%s\"", realm->nonce);
    err |= mbuf_printf(mb, ", uri=\"%s\"", req->path);
    err |= mbuf_printf(mb, ", response=\"%w\"",
            digest, sizeof(digest));

    if (realm->opaque)
        err |= mbuf_printf(mb, ", opaque=\"%s\"", realm->opaque);

    if (realm->qop) {
        err |= mbuf_printf(mb, ", cnonce=\"%016llx\"", cnonce);
	err |= mbuf_write_str(mb, ", qop=auth");
    	err |= mbuf_printf(mb, ", nc=%08x", realm->nc);
    }
    ++realm->nc;
    err |= mbuf_write_str(mb, "\r\n");
}
Пример #7
0
int sip_auth_encode(struct mbuf *mb, struct sip_auth *auth, const char *met,
		    const char *uri)
{
	struct le *le;
	int err = 0;

	if (!mb || !auth || !met || !uri)
		return EINVAL;

	for (le = auth->realml.head; le; le = le->next) {

		const uint64_t cnonce = rand_u64();
		struct realm *realm = le->data;
		uint8_t digest[MD5_SIZE];

		err = mkdigest(digest, realm, met, uri, cnonce);
		if (err)
			break;

		switch (realm->hdr) {

		case SIP_HDR_WWW_AUTHENTICATE:
			err = mbuf_write_str(mb, "Authorization: ");
			break;

		case SIP_HDR_PROXY_AUTHENTICATE:
			err = mbuf_write_str(mb, "Proxy-Authorization: ");
			break;

		default:
			continue;
		}

		err |= mbuf_printf(mb, "Digest username=\"%s\"", realm->user);
		err |= mbuf_printf(mb, ", realm=\"%s\"", realm->realm);
		err |= mbuf_printf(mb, ", nonce=\"%s\"", realm->nonce);
		err |= mbuf_printf(mb, ", uri=\"%s\"", uri);
		err |= mbuf_printf(mb, ", response=\"%w\"",
				   digest, sizeof(digest));

		if (realm->opaque)
			err |= mbuf_printf(mb, ", opaque=\"%s\"",
					   realm->opaque);

		if (realm->qop) {
			err |= mbuf_printf(mb, ", cnonce=\"%016llx\"", cnonce);
			err |= mbuf_write_str(mb, ", qop=auth");
			err |= mbuf_printf(mb, ", nc=%08x", realm->nc);
		}

		++realm->nc;

		err |= mbuf_write_str(mb, "\r\n");
		if (err)
			break;
	}

	return err;
}
Пример #8
0
int sip_dialog_encode(struct mbuf *mb, struct sip_dialog *dlg, uint32_t cseq,
		      const char *met)
{
	int err = 0;

	if (!mb || !dlg || !met)
		return EINVAL;

	err |= mbuf_write_mem(mb, mbuf_buf(dlg->mb), mbuf_get_left(dlg->mb));
	err |= mbuf_printf(mb, "Call-ID: %s\r\n", dlg->callid);
	err |= mbuf_printf(mb, "CSeq: %u %s\r\n", strcmp(met, "ACK") ?
			   dlg->lseq++ : cseq, met);

	return err;
}
Пример #9
0
static void status_handler(struct mbuf *mb)
{
	(void)mbuf_printf(mb, "TURN relay=%j relay6=%j (err %llu/%llu)\n",
			  &turnd.rel_addr, &turnd.rel_addr6,
			  turnd.errc_tx, turnd.errc_rx);
	(void)hash_apply(turnd.ht_alloc, allocation_status, mb);
}
Пример #10
0
static void httpd_handler(const struct pl *uri, struct mbuf *mb)
{
	struct pl cmd, params, r;
	uint32_t refresh = 0;

	if (re_regex(uri->p, uri->l, "/[^?]*[^]*", &cmd, &params))
		return;

	if (!re_regex(params.p, params.l, "[?&]1r=[0-9]+", NULL, &r))
		refresh = pl_u32(&r);

	mbuf_write_str(mb, "<html>\n<head>\n");
	mbuf_write_str(mb, " <title>Restund Server Status</title>\n");

	if (refresh)
		mbuf_printf(mb,
			    " <meta http-equiv=\"refresh\" content=\"%u\">\n",
			    refresh);

	mbuf_write_str(mb, "</head>\n<body>\n");
	mbuf_write_str(mb, "<h2>Restund Server Status</h2>\n");
	server_info(mb);
	mbuf_write_str(mb, "<hr size=\"1\"/>\n<pre>\n");
	restund_cmd(&cmd, mb);
	mbuf_write_str(mb, "</pre>\n</body>\n</html>\n");
}
Пример #11
0
int call_notify_sipfrag(struct call *call, uint16_t scode,
			const char *reason, ...)
{
	struct mbuf *mb;
	va_list ap;
	int err;

	if (!call)
		return EINVAL;

	mb = mbuf_alloc(512);
	if (!mb)
		return ENOMEM;

	va_start(ap, reason);
	(void)mbuf_printf(mb, "SIP/2.0 %u %v\n", scode, reason, &ap);
	va_end(ap);

	mb->pos = 0;

	if (scode >= 200) {
		err = sipevent_notify(call->not, mb, SIPEVENT_TERMINATED,
				      SIPEVENT_NORESOURCE, 0);

		call->not = mem_deref(call->not);
	}
	else {
		err = sipevent_notify(call->not, mb, SIPEVENT_ACTIVE,
				      SIPEVENT_NORESOURCE, 0);
	}

	mem_deref(mb);

	return err;
}
Пример #12
0
static void estab_handler(void *arg)
{
	struct rst *rst = arg;
	struct mbuf *mb;
	int err;

	re_printf("rst: connection established\n");

	mb = mbuf_alloc(512);
	if (!mb) {
		err = ENOMEM;
		goto out;
	}

	err = mbuf_printf(mb,
			  "GET %s HTTP/1.0\r\n"
			  "Icy-MetaData: 1\r\n"
			  "\r\n",
			  rst->path);
	if (err)
		goto out;

	mb->pos = 0;

	err = tcp_send(rst->tc, mb);
	if (err)
		goto out;

 out:
	if (err) {
		re_printf("rst: error sending HTTP request: %m\n", err);
	}

	mem_deref(mb);
}
Пример #13
0
void http_post(struct request *request, char* key, char* val)
{
    struct mbuf* mb;
    char *cur;
    int sz;

    memcpy(&request->meth, "POST", 5);
    if(request->post) {
        mb = request->post;
        mbuf_printf(mb, "&");
    } else {
	    mb = mbuf_alloc(1024);
    }

    if(key) {
        mbuf_printf(mb, "%s=", key);

        sz = 0;
        cur = val;
        while(*val) {
            switch(*val) {
            case '+':
            case '&':
                mbuf_write_mem(mb, (const uint8_t *)cur, sz);
                sz = 0;
                mbuf_printf(mb, "%%%02X", *val);
                val ++;
                cur = val;
                break;
            default:
                sz++;
                val++;
            }
        }
        if(cur != val) {
            mbuf_write_mem(mb, (const uint8_t *)cur, sz);
        }

	    request->form = 1;

    } else {
	    mbuf_printf(mb, "%s", val);
    }

    request->post = mb;
}
Пример #14
0
static int request(struct sip_request *req, enum sip_transp tp,
		   const struct sa *dst)
{
	struct mbuf *mb = NULL;
	char *branch = NULL;
	int err = ENOMEM;
	struct sa laddr;

	req->provrecv = false;

	branch = mem_alloc(24, NULL);
	mb = mbuf_alloc(1024);

	if (!branch || !mb)
		goto out;

	(void)re_snprintf(branch, 24, "z9hG4bK%016llx", rand_u64());

	err = sip_transp_laddr(req->sip, &laddr, tp, dst);
	if (err)
		goto out;

	err  = mbuf_printf(mb, "%s %s SIP/2.0\r\n", req->met, req->uri);
	err |= mbuf_printf(mb, "Via: SIP/2.0/%s %J;branch=%s;rport\r\n",
			   sip_transp_name(tp), &laddr, branch);
	err |= req->sendh ? req->sendh(tp, &laddr, dst, mb, req->arg) : 0;
	err |= mbuf_write_mem(mb, mbuf_buf(req->mb), mbuf_get_left(req->mb));
	if (err)
		goto out;

	mb->pos = 0;

	if (!req->stateful)
		err = sip_send(req->sip, NULL, tp, dst, mb);
	else
		err = sip_ctrans_request(&req->ct, req->sip, tp, dst, req->met,
					 branch, mb, response_handler, req);
	if (err)
		goto out;

 out:
	mem_deref(branch);
	mem_deref(mb);

	return err;
}
Пример #15
0
bool hdr_write(struct le *le, void *arg)
{
    struct http_hdr *hdr = le->data;
    struct mbuf *mb = arg;

    mbuf_printf(mb, "%r: %r\r\n", &hdr->name, &hdr->val);

    return false;
}
Пример #16
0
static bool status_handler(struct le *le, void *arg)
{
	struct chan *chan = le->data;
	struct mbuf *mb = arg;

	(void)mbuf_printf(mb, " (0x%x %J %is)", chan->numb, &chan->peer,
			  chan->expires - time(NULL));

	return false;
}
Пример #17
0
static int uri_complete(struct ua *ua, struct mbuf *buf, const char *uri)
{
	size_t len;
	int err = 0;

	/* Skip initial whitespace */
	while (isspace(*uri))
		++uri;

	len = str_len(uri);

	/* Append sip: scheme if missing */
	if (0 != re_regex(uri, len, "sip:"))
		err |= mbuf_printf(buf, "sip:");

	err |= mbuf_write_str(buf, uri);

	/* Append domain if missing */
	if (0 != re_regex(uri, len, "[^@]+@[^]+", NULL, NULL)) {
#if HAVE_INET6
		if (AF_INET6 == ua->acc->luri.af)
			err |= mbuf_printf(buf, "@[%r]",
					   &ua->acc->luri.host);
		else
#endif
			err |= mbuf_printf(buf, "@%r",
					   &ua->acc->luri.host);

		/* Also append port if specified and not 5060 */
		switch (ua->acc->luri.port) {

		case 0:
		case SIP_PORT:
			break;

		default:
			err |= mbuf_printf(buf, ":%u", ua->acc->luri.port);
			break;
		}
	}

	return err;
}
Пример #18
0
static int h263_fmtp_enc(struct mbuf *mb, const struct sdp_format *fmt,
			 bool offer, void *arg)
{
	(void)offer;
	(void)arg;

	if (!mb || !fmt)
		return 0;

	return mbuf_printf(mb, "a=fmtp:%s CIF=1;CIF4=1\r\n", fmt->id);
}
Пример #19
0
static int mpg4_fmtp_enc(struct mbuf *mb, const struct sdp_format *fmt,
			 bool offer, void *arg)
{
	(void)offer;
	(void)arg;

	if (!mb || !fmt)
		return 0;

	return mbuf_printf(mb, "a=fmtp:%s profile-level-id=3\r\n", fmt->id);
}
Пример #20
0
static int send_handler(enum sip_transp tp, const struct sa *src,
			const struct sa *dst, struct mbuf *mb, void *arg)
{
	struct sip_contact contact;
	struct sipsess *sess = arg;
	(void)dst;

	sip_contact_set(&contact, sess->cuser, src, tp);

	return mbuf_printf(mb, "%H", sip_contact_print, &contact);
}
Пример #21
0
int vie_rtx_fmtp_enc(struct mbuf *mb, const struct sdp_format *fmt,
		     bool offer, void *data)
{
	const struct vidcodec *vc = (const struct vidcodec *)data;
	int err = 0;
	(void)vc;

	err |= mbuf_printf(mb, "a=fmtp:%s apt=100\r\n", fmt->id);

	return err;
}
Пример #22
0
int vp8_fmtp_enc(struct mbuf *mb, const struct sdp_format *fmt,
		 bool offer, void *arg)
{
	const struct vp8_vidcodec *vp8 = arg;
	(void)offer;

	if (!mb || !fmt || !vp8 || !vp8->max_fs)
		return 0;

	return mbuf_printf(mb, "a=fmtp:%s max-fs=%u\r\n",
			   fmt->id, vp8->max_fs);
}
Пример #23
0
int amr_fmtp_enc(struct mbuf *mb, const struct sdp_format *fmt,
		 bool offer, void *arg)
{
	const struct aucodec *ac = arg;
	(void)offer;

	if (!mb || !fmt || !ac)
		return 0;

	return mbuf_printf(mb, "a=fmtp:%s octet-align=1\r\n",
			   fmt->id);
}
Пример #24
0
int vie_fmtp_enc(struct mbuf *mb, const struct sdp_format *fmt,
		 bool offer, void *data)
{
	const struct vidcodec *vc = (const struct vidcodec *)data;
	int err = 0;
	(void)vc;

	err |= mbuf_printf(mb, "a=rtcp-fb:%s ccm fir\r\n", fmt->id);
	err |= mbuf_printf(mb, "a=rtcp-fb:%s nack\r\n", fmt->id);
	err |= mbuf_printf(mb, "a=rtcp-fb:%s nack pli\r\n", fmt->id);

#if USE_REMB
	/* NOTE: REMB is not necessary */
	err |= mbuf_printf(mb, "a=rtcp-fb:%s goog-remb\r\n", fmt->id);

#endif

	err |= mbuf_printf(mb, "a=extmap:3 http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time\r\n");
	
#if USE_RTP_ROTATION
	err |= mbuf_printf(mb, "a=extmap:4 urn:3gpp:video-orientation\r\n");

#endif


	return err;
}
Пример #25
0
static void server_info(struct mbuf *mb)
{
	const uint32_t uptime = (uint32_t)(time(NULL) - stg.start);

	mbuf_write_str(mb, "<table>\n");
	mbuf_write_str(mb,
		       " <tr><td>Version:</td><td>" VERSION "</td></tr>\n");
	mbuf_write_str(mb,
		       " <tr><td>Built:</td><td>" __DATE__ " " __TIME__
		       "</td></tr>\n");
	mbuf_printf(mb, " <tr><td>Uptime:</td><td>%H</td></tr>\n",
		    fmt_human_time, &uptime);
	mbuf_write_str(mb, "</table>\n");
}
Пример #26
0
static bool record_route_handler(const struct sip_hdr *hdr,
				 const struct sip_msg *msg,
				 void *arg)
{
	struct route_enc *renc = arg;
	(void)msg;

	if (mbuf_printf(renc->mb, "Route: %r\r\n", &hdr->val))
		return true;

	if (!renc->end)
	        renc->end = renc->mb->pos - 2;

	return false;
}
Пример #27
0
/**
 * Send a SIP dialog request with formatted arguments
 *
 * @param reqp     Pointer to allocated SIP request object
 * @param sip      SIP Stack
 * @param stateful Stateful client transaction
 * @param met      Null-terminated SIP Method string
 * @param dlg      SIP Dialog state
 * @param cseq     CSeq number
 * @param auth     SIP authentication state
 * @param sendh    Send handler
 * @param resph    Response handler
 * @param arg      Handler argument
 * @param fmt      Formatted SIP headers
 *
 * @return 0 if success, otherwise errorcode
 */
int sip_drequestf(struct sip_request **reqp, struct sip *sip, bool stateful,
		  const char *met, struct sip_dialog *dlg, uint32_t cseq,
		  struct sip_auth *auth, sip_send_h *sendh, sip_resp_h *resph,
		  void *arg, const char *fmt, ...)
{
	struct mbuf *mb;
	va_list ap;
	int err;

	if (!sip || !met || !dlg || !fmt)
		return EINVAL;

	mb = mbuf_alloc(2048);
	if (!mb)
		return ENOMEM;

	err = mbuf_write_str(mb, "Max-Forwards: 70\r\n");

	if (auth)
		err |= sip_auth_encode(mb, auth, met, sip_dialog_uri(dlg));

	err |= sip_dialog_encode(mb, dlg, cseq, met);

	if (sip->software)
		err |= mbuf_printf(mb, "User-Agent: %s\r\n", sip->software);

	if (err)
		goto out;

	va_start(ap, fmt);
	err = mbuf_vprintf(mb, fmt, ap);
	va_end(ap);

	if (err)
		goto out;

	mb->pos = 0;

	err = sip_request(reqp, sip, stateful, met, -1, sip_dialog_uri(dlg),
			  -1, sip_dialog_route(dlg), mb, sendh, resph, arg);
	if (err)
		goto out;

 out:
	mem_deref(mb);

	return err;
}
Пример #28
0
static int opus_fmtp_enc(struct mbuf *mb, const struct sdp_format *fmt,
			 bool offer, void *arg)
{
	bool mirror;

	(void)arg;
	(void)offer;

	if (!mb || !fmt)
		return 0;

	mirror = !offer && str_isset(fmtp_mirror);

	return mbuf_printf(mb, "a=fmtp:%s %s\r\n",
			   fmt->id, mirror ? fmtp_mirror : fmtp);
}
Пример #29
0
static int h264_fmtp_enc(struct mbuf *mb, const struct sdp_format *fmt,
			 bool offer, void *arg)
{
	struct vidcodec *vc = arg;
	const uint8_t profile_idc = 0x42; /* baseline profile */
	const uint8_t profile_iop = 0x80;
	(void)offer;

	if (!mb || !fmt || !vc)
		return 0;

	return mbuf_printf(mb, "a=fmtp:%s"
			   " packetization-mode=0"
			   ";profile-level-id=%02x%02x%02x"
			   "\r\n",
			   fmt->id, profile_idc, profile_iop, h264_level_idc);
}
Пример #30
0
static bool allocation_status(struct le *le, void *arg)
{
	const uint32_t bsize = hash_bsize(turnd.ht_alloc);
	struct allocation *al = le->data;
	struct mbuf *mb = arg;

	(void)mbuf_printf(mb,
			  "- %04u %s/%J/%J - %J \"%s\" %us (drop %llu/%llu)\n",
			  sa_hash(&al->cli_addr, SA_ALL) & (bsize - 1),
			  net_proto2name(al->proto), &al->cli_addr,
			  &al->srv_addr, &al->rel_addr, al->username,
			  (uint32_t)tmr_get_expire(&al->tmr) / 1000,
			  al->dropc_tx, al->dropc_rx);

	perm_status(al->perms, mb);
	chan_status(al->chans, mb);

	return false;
}