예제 #1
0
/*
 * Setup RTSP(S) connection
 */
static int
iptv_rtsp_start
  ( iptv_mux_t *im, const char *raw, const url_t *u )
{
  rtsp_priv_t *rp;
  http_client_t *hc;
  udp_connection_t *rtp, *rtcp;
  int r;

  if (!(hc = http_client_connect(im, RTSP_VERSION_1_0, u->scheme,
                                 u->host, u->port, NULL)))
    return SM_CODE_TUNING_FAILED;

  if (u->user)
    hc->hc_rtsp_user = strdup(u->user);
  if (u->pass)
    hc->hc_rtsp_pass = strdup(u->pass);

  if (udp_bind_double(&rtp, &rtcp,
                      "IPTV", "rtp", "rtcp",
                      NULL, 0, NULL,
                      128*1024, 16384, 4*1024, 4*1024) < 0) {
    http_client_close(hc);
    return SM_CODE_TUNING_FAILED;
  }

  hc->hc_hdr_received        = iptv_rtsp_header;
  hc->hc_data_received       = iptv_rtsp_data;
  hc->hc_handle_location     = 1;                      /* allow redirects */
  hc->hc_rtsp_keep_alive_cmd = RTSP_CMD_GET_PARAMETER; /* start keep alive loop with GET_PARAMETER */
  http_client_register(hc);                            /* register to the HTTP thread */
  r = rtsp_setup(hc, u->path, u->query, NULL,
                 ntohs(IP_PORT(rtp->ip)),
                 ntohs(IP_PORT(rtcp->ip)));
  if (r < 0) {
    udp_close(rtcp);
    udp_close(rtp);
    http_client_close(hc);
    return SM_CODE_TUNING_FAILED;
  }

  rp = calloc(1, sizeof(*rp));
  rp->rtcp_info = calloc(1, sizeof(iptv_rtcp_info_t));
  rtcp_init(rp->rtcp_info);
  rp->rtcp_info->connection = rtcp;
  rp->hc = hc;
  udp_multirecv_init(&rp->um, IPTV_PKTS, IPTV_PKT_PAYLOAD);
  rp->path = strdup(u->path ?: "");
  rp->query = strdup(u->query ?: "");

  im->im_data = rp;
  im->mm_iptv_fd = rtp->fd;
  im->mm_iptv_connection = rtp;
  im->mm_iptv_fd2 = rtcp->fd;
  im->mm_iptv_connection2 = rtcp;

  return 0;
}
예제 #2
0
static void create_everything(void) {
	struct control_tcp *ct;
	struct control_udp *cu;
	struct cli *cl;
	struct timeval tmp_tv;
	struct timeval redis_start, redis_stop;
	double redis_diff = 0;

	if (rtpe_config.kernel_table < 0)
		goto no_kernel;
	if (kernel_setup_table(rtpe_config.kernel_table)) {
		if (rtpe_config.no_fallback) {
			ilog(LOG_CRIT, "Userspace fallback disallowed - exiting");
			exit(-1);
		}
		goto no_kernel;
	}

no_kernel:
	rtpe_poller = poller_new();
	if (!rtpe_poller)
		die("poller creation failed");

	dtls_timer(rtpe_poller);

	if (call_init())
		abort();

        rwlock_init(&rtpe_config.config_lock);
	if (rtpe_config.max_sessions < -1) {
		rtpe_config.max_sessions = -1;
	}

	if (rtpe_config.redis_num_threads < 1) {
#ifdef _SC_NPROCESSORS_ONLN
		rtpe_config.redis_num_threads = sysconf( _SC_NPROCESSORS_ONLN );
#endif
		if (rtpe_config.redis_num_threads < 1) {
			rtpe_config.redis_num_threads = REDIS_RESTORE_NUM_THREADS;
		}
	}

	ct = NULL;
	if (rtpe_config.tcp_listen_ep.port) {
		ct = control_tcp_new(rtpe_poller, &rtpe_config.tcp_listen_ep);
		if (!ct)
			die("Failed to open TCP control connection port");
	}

	cu = NULL;
	if (rtpe_config.udp_listen_ep.port) {
		interfaces_exclude_port(rtpe_config.udp_listen_ep.port);
		cu = control_udp_new(rtpe_poller, &rtpe_config.udp_listen_ep);
		if (!cu)
			die("Failed to open UDP control connection port");
	}

	rtpe_control_ng = NULL;
	if (rtpe_config.ng_listen_ep.port) {
		interfaces_exclude_port(rtpe_config.ng_listen_ep.port);
		rtpe_control_ng = control_ng_new(rtpe_poller, &rtpe_config.ng_listen_ep, rtpe_config.control_tos);
		if (!rtpe_control_ng)
			die("Failed to open UDP control connection port");
	}

	cl = NULL;
	if (rtpe_config.cli_listen_ep.port) {
		interfaces_exclude_port(rtpe_config.cli_listen_ep.port);
	    cl = cli_new(rtpe_poller, &rtpe_config.cli_listen_ep);
	    if (!cl)
	        die("Failed to open UDP CLI connection port");
	}

	if (!is_addr_unspecified(&rtpe_config.redis_write_ep.address)) {
		rtpe_redis_write = redis_new(&rtpe_config.redis_write_ep,
				rtpe_config.redis_write_db, rtpe_config.redis_write_auth,
				ANY_REDIS_ROLE, rtpe_config.no_redis_required);
		if (!rtpe_redis_write)
			die("Cannot start up without running Redis %s write database! See also NO_REDIS_REQUIRED parameter.",
				endpoint_print_buf(&rtpe_config.redis_write_ep));
	}

		if (!is_addr_unspecified(&rtpe_config.redis_ep.address)) {
			rtpe_redis = redis_new(&rtpe_config.redis_ep, rtpe_config.redis_db, rtpe_config.redis_auth, rtpe_redis_write ? ANY_REDIS_ROLE : MASTER_REDIS_ROLE, rtpe_config.no_redis_required);
			rtpe_redis_notify = redis_new(&rtpe_config.redis_ep, rtpe_config.redis_db, rtpe_config.redis_auth, rtpe_redis_write ? ANY_REDIS_ROLE : MASTER_REDIS_ROLE, rtpe_config.no_redis_required);
			if (!rtpe_redis || !rtpe_redis_notify)
			die("Cannot start up without running Redis %s database! See also NO_REDIS_REQUIRED parameter.",
				endpoint_print_buf(&rtpe_config.redis_ep));

		if (!rtpe_redis_write)
			rtpe_redis_write = rtpe_redis;
	}

	daemonize();
	wpidfile();

	homer_sender_init(&rtpe_config.homer_ep, rtpe_config.homer_protocol, rtpe_config.homer_id);

	rtcp_init(); // must come after Homer init

	if (rtpe_redis) {
		// start redis restore timer
		gettimeofday(&redis_start, NULL);

		// restore
		if (redis_restore(rtpe_redis))
			die("Refusing to continue without working Redis database");

		// stop redis restore timer
		gettimeofday(&redis_stop, NULL);

		// print redis restore duration
		redis_diff += timeval_diff(&redis_stop, &redis_start) / 1000.0;
		ilog(LOG_INFO, "Redis restore time = %.0lf ms", redis_diff);
	}

	gettimeofday(&rtpe_latest_graphite_interval_start, NULL);

	timeval_from_us(&tmp_tv, (long long) rtpe_config.graphite_interval*1000000);
	set_graphite_interval_tv(&tmp_tv);
}