/** Initialize the firewall rules */ int fw_init(void) { int result = 0; int new_fw_state; t_client *client = NULL; if (!init_icmp_socket()) { return 0; } debug(LOG_INFO, "Initializing Firewall"); result = iptables_fw_init(); if (restart_orig_pid) { debug(LOG_INFO, "Restoring firewall rules for clients inherited from parent"); LOCK_CLIENT_LIST(); client = client_get_first_client(); while (client) { new_fw_state = client->fw_connection_state; client->fw_connection_state = FW_MARK_NONE; fw_allow(client, new_fw_state); client = client->next; } UNLOCK_CLIENT_LIST(); } return result; }
int main(int argc, char **argv) { int opt, sockfd; int background_flag = 1; int if_index = 0; fd_set rfds; struct timeval timeout; while ((opt = getopt(argc, argv, "fi:")) != -1) { switch (opt) { case 'f': /* foreground */ background_flag = 0; break; case 'i': if_index = if_nametoindex(optarg); break; default: usage(); exit(EXIT_FAILURE); } } openlog("routeradv_listend", LOG_CONS|LOG_PERROR, LOG_DAEMON); sockfd = init_icmp_socket(if_index); if (sockfd < 0) return 1; if (background_flag) daemonize(sockfd); init_routers(); for (;;) { FD_ZERO(&rfds); FD_SET(sockfd, &rfds); memset(&timeout, 0, sizeof(timeout)); timeout.tv_sec = next_timeout(); if (select(sockfd + 1, &rfds, NULL, NULL, &timeout) < 0) { /* select() might have failed because we received a signal, so we need to check */ if (errno != EINTR) { syslog(LOG_CRIT, "select: %s", strerror(errno)); return 1; } /* handle signals */ continue; /* our file descriptor sets are undefined, so select again */ } if (FD_ISSET (sockfd, &rfds)) recv_icmp_msg(sockfd); handle_routers(); } return 0; }
int binary_search(SOCKADDR_IN *dst, int timeout, RouteInfo *rinfo) { int ttl=0, high=32, low=1, iterations=MAX_ITERATIONS, retries = 0; ULONG start_test_timestamp = GetTickCount(); SOCKET sr; sr = init_icmp_socket(); rinfo->cnt_packet_waste=0; strcpy(rinfo->path, UNDEFINED_PATH); rinfo->resp_ttl=UNDEFINED_TTL; rinfo->hopdist = UNDEFINED_TTL; // counting iterations is just to make sure // no one is fooling us into an infinite loop while (iterations--) { if (!ttl) ttl = STARTING_TTL; // this is the first time ttl is set. // since most sites are closer than 32, we start with it. else ttl = (high+low)/2; switch (udping(sr, dst, 0, timeout, &rinfo->rtt, &rinfo->cnt_packet_waste, (unsigned short)ttl)) { case -1: // too short low = ttl+1; break; case 1: // exact or too long if (high == ttl || (ttl+low)/2 == ttl) // exact! { rinfo->time_waste_on_test = GetTickCount()-start_test_timestamp; rinfo->hopdist = ttl; closesocket(sr); return 1; } high = ttl; // too long... break; case 0: // timeout if (ttl < high && retries != NUMBER_OF_RETRIES) // if possible, let's give it another chance. { high--; retries++; break; } rinfo->time_waste_on_test = GetTickCount()-start_test_timestamp; closesocket(sr); return 0; } } rinfo->time_waste_on_test = GetTickCount()-start_test_timestamp; closesocket(sr); return 0; }
int copied_ttl(SOCKADDR_IN *dst, unsigned int timeout, RouteInfo *rinfo) { SOCKET sr; SOCKADDR_IN from; int icmp_type, delta, is_packet_recieved, copiedttl; unsigned short seq_sent, seq_resp; ULONG start_test_timestamp = GetTickCount(); sr = init_icmp_socket(); strcpy(rinfo->path, UNDEFINED_PATH); rinfo->resp_ttl = UNDEFINED_TTL; rinfo->cnt_packet_waste = 0; seq_sent = INITIAL_SEQ; while(GetTickCount()-start_test_timestamp < timeout*1000) { ULONG start_packet_timestamp = GetTickCount(); send_udp_packet(dst, MAX_TTL, seq_sent); rinfo->cnt_packet_waste++; is_packet_recieved = wait_for_icmp(sr, &seq_resp, &icmp_type, &from, &copiedttl, timeout); delta = GetTickCount()-start_packet_timestamp; if (!is_packet_recieved) //we got no reply { // fprintf(stderr, "%3d Request timed out\t", MAX_TTL); break; } if(seq_sent == seq_resp) //check if this is our ICMP packet { if (icmp_type == ICMP_DEST_UNREACH) { rinfo->time_waste_on_test = GetTickCount() - start_test_timestamp; rinfo->rtt = delta; rinfo->hopdist = MAX_TTL+1-copiedttl; closesocket(sr); return 1; } } //it was not a response to our packet. send it again } closesocket(sr); return 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; }
/* 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); }