Esempio n. 1
0
File: amsg.c Progetto: genua/anoubis
/**
 * Try to retrieve data from the buffer associate with the file descriptor.
 * The read buffer is filled if required. If a complete message is available
 * it is returned. The message is passed through amsg_verify before it is
 * returned.
 *
 * @param fd The file descriptor to read a message from.
 * @return A complete message in malloced memory or NULL if there is no
 *     data or only an incomplete message. If this function returns NULL,
 *     it is guaranteed that data must be read from the file descriptor
 *     before a complete message can be returned. It is not guaranteed
 *     that all available data from the file descriptor was actuall read!
 */
struct anoubisd_msg *
get_msg(int fd)
{
	struct msg_buf		*mbp;
	struct anoubisd_msg	*msg;
	struct anoubisd_msg	*msg_r;
	int			 copy;

	if ((mbp = _get_mbp(fd)) == NULL) {
		log_warnx("msg_buf not initialized");
		return NULL;
	}

	if (mbp->rmsg) {
		if ((int)mbp->rmsgoff != mbp->rmsg->size)
			if (!_fill_buf(mbp))
				goto eof;
		if ((int)mbp->rmsgoff == mbp->rmsg->size) {
			msg_r = mbp->rmsg;
			mbp->rmsg = NULL;
			mbp->rmsgoff = 0;
			goto message;
		}
		return NULL;
	}
	/* we need at least the struct anoubisd_msg structure. */
	if (mbp->rtailp - mbp->rheadp < (int)sizeof(struct anoubisd_msg))
		if (!_fill_buf(mbp))
			goto eof;
	if (mbp->rtailp - mbp->rheadp < (int)sizeof(struct anoubisd_msg))
		return NULL;

	/* check for a complete message */
	msg = (struct anoubisd_msg *)mbp->rheadp;
	if (msg->size > MSG_SIZE_LIMIT
	    || msg->size < (int)sizeof(struct anoubisd_msg)) {
		log_warnx("get_msg: Bad message size %d", msg->size);
		master_terminate();
	}
	if ((msg_r = malloc(msg->size)) == NULL) {
		log_warn("get_msg: can't allocate memory");
		master_terminate();
	}
	copy = mbp->rtailp - mbp->rheadp;
	if (copy > msg->size)
		copy = msg->size;
	memcpy(msg_r, msg, copy);
	mbp->rheadp += copy;
	if (msg_r->size != copy) {
		mbp->rmsg = msg_r;
		mbp->rmsgoff = copy;
		return NULL;
	}
message:
	amsg_verify(msg_r);
	DEBUG(DBG_MSG_RECV, "get_msg: fd:%d size:%d", mbp->fd, msg_r->size);
	return msg_r;
eof:
	return NULL;
}
Esempio n. 2
0
/*
Поскольку точное время жизненно важно для хранилища, то обращаться с ним
следует следующим образом:

- проведем базовую проверку сравнив в временем компиляции и установим
  time_good если проверка пройдена.
- ждем, пока появится время GPS,
- проведем коррекцию. Если время RTC в прошлом - то просто добавим разницу
  к текущему значению, в противном случае сбросим флаг time_good, будем ждать,
  пока время GPS не догонит системное. Если разница больше чем
  STORAGE_VOID_LIMIT_US - обнулим хранилище и начнем с начала.
*/
bool_t bnapStorageDoRecord(BnapStorage_t *bsp){
  bool_t status;
  int64_t timestamp = -1;

  /* there is no sense to do something without normal time */
  if (GlobalFlags.time_good != 1)
    return CH_FAILED;

  if (GlobalFlags.time_proved == 1){
    timestamp = fastGetTimeUnixUsec();
    if (bsp->mtime > timestamp){
      if (bsp->mtime > (timestamp + STORAGE_VOID_LIMIT_US)){/* time too far in future */
        bnapStorageWipe(bsp);
      }
      return CH_FAILED; /* wait until mtime be older than current system time */
    }
  }

  _fill_buf(bsp->buf, &timestamp);
  status = bsp->mmcp->vmt->write(bsp->mmcp, bsp->tip, bsp->buf, 1);
  chDbgCheck(status == CH_SUCCESS, "write failed");

  bsp->tip++;
  if (bsp->tip >= bsp->mmcp->capacity)
    bsp->tip = 0; /* wrap ring buffer */

  bsp->used++;
  if (bsp->used >= bsp->mmcp->capacity)
    bsp->used = bsp->mmcp->capacity; /* clamp value */

  bsp->mtime = timestamp;
  return CH_SUCCESS;
}
Esempio n. 3
0
File: amsg.c Progetto: genua/anoubis
/**
 * Read an anoubis protocol message from a client connected to the session
 * engine. A client message on the wire consists of a 32 bit length in
 * network byte order followed by the actual message data. The length
 * given includes the 32 length itself and the 32 bit checksum at the
 * end of the message.
 *
 * @param fd The file descriptor to read from.
 * @param msgp A complete message (if any) is stored here. This value
 *     must never be NULL. The pointer pointed to by msgp is either set
 *     to NULL or is set to point to the result message. The result message
 *     is allocated using anoubis_msg_new and must be freed by the caller
 *     with anoubis_msg_free.
 * @return Zero if EOF is encountered. A negative error code if an error
 *     occured or a positive value in case of success.
 *     NOTE: Success does not mean that there is a complete message
 *     available. The message may still be incomplete. In this case
 *     NULL is stored in *msgp.
 */
int
get_client_msg(int fd, struct anoubis_msg **msgp)
{
	struct msg_buf		*mbp;
	u_int32_t		 len;
	struct anoubis_msg	*m;

	*msgp = NULL;
	if ((mbp = _get_mbp(fd)) == NULL)
		return 0;
	if (mbp->rmsg) {
		log_warnx("get_client_msg: Bad buffer state");
		return 0;
	}
	if ((unsigned int)(mbp->rtailp - mbp->rheadp) < sizeof(len))
		if (!_fill_buf(mbp))
			return 0;
	if ((unsigned int)(mbp->rtailp - mbp->rheadp) < sizeof(len))
		return 1;
	len = ntohl(*(u_int32_t*)mbp->rheadp);
	if ((unsigned int)(mbp->rtailp - mbp->rheadp) < len)
		if (!_fill_buf(mbp))
			return 0;
	if ((unsigned int)(mbp->rtailp - mbp->rheadp) < len)
		return 1;
	/*
	 * anoubis_msg_new expects the size of the message without
	 * the message length and without the trainling checksum (i.e.
	 * payload data only). However, m->length of the resulting
	 * message includes the checksum but not the message length.
	 * This is the reason for the somewhat surprising length calculations.
	 */
	m = anoubis_msg_new(len - sizeof(len) - CSUM_LEN);
	if (!m)
		return -ENOMEM;
	memcpy(m->u.buf, mbp->rheadp+sizeof(len), m->length);
	mbp->rheadp += len;
	*msgp = m;
	return 1;
}