Ejemplo n.º 1
0
void
remove_session(struct cfg *cf, struct rtpp_session *sp)
{
    int i;

    rtpp_log_write(RTPP_LOG_INFO, sp->log, "RTP stats: %lu in from callee, %lu "
      "in from caller, %lu relayed, %lu dropped", sp->pcount[0], sp->pcount[1],
      sp->pcount[2], sp->pcount[3]);
    rtpp_log_write(RTPP_LOG_INFO, sp->log, "RTCP stats: %lu in from callee, %lu "
      "in from caller, %lu relayed, %lu dropped", sp->rtcp->pcount[0],
      sp->rtcp->pcount[1], sp->rtcp->pcount[2], sp->rtcp->pcount[3]);
    rtpp_log_write(RTPP_LOG_INFO, sp->log, "session on ports %d/%d is cleaned up",
      sp->ports[0], sp->ports[1]);
    for (i = 0; i < 2; i++) {
	if (sp->addr[i] != NULL)
	    free(sp->addr[i]);
	if (sp->prev_addr[i] != NULL)
	    free(sp->prev_addr[i]);
	if (sp->rtcp->addr[i] != NULL)
	    free(sp->rtcp->addr[i]);
	if (sp->rtcp->prev_addr[i] != NULL)
	    free(sp->rtcp->prev_addr[i]);
	if (sp->fds[i] != -1) {
	    close(sp->fds[i]);
	    assert(cf->sessions[sp->sidx[i]] == sp);
	    cf->sessions[sp->sidx[i]] = NULL;
	    assert(cf->pfds[sp->sidx[i]].fd == sp->fds[i]);
	    cf->pfds[sp->sidx[i]].fd = -1;
	    cf->pfds[sp->sidx[i]].events = 0;
	}
	if (sp->rtcp->fds[i] != -1) {
	    close(sp->rtcp->fds[i]);
	    assert(cf->sessions[sp->rtcp->sidx[i]] == sp->rtcp);
	    cf->sessions[sp->rtcp->sidx[i]] = NULL;
	    assert(cf->pfds[sp->rtcp->sidx[i]].fd == sp->rtcp->fds[i]);
	    cf->pfds[sp->rtcp->sidx[i]].fd = -1;
	    cf->pfds[sp->rtcp->sidx[i]].events = 0;
	}
	if (sp->rrcs[i] != NULL)
	    rclose(sp, sp->rrcs[i], 1);
	if (sp->rtcp->rrcs[i] != NULL)
	    rclose(sp, sp->rtcp->rrcs[i], 1);
	if (sp->rtps[i] != NULL) {
	    cf->rtp_servers[sp->sridx] = NULL;
	    rtp_server_free(sp->rtps[i]);
	}
	if (sp->codecs[i] != NULL)
	    free(sp->codecs[i]);
	if (sp->rtcp->codecs[i] != NULL)
	    free(sp->rtcp->codecs[i]);
    }
    if (sp->timeout_data.notify_tag != NULL)
	free(sp->timeout_data.notify_tag);
    hash_table_remove(cf, sp);
    if (sp->call_id != NULL)
	free(sp->call_id);
    if (sp->tag != NULL)
	free(sp->tag);
    rtpp_log_close(sp->log);
    free(sp->rtcp);
    rtp_resizer_free(&sp->resizers[0]);
    rtp_resizer_free(&sp->resizers[1]);
    free(sp);
    cf->sessions_active--;
}
Ejemplo n.º 2
0
int
rtpp_command_ul_handle(struct cfg *cf, struct rtpp_command *cmd,
  struct ul_opts *ulop, int sidx)
{
    int pidx, lport, sessions_active;
    struct rtpp_socket *fds[2];
    const char *actor;
    struct rtpp_session *spa, *spb;

