示例#1
0
/**
 * Build the PATRICIA that maps a message name string into our internal
 * message ID.
 */
static void
g2_msg_build_map(void)
{
	uint i;

	STATIC_ASSERT(G2_MSG_MAX == N_ITEMS(g2_msg_english_names));
	STATIC_ASSERT(G2_MSG_MAX == N_ITEMS(g2_msg_symbolic_names));

	g_assert(NULL == g2_msg_pt);

	/*
	 * We must be prepared to handle all the possible packet names, not just
	 * the ones we know.  Therefore, the PATRICIA key size is computed to be
	 * able to handle the maximum architected size.
	 */

	g2_msg_pt = patricia_create(G2_FRAME_NAME_LEN_MAX * 8);	/* Size in bits */

	for (i = 0; i < N_ITEMS(g2_msg_symbolic_names); i++) {
		const char *key = g2_msg_symbolic_names[i];
		size_t len = strlen(key);

		patricia_insert_k(g2_msg_pt, key, len * 8, int_to_pointer(i));
	}
}
示例#2
0
/**
 * Mark a file descriptor as being preserved from closing by
 * fd_close_unpreserved_from().
 */
void
fd_preserve(int fd)
{
	g_assert(!is_a_socket(fd));

	ONCE_FLAG_RUN(fd_preserved_allocated, fd_preserved_allocate);
	hset_insert(fd_preserved, int_to_pointer(fd));
}
示例#3
0
/**
 * Notifies that a socket descriptor has been closed.
 *
 * This is only required on Windows, since we need to keep track of opened
 * socket descriptors, in order to close them before exec().  Failure to
 * do so would leave listen sockets around, and because we use SO_REUSEADDR
 * to bind our listening sockets, we would have two processes listening on
 * the same socket -- a recipe for blackouts on Windows!
 */
void
fd_notify_socket_closed(socket_fd_t fd)
{
	if (!is_running_on_mingw()) {
		s_carp_once("%s(): not needed on UNIX", G_STRFUNC);
		return;
	} else {
		if G_LIKELY(fd_sockets != NULL)
			hset_remove(fd_sockets, int_to_pointer(fd));
	}
}
示例#4
0
/**
 * Closes the file and sets the descriptor to -1. Does nothing if
 * the descriptor is already -1.
 *
 * @param fd_ptr Must point to a non-negative file descriptor or -1.
 *
 * @return 0 on success, -1 on error.
 */
int
fd_close(int *fd_ptr)
{
	int ret, fd;

	g_assert(NULL != fd_ptr);

	fd = *fd_ptr;
	g_assert(fd >= -1);

	if (fd < 0) {
		ret = 0;
	} else {
		if (fd_preserved != NULL)
			hset_remove(fd_preserved, int_to_pointer(fd));
		ret = close(fd);
		*fd_ptr = -1;
	}
	return ret;
}
示例#5
0
static inline void
ul_stats_set_row(struct ul_stats *us, int row)
{
	ul_stats_set_user_data(us, int_to_pointer(row));
}
示例#6
0
int
main(void) {
	struct fibheap *a;
	void *arr[10];
	int i;
	a = fh_makekeyheap();
	
	for (i=1 ; i < 10 ; i++)
	  {
              arr[i]= fh_insertkey(a,0,int_to_pointer(i));
	      printf("adding: 0 %d \n",i);
	  }
     
	printf(" \n");
	 fh_replacekey(a, arr[1],-38);
         fh_replacekey(a, arr[7],-34);
  
        printf("wert(minkey) %d\n",fh_minkey(a));
	printf("Knoten: %lld\n\n", pointer_to_ll(fh_extractmin(a)));
	 fh_replacekey(a, arr[2],-55);
         fh_replacekey(a, arr[5],-56);
        printf("Wert(minkey) %d\n",fh_minkey(a));
        printf("Knoten: %lld\n\n", pointer_to_ll(fh_extractmin(a)));
	
	 fh_replacekey(a, arr[4],-1);
         fh_replacekey(a, arr[2],-102);
	 fh_replacekey(a, arr[6],-1);
         fh_replacekey(a, arr[9],-1);
	 fh_replacekey(a, arr[8],-4);
        printf("Wert(minkey) %d\n",fh_minkey(a));
        printf("Knoten: %lld\n\n", pointer_to_ll(fh_extractmin(a)));
	 fh_replacekey(a, arr[3],-74);
         fh_replacekey(a, arr[8],-55);
	 fh_replacekey(a, arr[4],-2);
        	
        printf("Wert(minkey) %d\n",fh_minkey(a));
	printf("Knoten: %lld\n\n", pointer_to_ll(fh_extractmin(a)));
	 fh_replacekey(a, arr[4],-3);
         fh_replacekey(a, arr[6],-2);
         fh_replacekey(a, arr[7],-99);
        printf("Wert(minkey) %d\n",fh_minkey(a));
	printf("Knoten: %lld\n\n", pointer_to_ll(fh_extractmin(a)));
	 fh_replacekey(a, arr[6],-3);
         fh_replacekey(a, arr[4],-4);
	 fh_replacekey(a, arr[8],-94);
         fh_replacekey(a, arr[9],-2);
        printf("Wert(minkey) %d\n",fh_minkey(a));
	printf("Knoten: %lld\n\n", pointer_to_ll(fh_extractmin(a)));
        fh_replacekey(a, arr[6],-4);
	
        printf("Wert(minkey) %d\n",fh_minkey(a));
	printf("Knoten: %lld\n\n", pointer_to_ll(fh_extractmin(a)));
	
        printf("Wert(minkey) %d\n",fh_minkey(a));
        printf("Knoten: %lld\n\n", pointer_to_ll(fh_extractmin(a)));
	/*fh_replacekey(a, arr[9],-3);*/
        printf("Wert(minkey) %d\n",fh_minkey(a));
	printf("Knoten: %lld\n\n", pointer_to_ll(fh_extractmin(a)));
     
        /*fh_replacekey(a, arr[9],-49);*/
 
	fh_deleteheap(a);

	return 0;
}
示例#7
0
/**
 * Initiates a new TLS session.
 *
 * @return 0 on success, -1 on error.
 */
