Example #1
0
static wi_p7_message_t * _wi_p7_socket_read_xml_message(wi_p7_socket_t *p7_socket, wi_time_interval_t timeout, wi_string_t *prefix) {
	wi_string_t			*string;
	wi_p7_message_t		*p7_message;
	
	p7_message = wi_autorelease(wi_p7_message_init(wi_p7_message_alloc(), p7_socket));
	
	while(true) {
		string = wi_socket_read_to_string(p7_socket->socket, timeout, WI_STR(">"));
		
		if(!string || wi_string_length(string) == 0)
			return NULL;
		
		wi_string_delete_surrounding_whitespace(string);
		
		if(!p7_message->xml_string)
			p7_message->xml_string = wi_copy(string);
		else
			wi_string_append_string(p7_message->xml_string, string);
		
		if(wi_string_has_suffix(string, WI_STR("</p7:message>")) ||
		   (wi_string_has_suffix(string, WI_STR("/>")) &&
			wi_string_has_prefix(string, WI_STR("<p7:message")))) {
			break;
		}
	}
	
	wi_retain(p7_message->xml_string);
	
	if(prefix)
		wi_string_insert_string_at_index(p7_message->xml_string, prefix, 0);

	wi_string_delete_surrounding_whitespace(p7_message->xml_string);
	
	return p7_message;
}
Example #2
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);
}
Example #3
0
void wt_control_thread(wi_runtime_instance_t *argument) {
	wi_pool_t			*pool;
	wt_client_t			*client = argument;
	wi_string_t			*string;
	wi_socket_state_t	state;
	wi_uinteger_t		i = 0;
	
	pool = wi_pool_init(wi_pool_alloc());

	wt_client_set(client);

	while(client->state <= WT_CLIENT_STATE_SAID_HELLO) {
		do {
			state = wi_socket_wait(client->socket, 0.1);
		} while(state == WI_SOCKET_TIMEOUT && client->state <= WT_CLIENT_STATE_SAID_HELLO);

		if(client->state > WT_CLIENT_STATE_SAID_HELLO) {
			/* invalid state */
			break;
		}

		if(state == WI_SOCKET_ERROR) {
			if(wi_error_code() == EINTR) {
				/* got a signal */
				continue;
			} else {
				/* error in TCP communication */
				wi_log_err(WI_STR("Could not read from %@: %m"), client->ip);

				break;
			}
		}

		string = wi_socket_read_to_string(client->socket, 0.0, WI_STR(WT_MESSAGE_SEPARATOR_STR));

		if(!string || wi_string_length(string) == 0) {
			if(!string)
				wi_log_info(WI_STR("Could not read from %@: %m"), client->ip);
			
			break;
		}

		wt_parse_command(string);
		
		if(++i % 10 == 0)
			wi_pool_drain(pool);
	}

	wi_log_info(WI_STR("Disconnect from %@ after %.2fs"),
		client->ip,
		wi_time_interval() - client->connect_time);
	
	wi_release(pool);
}
Example #4
0
static wi_integer_t wr_runloop_server_callback(wi_socket_t *socket) {
	wi_string_t		*string;
	uint32_t		message = 0;
	
	string = wi_socket_read_to_string(wr_socket, 0.0, WI_STR(WR_MESSAGE_SEPARATOR_STR));
	
	if(string && wi_string_length(string) > 0) {
		message = wr_parse_message(string);
	} else {
		if(!string)
			wr_printf_prefix(WI_STR("Could not read from server: %m"));

		wr_disconnect();
	}
	
	return message;
}
Example #5
0
static wi_boolean_t wd_tracker_read(wd_tracker_t *tracker, uint32_t *message, wi_array_t **arguments) {
	wi_string_t		*string;

	*message	= 0;
	*arguments	= NULL;
	string		= wi_socket_read_to_string(tracker->socket, 30.0, WI_STR(WD_MESSAGE_SEPARATOR_STR));

	if(string && wi_string_length(string) > 0) {
		wi_parse_wired_message(string, message, arguments);
	} else {
		if(!string) {
			wi_log_err(WI_STR("Could not read from tracker %@: %m"),
				tracker->host);
		} else {
			wi_log_err(WI_STR("Could not read from tracker %@: %s"),
				tracker->host, "Connection closed");
		}
	}

	return (string != NULL);
}
Example #6
0
void wd_control_thread(wi_runtime_instance_t *argument) {
	wi_pool_t		*pool;
	wd_client_t		*client = argument;
	wi_string_t		*string;
	unsigned int	i = 0;
	int				state;
	
	pool = wi_pool_init(wi_pool_alloc());

	wd_clients_add_client(client);
	wd_client_set(client);

	while(client->state <= WD_CLIENT_STATE_LOGGED_IN) {
		if(!pool)
			pool = wi_pool_init(wi_pool_alloc());
		
		if(client->buffer_offset == 0) {
			do {
				state = wi_socket_wait(client->socket, 0.1);
			} while(state == 0 && client->state <= WD_CLIENT_STATE_LOGGED_IN);
			
			if(client->state > WD_CLIENT_STATE_LOGGED_IN) {
				/* invalid state */
				break;
			}

			if(state < 0) {
				if(wi_error_code() == EINTR) {
					/* got a signal */
					continue;
				} else {
					/* error in TCP communication */
					wi_log_err(WI_STR("Could not read from %@: %m"), client->ip);

					break;
				}
			}
		}

		wd_client_lock_socket(client);
		string = wi_socket_read_to_string(client->socket, 0.0, WI_STR(WD_MESSAGE_SEPARATOR_STR));
		wd_client_unlock_socket(client);
		
		if(!string || wi_string_length(string) == 0) {
			if(!string)
				wi_log_info(WI_STR("Could not read from %@: %m"), client->ip);
			
			break;
		}

		wd_parse_command(string);
		
		if(++i % 10 == 0) {
			wi_release(pool);
			pool = NULL;
		}
	}
	
	/* announce parting if client disconnected by itself */
	if(client->state == WD_CLIENT_STATE_LOGGED_IN) {
		client->state = WD_CLIENT_STATE_DISCONNECTED;

		wd_broadcast_lock();
		wd_client_broadcast_leave(client, WD_PUBLIC_CID);
		wd_broadcast_unlock();
	}

	/* update status for clients logged in and above */
	if(client->state >= WD_CLIENT_STATE_LOGGED_IN) {
		wi_lock_lock(wd_status_lock);
		wd_current_users--;
		wd_write_status(true);
		wi_lock_unlock(wd_status_lock);
	}

	wi_log_info(WI_STR("Disconnect from %@"), client->ip);
	
	wi_socket_close(client->socket);
	
	wd_clients_remove_client(client);
	
	wi_release(pool);
}
Example #7
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);
}