void tunnel_loop_epoll() { struct epoll_event events[MAX_EPOLL_EVENTS]; int timeout; nabto_stamp_t ne; nabto_stamp_t now; int nfds; if (!unabto_init()) { NABTO_LOG_FATAL(("Failed to initialize unabto")); } if (!init_tunnel_module()) { NABTO_LOG_FATAL(("Cannot initialize tunnel module")); return; } unabto_time_auto_update(false); // time is updated here and after the select since that's the only blocking point. unabto_time_update_stamp(); while (true) { int i; unabto_next_event(&ne); now = nabtoGetStamp(); timeout = nabtoStampDiff2ms(nabtoStampDiff(&ne, &now)); if (timeout < 0) { timeout = 0; } nfds = epoll_wait(unabto_epoll_fd, events, MAX_EPOLL_EVENTS, timeout); unabto_time_update_stamp(); for (i = 0; i < nfds; i++) { unabto_epoll_event_handler* handler = (unabto_epoll_event_handler*)events[i].data.ptr; if (handler->epollEventType == UNABTO_EPOLL_TYPE_UDP) { unabto_network_epoll_read(&events[i]); } #if NABTO_ENABLE_TCP_FALLBACK unabto_tcp_fallback_epoll_event(&events[i]); #endif unabto_tunnel_epoll_event(&events[i]); } unabto_time_event(); } deinit_tunnel_module(); unabto_close(); }
void wait_event() { int timeout; nabto_stamp_t ne; nabto_stamp_t now; int nfds; int max_read_fd = 0; int max_write_fd = 0; fd_set read_fds; fd_set write_fds; struct timeval timeout_val; unabto_next_event(&ne); now = nabtoGetStamp(); timeout = nabtoStampDiff2ms(nabtoStampDiff(&ne, &now)); if (timeout < 0) timeout = 0; FD_ZERO(&read_fds); FD_ZERO(&write_fds); unabto_network_select_add_to_read_fd_set(&read_fds, &max_read_fd); #if NABTO_ENABLE_TCP_FALLBACK unabto_tcp_fallback_select_add_to_read_fd_set(&read_fds, &max_read_fd); unabto_tcp_fallback_select_add_to_write_fd_set(&write_fds, &max_write_fd); #endif timeout_val.tv_sec = (timeout/1000); timeout_val.tv_usec = ((timeout)%1000)*1000; nfds = select(MAX(max_read_fd+1, max_write_fd+1), &read_fds, &write_fds, NULL, &timeout_val); NABTO_LOG_TRACE(("foobar %i", nfds)); if (nfds < 0) NABTO_LOG_FATAL(("Error in epoll_wait: %d", errno)); unabto_network_select_read_sockets(&read_fds); unabto_time_event(); }
intptr_t tick_thread_func(void* args) { nabto_stamp_t ne; nabto_stamp_t shortTime; bool received = false; unabto_mutex_lock(&lock); unabto_next_event(&ne); unabto_mutex_unlock(&lock); nabtoSetFutureStamp(&shortTime, 10); while (running) { //struct epoll_event events[1]; int timeout; nabto_stamp_t now; // updating next event is an expensive operation so only do it if // the earlier update is expired. if (nabtoIsStampPassed(&ne) || (received && nabtoIsStampPassed(&shortTime))) { unabto_mutex_lock(&lock); unabto_time_event(); unabto_next_event(&ne); unabto_mutex_unlock(&lock); nabtoSetFutureStamp(&shortTime, 10); received = false; } // the problem is that the timing is changed when packets is received. now = nabtoGetStamp(); timeout = nabtoStampDiff2ms(nabtoStampDiff(&ne, &now)); if (timeout < 0) { NABTO_LOG_DEBUG(("connection timestamp is in the past. setting timeout to 1ms, timeout=%i, this could be a problem.", timeout)); timeout = 1; } else if (timeout == 0) { timeout = 1; } if (received) { if (timeout > 10) { timeout = 10; } } else { if (timeout > 100) { timeout = 100; } } nabto_socket_t readySockets[16]; uint16_t nReady = nabto_read_events(readySockets, 16, timeout); uint16_t i; for (i = 0; i < nReady; i++) { unabto_mutex_lock(&lock); unabto_read_socket(readySockets[i]); unabto_mutex_unlock(&lock); received = true; } if (nReady == 0) { unabto_mutex_lock(&lock); unabto_time_event(); unabto_mutex_unlock(&lock); } } return 0; }
void tunnel_loop_epoll() { struct epoll_event events[MAX_EPOLL_EVENTS]; int timeout; nabto_stamp_t ne; nabto_stamp_t now; int nfds; int i; if (!unabto_init()) { NABTO_LOG_FATAL(("Failed to initialize unabto")); } if (!init_tunnel_module()) { NABTO_LOG_FATAL(("Cannot initialize tunnel module")); return; } unabto_time_auto_update(false); // time is updated here and after the select since that's the only blocking point. unabto_time_update_stamp(); while (true) { int i; unabto_next_event(&ne); now = nabtoGetStamp(); timeout = nabtoStampDiff2ms(nabtoStampDiff(&ne, &now)); if (timeout < 0) { timeout = 0; } nfds = epoll_wait(unabto_epoll_fd, events, MAX_EPOLL_EVENTS, timeout); unabto_time_update_stamp(); for (i = 0; i < nfds; i++) { unabto_epoll_event_handler* handler = (unabto_epoll_event_handler*)events[i].data.ptr; if (handler->epollEventType == UNABTO_EPOLL_TYPE_UDP) { unabto_epoll_event_handler_udp* udpHandler = (unabto_epoll_event_handler_udp*)handler; bool status; do { status = unabto_read_socket(udpHandler->fd); } while (status); } #if NABTO_ENABLE_TCP_FALLBACK if (handler->epollEventType == UNABTO_EPOLL_TYPE_TCP_FALLBACK) { nabto_connect* con = (nabto_connect*)handler; if (events[i].events & EPOLLIN) { unabto_tcp_fallback_read_ready(con); } if (events[i].events & EPOLLOUT) { unabto_tcp_fallback_write_ready(con); } } #endif if (handler->epollEventType == UNABTO_EPOLL_TYPE_TCP_TUNNEL) { tunnel* tunnelPtr = (tunnel*)handler; if (tunnelPtr->sock != INVALID_SOCKET) { tunnel_event(tunnelPtr, TUNNEL_EVENT_SOURCE_TCP_READ); } if (tunnelPtr->sock != INVALID_SOCKET) { tunnel_event(tunnelPtr, TUNNEL_EVENT_SOURCE_TCP_WRITE); } } } unabto_time_event(); } deinit_tunnel_module(); unabto_close(); }