Beispiel #1
0
/**
 * Free data structures used by the page cache.
 */
static void
free_cache(struct lru_cache *cache)
{
	hash_list_free(&cache->used);
	slist_free(&cache->available);
	gm_hash_table_destroy_null(&cache->pagnum);
	VMM_FREE_NULL(cache->arena, cache->pages * DBM_PBLKSIZ);
	WFREE_NULL(cache->numpag, cache->pages * sizeof(long));
	WFREE_NULL(cache->dirty, cache->pages);
	cache->pages = cache->next = 0;
}
Beispiel #2
0
static void
node_data_free(gpointer value)
{
	struct node_data *data = value;

	atom_str_free_null(&data->user_agent);
	WFREE_NULL(data->host, data->host_size);
	WFREE_NULL(data->info, data->info_size);
	nid_unref(data->node_id);
	WFREE(data);
}
Beispiel #3
0
static inline void
nodes_gui_reverse_lookup_selected_helper(GtkTreeModel *model,
		GtkTreePath *unused_path, GtkTreeIter *iter, gpointer unused_data)
{
	struct node_data *data;
	gnet_node_info_t info;

	(void) unused_path;
	(void) unused_data;

	gtk_tree_model_get(model, iter, 0, &data, (-1));
	g_assert(NULL != find_node(data->node_id));

	if (hset_contains(ht_pending_lookups, data->node_id))
		return;

	guc_node_fill_info(data->node_id, &info);
	g_assert(data->node_id == info.node_id);

	if (!info.is_pseudo) {
		const struct nid *key = nid_ref(data->node_id);

		WFREE_NULL(data->host, data->host_size);
		data->host_size = w_concat_strings(&data->host,
				_("Reverse lookup in progress..."),
				" (", host_addr_port_to_string(info.addr, info.port), ")",
				(void *) 0);

		hset_insert(ht_pending_lookups, key);
		adns_reverse_lookup(info.addr, host_lookup_callback,
			deconstify_gpointer(nid_ref(key)));
	}
	guc_node_clear_info(&info);
}
Beispiel #4
0
/**
 * Free routine for tokdata, to release internally allocated memory, not
 * the structure itself.
 */
static void
free_tokdata(void *valptr, size_t len)
{
	struct tokdata *td = valptr;

	g_assert(sizeof *td == len);

	WFREE_NULL(td->token, td->length);
}
Beispiel #5
0
void
fi_gui_file_invalidate(struct fileinfo_data *file)
{
	GtkTreeIter *iter = fileinfo_data_get_iter(file);
	if (iter) {
		fileinfo_data_set_iter(file, NULL);
		WFREE_NULL(iter, sizeof *iter);
	}
}
Beispiel #6
0
static inline void
update_row(const void *key, void *value, void *user_data)
{
	struct node_data *data = value;
	time_t *now_ptr = user_data, now = *now_ptr;
	gnet_node_status_t status;

	g_assert(NULL != data);
	g_assert(data->node_id == key);

	if (!guc_node_get_status(data->node_id, &status))
		return;

    /*
     * Update additional info too if it has recorded changes.
     */
    if (remove_item(ht_node_info_changed, data->node_id)) {
        gnet_node_info_t info;

        if (guc_node_fill_info(data->node_id, &info)) {
			nodes_gui_update_node_info(data, &info);
			guc_node_clear_info(&info);
		}
    }

    if (remove_item(ht_node_flags_changed, data->node_id)) {
        gnet_node_flags_t flags;

        if (guc_node_fill_flags(data->node_id, &flags)) {
			nodes_gui_update_node_flags(data, &flags);
		}
    }

	if (status.connect_date)
		data->connected = delta_time(now, status.connect_date);

	if (status.up_date)
		data->uptime = delta_time(now, status.up_date);

	/* Update the status line */
	{	
		const gchar *s;
		size_t size;
		
		s = nodes_gui_common_status_str(&status);
		size = 1 + strlen(s);
		if (size > data->info_size) {
			WFREE_NULL(data->info, data->info_size);
			data->info = wcopy(s, size);
			data->info_size = size;
		} else {
			memcpy(data->info, s, size);
		}
	}

	tree_model_iter_changed(GTK_TREE_MODEL(nodes_model), &data->iter);
}
Beispiel #7
0
static void
host_lookup_callback(const gchar *hostname, gpointer key)
{
	const struct nid *node_id = key;
	gnet_node_info_t info;
	struct node_data *data;
	host_addr_t addr;
	guint16 port;

	if (!ht_pending_lookups)
		goto finish;

	if (!remove_item(ht_pending_lookups, node_id))
		goto finish;

	data = find_node(node_id);
	if (!data)
		goto finish;

	guc_node_fill_info(node_id, &info);
	g_assert(node_id == info.node_id);
	
	addr = info.addr;
	port = info.port;
	guc_node_clear_info(&info);

	WFREE_NULL(data->host, data->host_size);
	
	if (hostname) {
		const gchar *host;
		gchar *to_free;

		if (utf8_is_valid_string(hostname)) {
			to_free = NULL;
			host = hostname;
		} else {
			to_free = locale_to_utf8_normalized(hostname, UNI_NORM_GUI);
			host = to_free;
		}
		
		data->host_size = w_concat_strings(&data->host,
							host, " (",
							host_addr_port_to_string(addr, port), ")",
							(void *) 0);

		G_FREE_NULL(to_free);
	} else {
		statusbar_gui_warning(10,
			_("Reverse lookup for %s failed"), host_addr_to_string(addr));
		data->host_size = w_concat_strings(&data->host,
							host_addr_port_to_string(addr, port),
							(void *) 0);
	}

finish:
	nid_unref(node_id);
}
Beispiel #8
0
/**
 * Free data structures used by the page cache.
 */
