Esempio n. 1
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. 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 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. 4
0
static void wd_transfer_upload(wd_transfer_t *transfer) {
	wi_pool_t				*pool;
	wi_string_t				*path;
	wd_account_t			*account;
	char					buffer[WD_TRANSFER_BUFFER_SIZE];
	wi_time_interval_t		timeout, interval, speedinterval, statusinterval, accountinterval;
	wi_socket_state_t		state;
	ssize_t					result, speedbytes, statsbytes;
	int						sd, bytes;

	pool = wi_pool_init(wi_pool_alloc());

	/* start upload */
	wi_log_info(WI_STR("Receiving \"%@\" from %@"),
		transfer->path,
		wd_user_identifier(transfer->user));
	
	wi_socket_set_direction(transfer->socket, WI_SOCKET_READ);

//	if(!wi_socket_set_blocking(transfer->socket, false))
//		wi_log_warn(WI_STR("Could not set non-blocking for %@: %m"), wd_user_ip(transfer->user));

	sd = wi_socket_descriptor(transfer->socket);
	speedinterval = statusinterval = accountinterval = wi_time_interval();
	speedbytes = statsbytes = 0;
	account = wd_user_account(transfer->user);

	/* update status */
	wi_lock_lock(wd_status_lock);
	wd_current_uploads++;
	wd_total_uploads++;
	wd_write_status(true);
	wi_lock_unlock(wd_status_lock);

	while(wd_transfer_state(transfer) == WD_TRANSFER_RUNNING && transfer->transferred < transfer->size) {
		/* wait to read */
		timeout = 0.0;
		
		do {
			state = wi_socket_wait_descriptor(sd, 0.1, true, false);
			
			if(state == WI_SOCKET_TIMEOUT) {
				timeout += 0.1;
				
				if(timeout >= 30.0)
					break;
			}
		} while(state == WI_SOCKET_TIMEOUT && wd_transfer_state(transfer) == WD_TRANSFER_RUNNING);
		
		if(state == WI_SOCKET_ERROR) {
			wi_log_err(WI_STR("Could not wait for upload from %@: %m"),
				wd_user_ip(transfer->user));

			break;
		}
		
		if(timeout >= 30.0) {
			wi_log_err(WI_STR("Timed out waiting to read upload from %@"),
				wd_user_ip(transfer->user));
			
			break;
		}

		/* read data */
		bytes = wi_socket_read_buffer(transfer->socket, 30.0, buffer, sizeof(buffer));
		
		if(bytes <= 0) {
			if(bytes < 0) {
				wi_log_err(WI_STR("Could not read upload from %@: %m"),
					wd_user_ip(transfer->user));
			}
			
			break;
		}
		
		if((wi_file_offset_t) bytes > transfer->size - transfer->transferred)
			bytes = transfer->size - transfer->transferred;

		/* write data */
		result = write(transfer->fd, buffer, bytes);
		
		if(result <= 0) {
			if(result < 0) {
				wi_log_err(WI_STR("Could not write upload to %@: %s"),
					transfer->realpath, strerror(errno));
			}
			
			break;
		}

		/* update counters */
		interval = wi_time_interval();
		transfer->transferred += bytes;
		speedbytes += bytes;
		statsbytes += bytes;

		/* update speed */
		transfer->speed = speedbytes / (interval - speedinterval);

		wd_transfer_limit_upload_speed(transfer, account, speedbytes, interval, speedinterval);
		
		if(interval - speedinterval > 30.0) {
			speedbytes = 0;
			speedinterval = interval;
		}

		/* update status */
		if(interval - statusinterval > wd_current_uploads) {
			wi_lock_lock(wd_status_lock);
			wd_uploads_traffic += statsbytes;
			wd_write_status(false);
			wi_lock_unlock(wd_status_lock);

			statsbytes = 0;
			statusinterval = interval;
		}
		
		/* update account */
		if(interval - accountinterval > 15.0) {
			account = wd_user_account(transfer->user);
			accountinterval = interval;
		}
		
		wi_pool_drain(pool);
	}

	wi_log_info(WI_STR("Received %@/%@ (%llu/%llu bytes) of \"%@\" from %@"),
		wd_files_string_for_bytes(transfer->transferred - transfer->offset),
		wd_files_string_for_bytes(transfer->size - transfer->offset),
		transfer->transferred - transfer->offset,
		transfer->size - transfer->offset,
		transfer->path,
		wd_user_identifier(transfer->user));

	/* update status */
	wd_transfer_set_state(transfer, WD_TRANSFER_STOPPED);
	
	wi_lock_lock(wd_status_lock);
	wd_current_uploads--;
	wd_uploads_traffic += statsbytes;
	wd_write_status(true);
	wi_lock_unlock(wd_status_lock);

	if(transfer->transferred == transfer->size) {
		path = wi_string_by_deleting_path_extension(transfer->realpath);

		if(wi_fs_rename_path(transfer->realpath, path)) {
			path = wi_string_by_appending_path_extension(transfer->path, WI_STR(WD_TRANSFERS_PARTIAL_EXTENSION));

			wd_files_move_comment(path, transfer->path);
		} else {
			wi_log_warn(WI_STR("Could not move %@ to %@: %m"),
				transfer->realpath, path);
		}
	}

	wi_release(pool);
}
Esempio n. 5
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. 6
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);
}