Exemplo n.º 1
0
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);
}
Exemplo n.º 2
0
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);
}
Exemplo n.º 3
0
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;
}
Exemplo n.º 4
0
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;
}
Exemplo n.º 5
0
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;
}