static void
free_cache(struct lru_cache *cache)
{
	hash_list_free(&cache->used);
	slist_free(&cache->available);
	htable_free_null(&cache->pagnum);
	VMM_FREE_NULL(cache->arena, cache->pages * DBM_PBLKSIZ);
	WFREE_ARRAY_NULL(cache->numpag, cache->pages);
	WFREE_NULL(cache->dirty, cache->pages);
	cache->pages = cache->next = 0;
}
Beispiel #9
0
/**
 * Destroy the security token generator and nullify its pointer.
 */
void
sectoken_gen_free_null(sectoken_gen_t **stg_ptr)
{
	sectoken_gen_t *stg = *stg_ptr;

	if (stg != NULL) {
		sectoken_gen_check(stg);

		cq_cancel(&stg->rotate_ev);
		WFREE_NULL(stg->keys, stg->keycnt * sizeof stg->keys[0]);
		stg->magic = 0;
		WFREE(stg);
		*stg_ptr = NULL;
	}
}
Beispiel #10
0
/**
 * Free descriptor managing large keys and values.
 */
void
big_free(DBM *db)
{
	DBMBIG *dbg = db->big;

	if (NULL == dbg)
		return;

	if (common_stats)
		log_bigstats(db);

	big_datfile_free_null(&dbg->file);
	WFREE_NULL(dbg->bitbuf, BIG_BLKSIZE);
	HFREE_NULL(dbg->bitcheck);
	HFREE_NULL(dbg->scratch);
	fd_forget_and_close(&dbg->fd);
	WFREE(dbg);
}
Beispiel #11
0
/**
 * Clear the .dat file.
 *
 * @return TRUE if we were able to successfully unlink the file.
 */
