Пример #1
0
static bool init_socket(netplay_t *handle, const char *server, uint16_t port)
{
   if (!netplay_init_network())
      return false;

   if (!init_tcp_socket(handle, server, port, handle->spectate))
      return false;
   if (!handle->spectate && !init_udp_socket(handle, server, port))
      return false;

   return true;
}
Пример #2
0
static bool init_socket(netplay_t *netplay, const char *server, uint16_t port)
{
    if (!network_init())
        return false;

    if (!init_tcp_socket(netplay, server, port, netplay->spectate.enabled))
        return false;
    if (!netplay->spectate.enabled && !init_udp_socket(netplay, server, port))
        return false;

    return true;
}
Пример #3
0
unsigned int __stdcall ping_thread_entry(void *data)
#endif
{
    PingThreadData *pdata = (PingThreadData *)data;
    
    int maxfd, ret;
    fd_set all_rset, rset;
    struct timeval to;

    I3ServerList *list = pdata->list;
    char *url = pdata->url;
    uint64_t *ping_start_time = pdata->ping_start_time;
       
    int num_pings;
    I3ServerListNode *next_to_ping;
    uint64_t last_ping_time, curr_time;
    uint64_t last_add_new_i3servers, last_update_serverlist;
 
    FD_ZERO(&all_rset);
    FD_ZERO(&rset);

    /* socket init */
#ifdef ICMP_PING
    if (init_icmp_socket(&ping_sock) == -1)
	abort();
#else
    if (init_udp_socket(&ping_sock) == -1)
	abort();
#endif
    FD_SET(ping_sock, &all_rset);
    maxfd = ping_sock + 1;
    
    /* initial populate the list of i3 servers */
    update_i3_server_list(url, list, &next_to_ping);

    /* determine coordinates */
    init_coordinates(list);

    /* add some close-by servers from the list based on coordinates */
    change_ping_list(list, &next_to_ping, 1);
       
    /* eternal loop */
    last_ping_time = last_add_new_i3servers = last_update_serverlist = wall_time();
    set_status(ping_start_time, last_ping_time);
    for (;;) {
		rset = all_rset;
        to.tv_sec = 0; to.tv_usec = 10000;
        if ((ret = select(maxfd, &rset, NULL, NULL, &to)) < 0) {
            if (errno == EINTR)
                continue;
            else {
                perror("select");
                abort();
            }
        }

		/* message received on icmp socket */
		if (FD_ISSET(ping_sock, &rset)) {
			uint32_t addr; uint16_t port, seq; uint64_t rtt;
#ifdef ICMP_PING
			if (recv_echo_reply(ping_sock, &addr, &seq, &rtt)) {
#else
			if (recv_i3_echo_reply(ping_sock, &addr, &port, &seq, &rtt)) {
#endif
				update_ping_information(list, addr, seq, rtt);
			}
		}

		/* need to ping */
		curr_time = wall_time();
		if (list->num_ping_list > 0) {
			char status = get_status(ping_start_time, curr_time);
			num_pings = (curr_time - last_ping_time)/
				(period_ping[status]/list->num_ping_list);
			if (num_pings > 0) {
				if (NULL == next_to_ping) {
					I3_PRINT_DEBUG0(I3_DEBUG_LEVEL_MINIMAL, 
							"No servers to ping. Aborting\n");
				}
				send_npings(ping_sock, list, &next_to_ping, num_pings);
				last_ping_time = curr_time;
			}
		}
	
		/* change the list of i3 servers */
		if (curr_time - last_add_new_i3servers >
					period_pick_new_server[get_status(ping_start_time, curr_time)]) {
			/* testing just the best server */
			uint32_t best_addr; uint16_t best_port; uint64_t best_rtt;
			struct in_addr ia;
			int required_k = 1;
			int ret = get_top_k(list, required_k, &best_addr, &best_port, &best_rtt);
			
			if (ret != required_k) {
				// We couldn't find the request k top nodes.

				I3_PRINT_INFO0 (
						I3_INFO_LEVEL_WARNING,
						"I3 Ping Thread: Unable to obtain top k nodes.\n"
						);
				// Dilip: Feb 20, 2006.  I don't think the following works.
				// TODO: Start
				// We set the last_add_new_servers to fool the thread
				// to wait for some time before trying again to get
				// the top k nodes.
				//last_add_new_i3servers = curr_time;
				// TODO: End

				// Sleep for some time before trying again.
#				if defined (_WIN32)
					Sleep ( 25 ); // 25 milliseconds
#				else
					usleep(25 * 1000); // 25 milliseconds
#				endif				
				continue;
			}

			ia.s_addr = htonl(best_addr);
			I3_PRINT_DEBUG3(I3_INFO_LEVEL_MINIMAL,
					"Best node: %s:%d with RTT %Ld\n", 
					inet_ntoa(ia), best_port, best_rtt
					);
	    
			I3_PRINT_DEBUG0(I3_DEBUG_LEVEL_VERBOSE, "Adding new servers to list\n");
			change_ping_list(list, &next_to_ping, 0);
			last_add_new_i3servers = curr_time;
		}
	
		/* update (wget) i3 server list */
		if (curr_time - last_update_serverlist > PERIOD_SERVERLIST_WGET) {
			I3_PRINT_DEBUG0(	I3_DEBUG_LEVEL_VERBOSE, 
								"Updating server list from server\n");
			update_i3_server_list(url, list, &next_to_ping);
			last_update_serverlist = curr_time;
		}
    }

#ifndef _WIN32
    pthread_exit(0);
#endif
    return 0;
}
Пример #4
0
/* To determine the coordinates of the local node initially
 * Ping a subset of nodes and determine coordinates */
void init_coordinates(I3ServerList *list)
{
    int n = MIN(NUM_LANDMARKS_COORDINATE, list->num_newservers + list->num_ping_list);
    I3ServerListNode *node = list->list, *temp_node;
    uint64_t start_time = wall_time();
    Coordinates_RTT coord_rtt[NUM_LANDMARKS_COORDINATE];
    int num_landmarks = 0; int started_full_list = 0;
    struct in_addr ia;
    nw_skt_t tmp_ping_sock;

#ifdef ICMP_PING
    if (init_icmp_socket(&tmp_ping_sock) == -1)
	abort();
#else
    if (init_udp_socket(&tmp_ping_sock) == -1)
	abort();
#endif

    // wait for responses and accumulate
    // cut and pasted from below
    while ((wall_time() - start_time < COORD_INIT_PING_WAIT_TIME) && 
	    (num_landmarks < n)) {
	fd_set rset;
	struct timeval to;
	int ret;

	FD_ZERO(&rset);

	if (!node && !started_full_list) {
	    node = list-> full_list;
	    started_full_list = 1;
	}
	
	if (node) {
	    ia.s_addr = htonl(node->addr);
	    I3_PRINT_DEBUG1(I3_DEBUG_LEVEL_VERBOSE,
		    "Sending ICMP echo request to %s\n", inet_ntoa(ia));
#ifdef ICMP_PING
	    send_echo_request(tmp_ping_sock, node->addr, 0);
#else
	    i3_echo_request(tmp_ping_sock, node->addr, node->port, 0);
#endif
	    node = node->next_list;
	}

	FD_SET(tmp_ping_sock, &rset);
        to.tv_sec = 0; to.tv_usec = 200000ULL;
        if ((ret = select(tmp_ping_sock+1, &rset, NULL, NULL, &to)) < 0) {
	    int err = nw_error();
            if (err == EINTR)
                continue;
            else {
                perror("select");
                abort();
            }
        }

	// message received on icmp socket
	if (FD_ISSET(tmp_ping_sock, &rset)) {
	    uint32_t addr; uint16_t port, seq; uint64_t rtt;
#ifdef ICMP_PING
	    if (recv_echo_reply(tmp_ping_sock, &addr, &seq, &rtt)) {
#else
	    if (recv_i3_echo_reply(tmp_ping_sock, &addr, &port, &seq, &rtt)) {
#endif
		temp_node = lookup_i3server(list, addr);
		assert(NULL != temp_node);

		coord_rtt[num_landmarks].coord = temp_node->coord;
		coord_rtt[num_landmarks].rtt = rtt;
		num_landmarks++;

		ia.s_addr = htonl(addr);
		I3_PRINT_DEBUG4(I3_DEBUG_LEVEL_VERBOSE,
			"Node: %s Coordinate: %.1f:%.1f RTT: %Ld\n",
			inet_ntoa(ia), temp_node->coord.latitude,
			temp_node->coord.longitude, rtt);
	    }
	}
    }
    nw_close(tmp_ping_sock);

    // compute own coordinate
    compute_coordinates(num_landmarks, coord_rtt);
}

/* Update the coordinates of a node using ping information */
void update_coordinate(I3ServerList *list, I3ServerListNode *next_to_ping)
{
    Coordinates_RTT coord_rtt[NUM_LANDMARKS_COORDINATE];
    int count, num_landmarks = 0;
    I3ServerListNode *node;

    // n1 and n2: number of landmarks from ping_list and rest in
    // proportion to the number of nodes in those lists
    int i, n = MIN(NUM_LANDMARKS_COORDINATE, 
	    list->num_newservers + list->num_ping_list);
    int n1 = ((float)list->num_ping_list/
	    (list->num_newservers + list->num_ping_list)) * n;
    int n2 = n-n1;

    // add from ping list
    count = 0;
    for (i = 0, node = list->list; 
	    i < list->num_ping_list, count < n1;
	    node = node->next_list, ++i) {
	if (node->n > 0) {
	    coord_rtt[count].rtt = get_rtt_node(node);
	    coord_rtt[count].coord = node->coord;
	    count++;
	}
    }
    num_landmarks = count;

    // add from rest
    count = 0;
    for (i = 0, node = list->full_list; 
	    i < list->num_newservers, count < n2; 
	    node = node->next_list, ++i) {
	if (node->n > 0) {
	    coord_rtt[num_landmarks + count].rtt = get_rtt_node(node);
	    coord_rtt[num_landmarks + count].coord = node->coord;
	    count++;
	}
    }
    num_landmarks += count;

    // recompute coordinates
    compute_coordinates(num_landmarks, coord_rtt);

    // repopulate ping list afresh
    change_ping_list(list, &next_to_ping, 1);
}