Beispiel #1
0
/* Handle close-tunnel frame received from the client */
int handle_client_tcp_fin_frame(protocol_frame *rcvd_frame)
{
    tunnel *tun=NULL;
    int offset = 0;
    int connid = rcvd_frame->connid;

    HASH_FIND_INT(by_id, &connid, tun);

    if(!tun)
    {
        log_printf(L_WARNING, "Got TCP FIN frame with unknown tunnel ID %d\n", rcvd_frame->connid);
        return -1;
    }

    if(tun->friendnumber != rcvd_frame->friendnumber)
    {
        log_printf(L_WARNING, "Friend #%d tried to close tunnel which belongs to #%d\n", rcvd_frame->friendnumber, tun->friendnumber);
        return -1;
    }
    
    tunnel_delete(tun);

    return 0;
}
Beispiel #2
0
int do_server_loop()
{
    struct timeval tv, tv_start, tv_end;
    unsigned long long ms_start, ms_end;
    fd_set fds;
    unsigned char tox_packet_buf[PROTOCOL_MAX_PACKET_SIZE];
    tunnel *tun = NULL;
    tunnel *tmp = NULL;
    TOX_CONNECTION connected = 0;

    tox_callback_friend_lossless_packet(tox, parse_lossless_packet, NULL);

    tv.tv_sec = 0;
    tv.tv_usec = 20000;

    FD_ZERO(&master_server_fds);

    while(1)
    {
        TOX_CONNECTION tmp_isconnected = 0;
        uint32_t tox_do_interval_ms;
        int select_rv = 0;

	/* Let tox do its stuff */
	tox_iterate(tox);

        /* Get the desired sleep time, used in select() later */
        tox_do_interval_ms = tox_iteration_interval(tox);
        tv.tv_usec = (tox_do_interval_ms % 1000) * 1000;
        tv.tv_sec = tox_do_interval_ms / 1000;
        log_printf(L_DEBUG2, "Iteration interval: %dms\n", tox_do_interval_ms);
        gettimeofday(&tv_start, NULL);

        /* Check change in connection state */
        tmp_isconnected = connection_status;
        if(tmp_isconnected != connected)
        {
            connected = tmp_isconnected;
            if(connected)
            {
                log_printf(L_DEBUG, "Connected to Tox network\n");
            }
            else
            {
                log_printf(L_DEBUG, "Disconnected from Tox network\n");
            }
        }

        fds = master_server_fds;

	/* Poll for data from our client connection */
	select_rv = select(select_nfds, &fds, NULL, NULL, &tv);
        if(select_rv == -1 || select_rv == 0)
        {
            if(select_rv == -1)
            {
                log_printf(L_DEBUG, "Reading from local socket failed: code=%d (%s)\n",
                        errno, strerror(errno));
            }
            else
            {
                log_printf(L_DEBUG2, "Nothing to read...");
            }
        }
        else
        {
            HASH_ITER(hh, by_id, tun, tmp)
            {
                if(FD_ISSET(tun->sockfd, &fds))
                {
                    int nbytes = recv(tun->sockfd, 
                            tox_packet_buf+PROTOCOL_BUFFER_OFFSET, 
                            READ_BUFFER_SIZE, 0);

                    /* Check if connection closed */
                    if(nbytes <= 0)
                    {
                        char data[PROTOCOL_BUFFER_OFFSET];
                        protocol_frame frame_st, *frame;

                        if(nbytes == 0)
                        {
                            log_printf(L_WARNING, "conn closed!\n");
                        }
                        else
                        {
                            log_printf(L_WARNING, "conn closed, code=%d (%s)\n",
                                    errno, strerror(errno));
                        }

                        frame = &frame_st;
                        memset(frame, 0, sizeof(protocol_frame));
                        frame->friendnumber = tun->friendnumber;
                        frame->packet_type = PACKET_TYPE_TCP_FIN;
                        frame->connid = tun->connid;
                        frame->data_length = 0;
                        send_frame(frame, data);

                        tunnel_delete(tun);
                                            
                        continue;
                    }
                    else
                    {
                        protocol_frame frame_st, *frame;

                        frame = &frame_st;
                        memset(frame, 0, sizeof(protocol_frame));
                        frame->friendnumber = tun->friendnumber;
                        frame->packet_type = PACKET_TYPE_TCP;
                        frame->connid = tun->connid;
                        frame->data_length = nbytes;
                        send_frame(frame, tox_packet_buf);
                    }
                }
            }
        }

        gettimeofday(&tv_end, NULL);
        ms_start = 1000 * tv_start.tv_sec + tv_start.tv_usec/1000;
        ms_end = 1000 * tv_end.tv_sec + tv_end.tv_usec/1000;
        
        if(ms_end - ms_start < tox_do_interval_ms)
        {
            /*log_printf(L_DEBUG, "Sleeping for %d ms extra to prevent high CPU usage\n", (tox_do_interval_ms - (ms_end - ms_start)));*/
            usleep((tox_do_interval_ms - (ms_end - ms_start)) * 1000);
        }
    }
}
Beispiel #3
0
/*
 * Call-back from the configuration server; save the configuration state.
 */
