uint8_t* insert_connection_stats_payload(uint8_t* ptr, uint8_t* end, nabto_connect* con) {
    nabto_stamp_t now;
    uint32_t connectionAge;

    UNABTO_ASSERT(ptr <= end);
    if (end-ptr < NP_PAYLOAD_CONNECTION_STATS_BYTELENGTH) {
        return NULL;
    }

    ptr = insert_payload(ptr, NP_PAYLOAD_TYPE_CONNECTION_STATS, 0, 21);
    
    WRITE_FORWARD_U8(ptr, NP_PAYLOAD_CONNECTION_STATS_VERSION);
    
    now = nabtoGetStamp();
    connectionAge = nabtoStampDiff2ms(nabtoStampDiff(&now, &con->stats.connectionStart));

    WRITE_FORWARD_U32(ptr, connectionAge);

    WRITE_FORWARD_U32(ptr, con->stats.packetsReceived);
    WRITE_FORWARD_U32(ptr, con->stats.packetsSent);
    WRITE_FORWARD_U32(ptr, con->stats.bytesReceived);
    WRITE_FORWARD_U32(ptr, con->stats.bytesSent);

    return ptr;
}
Beispiel #2
0
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();
}
Beispiel #3
0
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;
}
Beispiel #5
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();
}