Ejemplo n.º 1
0
/* Handle incoming packets and pass them to the DHT code */
void dht_handler( int rc, int sock ) {
	UCHAR buf[1500];
    IP from;
    socklen_t fromlen;
	time_t time_wait = 0;

	if( rc > 0 ) {
		/* Check which socket received the data */
		fromlen = sizeof(from);
		rc = recvfrom( sock, buf, sizeof(buf) - 1, 0, (struct sockaddr*) &from, &fromlen );

		if( rc <= 0 || rc >= sizeof(buf) ) {
			return;
		}

		/* The DHT code expects the message to be null-terminated. */
		buf[rc] = '\0';

		/* Handle incoming data */
		dht_lock();
		rc = dht_periodic( buf, rc, (struct sockaddr*) &from, fromlen, &time_wait, dht_callback_func, NULL );
		dht_unlock();

		if( rc < 0 && errno != EINTR ) {
			if( rc == EINVAL || rc == EFAULT ) {
				log_err( "DHT: Error calling dht_periodic." );
			}
			g_dht_maintenance = time_now_sec() + 1;
		} else {
			g_dht_maintenance = time_now_sec() + time_wait;
		}
	} else if( g_dht_maintenance <= time_now_sec() ) {
		/* Do a maintenance call */
		dht_lock();
		rc = dht_periodic( NULL, 0, NULL, 0, &time_wait, dht_callback_func, NULL );
		dht_unlock();

		/* Wait for the next maintenance call */
		g_dht_maintenance = time_now_sec() + time_wait;
		log_debug( "DHT: Next maintenance call in %u seconds.", (unsigned int) time_wait );
	} else {
		rc = 0;
	}

	if( rc < 0 ) {
		if( errno == EINTR ) {
			return;
		} else if( rc == EINVAL || rc == EFAULT ) {
			log_err( "DHT: Error using select: %s", strerror( errno ) );
			return;
		} else {
			g_dht_maintenance = time_now_sec() + 1;
		}
	}
}
Ejemplo n.º 2
0
/* handle 'GET /announce?foo.p2p' */
void handle_announce( char *reply_buf, char *params ) {

	if( kad_announce( params, 0, (time_now_sec() + 60) ) >= 0 ) {
		sprintf( reply_buf , "done\n" );
	} else {
		sprintf( reply_buf , "failed\n" );
	}
}
Ejemplo n.º 3
0
/*
* Lookup known nodes that are nearest to the given id.
*/
int kad_lookup_value( const char _query[], IP addr_array[], size_t *addr_num ) {
	char query[QUERY_MAX_SIZE];
	struct results_t *results;
	int is_new;
	int rc;

	if( query_sanitize( query, sizeof(query), _query ) != 0 ) {
		return -2;
	}

	log_debug( "KAD: Lookup string: %s", query );

	dht_lock();

	/* Find existing or create new item */
	results = results_add( query, &is_new );

	if( results && is_new ) {
		/* Search own announced values */
		kad_lookup_local_values( results );
	}

	if( results == NULL ) {
		/* Failed to create a new search */
		rc = -1;
	} else if( results->done ) {
		/*
		* The search exists already but has finished. Restart the search when
		* no results have been found or more than half of the searches lifetime
		* has expired.
		*/
		if( results_entries_count( results ) == 0 ||
			(time_now_sec() - results->start_time) > (MAX_SEARCH_LIFETIME / 2)
		) {
			/* Mark search as in progress */
			results_done( results, 0 );

			/* Start another search for this id */
			dht_search( results->id, 0, gconf->af, dht_callback_func, NULL );
		}
		rc = 2;
	} else if( is_new ) {
		/* Start a new DHT search */
		dht_search( results->id, 0, gconf->af, dht_callback_func, NULL );
		rc = 1;
	} else {
		/* Search is still running */
		rc = 0;
	}

	/* Collect addresses to be returned */
	*addr_num = results_collect( results, addr_array, *addr_num );

	dht_unlock();

	return rc;
}
Ejemplo n.º 4
0
int cmd_exec( REPLY *r, int argc, char **argv ) {
	char addrbuf[FULL_ADDSTRLEN+1];
	time_t lifetime;
	int minutes;
	IP addrs[16];
	int port;
	int count;
	static struct value_t *value;
	char *p;
	int rc = 0;

	if( argc == 0 ) {

		/* Print usage */
		r_printf( r, cmd_usage );
		if( r->allow_debug ) {
			r_printf( r, cmd_usage_debug );
		}
		rc = 1;

	} else if( match( argv[0], "import" ) && argc == 2 ) {

		rc = cmd_import( r, argv[1] );
#if 0
	} else if( match( argv[0], "lookup_node" ) && argc == 2 ) {

		/* Check searches for node */
		rc = kad_lookup_node( argv[1], &addrs[0] );
		if( rc == 0 ) {
			r_printf( r, "%s\n", str_addr( &addrs[0], addrbuf ) );
		} else if( rc == 1 ) {
			r_printf( r ,"No search found.\n" );
			rc = 1;
		} else if( rc == 2 ) {
			r_printf( r ,"Invalid id format. 20 digit hex string expected.\n" );
			rc = 1;
		} else {
			rc = 1;
		}
#endif
	} else if( match( argv[0], "lookup" ) && argc == 2 ) {

		size_t num = N_ELEMS(addrs);
		size_t i;

		/* Check searches for node */
		rc = kad_lookup_value( argv[1], addrs, &num );

		if( rc >= 0 && num > 0 ) {
			for( i = 0; i < num; ++i ) {
				r_printf( r, "%s\n", str_addr( &addrs[i], addrbuf ) );
			}
		} else if( rc < 0 ) {
			r_printf( r ,"Some error occured.\n" );
			rc = 1;
		} else if( rc == 0 ) {
			r_printf( r ,"Search in progress.\n" );
			rc = 1;
		} else {
			r_printf( r ,"Search started.\n" );
			rc = 1;
		}
	} else if( match( argv[0], "status" ) && argc == 1 ) {

		/* Print node id and statistics */
		cmd_print_status( r );

	} else if( match( argv[0], "announce" ) && (argc == 1 || argc == 2 || argc == 3) ) {

		if( argc == 1 ) {
			/* Announce all values; does not update value.refreshed */
			count = 0;
			value = values_get();
			while( value ) {
				kad_announce_once( value->id, value->port );
				count++;
				value = value->next;
			}
			r_printf( r ,"%d announcements started.\n", count );
			rc = 0;
			goto end;
		} else if( argc == 2 ) {
			minutes = 0;
			lifetime = 0;
		} else if( argc == 3 ) {
			minutes = atoi( argv[2] );
			if( minutes < 0 ) {
				minutes = 0;
				lifetime = LONG_MAX;
			} else {
				/* Round up to multiple of 30 minutes */
				minutes = (30 * (minutes/30 + 1));
				lifetime = (time_now_sec() + (minutes * 60));
			}
		} else {
			/* Make compilers happy */
			exit( 1 );
		}

		int is_random_port = 0;

		/* Find <id>:<port> delimiter */
		p = strchr( argv[1], ':' );

		if( p ) {
			*p = '\0';
			port = port_parse( p + 1, -1 );
		} else {
			/* A valid port will be choosen inside kad_announce() */
			port = 0;
			is_random_port = 1;
		}

		if( kad_announce( argv[1], port, lifetime ) >= 0 ) {
#ifdef FWD
			if( !is_random_port ) {
				forwardings_add( port, lifetime);
			}
#endif
			if( lifetime == 0 ) {
				r_printf( r ,"Start single announcement now.\n" );
			} else if( lifetime == LONG_MAX ) {
				r_printf( r ,"Start regular announcements for the entire run time (%sport %d).\n", (is_random_port ? "random " : ""), port );
			} else {
				r_printf( r ,"Start regular announcements for %d minutes (%sport %d).\n", minutes, (is_random_port ? "random " : ""), port );
			}
		} else {
			r_printf( r ,"Invalid port or query too long.\n" );
			rc = 1;
		}

	} else if( match( argv[0], "blacklist" ) && argc == 2 ) {

		rc = cmd_blacklist( r, argv[1] );

	} else if( match( argv[0], "export" ) && argc == 1 ) {

		rc = cmd_export( r );

	} else if( match( argv[0], "list" ) && argc == 2 && r->allow_debug ) {

		if( gconf->is_daemon == 1 ) {
			r_printf( r ,"The 'list' command is not available while KadNode runs as daemon.\n" );
			rc = 1;
			goto end;
		} else if( match( argv[1], "blacklist" ) ) {
			kad_debug_blacklist( STDOUT_FILENO );
			rc = 0;
		} else if( match( argv[1], "buckets" ) ) {
			kad_debug_buckets( STDOUT_FILENO );
			rc = 0;
		} else if( match( argv[1], "constants" ) ) {
			kad_debug_constants( STDOUT_FILENO );
			rc = 0;
#ifdef FWD
		} else if( match( argv[1], "forwardings" ) ) {
			forwardings_debug( STDOUT_FILENO );
			rc = 0;
#endif
#ifdef AUTH
		} else if( match( argv[1], "pkeys" ) ) {
			auth_debug_pkeys( STDOUT_FILENO );
			rc = 0;
		} else if( match( argv[1], "skeys" ) ) {
			auth_debug_skeys( STDOUT_FILENO );
			rc = 0;
#endif
		} else if( match( argv[1], "results" ) ) {
			results_debug( STDOUT_FILENO );
			rc = 0;
		} else if( match( argv[1], "searches" ) ) {
			kad_debug_searches( STDOUT_FILENO );
			rc = 0;
		} else if( match( argv[1], "storage" ) ) {
			kad_debug_storage( STDOUT_FILENO );
			rc = 0;
		} else if( match( argv[1], "values" ) ) {
			values_debug( STDOUT_FILENO );
			rc = 0;
		} else {
			dprintf( STDERR_FILENO, "Unknown argument.\n" );
			rc = 1;
		}
		r_printf( r ,"\nOutput send to console.\n" );

	} else {
		/* print usage */
		r_printf( r, cmd_usage );
		if( r->allow_debug ) {
			r_printf( r, cmd_usage_debug );
		}
		rc = 1;
	}

end:
	;
	return rc;
}
Ejemplo n.º 5
0
void handle_mcast( int rc, int sock_recv ) {
	char addrbuf[FULL_ADDSTRLEN+1];
	char buf[512];
	IP c_addr;
	socklen_t addrlen;
	int rc_recv;

	if( g_mcast_time <= time_now_sec() ) {
		if( kad_count_nodes( 0 ) == 0 ) {
			/* Join multicast group if possible */
			if( g_mcast_registered == 0 && multicast_set_groups( sock_recv, &g_lpd_addr, gconf->dht_ifname, 1 ) == 0 ) {
				log_info( "LPD: No peers known. Joined multicast group." );
				g_mcast_registered = 1;
			}

			if( g_mcast_registered == 1 ) {
				log_info( "LPD: Send multicast message to find nodes." );

				/* Create message */
				snprintf(
					buf, sizeof(buf),
					msg_fmt, str_addr( &g_lpd_addr, addrbuf ),
					atoi( gconf->dht_port ), g_infohash
				);

				mcast_send_packets( buf, gconf->dht_ifname );
			}
		}

		/* Cap number of received packets to 10 per minute */
		g_packet_limit = 5 * PACKET_LIMIT_MAX;

		/* Try again in ~5 minutes */
		g_mcast_time = time_add_min( 5 );
	}

	if( rc <= 0 ) {
		return;
	}

	/* Reveice multicast ping */
	addrlen = sizeof(IP);
	rc_recv = recvfrom( sock_recv, buf, sizeof(buf), 0, (struct sockaddr*) &c_addr, (socklen_t*) &addrlen );
	if( rc_recv < 0 ) {
		log_warn( "LPD: Cannot receive multicast message: %s", strerror( errno ) );
		return;
	}

	if( g_packet_limit < 0 ) {
		/* Too much traffic - leave multicast group for now */
		if( g_mcast_registered == 1 && multicast_set_groups( sock_recv, &g_lpd_addr, gconf->dht_ifname, 0 ) == 0 ) {
			log_warn( "LPD: Too much traffic. Left multicast group." );
			g_mcast_registered = 0;
		}
		return;
	} else {
		g_packet_limit--;
	}

	if( rc_recv >= sizeof(buf) ) {
		return;
	} else {
		buf[rc_recv] = '\0';
	}

	int port = parse_packet( buf );
	if( port > 0 ) {
		port_set( &c_addr, port );
		log_debug( "LPD: Ping lonely peer at %s", str_addr( &c_addr, addrbuf ) );
		kad_ping( &c_addr );
	} else {
		log_debug( "LPD: Received invalid packet on multicast group." );
	}
}
Ejemplo n.º 6
0
time_t time_add_hour( unsigned int hours ) {
	return time_now_sec() + (60 * 60 * hours);
}
Ejemplo n.º 7
0
time_t time_add_min( unsigned int minutes ) {
	return time_now_sec() + (60 * minutes);
}