    pidx = 1;
    lport = 0;
    spa = spb = NULL;
    fds[0] = fds[1] = NULL;
    if (sidx != -1) {
        RTPP_DBG_ASSERT(cmd->cca.op == UPDATE || cmd->cca.op == LOOKUP);
        spa = cmd->sp;
        if (spa->rtp->stream[sidx]->fd == NULL || ulop->new_port != 0) {
            if (ulop->local_addr != NULL) {
                spa->rtp->stream[sidx]->laddr = ulop->local_addr;
            }
            if (rtpp_create_listener(cf, spa->rtp->stream[sidx]->laddr, &lport, fds) == -1) {
                RTPP_LOG(spa->log, RTPP_LOG_ERR, "can't create listener");
                reply_error(cmd, ECODE_LSTFAIL_1);
                goto err_undo_0;
            }
            if (spa->rtp->stream[sidx]->fd != NULL && ulop->new_port != 0) {
                RTPP_LOG(spa->log, RTPP_LOG_INFO,
                  "new port requested, releasing %d/%d, replacing with %d/%d",
                  spa->rtp->stream[sidx]->port, spa->rtcp->stream[sidx]->port, lport, lport + 1);
                CALL_METHOD(cf->stable->sessinfo, update, spa, sidx, fds);
            } else {
                RTPP_DBG_ASSERT(spa->rtp->stream[sidx]->fd == NULL);
                spa->rtp->stream[sidx]->fd = fds[0];
                RTPP_DBG_ASSERT(spa->rtcp->stream[sidx]->fd == NULL);
                spa->rtcp->stream[sidx]->fd = fds[1];
                CALL_METHOD(cf->stable->sessinfo, append, spa, sidx);
            }
            spa->rtp->stream[sidx]->port = lport;
            spa->rtcp->stream[sidx]->port = lport + 1;
            if (spa->complete == 0) {
                cmd->csp->nsess_complete.cnt++;
            }
            spa->complete = 1;
        }
        if (ulop->weak)
            spa->rtp->stream[sidx]->weak = 1;
        else if (cmd->cca.op == UPDATE)
            spa->strong = 1;
        lport = spa->rtp->stream[sidx]->port;
        ulop->lia[0] = spa->rtp->stream[sidx]->laddr;
        pidx = (sidx == 0) ? 1 : 0;
        if (cmd->cca.op == UPDATE) {
            CALL_METHOD(spa->rtp->stream[0]->ttl, reset_with,
              cf->stable->max_setup_ttl);
            CALL_METHOD(spa->rtp->stream[1]->ttl, reset_with,
              cf->stable->max_setup_ttl);
            RTPP_LOG(spa->log, RTPP_LOG_INFO,
              "adding %s flag to existing session, new=%d/%d/%d",
              ulop->weak ? ( sidx ? "weak[1]" : "weak[0]" ) : "strong",
              spa->strong, spa->rtp->stream[0]->weak, spa->rtp->stream[1]->weak);
        } else {
            CALL_METHOD(spa->rtp->stream[0]->ttl, reset_with, cf->stable->max_ttl);
            CALL_METHOD(spa->rtp->stream[1]->ttl, reset_with, cf->stable->max_ttl);
        }
        RTPP_LOG(spa->log, RTPP_LOG_INFO,
          "lookup on ports %d/%d, session timer restarted", spa->rtp->stream[0]->port,
          spa->rtp->stream[1]->port);
    } else {
        struct rtpp_hash_table_entry *hte;

        RTPP_DBG_ASSERT(cmd->cca.op == UPDATE);
        RTPP_LOG(cf->stable->glog, RTPP_LOG_INFO,
          "new session %s, tag %s requested, type %s",
          cmd->cca.call_id, cmd->cca.from_tag, ulop->weak ? "weak" : "strong");
        if (cf->stable->slowshutdown != 0) {
            RTPP_LOG(cf->stable->glog, RTPP_LOG_INFO,
              "proxy is in the deorbiting-burn mode, new session rejected");
            reply_error(cmd, ECODE_SLOWSHTDN);
            goto err_undo_0;
        }
        if (ulop->local_addr != NULL) {
            ulop->lia[0] = ulop->lia[1] = ulop->local_addr;
        }
        if (rtpp_create_listener(cf, ulop->lia[0], &lport, fds) == -1) {
            RTPP_LOG(cf->stable->glog, RTPP_LOG_ERR, "can't create listener");
            reply_error(cmd, ECODE_LSTFAIL_2);
            goto err_undo_0;
        }

        /*
         * Session creation. If creation is requested with weak flag,
         * set weak[0].
         */
        spa = rtpp_session_ctor(cf->stable, &cmd->cca, cmd->dtime, ulop->lia,
          ulop->weak, lport, fds);
        if (spa == NULL) {
            handle_nomem(cf, cmd, ECODE_NOMEM_4, ulop,
              fds, NULL);
            return (-1);
        }

        hte = CALL_METHOD(cf->stable->sessions_ht, append_refcnt, spa->call_id,
          spa->rcnt);
        if (hte == NULL) {
            handle_nomem(cf, cmd, ECODE_NOMEM_5, ulop, NULL, spa);
            return (-1);
        }
        if (CALL_METHOD(cf->stable->sessions_wrt, reg, spa->rcnt, spa->seuid) != 0) {
            CALL_METHOD(cf->stable->sessions_ht, remove, spa->call_id, hte);
            handle_nomem(cf, cmd, ECODE_NOMEM_8, ulop, NULL, spa);
            return (-1);
        }

        cmd->csp->nsess_created.cnt++;

        /*
         * Each session can consume up to 5 open file descriptors (2 RTP,
         * 2 RTCP and 1 logging) so that warn user when he is likely to
         * exceed 80% mark on hard limit.
         */
        sessions_active = CALL_METHOD(cf->stable->sessions_wrt, get_length);
        if (sessions_active > (rtpp_rlim_max(cf) * 80 / (100 * 5)) &&
          cf->nofile_limit_warned == 0) {
            cf->nofile_limit_warned = 1;
            RTPP_LOG(cf->stable->glog, RTPP_LOG_WARN, "passed 80%% "
              "threshold on the open file descriptors limit (%d), "
              "consider increasing the limit using -L command line "
              "option", (int)rtpp_rlim_max(cf));
        }

        RTPP_LOG(spa->log, RTPP_LOG_INFO, "new session on a port %d created, "
          "tag %s", lport, cmd->cca.from_tag);
        if (cf->stable->record_all != 0) {
            handle_copy(cf, spa, 0, NULL, 0);
            handle_copy(cf, spa, 1, NULL, 0);
        }
        /* Save ref, it will be decref'd by the command disposal code */
        RTPP_DBG_ASSERT(cmd->sp == NULL);
        cmd->sp = spa;
    }