void config_callback(struct http_user_vars_s *vars)
{
    bool should_save;
    if (http_user_var_lookup(vars, VAR_POST) == NULL)
    {
        // This is a GET request -- initialise variables:
        char buff[32];
        http_user_var_insert(vars, VAR_ENABLED,
            bool_to_string(config.enabled));
        http_user_var_insert(vars, VAR_HIDE_TCP,
            bool_to_string(config.hide_tcp));
        http_user_var_insert(vars, VAR_HIDE_TCP_DATA,
            bool_to_string(config.hide_tcp_data));
        http_user_var_insert(vars, VAR_HIDE_TCP_SYN,
            enum_to_string(config.hide_tcp_syn, flag_def, DEF_SIZE(flag_def)));
        http_user_var_insert(vars, VAR_HIDE_TCP_ACK,
            enum_to_string(config.hide_tcp_ack, flag_def, DEF_SIZE(flag_def)));
        http_user_var_insert(vars, VAR_HIDE_TCP_PSH,
            enum_to_string(config.hide_tcp_psh, flag_def, DEF_SIZE(flag_def)));
        http_user_var_insert(vars, VAR_HIDE_TCP_FIN,
            enum_to_string(config.hide_tcp_fin, flag_def, DEF_SIZE(flag_def)));
        http_user_var_insert(vars, VAR_HIDE_TCP_RST,
            enum_to_string(config.hide_tcp_rst, flag_def, DEF_SIZE(flag_def)));
        http_user_var_insert(vars, VAR_SPLIT_MODE,
            enum_to_string(config.split, split_def, DEF_SIZE(split_def)));
        http_user_var_insert(vars, VAR_LOG_LEVEL,
            enum_to_string((config_enum_t)log_get_level(), log_level_def,
            DEF_SIZE(log_level_def)));
        http_user_var_insert(vars, VAR_HIDE_UDP,
            bool_to_string(config.hide_udp));
        http_user_var_insert(vars, VAR_GHOST_MODE,
            enum_to_string(config.ghost, ghost_def, DEF_SIZE(ghost_def)));
        http_user_var_insert(vars, VAR_GHOST_CHECK,
            bool_to_string(config.ghost_check));
        http_user_var_insert(vars, VAR_GHOST_SET_TTL,
            bool_to_string(config.ghost_set_ttl));
        snprintf(buff, sizeof(buff)-1, "%u", config.ghost_ttl);
        http_user_var_insert(vars, VAR_GHOST_TTL, buff);
        http_user_var_insert(vars, VAR_FRAG_MODE,
            enum_to_string(config.fragment, frag_def, DEF_SIZE(frag_def)));
        snprintf(buff, sizeof(buff)-1, "%u", config.tcp_port);
        http_user_var_insert(vars, VAR_TCP_PORT, buff);
        http_user_var_insert(vars, VAR_TCP_PROTO,
            protocol_get_name(config.tcp_proto));
        snprintf(buff, sizeof(buff)-1, "%u", config.udp_port);
        http_user_var_insert(vars, VAR_UDP_PORT, buff);
        http_user_var_insert(vars, VAR_UDP_PROTO,
            protocol_get_name(config.udp_proto));
        snprintf(buff, sizeof(buff)-1, "%u", config.mtu);
        http_user_var_insert(vars, VAR_MTU, buff);
        http_user_var_insert(vars, VAR_LAUNCH_UI,
            bool_to_string(config.launch_ui));

    }
    else if (http_get_bool_var(vars, VAR_SAVE, &should_save) && should_save)
    {
        // This is a POST request that wishes to save a new configuration:
        struct config_s config_temp;
        memmove(&config_temp, &config, sizeof(struct config_s));
        load_config(vars, &config_temp);

        // Copy to the global configuration state.
        thread_lock(&config_lock);
        memmove(&config, &config_temp, sizeof(struct config_s));
        thread_unlock(&config_lock);

        // Save the new configuration to disk.
        write_config(&config_temp);

        // Handle add/del of tunnel URLs
        const char *url;
        if (http_get_string_var(vars, VAR_ADD_URL, &url) && url[0] != '\0')
        {
            tunnel_add(url);
        }
        else if (http_get_string_var(vars, VAR_DEL_URL, &url) &&
                    url[0] != '\0')
        {
            tunnel_delete(url);
        }
    }
}