Esempio n. 1
0
int rd_kafka_sasl_io_event (rd_kafka_transport_t *rktrans, int events,
			    char *errstr, int errstr_size) {

	if (events & POLLIN) {
		rd_kafka_buf_t *rkbuf;
		int r;
		
		r = rd_kafka_transport_framed_recvmsg(rktrans, &rkbuf,
						      errstr, errstr_size);
		if (r == -1)
			return -1;
		else if (r == 0)
			return 0;

		return rd_kafka_sasl_handle_recv(rktrans, rkbuf,
						 errstr, errstr_size);
	}

	return 0;
}
Esempio n. 2
0
/**
 * Length framed receive handling.
 * Currently only supports a the following framing:
 *     [int32_t:big_endian_length_of_payload][payload]
 *
 * To be used on POLLIN event, will return:
 *   -1: on fatal error (errstr will be updated, *rkbufp remains unset)
 *    0: still waiting for data (*rkbufp remains unset)
 *    1: data complete, (buffer returned in *rkbufp)
 */
int rd_kafka_transport_framed_recvmsg (rd_kafka_transport_t *rktrans,
				       rd_kafka_buf_t **rkbufp,
				       char *errstr, size_t errstr_size) {
	rd_kafka_buf_t *rkbuf = rktrans->rktrans_recv_buf;
	ssize_t r;
	const int log_decode_errors = 0;

	/* States:
	 *   !rktrans_recv_buf: initial state; set up buf to receive header.
	 *    rkbuf_len == 0:   awaiting header
	 *    rkbuf_len > 0:    awaiting payload
	 */

	if (!rkbuf) {
		rkbuf = rd_kafka_buf_new(NULL, 1, 4);
		/* Point read buffer to main buffer. */
		rkbuf->rkbuf_rbuf = rkbuf->rkbuf_buf;
		rd_kafka_buf_push(rkbuf, rkbuf->rkbuf_buf, 4);

		rktrans->rktrans_recv_buf = rkbuf;
	}


	r = rd_kafka_transport_recvmsg(rktrans, &rkbuf->rkbuf_msg,
				       errstr, errstr_size);
	if (r == 0)
		return 0;
	else if (r == -1)
		return -1;

	rkbuf->rkbuf_wof += r;

	if (rkbuf->rkbuf_len == 0) {
		/* Frame length not known yet. */
		int32_t frame_len;

		if (rkbuf->rkbuf_wof < sizeof(frame_len)) {
			/* Wait for entire frame header. */
			return 0;
		}

		/* Reader header: payload length */
		rd_kafka_buf_read_i32(rkbuf, &frame_len);

		if (frame_len < 0 ||
		    frame_len > rktrans->rktrans_rkb->
		    rkb_rk->rk_conf.recv_max_msg_size) {
			rd_snprintf(errstr, errstr_size,
				    "Invalid frame size %"PRId32, frame_len);
			return -1;
		}

		rkbuf->rkbuf_len = frame_len;
		if (frame_len == 0) {
			/* Payload is empty, we're done. */
			rktrans->rktrans_recv_buf = NULL;
			*rkbufp = rkbuf;
			return 1;
		}

		/* Allocate memory to hold entire frame payload in contigious
		 * memory. */
		rd_kafka_buf_alloc_recvbuf(rkbuf, frame_len);

		/* Try reading directly, there is probably more data available*/
		return rd_kafka_transport_framed_recvmsg(rktrans, rkbufp,
							 errstr, errstr_size);
	}

	if (rkbuf->rkbuf_wof == rkbuf->rkbuf_len) {
		/* Payload is complete. */
		rktrans->rktrans_recv_buf = NULL;
		*rkbufp = rkbuf;
		return 1;
	}

	/* Wait for more data */
	return 0;

 err:
	if (rkbuf)
		rd_kafka_buf_destroy(rkbuf);
	rd_snprintf(errstr, errstr_size, "Frame header parsing failed");
	return -1;
}