gboolean
big_clear(DBM *db)
{
	DBMBIG *dbg = db->big;

	if (-1 == dbg->fd) {
		/*
		 * We do not want to call big_open() unless the .dat file already
		 * exists because that would create it and it was not needed so far.
		 */

		if (-1 == big_open_lazy(dbg, FALSE)) {
			if (EEXIST == errno) {
				if (-1 != unlink(dbg->file->datname)) {
					errno = 0;
				}
			}
			return 0 == errno;
		}
	}

	g_assert(dbg->fd != -1);

	if (-1 == fd_forget_and_close(&dbg->fd))
		return FALSE;

	dbg->bitbno = -1;
	WFREE_NULL(dbg->bitbuf, BIG_BLKSIZE);
	HFREE_NULL(dbg->scratch);
	dbg->scratch_len = 0;

	if (-1 == unlink(dbg->file->datname))
		return FALSE;

	return TRUE;
}
Beispiel #12
0
void
hsep_send_msg(struct gnutella_node *n, time_t now)
{
	hsep_triple tmp[G_N_ELEMENTS(n->hsep->sent_table)], other;
	unsigned int i, j, msglen, msgsize, triples, opttriples;
	gnutella_msg_hsep_t *msg;
	hsep_ctx_t *hsep;

	g_assert(n);
	g_assert(n->hsep);

	hsep = n->hsep;
	ZERO(&other);

	/*
	 * If we are a leaf, we just need to send one triple,
	 * which contains our own data (this triple is expanded
	 * to the needed number of triples on the peer's side).
	 * As the 0'th global and 0'th connection triple are zero,
	 * it contains only our own triple, which is correct.
	 */

	triples = settings_is_leaf() ? 1 : G_N_ELEMENTS(tmp);

	/*
	 * Allocate and initialize message to send.
	 */

	msgsize = GTA_HEADER_SIZE + triples * (sizeof *msg - GTA_HEADER_SIZE);
	msg = walloc(msgsize);

	{
		gnutella_header_t *header;
		
		header = gnutella_msg_hsep_header(msg);
		message_set_muid(header, GTA_MSG_HSEP_DATA);
		gnutella_header_set_function(header, GTA_MSG_HSEP_DATA);
		gnutella_header_set_ttl(header, 1);
		gnutella_header_set_hops(header, 0);
	}

	/*
	 * Collect HSEP data to send and convert the data to
	 * little endian byte order.
	 */

	if (triples > 1) {
		/* determine what we know about non-HSEP nodes in 1 hop distance */
		hsep_get_non_hsep_triple(&other);
	}

	for (i = 0; i < triples; i++) {
		for (j = 0; j < G_N_ELEMENTS(other); j++) {
			uint64 val;

			val = hsep_own[j] + (0 == i ? 0 : other[j]) +
				hsep_global_table[i][j] - hsep->table[i][j];
			poke_le64(&tmp[i][j], val);
		}
	}

	STATIC_ASSERT(sizeof hsep->sent_table == sizeof tmp);
	/* check if the table differs from the previously sent table */
	if (
		0 == memcmp(tmp, hsep->sent_table, sizeof tmp)
	) {
		WFREE_NULL(msg, msgsize);
		goto charge_timer;
	}

	memcpy(cast_to_char_ptr(msg) + GTA_HEADER_SIZE,
		tmp, triples * sizeof tmp[0]);

	/* store the table for later comparison */
	memcpy(hsep->sent_table, tmp, triples * sizeof tmp[0]);

	/*
	 * Note that on big endian architectures the message data is now in
	 * the wrong byte order. Nevertheless, we can use hsep_triples_to_send()
	 * with that data.
	 */

	/* optimize number of triples to send */
	opttriples = hsep_triples_to_send(cast_to_pointer(tmp), triples);

	if (GNET_PROPERTY(hsep_debug) > 1) {
		printf("HSEP: Sending %d %s to node %s (msg #%u): ", opttriples,
		    opttriples == 1 ? "triple" : "triples",
			host_addr_port_to_string(n->addr, n->port),
			hsep->msgs_sent + 1);
	}

	for (i = 0; i < opttriples; i++) {
		if (GNET_PROPERTY(hsep_debug) > 1) {
			char buf[G_N_ELEMENTS(hsep_own)][32];

			for (j = 0; j < G_N_ELEMENTS(buf); j++) {
				uint64 v;

				v = hsep_own[j] + hsep_global_table[i][j] - hsep->table[i][j];
				uint64_to_string_buf(v, buf[j], sizeof buf[0]);
			}

			STATIC_ASSERT(3 == G_N_ELEMENTS(buf));
			printf("(%s, %s, %s) ", buf[0], buf[1], buf[2]);
		}
	}

	if (GNET_PROPERTY(hsep_debug) > 1)
		puts("\n");

	/* write message size */
	msglen = opttriples * 24;
	gnutella_header_set_size(gnutella_msg_hsep_header(msg), msglen);

	/* correct message length */
	msglen += GTA_HEADER_SIZE;

	/* send message to peer node */
	gmsg_sendto_one(n, msg, msglen);

	WFREE_NULL(msg, msgsize);

	/*
	 * Update counters.
	 */

	hsep->msgs_sent++;
	hsep->triples_sent += opttriples;

charge_timer:

	hsep->last_sent = now;
	hsep->random_skew = random_value(2 * HSEP_MSG_SKEW) - HSEP_MSG_SKEW;
}
Beispiel #13
0
/**
 * Successful SOAP RPC reply callback.
 *
 * @param sr	the SOAP RPC request
 * @param root	XML tree of SOAP reply
 * @param arg	the UPnP control request
 */