    if (cmd->cca.op == UPDATE) {
        if (!CALL_METHOD(cf->stable->rtpp_tnset_cf, isenabled) && ulop->notify_socket != NULL)
            RTPP_LOG(spa->log, RTPP_LOG_ERR, "must permit notification socket with -n");
        if (spa->timeout_data.notify_tag != NULL) {
            free(spa->timeout_data.notify_tag);
            spa->timeout_data.notify_tag = NULL;
        }
        if (ulop->notify_socket != NULL) {
            struct rtpp_tnotify_target *rttp;

            rttp = CALL_METHOD(cf->stable->rtpp_tnset_cf, lookup, ulop->notify_socket,
              (cmd->rlen > 0) ? sstosa(&cmd->raddr) : NULL, (cmd->rlen > 0) ? cmd->laddr : NULL);
            if (rttp == NULL) {
                RTPP_LOG(spa->log, RTPP_LOG_ERR, "invalid socket name %s", ulop->notify_socket);
                ulop->notify_socket = NULL;
            } else {
                RTPP_LOG(spa->log, RTPP_LOG_INFO, "setting timeout handler");
                spa->timeout_data.notify_target = rttp;
                spa->timeout_data.notify_tag = strdup(ulop->notify_tag);
            }
        } else if (spa->timeout_data.notify_target != NULL) {
            spa->timeout_data.notify_target = NULL;
            RTPP_LOG(spa->log, RTPP_LOG_INFO, "disabling timeout handler");
        }
    }

    if (ulop->ia[0] != NULL && ulop->ia[1] != NULL) {
        CALL_METHOD(spa->rtp->stream[pidx], prefill_addr, &(ulop->ia[0]),
          cmd->dtime);
        CALL_METHOD(spa->rtcp->stream[pidx], prefill_addr, &(ulop->ia[1]),
          cmd->dtime);
    }
    spa->rtp->stream[pidx]->asymmetric = spa->rtcp->stream[pidx]->asymmetric = ulop->asymmetric;
    spa->rtp->stream[pidx]->latch_info.latched = spa->rtcp->stream[pidx]->latch_info.latched = ulop->asymmetric;
    if (spa->rtp->stream[pidx]->codecs != NULL) {
        free(spa->rtp->stream[pidx]->codecs);
        spa->rtp->stream[pidx]->codecs = NULL;
    }
    if (ulop->codecs != NULL) {
        spa->rtp->stream[pidx]->codecs = ulop->codecs;
        ulop->codecs = NULL;
    }
    spa->rtp->stream[NOT(pidx)]->ptime = ulop->requested_ptime;
    actor = CALL_METHOD(spa->rtp->stream[pidx], get_actor);
    if (ulop->requested_ptime > 0) {
        RTPP_LOG(spa->log, RTPP_LOG_INFO, "RTP packets from %s "
          "will be resized to %d milliseconds", actor, ulop->requested_ptime);
    } else if (spa->rtp->stream[pidx]->resizer != NULL) {
          RTPP_LOG(spa->log, RTPP_LOG_INFO, "Resizing of RTP "
          "packets from %s has been disabled", actor);
    }
    if (ulop->requested_ptime > 0) {
        if (spa->rtp->stream[pidx]->resizer != NULL) {
            rtp_resizer_set_ptime(spa->rtp->stream[pidx]->resizer, ulop->requested_ptime);
        } else {
            spa->rtp->stream[pidx]->resizer = rtp_resizer_new(ulop->requested_ptime);
        }
    } else if (spa->rtp->stream[pidx]->resizer != NULL) {
        rtp_resizer_free(cf->stable->rtpp_stats, spa->rtp->stream[pidx]->resizer);
        spa->rtp->stream[pidx]->resizer = NULL;
    }

    RTPP_DBG_ASSERT(lport != 0);
    ulop->reply.port = lport;
    ulop->reply.ia = ulop->lia[0];
    if (cf->stable->advaddr[0] != NULL) {
        if (cf->stable->bmode != 0 && cf->stable->advaddr[1] != NULL &&
          ulop->lia[0] == cf->stable->bindaddr[1]) {
            ulop->reply.ia_ov = cf->stable->advaddr[1];
        } else {
            ulop->reply.ia_ov = cf->stable->advaddr[0];
        }
    }
    ul_reply_port(cmd, &ulop->reply);
    rtpp_command_ul_opts_free(ulop);
    return (0);

err_undo_0:
    rtpp_command_ul_opts_free(ulop);
    return (-1);
}
Ejemplo n.º 3
0
int
rtpp_command_ul_handle(struct cfg *cf, struct rtpp_command *cmd,
  struct common_cmd_args *ccap, struct ul_opts *ulop,
  struct rtpp_session *sp, int sidx)
{
    int pidx, lport, i;
    int fds[2];
    char *cp;
    struct rtpp_session *spa, *spb;

