Exemple #1
0
/* non-blocking, returns socket descriptor or -1 if none available
 * NOTE:  This function assumes that the cursor of all buf's is zero,
 *        and it can call buf_reset(source, tag).
 */
int MPINU_rank_of_msg_avail_in_cache(int source, int tag) {
    if (source != MPI_ANY_SOURCE) {
      if (tag == MPI_ANY_TAG) {
	if (buf_avail(source, sizeof(struct msg_hdr)))
          return source;
      }
      else
	while (buf_avail(source, sizeof(struct msg_hdr))) {
	  struct msg_hdr *hdr = buf_peek(source, sizeof(struct msg_hdr));
	  if ( ntohl( hdr->tag ) == tag ) {
	    buf_reset(source, tag); /* clean up for next caller */
	    return source;
	  } else { /* Else skip header and body */
	    buf_skip( source, sizeof(struct msg_hdr) + ntohl(hdr->size) );
	  }
	}
      buf_reset(source, tag); /* clean up for next caller */
    }
    else /* else source == MPI_ANY_SOURCE */
      for (source = 0; source < MPINU_num_slaves; source++) {
	int rank = MPINU_rank_of_msg_avail_in_cache(source, tag);
	if (rank != -1)
	  return rank;
      }
    /* if no source had buf_avail, then no msg avail */
    return -1;
}
Exemple #2
0
int
isns_authblock_decode(buf_t *bp, struct isns_authblk *auth)
{
	unsigned int	avail = buf_avail(bp);

	if (!buf_get32(bp, &auth->iab_bsd)
	 || !buf_get32(bp, &auth->iab_length)
	 || !buf_get64(bp, &auth->iab_timestamp)
	 || !buf_get32(bp, &auth->iab_spi_len))
		 return 0;

	/* Make sure the length specified by the auth block
	 * is reasonable. */
	if (auth->iab_length < ISNS_AUTHBLK_SIZE
	 || auth->iab_length > avail)
		return 0;

	/* This chops off any data trailing the auth block.
	 * It also makes sure that we detect if iab_length
	 * exceeds the amount of available data. */
	if (!buf_truncate(bp, auth->iab_length - ISNS_AUTHBLK_SIZE))
		return 0;

	auth->iab_spi = buf_head(bp);
	if (!buf_pull(bp, auth->iab_spi_len))
		return 0;

	auth->iab_sig = buf_head(bp);
	auth->iab_sig_len = buf_avail(bp);
	return 1;
}
Exemple #3
0
ssize_t MPINU_recv_msg_body_with_cache(int source, void *buf, size_t len) {
    if ( buf_avail(source, len) ) {
      buf_dequeue(source, buf, len, 0); /* flags = 0: Never peek for body */
      return len;
    } else {
      /* Body cannot be split between buf and network;
       * If len bytes weren't available in buf, then expect 0 bytes in buf */
      assert( !buf_avail(source, 1) );
      /* flags = 0: Never peek for body */
      len = MPINU_recvall(MPINU_pg_array[source].sd, buf, len, 0);
      return len;
    }
}
Exemple #4
0
/* Account for "n" bytes being added in the buffer. */
static void
buf_more(struct buf *buf, size_t n)
{

	assert(n <= buf_avail(buf));
	buf->in += n;
}
Exemple #5
0
/* On receiving a msg_hdr, we first do buf_reset(source, tag),
 * but _not_ on receiving a msg_body */
ssize_t MPINU_recv_msg_hdr_with_cache(int s, int tag,
				      void *buf, size_t len, int flags) {
    int msg_found = 0;
    int source = MPINU_rank_from_socket(s);
    buf_reset(source, tag);
    while ( !msg_found && buf_avail(source, len) ) {
      if ( ntohl( ((struct msg_hdr *)buf_peek(source, len))->tag ) == tag
	   || tag == MPI_ANY_TAG ) {
	buf_dequeue(source, buf, len, flags & MSG_PEEK);
	msg_found = 1;
      }
      else {
        int body_len;
	buf_skip(source, len); /* Skip header */
	body_len = ntohl( ((struct msg_hdr *)buf)->size );
	buf_skip(source, body_len); /* Skip body */
      }
    }
    if ( !msg_found )
      assert( !buf_avail(source, len) );
    while ( !msg_found ) {
      len = MPINU_recvall(MPINU_pg_array[source].sd, buf, len, flags);
      assert( len == sizeof(struct msg_hdr) );
      if ( ntohl( ((struct msg_hdr *)buf)->tag ) == tag
	   || tag == MPI_ANY_TAG )
	msg_found = 1;
      else if ( ! (flags & MSG_PEEK) ) {
#       define STATIC_SIZE 1000
        static char body_buf_array[STATIC_SIZE];
	void *body_buf;
	int body_len;
	buf_enqueue(source, buf, len);  /* Store header */
	/* After storing the header, we have to store the corresponding body */
	body_len = ntohl( ((struct msg_hdr *)buf)->size );
	if (body_len > STATIC_SIZE)
          body_buf = malloc(body_len);
	else
          body_buf = body_buf_array;
        body_len = MPINU_recvall(MPINU_pg_array[source].sd, body_buf, body_len,
			         flags);
	buf_enqueue(source, body_buf, body_len);  /* Store body */
	if (body_len > STATIC_SIZE)
          free(body_buf);
      }
    }
    return len;
}
Exemple #6
0
/* Make more room in the buffer if needed. */
static void
buf_prewrite(struct buf *buf)
{

	if (buf_count(buf) == buf_size(buf))
		buf_grow(buf, 0);
	if (buf_count(buf) > 0 && buf_avail(buf) == 0) {
		memmove(buf->buf, buf->buf + buf->off, buf_count(buf));
		buf->off = 0;
	}
}
Exemple #7
0
/*
 * DSA signature generation and verification
 */
static void
isns_message_digest(EVP_MD_CTX *md, const buf_t *pdu,
		const struct isns_authblk *blk)
{
	uint64_t	stamp;

	EVP_DigestUpdate(md, buf_head(pdu), buf_avail(pdu));

	/* The RFC doesn't say which pieces of the
	 * message should be hashed.
	 * We make an educated guess.
	 */
	stamp = htonll(blk->iab_timestamp);
	EVP_DigestUpdate(md, &stamp, sizeof(stamp));
}
Exemple #8
0
int
buf_drain(buf_t *bp)
{
	int	n;

	if (!bp->write_mode || bp->fd < 0)
		return 0;

	n = write(bp->fd, bp->base + bp->head, buf_avail(bp));
	if (n < 0) {
		warn("write error");
		return 0;
	}

	bp->head += n;
	return n;
}
Exemple #9
0
	if (new_base == NULL)
		return 0;

	bp->base = new_base;
	bp->size = new_size;
	bp->allocated = 1;
	return new_size;
}

buf_t *
buf_split(buf_t **to_split, size_t size)
{
	buf_t *old = *to_split, *new;
	size_t avail;

	avail = buf_avail(old);
	if (size > avail)
		return NULL;

	if (size == avail) {
		*to_split = NULL;
		return old;
	}

	new = buf_alloc(size);
	buf_put(new, buf_head(old), size);
	buf_pull(old, size);

	return new;
}