static void
upnp_ctrl_soap_reply(const soap_rpc_t *sr, xnode_t *root, void *arg)
{
	upnp_ctrl_t *ucd = arg;
	xnode_t *xn;
	nv_table_t *nvt;
	void *reply;
	size_t reply_len;
	host_addr_t local_addr;
	int code;

	upnp_ctrl_check(ucd);

	if (GNET_PROPERTY(upnp_debug) > 1) {
		g_debug("UPNP got SOAP reply for %s", ucd->action);

		if (GNET_PROPERTY(upnp_debug) > 2)
			xfmt_tree_dump(root, stderr);
	}

	ucd->sr = NULL;		/* Done with SOAP request */

	if (soap_rpc_local_addr(sr, &local_addr))
		upnp_set_local_addr(local_addr);

	/*
	 * Decompile the returned values.
	 *
	 * <u:actionResponse xmlns:u="urn:schemas-upnp-org:service:serviceType:v">
	 *	 <arg1>out value1</arg1>
	 *	 <arg2>out value2</arg2>
	 *       :  :  :  :
	 *   <argn>out valuen</argn>
	 * </u:actionResponse>
	 *
	 * Values are inserted in name / value pairs: "arg1" -> "out value 1" and
	 * given to the launch callback for extracting and decompiling the values.
	 */

	nvt = nv_table_make(TRUE);

	for (xn = xnode_first_child(root); xn; xn = xnode_next_sibling(xn)) {
		nv_pair_t *nv;
		xnode_t *xt;

		if (!xnode_is_element(xn)) {
			if (GNET_PROPERTY(upnp_debug)) {
				g_warning("UPNP \"%s\" skipping XML node %s",
					ucd->action, xnode_to_string(xn));
			}
			continue;
		}

		xt = xnode_first_child(xn);

		if (NULL == xt || !xnode_is_text(xt)) {
			if (GNET_PROPERTY(upnp_debug)) {
				g_warning("UPNP \"%s\" bad child node %s in %s",
					ucd->action, xnode_to_string(xt), xnode_to_string2(xn));
			}
		} else {
			/*
			 * Name/value strings point in the tree, which is going to be
			 * alive for the duration of the processing, so we can use the
			 * strings without copying them.
			 */

			nv = nv_pair_make_static_str(
				xnode_element_name(xn), xnode_text(xt));

			nv_table_insert_pair(nvt, nv);

			if (xnode_next_sibling(xt) != NULL) {
				if (GNET_PROPERTY(upnp_debug)) {
					g_warning("UPNP \"%s\" content of %s is not pure text",
						ucd->action, xnode_to_string(xt));
				}
			}
		}
	}

	/*
	 * Attempt to decompile the replied values, if any are expected.
	 *
	 * Allocated data is done via walloc(), and the returned structure is flat.
	 * It will be freed after invoking the user callback.
	 */

	if (ucd->lcb != NULL) {
		reply = (*ucd->lcb)(nvt, &reply_len);
		code = NULL == reply ? UPNP_ERR_OK : UPNP_ERR_BAD_REPLY;
	} else {
		code = UPNP_ERR_OK;
		reply = NULL;
		reply_len = 0;
	}

	/*
	 * Let UPnP control invoker know about the result of the query.
	 */

	(*ucd->cb)(code, reply, reply_len, ucd->cb_arg);

	/*
	 * Done, final cleanup.
	 */

	WFREE_NULL(reply, reply_len);
	nv_table_free(nvt);
	upnp_ctrl_free(ucd);
}