⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 monitor.cc

📁 rtpmon-1.0a7.tar.gz for UNIX like
💻 CC
📖 第 1 页 / 共 2 页
字号:
	  case RTCP_PT_BYE:	    parse_bye(rh, flags, ep, m);	    break;	  default:	    m->badopt(1);	    break;	}	rh = (rtcphdr*)ep;    }}voidMonitor::parse_sr(rtcphdr* rh, int flags, u_char* ep,		  Member* m, u_int32_t addr){    rtcp_sr* sr = (rtcp_sr*)(rh + 1);    u_int32_t ssrc = rh->rh_ssrc;    if (m->srcid() != ssrc) {	m = lookup(ssrc, addr);    }    time_t tm = time(0);    m->ts(tm);#ifdef RTCP_DEBUG    Tcl& tcl = Tcl::instance();    tcl.evalf("rtcp_debug \"%u\" \"sr: npkts: %d nbytes: %d\"", ssrc,	      ntohl(sr->sr_np), ntohl(sr->sr_nb));#endif    int cnt = flags >> 8 & 0x1f;    parse_rr_records(ssrc, (rtcp_rr*)(sr + 1), cnt, ep, m, addr);}voidMonitor::parse_rr(rtcphdr* rh, int flags, u_char* ep,		  Member* m, u_int32_t addr){    u_int32_t ssrc = rh->rh_ssrc;    if (m->srcid() != ssrc) {	m = lookup(ssrc, addr);    }    time_t tm = time(0);    m->ts(tm);    int cnt = flags >> 8 & 0x1f;    parse_rr_records(ssrc, (rtcp_rr*)(rh + 1), cnt, ep, m, addr);}voidMonitor::parse_rr_records(u_int32_t ssrc, rtcp_rr* rr, int cnt,			     u_char* ep, Member *m, u_int32_t addr){    while ((u_char*)rr < ep) {	u_int32_t srcid = rr->rr_srcid;	Member* s = lookup(srcid, 0);#ifdef RTCP_DEBUG	{	    Tcl& tcl = Tcl::instance();	    const char *p = NULL;	    if (s != 0)		p = s->sdes(RTCP_SDES_CNAME);	    tcl.evalf("rtcp_debug \"%u\" \"rr: srcid: %u (%s) fracloss: %u%% cumloss: %u ehsr: %u dv: %u lsr: %u dlsr: %u\"",		      m->srcid(), ntohl(rr->rr_srcid), p ? p : "?",		      ((ntohl(rr->rr_loss) >> 24) & 0xff) * 100 / 256,		      (ntohl(rr->rr_loss) & 0xffffff), ntohl(rr->rr_ehsr),		      ntohl(rr->rr_dv), ntohl(rr->rr_lsr), ntohl(rr->rr_dlsr));	}#endif	if (s == 0) {	    rr++;	    continue;	}	if (! s->sender()) {	    /*	     * senders list must be kept in order -- add to the	     * end of the list	     */	    s->snext_ = 0;	    if (senders_ == 0)		senders_ = s;	    else {		Member* sn = senders_;		while (sn->snext_ != 0)		    sn = sn->snext_;		sn->snext_ = s;	    }			    s->pos(getpos());	    s->sender(true);	    /*	     * don't update stats yet; wait until we hear at least	     * twice that this srcid is a sender	     */	    rr++;	    continue;	}	int n = s->pos();	m->loss(n, ntohl(rr->rr_loss)&0x0ffffff, ntohl(rr->rr_ehsr));	m->filtloss(n, ntohl(rr->rr_loss) >> 24);	u_int32_t jit = ntohl(rr->rr_dv);	if ((jit > 0x1000) && ((jit & 0x00f0ffff) == 0)) {	    jit = (jit & 0xff000000) >> 24 | (jit & 0x000f0000) >> 16;	}	m->jitter(n, jit);	char idx[64];	sprintf(idx, "%s:%s", m->name(), s->name());	char statbuf[32];	bool isnew = false;	//XXX this is ugly; fix it later	u_char l;	switch (stat_) {	  case 0:  // packet loss	    l = m->loss(n);	    if (!m->locked() && l >= thresh_)		isnew = true;	    sprintf(statbuf, "%d %%", (int)l );	    break;	  case 1:  // filtered packet loss	    l = m->filtloss(n);	    if (!m->locked() && l >= thresh_)		isnew = true;	    sprintf(statbuf, "%d %%", (int)m->filtloss(n) );	    break;	  case 2:  // jitter	    u_int32_t j = m->jitter(n);	    if (!m->locked() && j >= thresh_)		isnew = true;	    j = (j&0x0ffff) * 1000 >> 16;	    sprintf(statbuf, "%u ms", j);	    break;	}	Tcl& tcl = Tcl::instance();	if (isnew) {	    m->locked(1);	    tcl.evalf("new-listener %s", m->name());	}	Tcl_Interp* interp = tcl.interp();	Tcl_SetVar2(interp, "stats", idx, statbuf, TCL_GLOBAL_ONLY);	rr++;    }}voidMonitor::parse_sdes(rtcphdr* rh, int flags, u_char* ep, Member* m,		       u_int32_t ssrc, u_int32_t addr){    int cnt = flags >> 8 & 0x1f;    u_int32_t* p = (u_int32_t*)&rh->rh_ssrc;    while (--cnt >= 0) {	int n = sdesbody(p, ep, m, addr);	if (n == 0)	    break;	p += n;    }    if (cnt >= 0)	m->badsdes(1);}intMonitor::sdesbody(u_int32_t* p, u_char* ep, Member* m, u_int32_t addr){    u_int32_t srcid = *p;    if (m->srcid() != srcid)	m = lookup(srcid, addr);    if (m == 0)	return (0);    u_char* cp = (u_char*)(p + 1);    while (cp < ep) {	u_int type = cp[0];	if (type == 0) {	    /* end of chunk */	    return (((cp - (u_char*)p) >> 2) + 1);	}	u_int len = cp[1];	u_char* eopt = cp + len + 2;	if (eopt > ep)	    return (0);	if (type >= RTCP_SDES_MIN && type <= RTCP_SDES_MAX) {	    char buf[256];	    memcpy(buf, (char*)&cp[2], len);	    buf[len] = 0;	    const char* oldval= m->sdes(RTCP_SDES_NAME);	    char newval[256];	    newval[0] = '\0';	    if (type == RTCP_SDES_NAME && buf != 0		&& (oldval == 0 || strcmp(oldval, buf)))		strcpy(newval, buf);	    oldval = m->sdes(RTCP_SDES_CNAME);	    if (type == RTCP_SDES_CNAME && buf != 0		&& (oldval == 0 || strcmp(oldval, buf)))		strcpy(newval, buf);	    m->sdes(type, buf);	    if (newval[0] != 0) {		char objname[32];		strcpy(objname, m->name());		Tcl_Interp* interp = Tcl::instance().interp();		Tcl_SetVar2(interp, "names", objname, newval, TCL_GLOBAL_ONLY);	    }	}	cp = eopt;    }    return (0);}voidMonitor::parse_bye(rtcphdr* rh, int flags, u_char* ep, Member* m){    int cnt = flags >> 8 & 0x1f;    u_int32_t* p = (u_int32_t*)&rh->rh_ssrc;    while (--cnt >= 0) {	if (p >= (u_int32_t*)ep) {	    //m->badbye(1);	    return;	}	if (m->srcid() != rh->rh_ssrc)	    m = lookup(*p, 0);	if (m != 0)	    m->active(0);	++p;    }}voidMonitor::sort(){    Member* m;    int i, b;    u_int32_t v;    for (m=members_; m!=NULL; m=m->next_) {	v = 0;		switch(sorttype_) {	  case SORT_MAX:	    for (i=0, b=bits_; b!=0; i++, b>>=1) {		if (! b&1) continue;		if (stat_ == 0 && m->loss(i) > v)		    v = m->loss(i);		if (stat_ == 1 && m->filtloss(i) > v)		    v = m->filtloss(i);		if (stat_ == 2 && m->jitter(i) > v)		    v = m->jitter(i);	    }	    m->val(v);	    break;	  case SORT_AVG:	    for (i=0, b=bits_; b!=0; i++, b>>=1) {		if (! b&1) continue;		switch (stat_) {		  case 0:		    v += m->loss(i);		    break;		  case 1:		    v += m->filtloss(i);		    break;		  case 2:		    v += m->jitter(i);		    break;		}	    }	    m->val(v);	    break;	    	  case SORT_ADDR:	    m->val(~m->addr());	    break;	    	  default:	    if (! (bits_>>sorttype_)&1)		return;  // XXX error	    switch (stat_) {	      case 0:		m->val(m->loss(sorttype_));		break;	      case 1:		m->val(m->filtloss(sorttype_));		break;	      case 2:		m->val(m->jitter(sorttype_));		break;	    }	}    }        members_ = dosort(members_);    // reset the end pointer    for (Member* t = members_; t != 0; t = t->next_)	if (t->next_ == 0)	    last_ = t;}Member*Monitor::dosort(Member* l){    if (l == NULL || l->next_ == NULL)	return (l);    Member* a = l;    Member* b = l->next_;    while (b != NULL && b->next_ != NULL) {	a = a->next_;	b = b->next_->next_;    }    b = a->next_;    a->next_ = NULL;    b = dosort(b);    a = dosort(l);    Member* first;    if (a->val() >= b->val()) {	first = a;	a = a->next_;    } else {	first = b;	b = b->next_;    }    Member* m = first;    while (a != NULL && b != NULL) {	if (a->val() >= b->val()) {	    m->next_ = a;	    m = a;	    a = a->next_;	} else {	    m->next_ = b;	    m = b;	    b = b->next_;	}    }    if (a != NULL)	m->next_ = a;    if (b != NULL)	m->next_ = b;    return (first);}intMonitor::CheckActive(double maxbw){    time_t now = time(0);    double idletime = (double(nmembers_) * avgpktsize_) / maxbw;    if (idletime < 5.0) idletime = 5.0;    u_int maxidle = u_int(idletime) * CTRL_IDLE;        Member *m, *next;    for (m = members_; m != 0; m = next) {	next = m->next_;	u_int32_t t = (u_int32_t) m->ts();	if (u_int(now - t) > maxidle)	    m->active(0);    }    // Return interval until next re-sort    return (int(idletime * 1000.));}voidMonitor::median(){    int n, b;    Member *less, *more;    int nless, nmore;    if (nmembers_ == 0) return;    Tcl_Interp* interp = Tcl::instance().interp();    for (Member* s = senders_ ; s!= 0; s = s->snext_) {	n = s->pos();	less = more = 0;	nless = nmore = 0;	if (nmembers_ > 2) {	    u_int32_t pivot;	    if (median_ == 0)		pivot = 5;	// XXX	    else		pivot = median_->getstat(stat_, n);	    u_int32_t max = 0;	    // do the first separation before calling mselect	    // since the member list is linked by next, not mnext	    for (Member* m = members_; m != 0; m = m->next_) {		u_int32_t stat = m->getstat(stat_, n);		if (stat > max) max = stat;		if (stat < pivot) {		    m->mnext_ = less;		    less = m;		    nless++;		} else {		    m->mnext_ = more;		    more = m;		    nmore++;		}	    }	    int i = nmembers_ / 2;	    if (nless > i)		median_ = mselect(less, i, 0, pivot, n);	    else		median_ = mselect(more, i-nless, pivot, max, n);	} else {	    median_ = members_;	}	char val[32];	switch (stat_) {	  case 0:  case 1:	    sprintf(val, "%d %%", (int)median_->getstat(stat_, n));	    break;	  case 2:	    u_int32_t j = median_->jitter(n);	    j = (j&0x0ffff) * 1000 > 16;	    sprintf(val, "%u ms", j);	    break;	}	Tcl_SetVar2(interp, "median", s->name(), val, TCL_GLOBAL_ONLY);    }}Member*Monitor::mselect(Member* m, int i, int low, int high, int n){    Member *less = 0, *more = 0;    int nless = 0, nmore = 0, done = 1;    if (m->mnext_ == 0 || high == low) return m;    if (high == low+1) return m;	// XXX    u_int32_t v = m->getstat(stat_, n);    u_int32_t pivot = (low + high) / 2;    Member *t, *next;    for (t = m; t != 0; t = next) {	next = t->mnext_;	u_int32_t s = t->getstat(stat_, n);	if (s != v) done = 0;	if (s < pivot) {	    t->mnext_ = less;	    less = t;	    nless++;	} else {	    t->mnext_ = more;	    more = t;	    nmore++;	}    }    if (done) return m;    return (nless>i) ? mselect(less, i, low, pivot, n)	: mselect(more, i-nless, pivot, high, n);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -