示例#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);
}
示例#2
0
static int
rtpp_notify_schedule(struct rtpp_notify *pub,
  struct rtpp_tnotify_target *rttp, const char *notify_tag)
{
    struct rtpp_notify_wi *wi_data;
    struct rtpp_wi *wi;
    int len;
    struct rtpp_notify_priv *pvt;

    pvt = PUB2PVT(pub);

    /* string, \0 and \n */
    len = strlen(notify_tag) + 2;

    wi = rtpp_wi_malloc_udata((void **)&wi_data,
      sizeof(struct rtpp_notify_wi) + len);
    if (wi == NULL) {
        return (-1);
    }
    memset(wi_data, '\0', sizeof(struct rtpp_notify_wi) + len);

    wi_data->rttp = rttp;
    wi_data->len = len;

    len = snprintf(wi_data->notify_buf, len, "%s\n", notify_tag);

    CALL_METHOD(pvt->glog->rcnt, incref);
    wi->log = pvt->glog;

    rtpp_queue_put_item(wi, pvt->nqueue);
    return (0);
}
示例#3
0
static struct rtp_packet *
rtpp_socket_rtp_recv_simple(struct rtpp_socket *self, const struct rtpp_timestamp *dtime,
  struct sockaddr *laddr, int port)
{
    struct rtpp_socket_priv *pvt;
    struct rtp_packet *packet;

    packet = rtp_packet_alloc();
    if (packet == NULL) {
        return NULL;
    }

    pvt = PUB2PVT(self);

    packet->rlen = sizeof(packet->raddr);
    packet->size = recvfrom(pvt->fd, packet->data.buf, sizeof(packet->data.buf), 0, 
      sstosa(&packet->raddr), &packet->rlen);

    if (packet->size == -1) {
        rtp_packet_free(packet);
        return (NULL);
    }
    packet->laddr = laddr;
    packet->lport = port;
    if (dtime != NULL) {
        packet->rtime.wall = dtime->wall;
        packet->rtime.mono = dtime->mono;
    }

    return (packet);
}
示例#4
0
static void
rtpp_tnotify_set_dtor(struct rtpp_tnotify_set_obj *pub)
{
    struct rtpp_tnotify_set *pvt;
    struct rtpp_tnotify_target *tp;
    int i;

    pvt = PUB2PVT(pub);
    for (i = 0; i < pvt->tp_len; i++) {
        tp = pvt->tp[i];
        if (tp->socket_name != NULL)
            free(tp->socket_name);
        if (tp->connected) {
            assert(tp->fd >= 0);
            close(tp->fd);
        }
        if (tp->local != NULL)
            free(tp->local);
        free(tp);
    }
    for (i = 0; i < pvt->wp_len; i++) {
        free(pvt->wp[i]->socket_name);
        free(pvt->wp[i]);
    }
    free(pvt);
}
示例#5
0
static void
rtpp_command_async_dtor(struct rtpp_cmd_async_obj *pub)
{
    struct rtpp_cmd_async_cf *cmd_cf;
    int i;

    cmd_cf = PUB2PVT(pub);

    pthread_mutex_lock(&cmd_cf->cmd_mutex);
    cmd_cf->tstate_queue = TSTATE_CEASE;
    /* nudge acceptor thread */
    if (cmd_cf->acceptor_started != 0) {
        cmd_cf->tstate_acceptor = TSTATE_CEASE;
        for (i = 0; i < cmd_cf->aset.pfds_used; i ++) {
            close(cmd_cf->aset.pfds[i].fd);
        }
    }
    /* notify worker thread */
    pthread_cond_signal(&cmd_cf->cmd_cond);
    pthread_mutex_unlock(&cmd_cf->cmd_mutex);
    pthread_join(cmd_cf->thread_id, NULL);        
    if (cmd_cf->acceptor_started != 0) {
        pthread_join(cmd_cf->acpt_thread_id, NULL);
    }

    CALL_METHOD(cmd_cf->rcache, dtor);
    pthread_cond_destroy(&cmd_cf->cmd_cond);
    pthread_mutex_destroy(&cmd_cf->cmd_mutex);
    free_pollset(&cmd_cf->pset);
    free_accptset(&cmd_cf->aset);
    free(cmd_cf);
}
示例#6
0
static int
rtpp_stream_guess_addr(struct rtpp_stream *self,
  struct rtp_packet *packet)
{
    int rport;
    const char *actor, *ptype;
    struct rtpp_stream_priv *pvt;

    pvt = PUB2PVT(self);

    if (self->addr != NULL && ishostseq(self->addr, sstosa(&packet->raddr))) {
        return (0);
    }
    if (self->addr == NULL) {
        self->addr = malloc(packet->rlen);
        if (self->addr == NULL) {
            return (-1);
        }
    }
    actor = rtpp_stream_get_actor(self);
    ptype =  rtpp_stream_get_proto(self);
    rport = ntohs(satosin(&packet->raddr)->sin_port);
    if (IS_LAST_PORT(rport)) {
        return (-1);
    }
    memcpy(self->addr, &packet->raddr, packet->rlen);
    satosin(self->addr)->sin_port = htons(rport + 1);
    /* Use guessed value as the only true one for asymmetric clients */
    self->latch_info.latched = self->asymmetric;
    RTPP_LOG(pvt->pub.log, RTPP_LOG_INFO, "guessing %s port "
      "for %s to be %d", ptype, actor, rport + 1);

    return (0);
}
示例#7
0
static int
rtpp_socket_settos(struct rtpp_socket *self, int tos)
{
    struct rtpp_socket_priv *pvt;

    pvt = PUB2PVT(self);
    return (setsockopt(pvt->fd, IPPROTO_IP, IP_TOS, &tos, sizeof(tos)));
}
示例#8
0
static int
rtpp_wref_purge(struct rtpp_weakref_obj *pub)
{
    struct rtpp_weakref_priv *pvt;

    pvt = PUB2PVT(pub);
    return (CALL_METHOD(pvt->ht, purge));
}
示例#9
0
static int
rtpp_wref_get_length(struct rtpp_weakref_obj *pub)
{
    struct rtpp_weakref_priv *pvt;

    pvt = PUB2PVT(pub);
    return (CALL_METHOD(pvt->ht, get_length));
}
示例#10
0
static int
rtpp_tnotify_set_isenabled(struct rtpp_tnotify_set_obj *pub)
{
    struct rtpp_tnotify_set *pvt;

    pvt = PUB2PVT(pub);
    return (pvt->wp_len > 0 || pvt->tp_len > 0);
}
示例#11
0
static int
rtpp_socket_getfd(struct rtpp_socket *self)
{
    struct rtpp_socket_priv *pvt;

    pvt = PUB2PVT(self);
    return (pvt->fd);
}
示例#12
0
static const char *
rtpp_stream_get_actor(struct rtpp_stream *self)
{
    struct rtpp_stream_priv *pvt;

    pvt = PUB2PVT(self);
    return ((pvt->side == RTPP_SSIDE_CALLER) ? "caller" : "callee");
}
示例#13
0
static int
rtpp_tnotify_set_append(struct rtpp_tnotify_set_obj *pub,
  const char *socket_name, const char **e)
{
    int rval;
    struct rtpp_tnotify_set *pvt;
    struct rtpp_tnotify_target *tntp;
    struct rtpp_tnotify_wildcard *tnwp;
    union rtpp_tnotify_entry rte;

    pvt = PUB2PVT(pub);
    memset(&rte, '\0', sizeof(union rtpp_tnotify_entry));
    rval = parse_timeout_sock(socket_name, &rte, e);
    if (rval < 0) {
        goto e0;
    }
    tntp = NULL;
    tnwp = NULL;
    if (rval == 0) {
        if (pvt->tp_len == RTPP_TNOTIFY_TARGETS_MAX) {
            *e = "Number of notify targets exceeds RTPP_TNOTIFY_TARGETS_MAX";
            goto e0;
        }
        tntp = malloc(sizeof(struct rtpp_tnotify_target));
        if (tntp == NULL) {
             *e = strerror(errno);
             goto e1;
        }
        memcpy(tntp, &rte.rtt, sizeof(struct rtpp_tnotify_target));
        tntp->connected = 0;
        tntp->fd = -1;
        pvt->tp[pvt->tp_len] = tntp;
        pvt->tp_len += 1;
    } else {
        if (pvt->wp_len == RTPP_TNOTIFY_WILDCARDS_MAX) {
            *e = "Number of notify wildcards exceeds RTPP_TNOTIFY_WILDCARDS_MAX";
            goto e0;
        }
        tnwp = malloc(sizeof(struct rtpp_tnotify_wildcard));
        if (tnwp == NULL) {
             *e = strerror(errno);
             goto e1;
        }
        memcpy(tnwp, &rte.rtw, sizeof(struct rtpp_tnotify_wildcard));
        pvt->wp[pvt->wp_len] = tnwp;
        pvt->wp_len += 1;
    }

    return (0);

e1:
    if (tntp != NULL)
        free(tntp);
    if (tnwp != NULL)
        free(tnwp);
e0:
    return (-1);
}
示例#14
0
static void
rtpp_wref_foreach(struct rtpp_weakref_obj *pub, rtpp_weakref_foreach_t foreach_f,
  void *foreach_d)
{
    struct rtpp_weakref_priv *pvt;

    pvt = PUB2PVT(pub);
    CALL_METHOD(pvt->ht, foreach, foreach_f, foreach_d);
}
示例#15
0
static int
rtpp_socket_bind(struct rtpp_socket *self, const struct sockaddr *addr,
  int addrlen)
{
    struct rtpp_socket_priv *pvt;

    pvt = PUB2PVT(self);
    return (bind(pvt->fd, addr, addrlen));
}
示例#16
0
static int
rtpp_socket_setrbuf(struct rtpp_socket *self, int so_rcvbuf)
{
    struct rtpp_socket_priv *pvt;

    pvt = PUB2PVT(self);
    return (setsockopt(pvt->fd, SOL_SOCKET, SO_RCVBUF, &so_rcvbuf,
      sizeof(so_rcvbuf)));
}
示例#17
0
static void
rtpp_pcount_get_stats(struct rtpp_pcount *self, struct rtpps_pcount *ocnt)
{
    struct rtpp_pcount_priv *pvt;

    pvt = PUB2PVT(self);
    pthread_mutex_lock(&pvt->lock);
    memcpy(ocnt, &pvt->cnt, sizeof(struct rtpps_pcount));
    pthread_mutex_unlock(&pvt->lock);
}
示例#18
0
static void
rtpp_pcount_reg_reld(struct rtpp_pcount *self)
{
    struct rtpp_pcount_priv *pvt;

    pvt = PUB2PVT(self);
    pthread_mutex_lock(&pvt->lock);
    pvt->cnt.nrelayed++;
    pthread_mutex_unlock(&pvt->lock);
}
示例#19
0
static void
rtpp_weakref_dtor(struct rtpp_weakref_obj *pub)
{
    struct rtpp_weakref_priv *pvt;

    pvt = PUB2PVT(pub);

    CALL_METHOD(pvt->ht, dtor);
    free(pvt);
}
示例#20
0
static void
rtpp_ttl_reset(struct rtpp_ttl *self)
{
    struct rtpp_ttl_priv *pvt;

    pvt = PUB2PVT(self);
    pthread_mutex_lock(&pvt->lock);
    pvt->ttl = pvt->max_ttl;
    pthread_mutex_unlock(&pvt->lock);
}
示例#21
0
static int
rtpp_socket_setnonblock(struct rtpp_socket *self)
{
    int flags;
    struct rtpp_socket_priv *pvt;

    pvt = PUB2PVT(self);
    flags = fcntl(pvt->fd, F_GETFL);
    return (fcntl(pvt->fd, F_SETFL, flags | O_NONBLOCK));
}
示例#22
0
static int
rtpp_stream_handle_play(struct rtpp_stream *self, char *codecs,
  char *pname, int playcount, struct rtpp_command *cmd, int ptime)
{
    struct rtpp_stream_priv *pvt;
    int n;
    char *cp;
    struct rtpp_server *rsrv;
    uint16_t seq;
    uint32_t ssrc;
    const char *plerror;

    pvt = PUB2PVT(self);
    pthread_mutex_lock(&pvt->lock);
    plerror = "reason unknown";
    while (*codecs != '\0') {
        n = strtol(codecs, &cp, 10);
        if (cp == codecs) {
            plerror = "invalid codecs";
            break;
        }
        codecs = cp;
        if (*codecs != '\0')
            codecs++;
        rsrv = rtpp_server_ctor(pname, n, playcount, cmd->dtime, ptime);
        if (rsrv == NULL) {
            RTPP_LOG(pvt->pub.log, RTPP_LOG_DBUG, "rtpp_server_ctor(\"%s\", %d, %d) failed",
              pname, n, playcount);
            plerror = "rtpp_server_ctor() failed";
            continue;
        }
        rsrv->stuid = self->stuid;
        ssrc = CALL_METHOD(rsrv, get_ssrc);
        seq = CALL_METHOD(rsrv, get_seq);
        if (CALL_METHOD(pvt->servers_wrt, reg, rsrv->rcnt, rsrv->sruid) != 0) {
            CALL_METHOD(rsrv->rcnt, decref);
            plerror = "servers_wrt->reg() method failed";
            break;
        }
        assert(pvt->rtps == RTPP_UID_NONE);
        pvt->rtps = rsrv->sruid;
        pthread_mutex_unlock(&pvt->lock);
        cmd->csp->nplrs_created.cnt++;
        CALL_METHOD(rsrv->rcnt, reg_pd, (rtpp_refcnt_dtor_t)player_predestroy_cb,
          pvt->rtpp_stats);
        CALL_METHOD(rsrv->rcnt, decref);
        RTPP_LOG(pvt->pub.log, RTPP_LOG_INFO,
          "%d times playing prompt %s codec %d: SSRC=" SSRC_FMT ", seq=%u",
          playcount, pname, n, ssrc, seq);
        return 0;
    }
    pthread_mutex_unlock(&pvt->lock);
    RTPP_LOG(pvt->pub.log, RTPP_LOG_ERR, "can't create player: %s", plerror);
    return -1;
}
示例#23
0
static int
rtpp_socket_send_pkt_na(struct rtpp_socket *self, struct sthread_args *str,
  struct rtpp_netaddr *daddr, struct rtp_packet *pkt,
  struct rtpp_log *log)
{
    struct rtpp_socket_priv *pvt;

    pvt = PUB2PVT(self);
    return (rtpp_anetio_send_pkt_na(str, pvt->fd, daddr, pkt,
      self->rcnt, log));
}
示例#24
0
static struct rtpp_refcnt *
rtpp_weakref_unreg(struct rtpp_weakref_obj *pub, uint64_t suid)
{
    struct rtpp_weakref_priv *pvt;
    struct rtpp_refcnt *sp;

    pvt = PUB2PVT(pub);

    sp = CALL_METHOD(pvt->ht, remove_by_key, &suid);
    return (sp);
}
示例#25
0
static void
rtpp_notify_dtor(struct rtpp_notify_obj *pub)
{
    struct rtpp_notify_priv *pvt;

    pvt = PUB2PVT(pub);

    rtpp_queue_put_item(pvt->sigterm, pvt->nqueue);
    pthread_join(pvt->thread_id, NULL);
    rtpp_queue_destroy(pvt->nqueue);
    free(pvt);
}
示例#26
0
static void
rtpp_log_obj_setlevel(struct rtpp_log *self, int log_level)
{
    struct rtpp_log_priv *pvt;

    pvt = PUB2PVT(self);
    if (log_level != -1) {
        rtpp_log_setlevel(pvt->log, log_level);
    } else {
        rtpp_log_setlevel(pvt->log, RTPP_LOG_ERR);
    }
}
示例#27
0
static int
rtpp_ttl_get_remaining(struct rtpp_ttl *self)
{
    struct rtpp_ttl_priv *pvt;
    int rval;

    pvt = PUB2PVT(self);
    pthread_mutex_lock(&pvt->lock);
    rval = pvt->ttl;
    pthread_mutex_unlock(&pvt->lock);
    return (rval);
}
示例#28
0
static uint64_t
rtpp_stream_get_rtps(struct rtpp_stream *self)
{
    struct rtpp_stream_priv *pvt;
    uint64_t rval;

    pvt = PUB2PVT(self);
    pthread_mutex_lock(&pvt->lock);
    rval = pvt->rtps;
    pthread_mutex_unlock(&pvt->lock);
    return (rval);
}
示例#29
0
static int
rtpp_stream_isplayer_active(struct rtpp_stream *self)
{
    struct rtpp_stream_priv *pvt;
    int rval;

    pvt = PUB2PVT(self);
    pthread_mutex_lock(&pvt->lock);
    rval = (pvt->rtps != RTPP_UID_NONE) ? 1 : 0;
    pthread_mutex_unlock(&pvt->lock);
    return (rval);
}
示例#30
0
static void
rtpp_notify_dtor(struct rtpp_notify *pub)
{
    struct rtpp_notify_priv *pvt;

    pvt = PUB2PVT(pub);

    rtpp_queue_put_item(pvt->sigterm, pvt->nqueue);
    pthread_join(pvt->thread_id, NULL);
    rtpp_queue_destroy(pvt->nqueue);
    CALL_METHOD(pvt->glog->rcnt, decref);
    free(pvt);
}