示例#1
0
int rtspsrv_init(STREAM_RTSP_SESSIONS_T *pRtsp) {

  pthread_t ptdMonitor;
  struct sockaddr_storage sa;
  pthread_attr_t attrMonitor;
  RTSP_MONITOR_CTXT_T startCtxt;
  const char *s;

  if(!pRtsp || pRtsp->max <= 0) {
    return -1;
  }

  if(pRtsp->psessions) {
    avc_free((void *) &pRtsp->psessions);
  }

  destroy_rtspgetsessions(pRtsp);

  if(!(pRtsp->psessions = (RTSP_SESSION_T *)
                          avc_calloc(pRtsp->max, sizeof(RTSP_SESSION_T)))) {
    return -1;
  }

  pRtsp->numRtspGetSessions = pRtsp->max * 2;
  if(!(pRtsp->pRtspGetSessionsBuf = (RTSP_HTTP_SESSION_T *)
                          avc_calloc(pRtsp->numRtspGetSessions, sizeof(RTSP_HTTP_SESSION_T)))) {
    avc_free((void *) &pRtsp->psessions);
    pRtsp->numRtspGetSessions = 0;
    return -1;
  }

  pthread_mutex_init(&pRtsp->mtx, NULL);
 
  //
  // If all UDP / RTP sockets are bound to the same port then establish
  // the listener of this port prior to any RTSP interaction because some app
  // gateways may send some UDP polling data to the base port - and returning
  // an ICMP port unreachable would prevent such app gateways from allocating
  // UDP proxy ports
  //
  pRtsp->sockStaticLocalPort = INVALID_SOCKET;
  if(pRtsp->staticLocalPort > 0) {
    memset(&sa, 0, sizeof(sa));
    sa.ss_family = AF_INET;
    ((struct sockaddr_in *) &sa)->sin_addr.s_addr = INADDR_ANY;
    INET_PORT(sa) = htons(pRtsp->staticLocalPort);
    if((pRtsp->sockStaticLocalPort = net_opensocket(SOCK_DGRAM, 0, 0, (struct sockaddr *) &sa)) == INVALID_SOCKET) {
      LOG(X_ERROR("Failed to open RTSP static local RTP port %d"), pRtsp->staticLocalPort);
    } else {
      if(net_setsocknonblock(pRtsp->sockStaticLocalPort, 1) < 0) {
      LOG(X_ERROR("Failed to listen on RTSP static local RTP port %d"), pRtsp->staticLocalPort);
        net_closesocket(&pRtsp->sockStaticLocalPort);
      }
    }
    //if(pRtsp->sockStaticLocalPort != INVALID_SOCKET) {
    //  sain.sin_addr.s_addr = inet_addr("127.0.0.1");
    //  rc = sendto(pRtsp->sockStaticLocalPort, &sain, 1, 0, (struct sockaddr *) &sain, sizeof(sain));
    //  fprintf(stderr, "SENDTO:%d\n", rc);
    //}
  }

  //
  // Parse any CSV of quoted User-Agent matches which should try to force TCP interleaved mode
  //
  pRtsp->rtspForceTcpUAList.count = 0;
  if(pRtsp->rtspForceTcpUAList.str) {
    strutil_parse_csv(cbparse_entry_rtspua, pRtsp, pRtsp->rtspForceTcpUAList.str);
  }

  pRtsp->runMonitor = 2;
  memset(&startCtxt, 0, sizeof(startCtxt));
  startCtxt.pRtsp = pRtsp;
  if((s = logutil_tid_lookup(pthread_self(), 0)) && s[0] != '\0') {
    snprintf(startCtxt.tid_tag, sizeof(startCtxt.tid_tag), "%s-rtspmon", s);
  }
  pthread_attr_init(&attrMonitor);
  pthread_attr_setdetachstate(&attrMonitor, PTHREAD_CREATE_DETACHED);

  if(pthread_create(&ptdMonitor,
                    &attrMonitor,
                    (void *) rtsp_monitor_proc,
                    (void *) &startCtxt) != 0) {
    LOG(X_ERROR("Unable to create RTP monitor thread"));
    pRtsp->runMonitor = 0;
    if(pRtsp->psessions) {
      avc_free((void *) &pRtsp->psessions);
    }
    destroy_rtspgetsessions(pRtsp);
    pthread_mutex_destroy(&pRtsp->mtx);
  }

  while(pRtsp->runMonitor != 1 && pRtsp->runMonitor != -1) {
    usleep(5000);
  }

  return 0;
}
示例#2
0
//TODO: move this to http files
int http_getpage(const char *addr, uint16_t port, const char *uri,
                 char *buf, unsigned int szbuf, unsigned int tmtms) {
  int rc = 0;
  NETIO_SOCK_T netsock;
  struct sockaddr_in sa;
  HTTP_PARSE_CTXT_T hdrCtxt;
  HTTP_RESP_T httpResp;
  unsigned int contentLen = 0;
  const char *p;
  unsigned int consumed = 0;
  struct timeval tv0, tv1;
  char hdr[1024];

  if(!addr || !buf || szbuf <= 0) {
    return -1;
  }
  if(!uri) {
    uri = "/";
  }

  memset(&netsock, 0, sizeof(netsock));
  if((NETIOSOCK_FD(netsock) = net_opensocket(SOCK_STREAM, 0, 0, NULL)) == INVALID_SOCKET) {
    return -1;
  }

  memset(&sa, 0, sizeof(sa));
  sa.sin_addr.s_addr = inet_addr(addr);
  sa.sin_port = htons(port);

  if((rc = net_connect(NETIOSOCK_FD(netsock), &sa)) != 0) {
    return rc;
  }

  gettimeofday(&tv0, NULL);

  memset(&hdrCtxt, 0, sizeof(hdrCtxt));
  memset(&httpResp, 0, sizeof(httpResp));
  hdrCtxt.pnetsock = &netsock;
  hdrCtxt.pbuf = hdr;
  hdrCtxt.szbuf = sizeof(hdr);
  hdrCtxt.tmtms = tmtms;

  VSX_DEBUG_MGR(LOG(X_DEBUG("MGR - Sending local status command: '%s' to: %d"), uri, htons(sa.sin_port)));

  if((httpcli_gethdrs(&hdrCtxt, &httpResp, &sa, uri, NULL, 0, 0, NULL, NULL)) < 0) {
    return -1;
  }

  if(rc >= 0 && (p = conf_find_keyval(httpResp.hdrPairs, HTTP_HDR_CONTENT_LEN))) {
    contentLen = atoi(p);  
  } 

  if(rc >= 0) {
    if(contentLen <= 0) {
      LOG(X_ERROR("Content-Length not found in response"));
      rc = -1;
    } else if(contentLen > szbuf) {
      LOG(X_ERROR("Input buffer size too small %d / %d"), szbuf, contentLen);
      rc = -1;
    } else if(hdrCtxt.idxbuf > hdrCtxt.hdrslen) {
      if((consumed = hdrCtxt.idxbuf - hdrCtxt.hdrslen) < szbuf) {
        memcpy(buf, &hdr[hdrCtxt.hdrslen], consumed);
      } else {
        LOG(X_ERROR("Input buffer size too small %d / %d"), szbuf, contentLen);
        rc = -1;
      }
    }
  }

  if(rc >= 0 && net_setsocknonblock(NETIOSOCK_FD(netsock), 1) < 0) {
    rc = -1;
  } 

    //fprintf(stderr, "GET PAGE OK idx:%d hdrs:%d conentlen:%d\n", hdrCtxt.idxbuf, hdrCtxt.hdrslen, contentLen);

  while(rc >= 0 && consumed < contentLen) {
    if((rc = netio_recvnb(&netsock, (unsigned char *) &buf[consumed], 
                          contentLen - consumed, 500)) > 0) {
      consumed += rc;
    } 

    gettimeofday(&tv1, NULL);
    if(tmtms > 0 && consumed < contentLen && TIME_TV_DIFF_MS(tv1, tv0) > tmtms) {
      LOG(X_WARNING("HTTP %s:%d%s timeout %d ms exceeded"), net_inet_ntoa(sa.sin_addr, hdr), 
           ntohs(sa.sin_port), uri, tmtms);
      break;
      rc = -1;
    }
  }

  if(contentLen > 0 && consumed >= contentLen) {
    rc = consumed;
  } else {
    rc = -1;
  }

  netio_closesocket(&netsock);

  return rc;
}