int
tls_init(struct gnutella_socket *s)
{
    /**
     * ANON-DH is enabled because we don't use PKI.
     * DEFLATE is disabled because it seems to cause crashes.
     * ARCFOUR-40 is disabled because it is deprecated.
     */
    static const char prio_want[] = "NORMAL:+ANON-DH:-ARCFOUR-40:-COMP-DEFLATE";
    /* "-COMP-DEFLATE" is causing an error on MinGW with GnuTLS 2.10.2 */
    static const char prio_must[] = "NORMAL:+ANON-DH:-ARCFOUR-40";
    const bool server = SOCK_CONN_INCOMING == s->direction;
    struct tls_context *ctx;
    const char *fn;
    int e;

#define TRY(function) (fn = (#function)), e = function

    socket_check(s);

    WALLOC0(ctx);
    ctx->s = s;
    s->tls.ctx = ctx;

    if (
        TRY(gnutls_init)(&ctx->session, server ? GNUTLS_SERVER : GNUTLS_CLIENT)
    ) {
        ctx->session = NULL;
        goto failure;
    }

    if (TRY(gnutls_priority_set_direct)(ctx->session, prio_want, NULL)) {
        const char *error;
        if (TRY(gnutls_priority_set_direct)(ctx->session, prio_must, &error)) {
            g_warning("%s() failed at \"%s\"", fn, error);
            goto failure;
        }
    }

    if (TRY(gnutls_credentials_set)(ctx->session,
                                    GNUTLS_CRD_CERTIFICATE, cert_cred))
        goto failure;

    gnutls_dh_set_prime_bits(ctx->session, TLS_DH_BITS);

#ifdef USE_TLS_CUSTOM_IO
    gnutls_transport_set_ptr(ctx->session, s);
    gnutls_transport_set_push_function(ctx->session, tls_push);
    gnutls_transport_set_pull_function(ctx->session, tls_pull);
#if !HAS_TLS(2, 12)
    /*
     * This routine has been removed starting TLS 3.0.  It was used to disable
     * the lowat feature, and apparently this is now always the case in recent
     * TLS versions.	--RAM, 2011-09-28
     *
     * It's also flagged as deprecated in 2.12.x, so don't use it there.
     *		--RAM, 2011-12-15
     */
    gnutls_transport_set_lowat(ctx->session, 0);
#endif
#else	/* !USE_TLS_CUSTOM_IO */
    g_assert(is_valid_fd(s->file_desc));
    gnutls_transport_set_ptr(ctx->session, int_to_pointer(s->file_desc));
#endif	/* USE_TLS_CUSTOM_IO */

    if (server) {
        if (TRY(gnutls_anon_allocate_server_credentials)(&ctx->server_cred))
            goto failure;

        gnutls_anon_set_server_dh_params(ctx->server_cred, get_dh_params());

        if (TRY(gnutls_credentials_set)(ctx->session,
                                        GNUTLS_CRD_ANON, ctx->server_cred))
            goto failure;

    } else {
        if (TRY(gnutls_anon_allocate_client_credentials)(&ctx->client_cred))
            goto failure;

        if (TRY(gnutls_credentials_set)(ctx->session,
                                        GNUTLS_CRD_ANON, ctx->client_cred))
            goto failure;
    }

    return 0;

failure:
    g_warning("%s() failed: %s", EMPTY_STRING(fn), gnutls_strerror(e));
    tls_free(s);
    return -1;
#undef TRY
}
示例#8
0
/**
 * Get a new index in the cache, and update LRU data structures.
 *
 * @param db	the database
 * @param num	page number in the DB for which we want a cache index
 *
 *
 * @return -1 on error, or the allocated cache index.
 */