    pidx = 1;
    lport = 0;
    spa = spb = NULL;
    fds[0] = fds[1] = -1;
    if (sidx != -1) {
        assert(ccap->op == UPDATE || ccap->op == LOOKUP);
        spa = sp;
        if (spa->fds[sidx] == -1) {
            if (ulop->local_addr != NULL) {
                spa->laddr[sidx] = ulop->local_addr;
            }
            if (rtpp_create_listener(cf, spa->laddr[sidx], &lport, fds) == -1) {
                rtpp_log_write(RTPP_LOG_ERR, spa->log, "can't create listener");
                reply_error(cf, cmd, ECODE_LSTFAIL_1);
                goto err_undo_0;
            }
            assert(spa->fds[sidx] == -1);
            spa->fds[sidx] = fds[0];
            assert(spa->rtcp->fds[sidx] == -1);
            spa->rtcp->fds[sidx] = fds[1];
            spa->ports[sidx] = lport;
            spa->rtcp->ports[sidx] = lport + 1;
            if (spa->complete == 0) {
                cmd->csp->nsess_complete.cnt++;
            }
            spa->complete = spa->rtcp->complete = 1;
            append_session(cf, spa, sidx);
        }
        if (ulop->weak)
            spa->weak[sidx] = 1;
        else if (ccap->op == UPDATE)
            spa->strong = 1;
        lport = spa->ports[sidx];
        ulop->lia[0] = spa->laddr[sidx];
        pidx = (sidx == 0) ? 1 : 0;
        spa->ttl_mode = cf->stable->ttl_mode;
        spa->ttl[0] = cf->stable->max_ttl;
        spa->ttl[1] = cf->stable->max_ttl;
        if (ccap->op == UPDATE) {
            rtpp_log_write(RTPP_LOG_INFO, spa->log,
              "adding %s flag to existing session, new=%d/%d/%d",
              ulop->weak ? ( sidx ? "weak[1]" : "weak[0]" ) : "strong",
              spa->strong, spa->weak[0], spa->weak[1]);
        }
        rtpp_log_write(RTPP_LOG_INFO, spa->log,
          "lookup on ports %d/%d, session timer restarted", spa->ports[0],
          spa->ports[1]);
    } else {
        assert(ccap->op == UPDATE);
        rtpp_log_write(RTPP_LOG_INFO, cf->stable->glog,
          "new session %s, tag %s requested, type %s",
          ccap->call_id, ccap->from_tag, ulop->weak ? "weak" : "strong");
        if (cf->stable->slowshutdown != 0) {
            rtpp_log_write(RTPP_LOG_INFO, cf->stable->glog,
              "proxy is in the deorbiting-burn mode, new session rejected");
            reply_error(cf, cmd, ECODE_SLOWSHTDN);
            goto err_undo_0;
        }
        if (ulop->local_addr != NULL) {
            ulop->lia[0] = ulop->lia[1] = ulop->local_addr;
        }
        if (rtpp_create_listener(cf, ulop->lia[0], &lport, fds) == -1) {
            rtpp_log_write(RTPP_LOG_ERR, cf->stable->glog, "can't create listener");
            reply_error(cf, cmd, ECODE_LSTFAIL_2);
            goto err_undo_0;
        }

        /*
         * Session creation. If creation is requested with weak flag,
         * set weak[0].
         */
        spa = malloc(sizeof(*spa));
        if (spa == NULL) {
            handle_nomem(cf, cmd, ECODE_NOMEM_4, ulop,
              fds, spa, spb);
            return (-1);
        }
        /* spb is RTCP twin session for this one. */
        spb = malloc(sizeof(*spb));
        if (spb == NULL) {
            handle_nomem(cf, cmd, ECODE_NOMEM_5, ulop,
              fds, spa, spb);
            return (-1);
        }
        memset(spa, 0, sizeof(*spa));
        memset(spb, 0, sizeof(*spb));
        spa->init_ts = cmd->dtime;
        spb->init_ts = cmd->dtime;
        for (i = 0; i < 2; i++) {
            spa->fds[i] = spb->fds[i] = -1;
            spa->last_update[i] = 0;
            spb->last_update[i] = 0;
        }
        spa->call_id = strdup(ccap->call_id);
        if (spa->call_id == NULL) {
            handle_nomem(cf, cmd, ECODE_NOMEM_6, ulop,
              fds, spa, spb);
            return (-1);
        }
        spb->call_id = spa->call_id;
        spa->tag = strdup(ccap->from_tag);
        spa->tag_nomedianum = strdup(ccap->from_tag);
        if (spa->tag == NULL) {
            handle_nomem(cf, cmd, ECODE_NOMEM_7, ulop,
              fds, spa, spb);
            return (-1);
        }
        cp = strrchr(spa->tag_nomedianum, ';');
        if (cp != NULL)
            *cp = '\0';
        spb->tag = spa->tag;
        spb->tag_nomedianum = spa->tag_nomedianum;
        for (i = 0; i < 2; i++) {
            spa->rrcs[i] = NULL;
            spb->rrcs[i] = NULL;
            spa->laddr[i] = ulop->lia[i];
            spb->laddr[i] = ulop->lia[i];
        }
        spa->strong = spa->weak[0] = spa->weak[1] = 0;
        if (ulop->weak)
            spa->weak[0] = 1;
        else
            spa->strong = 1;
        assert(spa->fds[0] == -1);
        spa->fds[0] = fds[0];
        assert(spb->fds[0] == -1);
        spb->fds[0] = fds[1];
        spa->ports[0] = lport;
        spb->ports[0] = lport + 1;
        spa->ttl[0] = cf->stable->max_ttl;
        spa->ttl[1] = cf->stable->max_ttl;
        spb->ttl[0] = -1;
        spb->ttl[1] = -1;
        spa->log = rtpp_log_open(cf->stable, "rtpproxy", spa->call_id, 0);
        rtpp_log_setlevel(spa->log, cf->stable->log_level);
        spb->log = spa->log;
        spa->rtcp = spb;
        spb->rtcp = NULL;
        spa->rtp = NULL;
        spb->rtp = spa;
        spa->sridx = spb->sridx = -1;

        append_session(cf, spa, 0);
        append_session(cf, spa, 1);

        spa->hte = CALL_METHOD(cf->stable->sessions_ht, append, spa->call_id, spa);
        if (spa->hte == NULL) {
            remove_session(cf, spa);
            remove_session(cf, spb);
            handle_nomem(cf, cmd, ECODE_NOMEM_8, ulop, fds, spa, spb);
            return (-1);
        }

        cf->sessions_created++;
        cf->sessions_active++;
        cmd->csp->nsess_created.cnt++;

        /*
         * Each session can consume up to 5 open file descriptors (2 RTP,
         * 2 RTCP and 1 logging) so that warn user when he is likely to
         * exceed 80% mark on hard limit.
         */
        if (cf->sessions_active > (rtpp_rlim_max(cf) * 80 / (100 * 5)) &&
          cf->nofile_limit_warned == 0) {
            cf->nofile_limit_warned = 1;
            rtpp_log_write(RTPP_LOG_WARN, cf->stable->glog, "passed 80%% "
              "threshold on the open file descriptors limit (%d), "
              "consider increasing the limit using -L command line "
              "option", (int)rtpp_rlim_max(cf));
        }

        rtpp_log_write(RTPP_LOG_INFO, spa->log, "new session on a port %d created, "
          "tag %s", lport, ccap->from_tag);
        if (cf->stable->record_all != 0) {
            handle_copy(cf, spa, 0, NULL, 0);
            handle_copy(cf, spa, 1, NULL, 0);
        }
    }

