explicit IntervalTimer(const Duration &duration) { tval_.it_interval = zeroTimeVal; // too small values are dangerous tval_.it_value = duration < resolution ? toTimeval(resolution) : toTimeval(duration); tval_.it_interval = toTimeval(resolution); // in case event is missed BUNSAN_LOG_TRACE << "Setting timer for " << tval_.it_value.tv_sec << "s + " << tval_.it_value.tv_usec << "us"; system::unistd::setitimer(ITIMER_REAL, tval_); }
void Config::load(boost::filesystem::path file) { try { boost::program_options::store(boost::program_options::parse_config_file<char>(file.c_str(), desc), options); } catch (const std::exception& e) { CS_DIE("faild on read/parse config-file: " << file << "\n" << e.what()); } boost::program_options::notify(options); pidFile = options["pid-file"].as<boost::filesystem::path>(); usTcpNodelay = options["upstream-tcp-nodelay"].as<bool>(); dsSendTimeout = toTimeval(options["downstream-send-timeout"].as<std::time_t>()); usSendTimeout = toTimeval(options["upstream-send-timeout"].as<std::time_t>()); drBufferSize = options["downstream-read-buffer-size"].as<std::size_t>() << 10; dwBufferSize = options["downstream-write-buffer-size"].as<std::size_t>() << 10; urBufferSize = options["upstream-read-buffer-size"].as<std::size_t>() << 10; uwBufferSize = options["upstream-write-buffer-size"].as<std::size_t>() << 10; usLinger = options["upstream-linger"].as<bool>(); usLingerTimeout = options["upstream-linger-timeout"].as<int>(); dwPendingInterval = options["downstream-write-pending-interval"].as<int>(); uwPendingInterval = options["upstream-write-pending-interval"].as<int>(); userPassTotalLen = options["username-password-total-max-len"].as<std::size_t>(); ifaceName = options["iface-name"].as<std::string>(); ifaceMtu = options["iface-mtu"].as<uint16_t>(); CS_SAY( "loaded configs in [" << file.string() << "]:" << std::endl _PECAR_OUT_CONFIG_PROPERTY(programName) _PECAR_OUT_CONFIG_PROPERTY(usTcpNodelay) _PECAR_OUT_CONFIG_PROPERTY(drBufferSize) _PECAR_OUT_CONFIG_PROPERTY(dwBufferSize) _PECAR_OUT_CONFIG_PROPERTY(urBufferSize) _PECAR_OUT_CONFIG_PROPERTY(uwBufferSize) _PECAR_OUT_CONFIG_PROPERTY(dwPendingInterval) _PECAR_OUT_CONFIG_PROPERTY(uwPendingInterval) _PECAR_OUT_CONFIG_PROPERTY(usLinger) _PECAR_OUT_CONFIG_PROPERTY(usLingerTimeout) _PECAR_OUT_CONFIG_PROPERTY(userPassTotalLen) _PECAR_OUT_CONFIG_PROPERTY(ifaceName) _PECAR_OUT_CONFIG_PROPERTY(ifaceMtu) ); }
static error waitUntilReady(const SocketFD& fd, fd_set* readfds, fd_set* writefds, fd_set* exceptfds, int64_t timeoutMilliseconds) { if (readfds != nullptr) { FD_ZERO(readfds); FD_SET(fd, readfds); } if (writefds != nullptr) { FD_ZERO(writefds); FD_SET(fd, writefds); } if (exceptfds != nullptr) { FD_ZERO(exceptfds); FD_SET(fd, exceptfds); } struct timeval timeout; toTimeval(timeoutMilliseconds, &timeout); int result = select(0, readfds, writefds, exceptfds, &timeout); if (result == SOCKET_ERROR) { return error::wrap(etype::os, WSAGetLastError()); } else if (result == 0) { return error::timedout; } else { int soErr = 0; int optlen = sizeof(soErr); getsockopt(fd, SOL_SOCKET, SO_ERROR, (char*) &soErr, &optlen); if (soErr != 0) { return error::wrap(etype::os, soErr); } return error::nil; } }
/** Convert time into a string * \param resolution Resolution which the string should present * \param mainFormat Main format to use -- this is passed to strftime and appended by ':' plus the * below seconds resolution if requested by the resolution argument **/ std::string toString(base::Time::Resolution resolution = Microseconds, const std::string& mainFormat = "%Y%m%d-%H:%M:%S") const { struct timeval tv = toTimeval(); int uSecs = tv.tv_usec; time_t when = tv.tv_sec; struct tm *tm = localtime(&when); char time[50]; strftime(time,50, mainFormat.c_str(), tm); char buffer[57]; switch(resolution) { case Seconds: return std::string(time); case Milliseconds: sprintf(buffer,"%s:%03d", time, (int) (uSecs/1000.0)); break; case Microseconds: sprintf(buffer,"%s:%06d", time, uSecs); break; default: assert(-1); } return std::string(buffer); }
static jboolean OSNetworkSystem_selectImpl(JNIEnv* env, jclass, jobjectArray readFDArray, jobjectArray writeFDArray, jint countReadC, jint countWriteC, jintArray outFlags, jlong timeoutMs) { // Initialize the fd_sets. int maxFd = -1; fd_set readFds; fd_set writeFds; FD_ZERO(&readFds); FD_ZERO(&writeFds); bool initialized = initFdSet(env, readFDArray, countReadC, &readFds, &maxFd) && initFdSet(env, writeFDArray, countWriteC, &writeFds, &maxFd); if (!initialized) { return -1; } // Initialize the timeout, if any. timeval tv; timeval* tvp = NULL; if (timeoutMs >= 0) { tv = toTimeval(timeoutMs); tvp = &tv; } // Perform the select. int result = select(maxFd + 1, &readFds, &writeFds, NULL, tvp); if (result == 0) { // Timeout. return JNI_FALSE; } else if (result == -1) { // Error. if (errno == EINTR) { return JNI_FALSE; } else { jniThrowSocketException(env, errno); return JNI_FALSE; } } // Translate the result into the int[] we're supposed to fill in. ScopedIntArrayRW flagArray(env, outFlags); if (flagArray.get() == NULL) { return JNI_FALSE; } return translateFdSet(env, readFDArray, countReadC, readFds, flagArray.get(), 0, SOCKET_OP_READ) && translateFdSet(env, writeFDArray, countWriteC, writeFds, flagArray.get(), countReadC, SOCKET_OP_WRITE); }
// Returns 0 if we're connected; -EINPROGRESS if we're still hopeful, -errno if we've failed. // 'timeout' the timeout in milliseconds. If timeout is negative, perform a blocking operation. int isConnected(int fd, int timeout) { timeval passedTimeout(toTimeval(timeout)); // Initialize the fd sets for the select. fd_set readSet; fd_set writeSet; FD_ZERO(&readSet); FD_ZERO(&writeSet); FD_SET(fd, &readSet); FD_SET(fd, &writeSet); int nfds = fd + 1; timeval* tp = timeout >= 0 ? &passedTimeout : NULL; int rc = select(nfds, &readSet, &writeSet, NULL, tp); if (rc == -1) { if (errno == EINTR) { // We can't trivially retry a select with TEMP_FAILURE_RETRY, so punt and ask the // caller to try again. return -EINPROGRESS; } return -errno; } // If the fd is just in the write set, we're connected. if (FD_ISSET(fd, &writeSet) && !FD_ISSET(fd, &readSet)) { return 0; } // If the fd is in both the read and write set, there was an error. if (FD_ISSET(fd, &readSet) || FD_ISSET(fd, &writeSet)) { // Get the pending error. int error = 0; socklen_t errorLen = sizeof(error); if (getsockopt(fd, SOL_SOCKET, SO_ERROR, &error, &errorLen) == -1) { return -errno; // Couldn't get the real error, so report why not. } return -error; } // Timeout expired. return -EINPROGRESS; }
static int handle_client(int client_fd) { int status; size_t size, nitems; FILE *serial_file; char buf[1024]; /* buffer for serial IO */ CapCommand cmd; char ruser[64], rhost[64], realhost[64]; double rate, time; fd_set rd_fds; struct timeval timeout, now, *timeoutPtr; int recording = 0; double recordNow = 0.; double recordNext = 0.; double recordPeriod = 0.; double recordDelta = 0.; #ifdef _WIN32 int ms; #endif while (1) { FD_ZERO(&rd_fds); FD_SET(client_fd, &rd_fds); if ( !recording ) { timeoutPtr = NULL; } else { /* record and schedule the next recording */ #ifdef LINUX gettimeofday(&now, NULL); #else gettimeofday(&now); #endif recordNow = toDouble(now); if ( recordNext == 0.0 ) /* The first record */ recordNext = recordNow; while ( recordNext <= recordNow ) { get_data(client_fd); recordNext = recordNext + recordPeriod; } timeout = toTimeval( recordNext - recordNow ); timeoutPtr = &timeout; } /* * wait for commands or a timeout */ #ifndef _WIN32 status = select(FD_SETSIZE, &rd_fds, NULL, NULL, timeoutPtr); #else /* Should really use CapWaitTimeout when possible */ ms = -1; if (timeoutPtr) ms = timeoutPtr->tv_sec*1000 + timeoutPtr->tv_usec/1000; status = CapWaitTimeout(client_fd, ms); #endif if (status < 0 ) { if (errno == EINTR) { /* Ignore signals and try again */ continue; } /* Otherwise, give a fatal error message */ CapError(client_fd, CAP_SEV_FATAL, gProgramName, "select failed"); CapError(client_fd, CAP_SEV_FATAL, "select", NULL); exit(1); } else if (status == 0) { /* Try again */ continue; } /* There is data on the client file descriptor */ cmd = CapGetCommand(client_fd); switch (cmd) { case CAP_CMD_QUIT: return 0; case CAP_CMD_AUTHORIZE: status = CapGetAuthInfo(client_fd, ruser, rhost, realhost); if (status < 0) { return -1; } /* * If user@host is not authorized to use this server then: * * status = CapAuthorize(client_fd, 0); */ status = CapAuthorize(client_fd, 1); break; case CAP_CMD_INIT: /* Initial client/server handshake */ status = CapInitialize(client_fd, gProgramName); break; case CAP_CMD_VERSION: /* Send version information */ status = CapVersion(client_fd, gProgramName, "1.0", "Extern server (example) - v1.0"); break; case CAP_CMD_INFO: if (NULL == gChannels) { /* Only create the channel data once */ gChannels = create_channels(gConfigFile, client_fd); if ( NULL == gChannels) { status = CapError(client_fd, CAP_SEV_ERROR, gProgramName, "Missing or empty config file"); } } /* Return the recording information. gMaxRecordRate <= 0. * says recording is not supported */ { size_t buf_size = 0; if ( 0. < gMaxRecordRate) buf_size = INT_MAX; status = CapInfo(client_fd, gMinRecordRate, gMaxRecordRate, gDefRecordRate, buf_size, 1); } break; case CAP_CMD_DATA: /* Send frame data */ if (!recording ) get_data(client_fd); status = CapData(client_fd); break; case CAP_CMD_START_RECORD: /* Start recording */ rate = CapGetRequestedRecordRate(client_fd); size = CapGetRequestedRecordSize(client_fd); /* * Set up for recording operations */ if (rate < gMinRecordRate ) rate = gMinRecordRate; else if (rate > gMaxRecordRate ) rate = gMaxRecordRate; status = CapStartRecord(client_fd, rate, size); if (status != -1) { recordPeriod = 1.0 / rate; recordNext = 0.; recording = 1; } break; case CAP_CMD_STOP_RECORD: /* Stop recording */ status = CapStopRecord(client_fd); recording = 0; break; default: /* Ignore unknown commands */ status = CapError(client_fd, CAP_SEV_ERROR, gProgramName, "Unknown server command."); break; } if (status < 0) { return -1; } } /* return 0; */ }
static void OSNetworkSystem_accept(JNIEnv* env, jobject, jobject serverFileDescriptor, jobject newSocket, jobject clientFileDescriptor) { if (newSocket == NULL) { jniThrowNullPointerException(env, NULL); return; } NetFd serverFd(env, serverFileDescriptor); if (serverFd.isClosed()) { return; } sockaddr_storage ss; socklen_t addrLen = sizeof(ss); sockaddr* sa = reinterpret_cast<sockaddr*>(&ss); int clientFd; { int intFd = serverFd.get(); AsynchronousSocketCloseMonitor monitor(intFd); clientFd = NET_FAILURE_RETRY(serverFd, accept(intFd, sa, &addrLen)); } if (env->ExceptionOccurred()) { return; } if (clientFd == -1) { if (errno == EAGAIN || errno == EWOULDBLOCK) { jniThrowSocketTimeoutException(env, errno); } else { jniThrowSocketException(env, errno); } return; } // Reset the inherited read timeout to the Java-specified default of 0. timeval timeout(toTimeval(0)); int rc = setsockopt(clientFd, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout)); if (rc == -1) { LOGE("couldn't reset SO_RCVTIMEO on accepted socket fd %i: %s", clientFd, strerror(errno)); jniThrowSocketException(env, errno); } /* * For network sockets, put the peer address and port in instance variables. * We don't bother to do this for UNIX domain sockets, since most peers are * anonymous anyway. */ if (ss.ss_family == AF_INET || ss.ss_family == AF_INET6) { // Remote address and port. jobject remoteAddress = socketAddressToInetAddress(env, &ss); if (remoteAddress == NULL) { close(clientFd); return; } int remotePort = getSocketAddressPort(&ss); env->SetObjectField(newSocket, gCachedFields.socketimpl_address, remoteAddress); env->SetIntField(newSocket, gCachedFields.socketimpl_port, remotePort); // Local port. memset(&ss, 0, addrLen); int rc = getsockname(clientFd, sa, &addrLen); if (rc == -1) { close(clientFd); jniThrowSocketException(env, errno); return; } int localPort = getSocketAddressPort(&ss); env->SetIntField(newSocket, gCachedFields.socketimpl_localport, localPort); } jniSetFileDescriptorOfFD(env, clientFileDescriptor, clientFd); }
static void OSNetworkSystem_setSocketOption(JNIEnv* env, jobject, jobject fileDescriptor, jint option, jobject optVal) { NetFd fd(env, fileDescriptor); if (fd.isClosed()) { return; } int intVal; bool wasBoolean = false; if (env->IsInstanceOf(optVal, JniConstants::integerClass)) { intVal = (int) env->GetIntField(optVal, gCachedFields.integer_class_value); } else if (env->IsInstanceOf(optVal, JniConstants::booleanClass)) { intVal = (int) env->GetBooleanField(optVal, gCachedFields.boolean_class_value); wasBoolean = true; } else if (env->IsInstanceOf(optVal, JniConstants::inetAddressClass)) { // We use optVal directly as an InetAddress for IP_MULTICAST_IF. } else if (env->IsInstanceOf(optVal, JniConstants::multicastGroupRequestClass)) { // We use optVal directly as a MulticastGroupRequest for MCAST_JOIN_GROUP/MCAST_LEAVE_GROUP. } else { jniThrowSocketException(env, EINVAL); return; } int family = getSocketAddressFamily(fd.get()); if (family != AF_INET && family != AF_INET6) { jniThrowSocketException(env, EAFNOSUPPORT); return; } // Since we expect to have a AF_INET6 socket even if we're communicating via IPv4, we always // set the IPPROTO_IP options. As long as we fall back to creating IPv4 sockets if creating // an IPv6 socket fails, we need to make setting the IPPROTO_IPV6 options conditional. switch (option) { case JAVASOCKOPT_IP_TOS: setSocketOption(env, fd, IPPROTO_IP, IP_TOS, &intVal); if (family == AF_INET6) { setSocketOption(env, fd, IPPROTO_IPV6, IPV6_TCLASS, &intVal); } return; case JAVASOCKOPT_SO_BROADCAST: setSocketOption(env, fd, SOL_SOCKET, SO_BROADCAST, &intVal); return; case JAVASOCKOPT_SO_KEEPALIVE: setSocketOption(env, fd, SOL_SOCKET, SO_KEEPALIVE, &intVal); return; case JAVASOCKOPT_SO_LINGER: { linger l; l.l_onoff = !wasBoolean; l.l_linger = intVal <= 65535 ? intVal : 65535; setSocketOption(env, fd, SOL_SOCKET, SO_LINGER, &l); return; } case JAVASOCKOPT_SO_OOBINLINE: setSocketOption(env, fd, SOL_SOCKET, SO_OOBINLINE, &intVal); return; case JAVASOCKOPT_SO_RCVBUF: setSocketOption(env, fd, SOL_SOCKET, SO_RCVBUF, &intVal); return; case JAVASOCKOPT_SO_REUSEADDR: setSocketOption(env, fd, SOL_SOCKET, SO_REUSEADDR, &intVal); return; case JAVASOCKOPT_SO_SNDBUF: setSocketOption(env, fd, SOL_SOCKET, SO_SNDBUF, &intVal); return; case JAVASOCKOPT_SO_TIMEOUT: { timeval timeout(toTimeval(intVal)); setSocketOption(env, fd, SOL_SOCKET, SO_RCVTIMEO, &timeout); return; } case JAVASOCKOPT_TCP_NODELAY: setSocketOption(env, fd, IPPROTO_TCP, TCP_NODELAY, &intVal); return; #ifdef ENABLE_MULTICAST case JAVASOCKOPT_MCAST_JOIN_GROUP: mcastJoinLeaveGroup(env, fd.get(), optVal, true); return; case JAVASOCKOPT_MCAST_LEAVE_GROUP: mcastJoinLeaveGroup(env, fd.get(), optVal, false); return; case JAVASOCKOPT_IP_MULTICAST_IF: { sockaddr_storage sockVal; if (!env->IsInstanceOf(optVal, JniConstants::inetAddressClass) || !inetAddressToSocketAddress(env, optVal, 0, &sockVal)) { return; } // This call is IPv4 only. The socket may be IPv6, but the address // that identifies the interface to join must be an IPv4 address. if (sockVal.ss_family != AF_INET) { jniThrowSocketException(env, EAFNOSUPPORT); return; } ip_mreqn mcast_req; memset(&mcast_req, 0, sizeof(mcast_req)); mcast_req.imr_address = reinterpret_cast<sockaddr_in*>(&sockVal)->sin_addr; setSocketOption(env, fd, IPPROTO_IP, IP_MULTICAST_IF, &mcast_req); return; } case JAVASOCKOPT_IP_MULTICAST_IF2: // TODO: is this right? should we unconditionally set the IPPROTO_IP state in case // we have an IPv6 socket communicating via IPv4? if (family == AF_INET) { // IP_MULTICAST_IF expects a pointer to an ip_mreqn struct. ip_mreqn multicastRequest; memset(&multicastRequest, 0, sizeof(multicastRequest)); multicastRequest.imr_ifindex = intVal; setSocketOption(env, fd, IPPROTO_IP, IP_MULTICAST_IF, &multicastRequest); } else { // IPV6_MULTICAST_IF expects a pointer to an integer. setSocketOption(env, fd, IPPROTO_IPV6, IPV6_MULTICAST_IF, &intVal); } return; case JAVASOCKOPT_MULTICAST_TTL: { // Although IPv6 was cleaned up to use int, and IPv4 non-multicast TTL uses int, // IPv4 multicast TTL uses a byte. u_char ttl = intVal; setSocketOption(env, fd, IPPROTO_IP, IP_MULTICAST_TTL, &ttl); if (family == AF_INET6) { setSocketOption(env, fd, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, &intVal); } return; } case JAVASOCKOPT_IP_MULTICAST_LOOP: { // Although IPv6 was cleaned up to use int, IPv4 multicast loopback uses a byte. u_char loopback = intVal; setSocketOption(env, fd, IPPROTO_IP, IP_MULTICAST_LOOP, &loopback); if (family == AF_INET6) { setSocketOption(env, fd, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, &intVal); } return; } #else case JAVASOCKOPT_MULTICAST_TTL: case JAVASOCKOPT_MCAST_JOIN_GROUP: case JAVASOCKOPT_MCAST_LEAVE_GROUP: case JAVASOCKOPT_IP_MULTICAST_IF: case JAVASOCKOPT_IP_MULTICAST_IF2: case JAVASOCKOPT_IP_MULTICAST_LOOP: jniThrowException(env, "java/lang/UnsupportedOperationException", NULL); return; #endif // def ENABLE_MULTICAST default: jniThrowSocketException(env, ENOPROTOOPT); } }
main( int argc, char *argv[] ) { double playNow = 0; double playNext = 0; double playPeriod = 1./30.; FILE *dataFile = NULL; parseArgs( argc, argv); playPeriod = 1./ gPlayFreq; dataFile = fopen(gDataPath, "r"); if ( NULL == dataFile ) { fprintf(stderr, "%s: could not open file %s", gProgramName, gDataPath); exit(1); } gBuffer = malloc(gBufferSize); if ( NULL == gBuffer ) { fprintf(stderr, "%s: out of memory, -b %d failed", gProgramName, gBufferSize); exit(1); } strcpy(gBuffer,""); while (1) { struct timeval timeout, now; #ifdef LINUX gettimeofday(&now,NULL); #else gettimeofday(&now); #endif playNow = toDouble(now); if ( playNext == 0.0 ) /* The first record */ playNext = playNow; while ( playNext <= playNow ) { if ( NULL == fgets(gBuffer, gBufferSize, dataFile ) ) { rewind( dataFile); if ( NULL == fgets(gBuffer, gBufferSize, dataFile ) ) { fprintf(stderr, "%s: file read failed", gProgramName); exit(1); } } printf( "%s", gBuffer ); playNext = playNext + playPeriod; } fflush(stdout); /* * wait for commands or a timeout */ timeout = toTimeval( playNext - playNow ); select(FD_SETSIZE, NULL, NULL, NULL, &timeout); } }