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...
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; }
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; }
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; }