    if (ccap->op == UPDATE) {
        if (rtpp_th_get_sn(cf->timeout_handler) == NULL && ulop->socket_name_u != NULL)
            rtpp_log_write(RTPP_LOG_ERR, spa->log, "must permit notification socket with -n");
        if (spa->timeout_data.notify_tag != NULL) {
            free(spa->timeout_data.notify_tag);
            spa->timeout_data.notify_tag = NULL;
        }
        if (rtpp_th_get_sn(cf->timeout_handler) != NULL && ulop->socket_name_u != NULL) {
            if (strcmp(rtpp_th_get_sn(cf->timeout_handler), ulop->socket_name_u) != 0) {
                rtpp_log_write(RTPP_LOG_ERR, spa->log, "invalid socket name %s", ulop->socket_name_u);
                ulop->socket_name_u = NULL;
            } else {
                rtpp_log_write(RTPP_LOG_INFO, spa->log, "setting timeout handler");
                spa->timeout_data.handler = cf->timeout_handler;
                spa->timeout_data.notify_tag = strdup(ulop->notify_tag);
            }
        } else if (ulop->socket_name_u == NULL && spa->timeout_data.handler != NULL) {
            spa->timeout_data.handler = NULL;
            rtpp_log_write(RTPP_LOG_INFO, spa->log, "disabling timeout handler");
        }
    }

    if (ulop->ia[0] != NULL && ulop->ia[1] != NULL) {
        if (spa->addr[pidx] != NULL)
            spa->last_update[pidx] = cmd->dtime;
        if (spa->rtcp->addr[pidx] != NULL)
            spa->rtcp->last_update[pidx] = cmd->dtime;
        /*
         * Unless the address provided by client historically
         * cannot be trusted and address is different from one
         * that we recorded update it.
         */
        if (spa->untrusted_addr[pidx] == 0 && !(spa->addr[pidx] != NULL &&
          SA_LEN(ulop->ia[0]) == SA_LEN(spa->addr[pidx]) &&
          memcmp(ulop->ia[0], spa->addr[pidx], SA_LEN(ulop->ia[0])) == 0)) {
            rtpp_log_write(RTPP_LOG_INFO, spa->log, "pre-filling %s's address "
              "with %s:%s", (pidx == 0) ? "callee" : "caller", ulop->addr, ulop->port);
            if (spa->addr[pidx] != NULL) {
                if (spa->canupdate[pidx] == 0) {
                    if (spa->prev_addr[pidx] != NULL)
                         free(spa->prev_addr[pidx]);
                    spa->prev_addr[pidx] = spa->addr[pidx];
                } else {
                    free(spa->addr[pidx]);
                }
            }
            spa->addr[pidx] = ulop->ia[0];
            ulop->ia[0] = NULL;
        }
        if (spa->rtcp->untrusted_addr[pidx] == 0 && !(spa->rtcp->addr[pidx] != NULL &&
          SA_LEN(ulop->ia[1]) == SA_LEN(spa->rtcp->addr[pidx]) &&
          memcmp(ulop->ia[1], spa->rtcp->addr[pidx], SA_LEN(ulop->ia[1])) == 0)) {
            if (spa->rtcp->addr[pidx] != NULL) {
                if (spa->rtcp->canupdate[pidx] == 0) {
                    if (spa->rtcp->prev_addr[pidx] != NULL)
                        free(spa->rtcp->prev_addr[pidx]);
                    spa->rtcp->prev_addr[pidx] = spa->rtcp->addr[pidx];
                } else {
                    free(spa->rtcp->addr[pidx]);
                }
            }
            spa->rtcp->addr[pidx] = ulop->ia[1];
            ulop->ia[1] = NULL;
        }
    }
    spa->asymmetric[pidx] = spa->rtcp->asymmetric[pidx] = ulop->asymmetric;
    spa->canupdate[pidx] = spa->rtcp->canupdate[pidx] = NOT(ulop->asymmetric);
    if (spa->codecs[pidx] != NULL) {
        free(spa->codecs[pidx]);
        spa->codecs[pidx] = NULL;
    }
    if (ulop->codecs != NULL) {
        spa->codecs[pidx] = ulop->codecs;
        ulop->codecs = NULL;
    }
    if (ulop->requested_nsamples > 0) {
        rtpp_log_write(RTPP_LOG_INFO, spa->log, "RTP packets from %s "
          "will be resized to %d milliseconds",
          (pidx == 0) ? "callee" : "caller", ulop->requested_nsamples / 8);
    } else if (spa->resizers[pidx] != NULL) {
          rtpp_log_write(RTPP_LOG_INFO, spa->log, "Resizing of RTP "
          "packets from %s has been disabled",
          (pidx == 0) ? "callee" : "caller");
    }
    if (ulop->requested_nsamples > 0) {
        if (spa->resizers[pidx] != NULL) {
            rtp_resizer_set_onsamples(spa->resizers[pidx], ulop->requested_nsamples);
        } else {
            spa->resizers[pidx] = rtp_resizer_new(ulop->requested_nsamples);
        }
    } else if (spa->resizers[pidx] != NULL) {
        rtp_resizer_free(spa->resizers[pidx]);
        spa->resizers[pidx] = NULL;
    }

