Пример #1
0
int net_connect_tmt(SOCKET sock, const struct sockaddr *psa, unsigned int mstmt) {
  int rc = 0;
  struct timeval tv;
  fd_set fdsetRd, fdsetWr;
  char tmp[128];
  int try = 0;

  if(sock == INVALID_SOCKET || !psa) {
    return -1;
  } else if(mstmt == 0) {
    return net_connect(sock, psa);
  }

  VSX_DEBUG_NET( LOG(X_DEBUG("NET - net_connect family: %d, fd: %d, trying to %s:%d with timeout %d ms"),
             psa->sa_family, sock, FORMAT_NETADDR(*psa, tmp, sizeof(tmp)), ntohs(PINET_PORT(psa)), mstmt) );

  if((rc = net_setsocknonblock(sock, 1)) < 0) {
    return rc;
  }

  do {

    if((rc = connect(sock, psa, (socklen_t) INET_SIZE(*psa))) != 0) {

      if(errno == EINPROGRESS) {
        tv.tv_sec = (mstmt / 1000);
        tv.tv_usec = (mstmt % 1000) * 1000;

        FD_ZERO(&fdsetRd);
        FD_SET(sock, &fdsetRd);
        FD_ZERO(&fdsetWr);
        FD_SET(sock, &fdsetWr);

        if((rc = select(sock + 1, &fdsetRd, &fdsetWr, NULL, &tv)) > 0) {
          // call connect again to see if it was succesful 
          try++;
          rc = -1;
        } else if(rc == 0) {
          // timeout expired
          rc = -1;
          errno = ETIMEDOUT;
          break;
        } else {
          // select error
          break;
        }

      } else if(errno == EISCONN && try > 0) {
        // already connected
        rc = 0;
        break;
      } else {
        // connect failure
        rc = -1;
        break;
      }

    } // end of if((rc = connect...
Пример #2
0
int srvlisten_loop(SRV_LISTENER_CFG_T *pListenCfg, void *thread_func) {

  int salen;
  THREAD_FUNC_WRAPPER_ARG_T wrapArg;
  CLIENT_CONN_T *pConn;
  SOCKET_DESCR_T sdclient;
  int rc = -1;
  const char *s;
  //pthread_cond_t cond;
  pthread_mutex_t mtx;
  TIME_VAL tv0, tv1;
  char tmp[128];

#if defined(__APPLE__) 
  int sockopt = 0;
#endif // __APPLE__

  if(!pListenCfg || !pListenCfg->pnetsockSrv || !pListenCfg->pConnPool || !thread_func || 
     pListenCfg->pConnPool->numElements <= 0) {
    return -1;
  }

  //memset(&saSrv, 0, sizeof(saSrv));
  memset(&sdclient.netsocket, 0, sizeof(sdclient.netsocket));
  //salen = sizeof(saSrv);

  //if(getsockname(pListenCfg->pnetsockSrv->sock, (struct sockaddr *) &saSrv,  (socklen_t *) &salen) != 0) {
  //  LOG(X_ERROR("getsockopt failed on server socket"));
  //}

  pthread_mutex_init(&mtx, NULL);
  //pthread_cond_init(&cond, NULL);

  while(!g_proc_exit) {

    salen = sizeof(sdclient.sa);
    if((NETIOSOCK_FD(sdclient.netsocket) = 
                 accept(PNETIOSOCK_FD(pListenCfg->pnetsockSrv), (struct sockaddr *) &sdclient.sa, 
                                      (socklen_t *) &salen)) == INVALID_SOCKET) {
      if(!g_proc_exit) {
        LOG(X_ERROR("%saccept failed on %s:%d"), 
             ((pListenCfg->pnetsockSrv->flags & NETIO_FLAG_SSL_TLS) ? "SSL " : ""),
                 //inet_ntoa(saSrv.sin_addr), ntohs(saSrv.sin_port));
                 FORMAT_NETADDR(pListenCfg->sa, tmp, sizeof(tmp)), ntohs(INET_PORT(pListenCfg->sa)));
      }
      break;
    }

    if(g_proc_exit) {
      break;
    }

    sdclient.netsocket.flags = pListenCfg->pnetsockSrv->flags;

    //
    // Find an available client thread to process the client request
    //
    if((pConn = (CLIENT_CONN_T *) pool_get(pListenCfg->pConnPool)) == NULL) {
      LOG(X_WARNING("No available connection for %s:%d (max:%d) on port %d"), 
           FORMAT_NETADDR(sdclient.sa, tmp, sizeof(tmp)), ntohs(INET_PORT(sdclient.sa)), 
           pListenCfg->pConnPool->numElements, ntohs(INET_PORT(pListenCfg->sa)));

      netio_closesocket(&sdclient.netsocket);
      continue;
    }

#if defined(__APPLE__) 
    sockopt = 1;
    if(setsockopt(NETIOSOCK_FD(sdclient.netsocket), SOL_SOCKET, SO_NOSIGPIPE,
                 (char*) &sockopt, sizeof(sockopt)) != 0) {
      LOG(X_ERROR("Failed to set SO_NOSIGPIPE"));
    }
#endif // __APPLE__

    //pConn->psrvsaListen = &saSrv;
    //memcpy(&pConn->srvsaListen, &saSrv, sizeof(pConn->srvsaListen));

    LOG(X_DEBUG("Accepted connection on port %d from %s:%d"), htons(INET_PORT(pListenCfg->sa)), 
        FORMAT_NETADDR(sdclient.sa, tmp, sizeof(tmp)), htons(INET_PORT(sdclient.sa)));

    pthread_attr_init(&pConn->attr);
    pthread_attr_setdetachstate(&pConn->attr, PTHREAD_CREATE_DETACHED);
    memset(&pConn->sd.netsocket, 0, sizeof(pConn->sd.netsocket));
    NETIO_SET(pConn->sd.netsocket, sdclient.netsocket);
    memcpy(&pConn->sd.sa, &sdclient.sa, INET_SIZE(sdclient));
    pConn->pListenCfg = pListenCfg;
    NETIOSOCK_FD(sdclient.netsocket) = INVALID_SOCKET;

    wrapArg.thread_func = thread_func;
    wrapArg.pConnPool = pListenCfg->pConnPool;
    wrapArg.pConn = pConn;
    wrapArg.flags = 1;
    wrapArg.tid_tag[0] = '\0';
    if((s = logutil_tid_lookup(pthread_self(), 0)) && s[0] != '\0') {
      snprintf(wrapArg.tid_tag, sizeof(wrapArg.tid_tag), "%s-%u", s, pConn->pool.id);
    }
    //wrapArg.pcond = &cond;

  //fprintf(stderr, "%d CALLING wrap: 0x%x pConn:0x%x\n", pthread_self(), &wrapArg, wrapArg.pConn);

    if((rc = pthread_create(&pConn->ptd,
                    &pConn->attr,
                    (void *) thread_func_wrapper,
                    (void *) &wrapArg)) != 0) {
      LOG(X_ERROR("Unable to create connection handler thread on port %d from %s:%d (%d %s)"), 
          htons(INET_PORT(pListenCfg->sa)), FORMAT_NETADDR(sdclient.sa, tmp, sizeof(tmp)),
          htons(INET_PORT(sdclient.sa)), rc, strerror(rc));
      netio_closesocket(&pConn->sd.netsocket);
      pool_return(pListenCfg->pConnPool, &pConn->pool);
      wrapArg.flags = 0;
      //pthread_cond_broadcast(&cond);
      break;
    }

    pthread_attr_destroy(&pConn->attr);

    //
    // be careful not to reuse the same wrapArg instance 
    // since the stack variable arguments could get
    // overwritten by the next loop iteration, before the thread proc is 
    // invoked
    //
    //fprintf(stderr, "wait start\n");
    tv0 = timer_GetTime();
    //if(wrapArg.flags == 1) {

      //
      // It seems that calling pthread_cond_wait here to check if the thread creation is
      // complete is not completely reliable and portable, so we do the lame way 
      // of sleeping and polling.
      //
      //pthread_cond_wait(&cond, &mtx);

      while(wrapArg.flags == 1) {
        usleep(100);
        if(((tv1 = timer_GetTime()) - tv0) / TIME_VAL_MS > 1000) {
          LOG(X_WARNING("Abandoning wait for connection thread start on port %d from %s:%d"),
               htons(INET_PORT(pListenCfg->sa)),
              FORMAT_NETADDR(pListenCfg->sa, tmp, sizeof(tmp)), ntohs(INET_PORT(pListenCfg->sa)));
          break;
        } 
      }
      //fprintf(stderr, "THREAD STARTED AFTER %lld ns\n", (timer_GetTime() - tv0));
    //}

    //fprintf(stderr, "wait done\n");

    //while(wrapArg.flag == 1) {
    //  usleep(10000); 
    //}

  }

  //pthread_cond_destroy(&cond);
  pthread_mutex_destroy(&mtx);

  return rc;
}
Пример #3
0
RTSP_HTTP_SESSION_T *rtspsrv_newHttpSession(STREAM_RTSP_SESSIONS_T *pRtsp, const char *sessionCookie,
                                               const struct sockaddr *psa) {
  RTSP_HTTP_SESSION_T *pRtspGetSession = NULL; 
  size_t szCookie;
  unsigned int idx;

  if(!pRtsp || !pRtsp->pRtspGetSessionsBuf || !sessionCookie || sessionCookie[0] == '\0') {
    return NULL;
  }

  if((szCookie = strlen(sessionCookie)) > RTSP_HTTP_SESSION_COOKIE_MAX - 1) {
    LOG(X_ERROR("Client RTSP HTTP session cookie length %d exceeds %d"), szCookie, 
        RTSP_HTTP_SESSION_COOKIE_MAX - 1);
    return NULL;
  }

  pthread_mutex_lock(&pRtsp->mtx);

  for(idx = 0; idx < pRtsp->numRtspGetSessions; idx++) {

    if(!pRtsp->pRtspGetSessionsBuf[idx].inuse) {

      pRtspGetSession = &pRtsp->pRtspGetSessionsBuf[idx];

      if(!pRtspGetSession->pRequestBufWr) {
        if(!(pRtspGetSession->pRequestBufWr = (char *) avc_calloc(2, RTSP_HTTP_POST_BUFFER_SZ))) {
          pthread_mutex_unlock(&pRtsp->mtx);
          return NULL;
        }
        pRtspGetSession->pRequestBufRd = pRtspGetSession->pRequestBufWr + RTSP_HTTP_POST_BUFFER_SZ;

        pthread_mutex_init(&pRtspGetSession->cond.mtx, NULL);
        pthread_cond_init(&pRtspGetSession->cond.cond, NULL);
        pthread_mutex_init(&pRtspGetSession->mtx, NULL);
      }

      pRtspGetSession->inuse = 1;
      memset(&pRtspGetSession->netsocketPost, 0, sizeof(pRtspGetSession->netsocketPost));
      NETIOSOCK_FD(pRtspGetSession->netsocketPost) = INVALID_SOCKET;
      pRtspGetSession->expired = 0;
      strncpy(pRtspGetSession->cookie.sessionCookie, sessionCookie, RTSP_HTTP_SESSION_COOKIE_MAX - 1);
      if(psa) {
        memcpy(&pRtspGetSession->cookie.sa, psa, INET_SIZE(*psa));
      }
      gettimeofday(&pRtspGetSession->tvCreate, NULL);
      pRtspGetSession->tvLastMsg.tv_sec = 0;
      pRtspGetSession->requestSz = 0;
      pRtspGetSession->requestIdxWr = 0;
      pRtspGetSession->pRequestBufWr[0] = '\0';
      pRtspGetSession->pRequestBufRd[0] = '\0';
      pRtspGetSession->pnext = NULL;

      if(pRtsp->pRtspGetSessionsTail) {
        pRtsp->pRtspGetSessionsTail->pnext = pRtspGetSession;
      } else {
        pRtsp->pRtspGetSessionsHead = pRtspGetSession;
      }

      pRtsp->pRtspGetSessionsTail = pRtspGetSession;

      break;
    }

  }

  pthread_mutex_unlock(&pRtsp->mtx);

  return pRtspGetSession;
}
Пример #4
0
SOCKET net_opensocket(int socktype, unsigned int rcvbufsz, int sndbufsz, const struct sockaddr *psa) {
  int val;
  int sockbufsz = 0;
  char tmp[128];
  sa_family_t sa_family = AF_INET;
  SOCKET sock = INVALID_SOCKET;

  if(socktype != SOCK_STREAM && socktype != SOCK_DGRAM) {
    return INVALID_SOCKET;
  }

  if(psa && psa->sa_family == AF_INET6) {
    sa_family = psa->sa_family;
  }

  if((sock = socket(sa_family, socktype, 0)) == INVALID_SOCKET) {
    LOG(X_ERROR("Unable to create socket type %d"), socktype);
    return INVALID_SOCKET;
  }

  if(psa) {
    //LOG(X_DEBUG("NET_OPENSOCKET... family: %d, is_multicast: %d"), psa->sa_family, (socktype == SOCK_DGRAM && INET_IS_MULTICAST(psa)));
    //
    // Handle IGMP multicast group subscription
    //
    if(socktype == SOCK_DGRAM && INET_IS_MULTICAST(psa)) {
      if(add_multicast_group(sock, psa)  < 0) {
        closesocket(sock);
        LOG(X_ERROR("Failed to create socket family: %d %s:%d"), sa_family, 
                    FORMAT_NETADDR(*psa, tmp, sizeof(tmp)), htons(PINET_PORT(psa)));
        LOGHEX_DEBUGV(psa, sizeof(struct sockaddr_storage));
        return INVALID_SOCKET;
      }
    }

    val = 1;
    if(setsockopt (sock, SOL_SOCKET, SO_REUSEADDR,
                    (char *) &val, sizeof (val)) != 0) {
      LOG(X_WARNING("setsockopt SOL_SOCKET SO_REUSEADDR fail "ERRNO_FMT_STR), 
              ERRNO_FMT_ARGS);
    }

#if defined(__APPLE__)
    if(socktype == SOCK_DGRAM) {
      val = 1;
      if(setsockopt (sock, SOL_SOCKET, SO_REUSEPORT,
                      (char *) &val, sizeof (val)) != 0) {
        LOG(X_WARNING("setsockopt SOL_SOCKET SO_REUSEPORT fail "ERRNO_FMT_STR), 
                ERRNO_FMT_ARGS);
      }
    }
#endif // __APPLE__

    if(bind(sock, psa, INET_SIZE(*psa)) < 0) {
      LOG(X_ERROR("Unable to bind to local port %s:%d "ERRNO_FMT_STR),
                       FORMAT_NETADDR(*psa, tmp, sizeof(tmp)), ntohs(PINET_PORT(psa)), ERRNO_FMT_ARGS);
      closesocket(sock);
      return INVALID_SOCKET;
    }

     VSX_DEBUG_NET( LOG(X_DEBUG("NET - net_opensock: %s, family: %d (%d), fd: %d bound listener to %s:%d"), 
                socktype == SOCK_STREAM ? "stream" : "dgram", sa_family, psa->sa_family, sock, 
                FORMAT_NETADDR(*psa, tmp, sizeof(tmp)), ntohs(PINET_PORT(psa))) );

  } else {
     VSX_DEBUG_NET( LOG(X_DEBUG("NET - net_opensock: %s,family: %d, fd: %d"), 
                        socktype == SOCK_STREAM ? "stream" : "dgram", sa_family, sock) );
  }

  if(rcvbufsz > 0) {

    if(setsockopt(sock, SOL_SOCKET, SO_RCVBUF,
                  (char*) &rcvbufsz, sizeof(rcvbufsz)) != 0) {
      LOG(X_WARNING("Unable to setsockopt SOL_SOCKET SO_RCVBUF %u"), rcvbufsz);
    }

    sockbufsz = 0;
    val = sizeof(sockbufsz);
    if(getsockopt(sock, SOL_SOCKET, SO_RCVBUF,
                 (char*) &sockbufsz, (socklen_t *) &val) != 0) {
      LOG(X_ERROR("Unable to getsockopt SOL_SOCKET SO_RCVBUF %d"), val);
      closesocket(sock);
      return INVALID_SOCKET;
    }

    LOG(X_DEBUGV("socket receive buffer set to: %u"), sockbufsz);
  }

  if(sndbufsz > 0) {

    if(setsockopt(sock, SOL_SOCKET, SO_SNDBUF,
                  (char*) &sndbufsz, sizeof(rcvbufsz)) != 0) {
      LOG(X_WARNING("Unable to setsockopt SOL_SOCKET SO_SNDBUF %u"), sndbufsz);
    }

    sockbufsz = 0;
    val = sizeof(sockbufsz);
    if(getsockopt(sock, SOL_SOCKET, SO_SNDBUF,
                 (char*) &sockbufsz, (socklen_t *) &val) != 0) {
      LOG(X_ERROR("Unable to getsockopt SOL_SOCKET SO_SNDBUF %d"), val);
      closesocket(sock);
      return INVALID_SOCKET;
    }

    LOG(X_DEBUGV("socket send buffer set to: %u"), sockbufsz);
  }

  return sock;
}