static int
getidx(DBM *db, long num)
{
	struct lru_cache *cache = db->cache;
	long n;		/* Cache index */

	/*
	 * If we invalidated pages, reuse their indices.
	 * If we have not used all the pages yet, get the next one.
	 * Otherwise, use the least-recently requested page.
	 */

	if (slist_length(cache->available)) {
		void *v = slist_shift(cache->available);
		n = pointer_to_int(v);
		g_assert(n >= 0 && n < cache->pages);
		g_assert(!cache->dirty[n]);
		g_assert(-1 == cache->numpag[n]);
		hash_list_prepend(cache->used, int_to_pointer(n));
	} else if (cache->next < cache->pages) {
		n = cache->next++;
		cache->dirty[n] = FALSE;
		hash_list_prepend(cache->used, int_to_pointer(n));
	} else {
		void *last = hash_list_tail(cache->used);
		long oldnum;
		gboolean had_ioerr = booleanize(db->flags & DBM_IOERR_W);

		hash_list_moveto_head(cache->used, last);
		n = pointer_to_int(last);

		/*
		 * This page is no longer cached as its cache index is being reused
		 * Flush it to disk if dirty before discarding it.
		 */

		g_assert(n >= 0 && n < cache->pages);

		oldnum = cache->numpag[n];

		if (cache->dirty[n] && !writebuf(db, oldnum, n)) {
			hash_list_iter_t *iter;
			void *item;
			gboolean found = FALSE;

			/*
			 * Cannot flush dirty page now, probably because we ran out of
			 * disk space.  Look through the cache whether we can reuse a
			 * non-dirty page instead, which would let us keep the dirty
			 * page a little longer in the cache, in the hope it can then
			 * be properly flushed later.
			 */

			iter = hash_list_iterator_tail(cache->used);

			while (NULL != (item = hash_list_iter_previous(iter))) {
				long i = pointer_to_int(item);

				g_assert(i >= 0 && i < cache->pages);

				if (!cache->dirty[i]) {
					found = TRUE;	/* OK, reuse cache slot #i then */
					n = i;
					oldnum = cache->numpag[i];
					break;
				}
			}

			hash_list_iter_release(&iter);

			if (found) {
				g_assert(item != NULL);
				hash_list_moveto_head(cache->used, item);

				/*
				 * Clear error condition if we had none prior to the flush
				 * attempt, since we can do without it for now.
				 */

				if (!had_ioerr)
					db->flags &= ~DBM_IOERR_W;

				g_warning("sdbm: \"%s\": "
					"reusing cache slot used by clean page #%ld instead",
					sdbm_name(db), oldnum);
			} else {
				g_warning("sdbm: \"%s\": cannot discard dirty page #%ld",
					sdbm_name(db), oldnum);
				return -1;
			}
		}

		g_hash_table_remove(cache->pagnum, ulong_to_pointer(oldnum));
		cache->dirty[n] = FALSE;
	}

	/*
	 * Record the association between the cache index and the page number.
	 */

	g_assert(n >= 0 && n < cache->pages);

	cache->numpag[n] = num;
	g_hash_table_insert(cache->pagnum,
		ulong_to_pointer(num), int_to_pointer(n));

	return n;
}
示例#9
0
/**
 * Closes all file descriptors greater or equal to ``first_fd'', skipping
 * preserved ones if ``preserve'' is TRUE.
 */
static void
fd_close_from_internal(const int first_fd, bool preserve)
{
	int fd;

	g_return_if_fail(first_fd >= 0);

	if (!preserve && try_close_from(first_fd))
		return;

	fd = getdtablesize() - 1;
	while (fd >= first_fd) {
		if (preserve && hset_contains(fd_preserved, int_to_pointer(fd)))
			goto next;

#ifdef HAVE_GTKOSXAPPLICATION
		/* OS X doesn't allow fds being closed not opened by us. During
		 * GUI initialisation a new kqueue fd is created for UI events. This
		 * is visible to us as a fifo which we are not allowed to close.
		 * Set close on exec on all fifo's so we won't leak any of our other
		 * fifo's
		 *	-- JA 2011-11-28 */
		if (is_a_fifo(fd))
			fd_set_close_on_exec(fd);
		else
#endif
		/* OS X frowns upon random fds being closed --RAM 2011-11-13  */
		if (fd_is_opened(fd)) {
			if (close(fd)) {
#if defined(F_MAXFD)
				fd = fcntl(0, F_MAXFD);
				continue;
#endif	/* F_MAXFD */
			}
		}
	next:
		fd--;
	}

	/*
	 * When called with a first_fd of 3, and we are on Windows, also make
	 * sure we close all the known sockets we have.  This lets the process
	 * safely auto-restart, avoiding multiple listening sockets on the same
	 * port.
	 *		--RAM, 2015-04-05
	 */

	if (
		is_running_on_mingw() && !preserve &&
		3 == first_fd && NULL != fd_sockets
	) {
		hset_t *fds = fd_sockets;

		/*
		 * We're about to exec() another process, and we may be crashing,
		 * hence do not bother using hset_foreach_remove() to ensure minimal
		 * processing.  We also reset the fd_sockets pointer to NULL to
		 * make sure s_close() will do nothing when fd_notify_socket_closed()
		 * is called.
		 */

		fd_sockets = NULL;		/* We don't expect race conditions here */
		hset_foreach(fds, fd_socket_close, NULL);

		/* Don't bother freeing / clearing set, we're about to exec() */
	}
}