    assert(lport != 0);
    ulop->reply.port = lport;
    ulop->reply.ia = ulop->lia[0];
    if (cf->stable->advaddr[0] != NULL) {
        if (cf->stable->bmode != 0 && cf->stable->advaddr[1] != NULL &&
          ulop->lia[0] == cf->stable->bindaddr[1]) {
            ulop->reply.ia_ov = cf->stable->advaddr[1];
        } else {
            ulop->reply.ia_ov = cf->stable->advaddr[0];
        }
    }
    ul_reply_port(cf, cmd, &ulop->reply);
    rtpp_command_ul_opts_free(ulop);
    return (0);

err_undo_0:
    rtpp_command_ul_opts_free(ulop);
    return (-1);
}
Ejemplo n.º 4
0
static void
rtpp_stream_dtor(struct rtpp_stream_priv *pvt)
{
    struct rtpp_stream *pub;

    pub = &(pvt->pub);
    rtpp_stream_fin(pub);
    if (pub->analyzer != NULL) {
         struct rtpa_stats rst;
         char ssrc_buf[11];
         const char *actor, *ssrc;

         actor = rtpp_stream_get_actor(pub);
         CALL_METHOD(pub->analyzer, get_stats, &rst);
         if (rst.ssrc_changes != 0) {
             snprintf(ssrc_buf, sizeof(ssrc_buf), SSRC_FMT, rst.last_ssrc);
             ssrc = ssrc_buf;
         } else {
             ssrc = "NONE";
         }
         RTPP_LOG(pvt->pub.log, RTPP_LOG_INFO, "RTP stream from %s: "
           "SSRC=%s, ssrc_changes=%u, psent=%u, precvd=%u, plost=%d, pdups=%u",
           actor, ssrc, rst.ssrc_changes, rst.psent, rst.precvd,
           rst.plost, rst.pdups);
         if (rst.psent > 0) {
             CALL_METHOD(pvt->rtpp_stats, updatebyname, "rtpa_nsent", rst.psent);
         }
         if (rst.precvd > 0) {
             CALL_METHOD(pvt->rtpp_stats, updatebyname, "rtpa_nrcvd", rst.precvd);
         }
         if (rst.pdups > 0) {
             CALL_METHOD(pvt->rtpp_stats, updatebyname, "rtpa_ndups", rst.pdups);
         }
         if (rst.pecount > 0) {
             CALL_METHOD(pvt->rtpp_stats, updatebyname, "rtpa_perrs", rst.pecount);
         }
         CALL_METHOD(pvt->pub.analyzer->rcnt, decref);
    }
    if (pub->fd != NULL)
        CALL_METHOD(pub->fd->rcnt, decref);
    if (pub->addr != NULL)
        free(pub->addr);
    if (pvt->prev_addr != NULL)
        free(pvt->prev_addr);
    if (pub->codecs != NULL)
        free(pub->codecs);
    if (pvt->rtps != RTPP_UID_NONE)
        CALL_METHOD(pvt->servers_wrt, unreg, pvt->rtps);
    if (pub->resizer != NULL)
        rtp_resizer_free(pvt->rtpp_stats, pub->resizer);
    if (pub->rrc != NULL)
        CALL_METHOD(pub->rrc->rcnt, decref);
    if (pub->pcount != NULL)
        CALL_METHOD(pub->pcount->rcnt, decref);

    CALL_METHOD(pub->ttl->rcnt, decref);
    CALL_METHOD(pub->pcnt_strm->rcnt, decref);
    CALL_METHOD(pvt->pub.log->rcnt, decref);

    pthread_mutex_destroy(&pvt->lock);
    free(pvt);
}
Ejemplo n.º 5
0
void
remove_session(struct cfg *cf, struct rtpp_session *sp)
{

    int i;

    rtpp_log_write(RTPP_LOG_INFO, sp->log, "RTP stats: %lu in from callee, %lu "
                   "in from caller, %lu relayed, %lu dropped", sp->pcount[0], sp->pcount[1],
                   sp->pcount[2], sp->pcount[3]);
    rtpp_log_write(RTPP_LOG_INFO, sp->log, "RTCP stats: %lu in from callee, %lu "
                   "in from caller, %lu relayed, %lu dropped", sp->rtcp->pcount[0],
                   sp->rtcp->pcount[1], sp->rtcp->pcount[2], sp->rtcp->pcount[3]);
    rtpp_log_write(RTPP_LOG_INFO, sp->log, "session on ports %d/%d is cleaned up",
                   sp->ports[0], sp->ports[1]);

    for (i = 0; i < 2; i++)
    {
        if (sp->addr[i] != NULL)
            free(sp->addr[i]);
        if (sp->prev_addr[i] != NULL)
            free(sp->prev_addr[i]);
        if (sp->rtcp->addr[i] != NULL)
            free(sp->rtcp->addr[i]);
        if (sp->rtcp->prev_addr[i] != NULL)
            free(sp->rtcp->prev_addr[i]);
        //if(sp->stream[i]->bio != NULL) {
        //    BIO_free(sp->stream[i]->bio);
        //}
        if (sp->stream[i] != NULL)
        {
            rtpp_dtls_free_stream(sp->stream[i]);
        }
        if (sp->rtcp->stream[i] != NULL)
        {
            rtpp_dtls_free_stream(sp->rtcp->stream[i]);
        }
        if (sp->fds[i] != -1)
        {
            close(sp->fds[i]);
            assert(cf->sessions[sp->sidx[i]] == sp);
            cf->sessions[sp->sidx[i]] = NULL;
            assert(cf->pfds[sp->sidx[i]].fd == sp->fds[i]);
            cf->pfds[sp->sidx[i]].fd = -1;
            cf->pfds[sp->sidx[i]].events = 0;
        }
        if (sp->rtcp->fds[i] != -1)
        {
            close(sp->rtcp->fds[i]);
            assert(cf->sessions[sp->rtcp->sidx[i]] == sp->rtcp);
            cf->sessions[sp->rtcp->sidx[i]] = NULL;
            assert(cf->pfds[sp->rtcp->sidx[i]].fd == sp->rtcp->fds[i]);
            cf->pfds[sp->rtcp->sidx[i]].fd = -1;
            cf->pfds[sp->rtcp->sidx[i]].events = 0;
        }
        if (sp->rrcs[i] != NULL)
            rclose(sp, sp->rrcs[i], 1);
        if (sp->rtcp->rrcs[i] != NULL)
            rclose(sp, sp->rtcp->rrcs[i], 1);
        if (sp->rtps[i] != NULL)
        {
            cf->rtp_servers[sp->sridx] = NULL;
            rtp_server_free(sp->rtps[i]);
        }
        if (sp->codecs[i] != NULL)
            free(sp->codecs[i]);
        if (sp->rtcp->codecs[i] != NULL)
            free(sp->rtcp->codecs[i]);
        if (sp->bridgeBindAddr[i] != NULL) // VLAN Support (FRN4811)
            free(sp->bridgeBindAddr[i]);

        if (sp->ice_u[i] != NULL)
        {
            if (sp->ice_u[i]->local_user_name != NULL)
                free(sp->ice_u[i]->local_user_name);
            if (sp->ice_u[i]->local_password != NULL)
                free(sp->ice_u[i]->local_password);

            if (sp->ice_u[i]->remote_user_name != NULL)
                free(sp->ice_u[i]->remote_user_name);
            if (sp->ice_u[i]->remote_password != NULL)
                free(sp->ice_u[i]->remote_password);

            free(sp->ice_u[i]); 
        }

        if (sp->ice_candidate_list[i] != NULL) // ICE remote candidate support
            delete_ice_candidate(sp, i);
        if (sp->rtcp->ice_candidate_list[i] != NULL)
            delete_ice_candidate(sp->rtcp, i);
        if (sp->transcode)
            rtp_transcoder_free(&sp->trans[i],cf);
        if (sp->secure)
        {
            rtpp_srtp_free_context(&sp->srtp[i]);
            rtpp_srtp_free_context(&sp->rtcp->srtp[i]);
        }
        rtp_resizer_free(&sp->resizers[i]);

    }// for
    rtpp_stun_agent_remove(sp); //Remove stun agent Context.

    remove_session_frm_active_rsz_lst(sp);
    rtpp_log_write(RTPP_LOG_INFO, sp->log, "timed resizer lists cleaned up");


    if (sp->timeout_data.notify_tag != NULL)
        free(sp->timeout_data.notify_tag);
    hash_table_remove(cf, sp);
    if (sp->call_id != NULL)
        free(sp->call_id);
    if (sp->tag != NULL)
        free(sp->tag);
    rtpp_log_close(sp->log);

    free(sp->rtcp);
    free(sp);
    cf->sessions_active--;

}
Ejemplo n.º 6
0
void
remove_session(struct cfg *cf, struct rtpp_session *sp)
{
    int i;
    double session_time;

    session_time = getdtime() - sp->init_ts;
    /* Make sure structure is properly locked */
    assert(pthread_mutex_islocked(&cf->glock) == 1);
    assert(pthread_mutex_islocked(&cf->sessinfo.lock) == 1);

    rtpp_log_write(RTPP_LOG_INFO, sp->log, "RTP stats: %lu in from callee, %lu "
      "in from caller, %lu relayed, %lu dropped", sp->pcount[0], sp->pcount[1],
      sp->pcount[2], sp->pcount[3]);
    if (sp->pcount[0] == 0 && sp->pcount[1] == 0) {
        CALL_METHOD(cf->stable->rtpp_stats, updatebyname, "nsess_nortp", 1);
    } else if (sp->pcount[0] == 0 || sp->pcount[1] == 0) {
        CALL_METHOD(cf->stable->rtpp_stats, updatebyname, "nsess_owrtp", 1);
    }
    rtpp_log_write(RTPP_LOG_INFO, sp->log, "RTCP stats: %lu in from callee, %lu "
      "in from caller, %lu relayed, %lu dropped", sp->rtcp->pcount[0],
      sp->rtcp->pcount[1], sp->rtcp->pcount[2], sp->rtcp->pcount[3]);
    if (sp->rtcp->pcount[0] == 0 && sp->rtcp->pcount[1] == 0) {
        CALL_METHOD(cf->stable->rtpp_stats, updatebyname, "nsess_nortcp", 1);
    } else if (sp->rtcp->pcount[0] == 0 || sp->rtcp->pcount[1] == 0) {
        CALL_METHOD(cf->stable->rtpp_stats, updatebyname, "nsess_owrtcp", 1);
    }
    rtpp_log_write(RTPP_LOG_INFO, sp->log, "session on ports %d/%d is cleaned up",
      sp->ports[0], sp->ports[1]);
    for (i = 0; i < 2; i++) {
	if (sp->addr[i] != NULL)
	    free(sp->addr[i]);
	if (sp->prev_addr[i] != NULL)
	    free(sp->prev_addr[i]);
	if (sp->rtcp->addr[i] != NULL)
	    free(sp->rtcp->addr[i]);
	if (sp->rtcp->prev_addr[i] != NULL)
	    free(sp->rtcp->prev_addr[i]);
	if (sp->fds[i] != -1) {
	    shutdown(sp->fds[i], SHUT_RDWR);
	    close(sp->fds[i]);
	    assert(cf->sessinfo.sessions[sp->sidx[i]] == sp);
	    cf->sessinfo.sessions[sp->sidx[i]] = NULL;
	    assert(cf->sessinfo.pfds_rtp[sp->sidx[i]].fd == sp->fds[i]);
	    cf->sessinfo.pfds_rtp[sp->sidx[i]].fd = -1;
	    cf->sessinfo.pfds_rtp[sp->sidx[i]].events = 0;
	}
	if (sp->rtcp->fds[i] != -1) {
	    shutdown(sp->rtcp->fds[i], SHUT_RDWR);
	    close(sp->rtcp->fds[i]);
	    assert(cf->sessinfo.pfds_rtcp[sp->rtcp->sidx[i]].fd == sp->rtcp->fds[i]);
	    cf->sessinfo.pfds_rtcp[sp->rtcp->sidx[i]].fd = -1;
	    cf->sessinfo.pfds_rtcp[sp->rtcp->sidx[i]].events = 0;
	}
	if (sp->rrcs[i] != NULL) {
	    rclose(sp, sp->rrcs[i], 1);
            if (sp->record_single_file != 0) {
                sp->rtcp->rrcs[i] = NULL;
                sp->rrcs[NOT(i)] = NULL;
                sp->rtcp->rrcs[NOT(i)] = NULL;
            }
        }
	if (sp->rtcp->rrcs[i] != NULL)
	    rclose(sp, sp->rtcp->rrcs[i], 1);
	if (sp->rtps[i] != NULL) {
	    cf->rtp_servers[sp->sridx] = NULL;
	    rtp_server_free(sp->rtps[i]);
	}
	if (sp->codecs[i] != NULL)
	    free(sp->codecs[i]);
	if (sp->rtcp->codecs[i] != NULL)
	    free(sp->rtcp->codecs[i]);
        if (sp->resizers[i] != NULL)
             rtp_resizer_free(sp->resizers[i]);
    }
    if (sp->timeout_data.notify_tag != NULL)
	free(sp->timeout_data.notify_tag);
    if (sp->hte != NULL)
        CALL_METHOD(cf->stable->sessions_ht, remove, sp->call_id, sp->hte);
    if (sp->call_id != NULL)
	free(sp->call_id);
    if (sp->tag != NULL)
	free(sp->tag);
    if (sp->tag_nomedianum != NULL)
	free(sp->tag_nomedianum);
    rtpp_log_close(sp->log);
    free(sp->rtcp);
    free(sp);
    cf->sessions_active--;
    CALL_METHOD(cf->stable->rtpp_stats, updatebyname, "nsess_destroyed", 1);
    CALL_METHOD(cf->stable->rtpp_stats, updatebyname_d, "total_duration",
      session_time);
}