Example #1
0
void
pdu_send(struct pdu *pdu)
{
	struct connection *conn;
	ssize_t ret, total_len;
	size_t padding;
	uint32_t zero = 0;
	struct iovec iov[3];
	int iovcnt;

	conn = pdu->pdu_connection;
#ifdef ICL_KERNEL_PROXY
	if (conn->conn_conf.isc_iser != 0)
		return (pdu_send_proxy(pdu));
#endif

	assert(conn->conn_conf.isc_iser == 0);

	pdu_set_data_segment_length(pdu, pdu->pdu_data_len);
	iov[0].iov_base = pdu->pdu_bhs;
	iov[0].iov_len = sizeof(*pdu->pdu_bhs);
	total_len = iov[0].iov_len;
	iovcnt = 1;

	if (pdu->pdu_data_len > 0) {
		iov[1].iov_base = pdu->pdu_data;
		iov[1].iov_len = pdu->pdu_data_len;
		total_len += iov[1].iov_len;
		iovcnt = 2;

		padding = pdu_padding(pdu);
		if (padding > 0) {
			assert(padding < sizeof(zero));
			iov[2].iov_base = &zero;
			iov[2].iov_len = padding;
			total_len += iov[2].iov_len;
			iovcnt = 3;
		}
	}

	ret = writev(conn->conn_socket, iov, iovcnt);
	if (ret < 0) {
		if (timed_out())
			log_errx(1, "exiting due to timeout");
		log_err(1, "writev");
	}
	if (ret != total_len)
		log_errx(1, "short write");
}
Example #2
0
void
pdu_receive(struct pdu *pdu)
{
	size_t len, padding;
	char dummy[4];

#ifdef ICL_KERNEL_PROXY
	if (pdu->pdu_connection->conn_conf.isc_iser != 0)
		return (pdu_receive_proxy(pdu));
#endif

	assert(pdu->pdu_connection->conn_conf.isc_iser == 0);

	pdu_read(pdu->pdu_connection->conn_socket,
	    (char *)pdu->pdu_bhs, sizeof(*pdu->pdu_bhs));

	len = pdu_ahs_length(pdu);
	if (len > 0)
		log_errx(1, "protocol error: non-empty AHS");

	len = pdu_data_segment_length(pdu);
	if (len > 0) {
		if (len > ISCSI_MAX_DATA_SEGMENT_LENGTH) {
			log_errx(1, "protocol error: received PDU "
			    "with DataSegmentLength exceeding %d",
			    ISCSI_MAX_DATA_SEGMENT_LENGTH);
		}

		pdu->pdu_data_len = len;
		pdu->pdu_data = malloc(len);
		if (pdu->pdu_data == NULL)
			log_err(1, "malloc");

		pdu_read(pdu->pdu_connection->conn_socket,
		    (char *)pdu->pdu_data, pdu->pdu_data_len);

		padding = pdu_padding(pdu);
		if (padding != 0) {
			assert(padding < sizeof(dummy));
			pdu_read(pdu->pdu_connection->conn_socket,
			    (char *)dummy, padding);
		}
	}
}