static int rtpp_stream_check_latch_override(struct rtpp_stream *self, struct rtp_packet *packet) { const char *actor; struct rtpp_stream_priv *pvt; char saddr[MAX_AP_STRBUF]; pvt = PUB2PVT(self); if (self->session_type == SESS_RTCP || self->latch_info.ssrc == 0) return (0); if (rtp_packet_parse(packet) != RTP_PARSER_OK) return (0); if (packet->parsed->ssrc != self->latch_info.ssrc) return (0); if (packet->parsed->seq < self->latch_info.seq && self->latch_info.seq - packet->parsed->seq < 536) return (0); actor = rtpp_stream_get_actor(self); addrport2char_r(sstosa(&packet->raddr), saddr, sizeof(saddr)); RTPP_LOG(pvt->pub.log, RTPP_LOG_INFO, "%s's address re-latched: %s (%s), SSRC=" SSRC_FMT ", Seq=%u->%u", actor, saddr, "RTP", self->latch_info.ssrc, self->latch_info.seq, packet->parsed->seq); self->latch_info.seq = packet->parsed->seq; return (1); }
static int rtpp_stream_latch(struct rtpp_stream *self, double dtime, struct rtp_packet *packet) { const char *actor, *ptype, *ssrc, *seq, *relatch; char ssrc_buf[11], seq_buf[6]; struct rtpp_stream_priv *pvt; char saddr[MAX_AP_STRBUF]; pvt = PUB2PVT(self); if (pvt->last_update != 0 && \ dtime - pvt->last_update < UPDATE_WINDOW) { return (0); } actor = rtpp_stream_get_actor(self); ptype = rtpp_stream_get_proto(self); if (self->session_type == SESS_RTP) { if (rtp_packet_parse(packet) == RTP_PARSER_OK) { self->latch_info.ssrc = packet->parsed->ssrc; self->latch_info.seq = packet->parsed->seq; snprintf(ssrc_buf, sizeof(ssrc_buf), SSRC_FMT, packet->parsed->ssrc); snprintf(seq_buf, sizeof(seq_buf), "%u", packet->parsed->seq); ssrc = ssrc_buf; seq = seq_buf; } else { self->latch_info.ssrc = 0; ssrc = seq = "INVALID"; } } else { self->latch_info.ssrc = 0; ssrc = seq = "UNKNOWN"; } addrport2char_r(sstosa(&packet->raddr), saddr, sizeof(saddr)); if (self->latch_info.latched == 0) { relatch = ""; } else { relatch = "re-"; } RTPP_LOG(pvt->pub.log, RTPP_LOG_INFO, "%s's address %slatched in: %s (%s), SSRC=%s, Seq=%s", actor, relatch, saddr, ptype, ssrc, seq); self->latch_info.latched = 1; return (1); }
static void rtpp_stream_prefill_addr(struct rtpp_stream *self, struct sockaddr **iapp, double dtime) { struct rtpp_stream_priv *pvt; char saddr[MAX_AP_STRBUF]; const char *actor, *ptype; pvt = PUB2PVT(self); if (self->addr != NULL) pvt->last_update = dtime; /* * Unless the address provided by client historically * cannot be trusted and address is different from one * that we recorded update it. */ if (pvt->untrusted_addr != 0) return; if (self->addr != NULL && isaddrseq(self->addr, *iapp)) { return; } addrport2char_r(*iapp, saddr, sizeof(saddr)); actor = rtpp_stream_get_actor(self); ptype = rtpp_stream_get_proto(self); RTPP_LOG(pvt->pub.log, RTPP_LOG_INFO, "pre-filling %s's %s address " "with %s", actor, ptype, saddr); if (self->addr != NULL) { if (self->latch_info.latched != 0) { if (pvt->prev_addr != NULL) free(pvt->prev_addr); pvt->prev_addr = self->addr; } else { free(self->addr); } } self->addr = *iapp; *iapp = NULL; }
static void rtpp_stream_fill_addr(struct rtpp_stream *self, struct rtp_packet *packet) { const char *actor, *ptype; struct rtpp_stream_priv *pvt; char saddr[MAX_AP_STRBUF]; pvt = PUB2PVT(self); pvt->untrusted_addr = 1; memcpy(self->addr, &packet->raddr, packet->rlen); if (pvt->prev_addr == NULL || memcmp(pvt->prev_addr, &packet->raddr, packet->rlen) != 0) { self->latch_info.latched = 1; } actor = rtpp_stream_get_actor(self); ptype = rtpp_stream_get_proto(self); addrport2char_r(sstosa(&packet->raddr), saddr, sizeof(saddr)); RTPP_LOG(pvt->pub.log, RTPP_LOG_INFO, "%s's address filled in: %s (%s)", actor, saddr, ptype); return; }
static void rtpp_anetio_sthread(struct sthread_args *args) { int n, nsend, i, send_errno, nretry; struct rtpp_wi *wi, *wis[100]; #if RTPP_DEBUG_timers double tp[3], runtime, sleeptime; long run_n; runtime = sleeptime = 0.0; run_n = 0; tp[0] = getdtime(); #endif for (;;) { nsend = rtpp_queue_get_items(args->out_q, wis, 100, 0); #if RTPP_DEBUG_timers tp[1] = getdtime(); #endif for (i = 0; i < nsend; i++) { wi = wis[i]; if (wi->wi_type == RTPP_WI_TYPE_SGNL) { rtpp_wi_free(wi); goto out; } nretry = 0; do { n = sendto(wi->sock, wi->msg, wi->msg_len, wi->flags, wi->sendto, wi->tolen); send_errno = (n < 0) ? errno : 0; #if RTPP_DEBUG_netio >= 1 if (wi->debug != 0) { char daddr[MAX_AP_STRBUF]; addrport2char_r(wi->sendto, daddr, sizeof(daddr), ':'); if (n < 0) { RTPP_ELOG(wi->log, RTPP_LOG_DBUG, "sendto(%d, %p, %lld, %d, %p (%s), %d) = %d", wi->sock, wi->msg, (long long)wi->msg_len, wi->flags, wi->sendto, daddr, wi->tolen, n); } else if (n < wi->msg_len) { RTPP_LOG(wi->log, RTPP_LOG_DBUG, "sendto(%d, %p, %lld, %d, %p (%s), %d) = %d: short write", wi->sock, wi->msg, (long long)wi->msg_len, wi->flags, wi->sendto, daddr, wi->tolen, n); #if RTPP_DEBUG_netio >= 2 } else { RTPP_LOG(wi->log, RTPP_LOG_DBUG, "sendto(%d, %p, %d, %d, %p (%s), %d) = %d", wi->sock, wi->msg, wi->msg_len, wi->flags, wi->sendto, daddr, wi->tolen, n); #endif } } #endif if (n >= 0) { wi->nsend--; } else { /* "EPERM" is Linux thing, yield and retry */ if ((send_errno == EPERM || send_errno == ENOBUFS) && nretry < RTPP_ANETIO_MAX_RETRY) { sched_yield(); nretry++; } else { break; } } } while (wi->nsend > 0); rtpp_wi_free(wi); } #if RTPP_DEBUG_timers sleeptime += tp[1] - tp[0]; tp[0] = getdtime(); runtime += tp[0] - tp[1]; if ((run_n % 10000) == 0) { RTPP_LOG(args->glog, RTPP_LOG_DBUG, "rtpp_anetio_sthread(%p): run %ld aload = %f filtered = %f", \ args, run_n, runtime / (runtime + sleeptime), args->average_load.lastval); } if (runtime + sleeptime > 1.0) { recfilter_apply(&args->average_load, runtime / (runtime + sleeptime)); runtime = sleeptime = 0.0; } run_n += 1; #endif } out: return; }