Esempio n. 1
0
static void wd_transfer_listen_thread(wi_runtime_instance_t *argument) {
	wi_pool_t			*pool;
	wi_socket_t			*socket;
	wi_address_t		*address;
	
	pool = wi_pool_init(wi_pool_alloc());

	while(wd_running) {
		wi_pool_drain(pool);

		socket = wi_socket_accept_multiple(wd_transfer_sockets, 30.0, &address);
		
		if(!address) {
			wi_log_err(WI_STR("Could not accept a connection: %m"));
			
			continue;
		}
		
		if(!socket) {
			wi_log_err(WI_STR("Could not accept a connection for %@: %m"),
				wi_address_string(address));
			
			continue;
		}

		if(!wi_thread_create_thread(wd_transfer_accept_thread, socket)) {
			wi_log_err(WI_STR("Could not create a transfer thread for %@: %m"),
				wi_address_string(address));
			
			continue;
		}
	}
	
	wi_release(pool);
}
Esempio n. 2
0
static void wd_control_accept_thread(wi_runtime_instance_t *argument) {
	wi_pool_t			*pool;
	wi_socket_t			*socket = argument;
	wi_string_t			*ip;
	wd_user_t			*user;
	
	pool = wi_pool_init(wi_pool_alloc());
	
	ip = wi_address_string(wi_socket_address(socket));
	
	if(!wi_socket_accept_tls(socket, wd_control_socket_tls, 30.0)) {
		wi_log_err(WI_STR("Could not accept a TLS connection for %@: %m"), ip);
		
		goto end;
	}
	
	if(!wi_socket_set_timeout(socket, 30.0))
		wi_log_warn(WI_STR("Could not set timeout for %@: %m"), ip);
	
	wi_socket_set_direction(socket, WI_SOCKET_READ);

	wi_log_info(WI_STR("Connect from %@"), ip);
	
	user = wd_user_with_socket(socket);

	wd_users_add_user(user);
	wd_users_set_user_for_thread(user);
	
	wd_command_loop_for_user(user);

end:
	wi_socket_close(socket);
	
	wi_release(pool);
}
Esempio n. 3
0
static wi_string_t * _wi_address_description(wi_runtime_instance_t *instance) {
	wi_address_t			*address = instance;
	wi_string_t				*family;
	
	switch(wi_address_family(address)) {
		case WI_ADDRESS_IPV4:
			family = WI_STR("ipv4");
			break;

		case WI_ADDRESS_IPV6:
			family = WI_STR("ipv6");
			break;

		case WI_ADDRESS_NULL:
		default:
			family = WI_STR("none");
			break;
	}
	
	return wi_string_with_format(WI_STR("<%@ %p>{family = %@, address = %@, port = %lu}"),
	   wi_runtime_class_name(address),
	   address,
	   family,
	   wi_address_string(address),
	   wi_address_port(address));
}
Esempio n. 4
0
static void wd_transfer_accept_thread(wi_runtime_instance_t *argument) {
	wi_pool_t			*pool;
	wi_socket_t			*socket = argument;
	wi_array_t			*arguments;
	wi_string_t			*ip, *string, *command;
	wd_transfer_t		*transfer;
	
	pool = wi_pool_init(wi_pool_alloc());
	
	ip = wi_address_string(wi_socket_address(socket));
	
	if(!wi_socket_accept_tls(socket, wd_transfer_socket_tls, 30.0)) {
		wi_log_err(WI_STR("Could not accept a connection for %@: %m"), ip);
		
		goto end;
	}
	
	if(!wi_socket_set_timeout(socket, 30.0))
		wi_log_warn(WI_STR("Could not set timeout for %@: %m"), ip);
	
	string = wi_socket_read_to_string(socket, 5.0, WI_STR(WD_MESSAGE_SEPARATOR_STR));
	
	if(!string || wi_string_length(string) == 0) {
		if(!string)
			wi_log_warn(WI_STR("Could not read from %@: %m"), ip);
		
		goto end;
	}
	
	wi_parse_wired_command(string, &command, &arguments);
	
	if(wi_is_equal(command, WI_STR("TRANSFER")) && wi_array_count(arguments) >= 1) {
		transfer = wd_transfers_transfer_with_hash(WI_ARRAY(arguments, 0));
		
		if(!transfer)
			goto end;
		
		if(!wi_is_equal(ip, wd_user_ip(transfer->user)))
			goto end;
		
		wi_lock_lock(transfer->socket_lock);
		
		if(!transfer->socket) {
			transfer->socket = wi_retain(socket);
			wi_lock_unlock(transfer->socket_lock);
		
			wd_transfer_loop(transfer);
		} else {
			wi_lock_unlock(transfer->socket_lock);
		}
	}

end:
	wi_socket_close(socket);

	wi_release(pool);
}
Esempio n. 5
0
static void wr_command_save(wi_array_t *arguments) {
	wi_file_t		*file;
	wi_string_t		*path, *login, *password, *port;
	
	path = wi_user_home();
	path = wi_string_by_appending_path_component(path, WI_STR(WB_WIREBOT_USER_PATH));
	path = wi_string_by_appending_path_component(path, WI_ARRAY(arguments, 0));
	
	file = wi_file_for_writing(path);
	
	if(!file) {
		wr_printf_prefix(WI_STR("save: %@: %m"), path);
		
		return;
	}
	
	wi_file_write_format(file, WI_STR("charset %@\n"), wi_string_encoding_charset(wr_client_string_encoding));
	wi_file_write_format(file, WI_STR("timestamp %@\n"), wr_timestamp_format);
	wi_file_write_format(file, WI_STR("nick %@\n"), wr_nick);
	
	if(wi_string_length(wr_status) > 0)
		wi_file_write_format(file, WI_STR("status %@\n"), wr_status);
	
	if(wr_icon_path)
		wi_file_write_format(file, WI_STR("icon %@\n"), wr_icon_path);
	
	if(wr_connected) {
		if(wi_string_length(wi_p7_socket_user_name(wr_p7_socket)) > 0)
			login = wi_string_with_format(WI_STR("-l %@"), wi_p7_socket_user_name(wr_p7_socket));
		else
			login = NULL;
		
		if(wi_string_length(wr_password) > 0)
			password = wi_string_with_format(WI_STR("-p %@"), wr_password);
		else
			password = NULL;
		
		if(wi_address_port(wi_socket_address(wr_socket)) != WR_PORT)
			port = wi_string_with_format(WI_STR("-P %u"), wi_address_port(wi_socket_address(wr_socket)));
		else
			port = NULL;
		
		wi_file_write_format(file, WI_STR("open %#@ %#@ %#@ %@\n"),
			login, password, port, wi_address_string(wi_socket_address(wr_socket)));
	}
	
	wr_printf_prefix(WI_STR("save: \"%@\" saved"), path);
}
Esempio n. 6
0
static void wr_msg_400(wi_array_t *arguments) {
	wi_address_t		*address;
	wr_transfer_t		*transfer;

	transfer = wr_transfers_transfer_with_path(WI_ARRAY(arguments, 0));

	if(!transfer)
		return;
	
	address = wi_copy(wr_address);
	wi_address_set_port(address, wi_address_port(address) + 1);
	
	transfer->state			= WR_TRANSFER_RUNNING;
	transfer->offset		= wi_string_uint64(WI_ARRAY(arguments, 1));
	transfer->transferred	= transfer->offset;
	transfer->key			= wi_retain(WI_ARRAY(arguments, 2));
	transfer->start_time	= wi_time_interval();
	transfer->socket		= wi_socket_init_with_address(wi_socket_alloc(), address, WI_SOCKET_TCP);

	wi_socket_set_interactive(transfer->socket, false);
	
	if(!wi_socket_connect(transfer->socket, wr_socket_context, 15.0)) {
		wr_printf_prefix(WI_STR("Could not connect to %@: %m"), wi_address_string(address));
		
		wr_transfer_stop(transfer);

		goto end;
	}
	
	wi_file_seek(transfer->file, transfer->offset);

	if(transfer->type == WR_TRANSFER_DOWNLOAD) {
		wi_socket_set_direction(transfer->socket, WI_SOCKET_READ);
		wr_runloop_add_socket(transfer->socket, wr_runloop_download_callback);
	} else {
		wi_socket_set_direction(transfer->socket, WI_SOCKET_WRITE);
		wr_runloop_add_socket(transfer->socket, wr_runloop_upload_callback);
	}

	wr_send_command_on_socket(transfer->socket, WI_STR("TRANSFER %#@"), transfer->key);

	wr_printf_prefix(WI_STR("Starting transfer of \"%@\""), transfer->name);
	
	wr_draw_transfers(true);

end:
	wi_release(address);
}
Esempio n. 7
0
static void wd_control_listen_thread(wi_runtime_instance_t *argument) {
	wi_pool_t			*pool;
	wi_socket_t			*socket;
	wi_address_t		*address;
	wi_string_t			*ip;
	wd_user_t			*user;
	
	pool = wi_pool_init(wi_pool_alloc());

	while(wd_running) {
		wi_pool_drain(pool);

		/* accept new user */
		socket = wi_socket_accept_multiple(wd_control_sockets, wd_control_socket_context, 30.0, &address);

		if(!address) {
			wi_log_err(WI_STR("Could not accept a connection: %m"));
			
			continue;
		}
		
		ip = wi_address_string(address);
		
		if(!socket) {
			wi_log_err(WI_STR("Could not accept a connection for %@: %m"), ip);
			
			continue;
		}
		
		wi_socket_set_direction(socket, WI_SOCKET_READ);
		
		wi_log_info(WI_STR("Connect from %@"), ip);
		
		/* spawn a user thread */
		user = wd_user_with_socket(socket);

		if(!wi_thread_create_thread(wd_control_thread, user))
			wi_log_err(WI_STR("Could not create a thread for %@: %m"), ip);
	}
	
	wi_release(pool);
}
Esempio n. 8
0
void wr_client_disconnect(void) {
    if(wr_connected) {
        wi_log_info(WI_STR("Connection to %@ closed"),
                    wi_address_string(wi_socket_address(wr_socket)));

        wr_connected = false;
    }

    wr_runloop_remove_socket(wr_socket);
    wi_socket_close(wr_socket);
    wi_release(wr_p7_socket);
    wi_release(wr_socket);

    wi_release(wr_server);

    wi_release(wr_password);

    wr_chats_clear();
    wr_users_clear();
}
Esempio n. 9
0
static wd_user_t * wd_user_init_with_socket(wd_user_t *user, wi_socket_t *socket) {
	wi_address_t	*address;

	user->uid				= wd_user_next_uid();
	user->socket			= wi_retain(socket);
	user->state				= WD_USER_CONNECTED;
	user->login_time		= wi_time_interval();
	user->idle_time			= user->login_time;
	
	address					= wi_socket_address(socket);
	user->ip				= wi_retain(wi_address_string(address));
	user->host				= wi_retain(wi_address_hostname(address));
	
	user->user_lock			= wi_recursive_lock_init(wi_recursive_lock_alloc());
	user->socket_lock		= wi_lock_init(wi_lock_alloc());
	
	user->transfers_queue	= wi_array_init(wi_array_alloc());

	return user;
}
Esempio n. 10
0
static wd_user_t * wd_user_init_with_socket(wd_user_t *user, wi_socket_t *socket) {
	wi_address_t	*address;

	user->id						= wd_user_next_id();
	user->socket					= wi_retain(socket);
	user->state						= WD_USER_CONNECTED;
	user->login_time				= wi_date_init(wi_date_alloc());
	user->idle_time					= wi_date_init(wi_date_alloc());
	
	address							= wi_socket_address(socket);
	user->ip						= wi_retain(wi_address_string(address));
	user->host						= wi_retain(wi_address_hostname(address));
	
	user->user_lock					= wi_recursive_lock_init(wi_recursive_lock_alloc());
	user->socket_lock				= wi_recursive_lock_init(wi_recursive_lock_alloc());
	
	user->subscribed_paths			= wi_set_init_with_capacity(wi_mutable_set_alloc(), 0, true);
	user->subscribed_virtualpaths	= wi_dictionary_init(wi_mutable_dictionary_alloc());
	
	return user;
}
Esempio n. 11
0
void wr_client_disconnect(void) {
	if(wr_connected) {
		wr_wprintf_prefix(wr_console_window, WI_STR("Connection to %@ closed"),
			wi_address_string(wi_socket_address(wr_socket)));

		wr_connected = false;
	}
	
	wr_runloop_remove_socket(wr_socket);
	wi_socket_close(wr_socket);
	wi_release(wr_p7_socket);
	wi_release(wr_socket);

	wi_release(wr_server);
	
	wi_release(wr_password);

	wr_windows_clear();
	wr_chats_clear();
	wr_users_clear();

	wr_draw_header();
	wr_draw_divider();
}
Esempio n. 12
0
void wr_connect(wi_string_t *hostname, unsigned int port, wi_string_t *login, wi_string_t *password) {
	wi_list_t			*addresses;
	wi_list_node_t		*node;
	wi_address_t		*address;
	wi_socket_t			*socket;
	wi_string_t			*ip;
	
	if(wr_connected)
		wr_disconnect();
	
	wr_printf_prefix(WI_STR("Connecting to %@..."), hostname);
	
	if(port == 0)
		port = WR_CONTROL_PORT;
	
	addresses = wi_host_addresses(wi_host_with_string(hostname));
	
	if(!addresses) {
		wr_printf_prefix(WI_STR("Could not resolve \"%@\": %m"),
			hostname);
		
		return;
	}
	
	WI_LIST_FOREACH(addresses, node, address) {
		ip = wi_address_string(address);

		wr_printf_prefix(WI_STR("Trying %@..."), ip);
		
		wi_address_set_port(address, port);
		
		socket = wi_socket_init_with_address(wi_socket_alloc(), address, WI_SOCKET_TCP);
		wi_socket_set_interactive(socket, true);

		if(!wi_socket_connect(socket, wr_socket_context, 10.0)) {
			wr_printf_prefix(WI_STR("Could not connect to %@: %m"), ip);

			goto next;
		}

		wr_printf_prefix(WI_STR("Connected using %@/%@/%u bits, logging in..."),
			wi_socket_cipher_version(socket),
			wi_socket_cipher_name(socket),
			wi_socket_cipher_bits(socket));

		wr_connected	= true;
		wr_host			= wi_retain(hostname);
		wr_port			= port;
		wr_login		= wi_retain(login);
		wr_password		= wi_retain(password);
		wr_socket		= wi_retain(socket);
		wr_address		= wi_retain(address);
		
		wr_runloop_add_socket(wr_socket, &wr_runloop_server_callback);
		wr_send_command(WI_STR("HELLO"));

next:
		wi_release(socket);
		
		if(wr_connected)
			break;
	}
Esempio n. 13
0
void wd_server_init(void) {
	wi_enumerator_t			*enumerator;
	wi_array_t				*array, *addresses;
	wi_address_t			*address;
	wi_socket_t				*control_socket, *transfer_socket;
	wi_string_t				*ip, *string;
	wi_address_family_t		family;
	
	wd_control_sockets	= wi_array_init(wi_mutable_array_alloc());
	wd_transfer_sockets	= wi_array_init(wi_mutable_array_alloc());
	addresses			= wi_array_init(wi_mutable_array_alloc());

	if(wi_array_count(wd_settings.address) > 0) {
		/* listen on configured addresses */
		wi_array_rdlock(wd_settings.address);
		
		enumerator = wi_array_data_enumerator(wd_settings.address);
		
		while((string = wi_enumerator_next_data(enumerator))) {
			array = wi_host_addresses(wi_host_with_string(string));

			if(array)
				wi_mutable_array_add_data_from_array(addresses, array);
			else
				wi_log_err(WI_STR("Could not resolve \"%@\": %m"), string);
		}
		
		wi_array_unlock(wd_settings.address);
	} else {
		/* add wildcard addresses */
		wi_mutable_array_add_data(addresses, wi_address_wildcard_for_family(WI_ADDRESS_IPV6));
		wi_mutable_array_add_data(addresses, wi_address_wildcard_for_family(WI_ADDRESS_IPV4));
	}
	
	enumerator = wi_array_data_enumerator(addresses);
	
	while((address = wi_enumerator_next_data(enumerator))) {
		ip		= wi_address_string(address);
		family	= wi_address_family(address);

		/* force address family? */
		if(wd_address_family != WI_ADDRESS_NULL && family != wd_address_family)
			continue;
		
		/* create sockets */
		wi_address_set_port(address, wd_settings.port);
		control_socket = wi_autorelease(wi_socket_init_with_address(wi_socket_alloc(), address, WI_SOCKET_TCP));

		wi_address_set_port(address, wd_settings.port + 1);
		transfer_socket = wi_autorelease(wi_socket_init_with_address(wi_socket_alloc(), address, WI_SOCKET_TCP));
	
		if(!control_socket || !transfer_socket) {
			wi_log_warn(WI_STR("Could not create socket for %@: %m"), ip);
			
			continue;
		}

		/* listen on sockets */
		if(!wi_socket_listen(control_socket)) {
			wi_log_warn(WI_STR("Could not listen on %@ port %u: %m"),
				ip, wi_address_port(wi_socket_address(control_socket)));
			
			continue;
		}

		if(!wi_socket_listen(transfer_socket)) {
			wi_log_warn(WI_STR("Could not listen on %@ port %u: %m"),
				ip, wi_address_port(wi_socket_address(transfer_socket)));
			
			continue;
		}
		
		wi_socket_set_interactive(control_socket, true);
		wi_socket_set_interactive(transfer_socket, false);

		/* add to list of sockets */
		wi_mutable_array_add_data(wd_control_sockets, control_socket);
		wi_mutable_array_add_data(wd_transfer_sockets, transfer_socket);

		wi_log_info(WI_STR("Listening on %@ ports %d-%d"),
			ip, wd_settings.port, wd_settings.port + 1);
	}

	if(wi_array_count(wd_control_sockets) == 0 || wi_array_count(wd_transfer_sockets) == 0)
		wi_log_fatal(WI_STR("No addresses available for listening"));
	
	wi_release(addresses);
	
#ifdef HAVE_DNS_SD_H
	if(wd_settings.zeroconf)
		wd_server_register_dnssd();
#endif
}
Esempio n. 14
0
static void wd_transfer_listen_thread(wi_runtime_instance_t *argument) {
	wi_pool_t			*pool;
	wi_socket_t			*socket;
	wi_address_t		*address;
	wi_array_t			*arguments;
	wi_string_t			*ip, *string, *command;
	wd_transfer_t		*transfer;
	
	pool = wi_pool_init(wi_pool_alloc());

	while(wd_running) {
		wi_pool_drain(pool);

		/* accept new connection */
		socket = wi_socket_accept_multiple(wd_transfer_sockets, wd_transfer_socket_context, 30.0, &address);
		
		if(!address) {
			wi_log_err(WI_STR("Could not accept a connection: %m"));
			
			continue;
		}
		
		ip = wi_address_string(address);
		
		if(!socket) {
			wi_log_err(WI_STR("Could not accept a connection for %@: %m"), ip);
			
			continue;
		}

		string = wi_socket_read_to_string(socket, 5.0, WI_STR(WD_MESSAGE_SEPARATOR_STR));
		
		if(!string || wi_string_length(string) == 0) {
			if(!string)
				wi_log_warn(WI_STR("Could not read from %@: %m"), ip);

			continue;
		}
		
		/* parse command */
		wi_parse_wired_command(string, &command, &arguments);
		
		if(wi_is_equal(command, WI_STR("TRANSFER")) && wi_array_count(arguments) >= 1) {
			/* get transfer by identifier */
			transfer = wd_transfers_transfer_with_hash(WI_ARRAY(arguments, 0));
			
			if(!transfer)
				continue;
			
			if(!wi_is_equal(ip, wd_user_ip(transfer->user)))
				continue;
			
			transfer->socket = wi_retain(socket);
			
			/* spawn a transfer thread */
			if(!wi_thread_create_thread(wd_transfer_thread, transfer))
				wi_log_err(WI_STR("Could not create a thread for %@: %m"), ip);
		}
	}
	
	wi_release(pool);
}
Esempio n. 15
0
static wi_boolean_t _wi_address_is_equal(wi_runtime_instance_t *instance1, wi_runtime_instance_t *instance2) {
	wi_address_t		*address1 = instance1;
	wi_address_t		*address2 = instance2;
	
	return wi_is_equal(wi_address_string(address1), wi_address_string(address2));
}
Esempio n. 16
0
static wi_hash_code_t _wi_address_hash(wi_runtime_instance_t *instance) {
	wi_address_t		*address = instance;
	
	return wi_hash(wi_address_string(address));
}
Esempio n. 17
0
void wr_client_connect(wi_string_t *hostname, wi_uinteger_t port, wi_string_t *login, wi_string_t *password) {
	wi_enumerator_t		*enumerator;
	wi_array_t			*addresses;
	wi_address_t		*address;
	wi_p7_socket_t		*p7_socket;
	wi_p7_message_t		*message;
	wi_socket_t			*socket;
	wi_string_t			*ip;
	wr_server_t			*server;
	
	if(wr_connected)
		wr_client_disconnect();
	
	wr_printf_prefix(WI_STR("Connecting to %@..."), hostname);
	
	if(port == 0)
		port = WR_PORT;
	
	if(!login)
		login = WI_STR("guest");
	
	if(!password)
		password = WI_STR("");
	
	addresses = wi_host_addresses(wi_host_with_string(hostname));
	
	if(!addresses) {
		wr_printf_prefix(WI_STR("Could not resolve \"%@\": %m"),
			hostname);
		
		return;
	}
	
	enumerator = wi_array_data_enumerator(addresses);
	
	while((address = wi_enumerator_next_data(enumerator))) {
		ip = wi_address_string(address);

		wr_printf_prefix(WI_STR("Trying %@ at port %u..."), ip, port);
		
		wi_address_set_port(address, port);
		
		socket = wi_autorelease(wi_socket_init_with_address(wi_socket_alloc(), address, WI_SOCKET_TCP));
		
		if(!socket) {
			wr_printf_prefix(WI_STR("Could not open a socket to %@: %m"), ip);
			
			continue;
		}
		
		wi_socket_set_interactive(socket, true);
		
		if(!wi_socket_connect(socket, 10.0)) {
			wr_printf_prefix(WI_STR("Could not connect to %@: %m"), ip);

			continue;
		}
		
		p7_socket = wi_autorelease(wi_p7_socket_init_with_socket(wi_p7_socket_alloc(), socket, wr_p7_spec));
		
		if(!wi_p7_socket_connect(p7_socket,
								 10.0,
								 WI_P7_COMPRESSION_DEFLATE | WI_P7_ENCRYPTION_RSA_AES256_SHA1 | WI_P7_CHECKSUM_SHA1,
								 WI_P7_BINARY,
								 login,
								 wi_string_sha1(password))) {
			wr_printf_prefix(WI_STR("Could not connect to %@: %m"), ip);
			
			continue;
		}
		
		wr_printf_prefix(WI_STR("Connected using %@/%u bits, logging in..."),
			wi_cipher_name(wi_p7_socket_cipher(p7_socket)),
			wi_cipher_bits(wi_p7_socket_cipher(p7_socket)));
		
		server = wr_client_login(p7_socket, login, password);
		
		if(!server)
			break;

		wr_printf_prefix(WI_STR("Logged in, welcome to %@"), wr_server_name(server));
		
		message = wi_p7_message_with_name(WI_STR("wired.chat.join_chat"), wr_p7_spec);
		wi_p7_message_set_uint32_for_name(message, wr_chat_id(wr_public_chat), WI_STR("wired.chat.id"));
		wr_client_write_message(p7_socket, message);
		
		wr_connected	= true;
		wr_socket		= wi_retain(socket);
		wr_p7_socket	= wi_retain(p7_socket);
		wr_server		= wi_retain(server);
		wr_password		= wi_retain(password);
		
		wi_socket_set_direction(wr_socket, WI_SOCKET_READ);
		wr_runloop_add_socket(wr_socket, &wr_runloop_server_callback);

		break;
	}
		
	wr_draw_divider();
}
Esempio n. 18
0
static void wd_tracker_register(wd_tracker_t *tracker) {
	wi_enumerator_t		*enumerator;
	wi_address_t		*address;
	wi_array_t			*arguments;
	wi_string_t			*ip, *string;
	uint32_t			message;
	wi_boolean_t		fatal = false;
	
	if(!wi_lock_trylock(tracker->register_lock))
		return;

	enumerator = wi_array_data_enumerator(tracker->addresses);
	
	while((address = wi_enumerator_next_data(enumerator))) {
		tracker->active		= false;
		tracker->address	= NULL;
		ip					= wi_address_string(address);
		
		wi_log_info(WI_STR("Trying %@ for tracker %@..."),
			ip, tracker->host);
		
		tracker->socket = wi_autorelease(wi_socket_init_with_address(wi_socket_alloc(), address, WI_SOCKET_TCP));

		if(!tracker->socket) {
			wi_log_err(WI_STR("Could not create socket for tracker %@: %m"),
				tracker->host);
			
			continue;
		}

		if(!wi_socket_connect(tracker->socket, 30.0)) {
			wi_log_err(WI_STR("Could not connect to tracker %@: %m"),
				tracker->host);
			
			continue;
		}
		
		if(!wi_socket_connect_tls(tracker->socket, tracker->tls, 30.0)) {
			wi_log_err(WI_STR("Could not connect to tracker %@: %m"),
				tracker->host);
			
			continue;
		}
		
		if(!wd_tracker_write(tracker, WI_STR("HELLO")))
			continue;
		
		if(!wd_tracker_read(tracker, &message, &arguments))
			continue;
		
		if(message != 200) {
			string = wi_array_components_joined_by_string(arguments, WI_STR(" "));
			wi_log_err(WI_STR("Could not register with tracker %@: Unexpected reply \"%u %@\""),
				tracker->host, message, string);
			
			fatal = true;
			continue;
		}
		
		if(!wd_tracker_write(tracker, WI_STR("CLIENT %#@"), wd_server_version_string))
			continue;
		
		if(!wd_tracker_write(tracker, WI_STR("REGISTER %#@%c%#@%c%#@%c%u%c%#@"),
							 tracker->category,			WD_FIELD_SEPARATOR,
							 wd_settings.url,			WD_FIELD_SEPARATOR,
							 wd_settings.name,			WD_FIELD_SEPARATOR,
							 wd_settings.bandwidth,		WD_FIELD_SEPARATOR,
							 wd_settings.description))
			continue;
		
		
		if(!wd_tracker_read(tracker, &message, &arguments))
			continue;
		
		if(message != 700 || wi_array_count(arguments) < 1) {
			string = wi_array_components_joined_by_string(arguments, WI_STR(" "));
			wi_log_err(WI_STR("Could not register with tracker %@: Unexpected reply \"%u %@\""),
				tracker->host, message, string);
			
			break;
		}
		
		wi_release(tracker->key);
		tracker->key = wi_retain(WI_ARRAY(arguments, 0));
		
		tracker->public_key = wi_retain(wi_socket_ssl_public_key(tracker->socket));

		if(!tracker->public_key) {
			wi_log_err(WI_STR("Could not get public key from the tracker %@: %m"),
				tracker->host);
			
			break;
		}
		
		wi_log_info(WI_STR("Registered with the tracker %@"),
			tracker->host);
		
		tracker->active		= true;
		tracker->address	= address;
		
		break;
	}
	
	wi_lock_unlock(tracker->register_lock);
}
Esempio n. 19
0
void wr_connect(wi_string_t *hostname, wi_uinteger_t port, wi_string_t *login, wi_string_t *password) {
	wi_enumerator_t		*enumerator;
	wi_array_t			*addresses;
	wi_address_t		*address;
	wi_socket_t			*socket;
	wi_string_t			*ip;
	
	if(wr_connected)
		wr_disconnect();
	
	wr_printf_prefix(WI_STR("Connecting to %@..."), hostname);
	
	if(port == 0)
		port = WR_CONTROL_PORT;
	
	addresses = wi_host_addresses(wi_host_with_string(hostname));
	
	if(!addresses) {
		wr_printf_prefix(WI_STR("Could not resolve \"%@\": %m"),
			hostname);
		
		return;
	}
	
	enumerator = wi_array_data_enumerator(addresses);
	
	while((address = wi_enumerator_next_data(enumerator))) {
		ip = wi_address_string(address);

		wr_printf_prefix(WI_STR("Trying %@ at port %u..."), ip, port);
		
		wi_address_set_port(address, port);
		
		socket = wi_autorelease(wi_socket_init_with_address(wi_socket_alloc(), address, WI_SOCKET_TCP));
		
		if(!socket) {
			wr_printf_prefix(WI_STR("Could not open a socket to %@: %m"), ip);
			
			continue;
		}
		
		wi_socket_set_interactive(socket, true);
		
		if(!wi_socket_connect(socket, 10.0)) {
			wr_printf_prefix(WI_STR("Could not connect to %@: %m"), ip);

			continue;
		}

		if(!wi_socket_connect_tls(socket, wr_socket_tls, 10.0)) {
			wr_printf_prefix(WI_STR("Could not connect to %@: %m"), ip);

			continue;
		}

		wr_printf_prefix(WI_STR("Connected using %@/%@/%u bits, logging in..."),
			wi_socket_cipher_version(socket),
			wi_socket_cipher_name(socket),
			wi_socket_cipher_bits(socket));

		wr_connected	= true;
		wr_host			= wi_retain(hostname);
		wr_port			= port;
		wr_login		= wi_retain(login);
		wr_password		= wi_retain(password);
		wr_socket		= wi_retain(socket);
		wr_address		= wi_retain(address);
		
		wr_runloop_add_socket(wr_socket, &wr_runloop_server_callback);
		wr_send_command(WI_STR("HELLO"));

		break;
	}

	if(wr_socket)
		wi_socket_set_direction(wr_socket, WI_SOCKET_READ);
}