Merge branch 'master' into read_batch_pdu2

This commit is contained in:
Ronnie Sahlberg
2017-01-07 08:42:12 -08:00
committed by GitHub
16 changed files with 834 additions and 94 deletions

View File

@@ -43,7 +43,7 @@
/* */
/*****************************************************************/
static unsigned long crctable[256] = {
uint32_t crctable[256] = {
0x00000000L, 0xF26B8303L, 0xE13B70F7L, 0x1350F3F4L,
0xC79A971FL, 0x35F1141CL, 0x26A1E7E8L, 0xD4CA64EBL,
0x8AD958CFL, 0x78B2DBCCL, 0x6BE22838L, 0x9989AB3BL,
@@ -110,9 +110,9 @@ static unsigned long crctable[256] = {
0xBE2DA0A5L, 0x4C4623A6L, 0x5F16D052L, 0xAD7D5351L
};
unsigned long crc32c(char *buf, int len)
uint32_t crc32c(uint8_t *buf, int len)
{
unsigned long crc = 0xffffffff;
uint32_t crc = 0xffffffff;
while (len-- > 0) {
crc = (crc>>8) ^ crctable[(crc ^ (*buf++)) & 0xFF];
}

View File

@@ -111,15 +111,22 @@ char* iscsi_strdup(struct iscsi_context *iscsi, const char* str) {
return str2;
}
void* iscsi_szmalloc(struct iscsi_context *iscsi, size_t size) {
void* iscsi_smalloc(struct iscsi_context *iscsi, size_t size) {
void *ptr;
if (size > iscsi->smalloc_size) return NULL;
if (iscsi->smalloc_free > 0) {
ptr = iscsi->smalloc_ptrs[--iscsi->smalloc_free];
memset(ptr, 0, iscsi->smalloc_size);
iscsi->smallocs++;
} else {
ptr = iscsi_zmalloc(iscsi, iscsi->smalloc_size);
ptr = iscsi_malloc(iscsi, iscsi->smalloc_size);
}
return ptr;
}
void* iscsi_szmalloc(struct iscsi_context *iscsi, size_t size) {
void *ptr = iscsi_smalloc(iscsi, size);
if (ptr) {
memset(ptr, 0, size);
}
return ptr;
}

View File

@@ -2611,6 +2611,52 @@ iscsi_report_supported_opcodes_task(struct iscsi_context *iscsi, int lun,
return task;
}
struct scsi_task *
iscsi_receive_copy_results_task(struct iscsi_context *iscsi, int lun,
int sa, int list_id, int alloc_len,
iscsi_command_cb cb, void *private_data)
{
struct scsi_task *task;
task = scsi_cdb_receive_copy_results(sa, list_id, alloc_len);
if (task == NULL) {
iscsi_set_error(iscsi, "Out-of-memory: Failed to create "
"RECEIVE COPY RESULTS cdb.");
return NULL;
}
if (iscsi_scsi_command_async(iscsi, lun, task, cb,
NULL, private_data) != 0) {
scsi_free_scsi_task(task);
return NULL;
}
return task;
}
struct scsi_task *
iscsi_extended_copy_task(struct iscsi_context *iscsi, int lun,
struct iscsi_data *param_data,
iscsi_command_cb cb, void *private_data)
{
struct scsi_task *task;
task = scsi_cdb_extended_copy(param_data->size);
if (task == NULL) {
iscsi_set_error(iscsi, "Out-of-memory: Failed to create "
"EXTENDED COPY cdb.");
return NULL;
}
if (iscsi_scsi_command_async(iscsi, lun, task, cb,
param_data, private_data) != 0) {
scsi_free_scsi_task(task);
return NULL;
}
return task;
}
struct scsi_task *
iscsi_scsi_get_task_from_pdu(struct iscsi_pdu *pdu)
{

View File

@@ -83,6 +83,10 @@ iscsi_release6_sync
iscsi_release6_task
iscsi_report_supported_opcodes_sync
iscsi_report_supported_opcodes_task
iscsi_extended_copy_sync
iscsi_extended_copy_task
iscsi_receive_copy_results_sync
iscsi_receive_copy_results_task
iscsi_reconnect
iscsi_sanitize_sync
iscsi_sanitize_task

View File

@@ -81,6 +81,10 @@ iscsi_release6_sync
iscsi_release6_task
iscsi_report_supported_opcodes_sync
iscsi_report_supported_opcodes_task
iscsi_extended_copy_sync
iscsi_extended_copy_task
iscsi_receive_copy_results_sync
iscsi_receive_copy_results_task
iscsi_reconnect
iscsi_sanitize_sync
iscsi_sanitize_task

View File

@@ -1217,6 +1217,8 @@ iscsi_process_login_reply(struct iscsi_context *iscsi, struct iscsi_pdu *pdu,
must_have_chap_r = 0;
}
ISCSI_LOG(iscsi, 6, "TargetLoginReply: %s", ptr);
ptr += len + 1;
size -= len + 1;
}

View File

@@ -36,6 +36,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <inttypes.h>
#include "iscsi.h"
#include "iscsi-private.h"
#include "scsi-lowlevel.h"
@@ -429,6 +430,20 @@ iscsi_process_pdu(struct iscsi_context *iscsi, struct iscsi_in_pdu *in)
uint8_t ahslen = in->hdr[4];
struct iscsi_pdu *pdu;
/* verify header checksum */
if (iscsi->header_digest != ISCSI_HEADER_DIGEST_NONE) {
uint32_t crc, crc_rcvd = 0;
crc = crc32c(in->hdr, ISCSI_RAW_HEADER_SIZE);
crc_rcvd |= in->hdr[ISCSI_RAW_HEADER_SIZE+0];
crc_rcvd |= in->hdr[ISCSI_RAW_HEADER_SIZE+1] << 8;
crc_rcvd |= in->hdr[ISCSI_RAW_HEADER_SIZE+2] << 16;
crc_rcvd |= in->hdr[ISCSI_RAW_HEADER_SIZE+3] << 24;
if (crc != crc_rcvd) {
iscsi_set_error(iscsi, "header checksum verification failed: calculated 0x%" PRIx32 " received 0x%" PRIx32, crc, crc_rcvd);
return -1;
}
}
if (ahslen != 0) {
iscsi_set_error(iscsi, "cant handle expanded headers yet");
return -1;

View File

@@ -366,6 +366,7 @@ iscsi_connect_async(struct iscsi_context *iscsi, const char *portal,
}
freeaddrinfo(ai);
strncpy(iscsi->connected_portal, portal, MAX_STRING_SIZE);
return 0;
}
@@ -669,6 +670,25 @@ iscsi_read_from_socket(struct iscsi_context *iscsi)
return 0;
}
static int iscsi_pdu_update_headerdigest(struct iscsi_context *iscsi, struct iscsi_pdu *pdu)
{
uint32_t crc;
if (pdu->outdata.size < ISCSI_RAW_HEADER_SIZE + ISCSI_DIGEST_SIZE) {
iscsi_set_error(iscsi, "PDU too small (%u) to contain header digest",
(unsigned int) pdu->outdata.size);
return -1;
}
crc = crc32c(pdu->outdata.data, ISCSI_RAW_HEADER_SIZE);
pdu->outdata.data[ISCSI_RAW_HEADER_SIZE+3] = (crc >> 24);
pdu->outdata.data[ISCSI_RAW_HEADER_SIZE+2] = (crc >> 16);
pdu->outdata.data[ISCSI_RAW_HEADER_SIZE+1] = (crc >> 8);
pdu->outdata.data[ISCSI_RAW_HEADER_SIZE+0] = (crc);
return 0;
}
static int
iscsi_write_to_socket(struct iscsi_context *iscsi)
{
@@ -718,7 +738,13 @@ iscsi_write_to_socket(struct iscsi_context *iscsi)
/* set exp statsn */
iscsi_pdu_set_expstatsn(iscsi->outqueue_current, iscsi->statsn + 1);
/* calculate header checksum */
if (iscsi->header_digest != ISCSI_HEADER_DIGEST_NONE &&
iscsi_pdu_update_headerdigest(iscsi, iscsi->outqueue_current) != 0) {
return -1;
}
ISCSI_LIST_REMOVE(&iscsi->outqueue, iscsi->outqueue_current);
if (!(iscsi->outqueue_current->flags & ISCSI_PDU_DELETE_WHEN_SENT)) {
/* we have to add the pdu to the waitqueue already here
@@ -948,23 +974,6 @@ static int iscsi_tcp_queue_pdu(struct iscsi_context *iscsi,
return -1;
}
if (iscsi->header_digest != ISCSI_HEADER_DIGEST_NONE) {
unsigned long crc;
if (pdu->outdata.size < ISCSI_RAW_HEADER_SIZE + 4) {
iscsi_set_error(iscsi, "PDU too small (%u) to contain header digest",
(unsigned int) pdu->outdata.size);
return -1;
}
crc = crc32c((char *)pdu->outdata.data, ISCSI_RAW_HEADER_SIZE);
pdu->outdata.data[ISCSI_RAW_HEADER_SIZE+3] = (crc >> 24)&0xff;
pdu->outdata.data[ISCSI_RAW_HEADER_SIZE+2] = (crc >> 16)&0xff;
pdu->outdata.data[ISCSI_RAW_HEADER_SIZE+1] = (crc >> 8)&0xff;
pdu->outdata.data[ISCSI_RAW_HEADER_SIZE+0] = (crc) &0xff;
}
iscsi_add_to_outqueue(iscsi, pdu);
return 0;
@@ -973,7 +982,7 @@ static int iscsi_tcp_queue_pdu(struct iscsi_context *iscsi,
void
iscsi_free_iscsi_in_pdu(struct iscsi_context *iscsi, struct iscsi_in_pdu *in)
{
iscsi_free(iscsi, in->hdr);
iscsi_sfree(iscsi, in->hdr);
iscsi_free(iscsi, in->data);
in->data=NULL;
iscsi_sfree(iscsi, in);

View File

@@ -1667,6 +1667,46 @@ iscsi_report_supported_opcodes_sync(struct iscsi_context *iscsi, int lun,
return state.task;
}
struct scsi_task *
iscsi_receive_copy_results_sync(struct iscsi_context *iscsi, int lun,
int sa, int list_id, int alloc_len)
{
struct iscsi_sync_state state;
memset(&state, 0, sizeof(state));
if (iscsi_receive_copy_results_task(iscsi, lun, sa, list_id, alloc_len,
scsi_sync_cb, &state) == NULL) {
iscsi_set_error(iscsi, "Failed to send RECEIVE COPY RESULTS"
" command");
return NULL;
}
event_loop(iscsi, &state);
return state.task;
}
struct scsi_task *
iscsi_extended_copy_sync(struct iscsi_context *iscsi, int lun,
struct iscsi_data *param_data)
{
struct iscsi_sync_state state;
memset(&state, 0, sizeof(state));
if (iscsi_extended_copy_task(iscsi, lun, param_data,
scsi_sync_cb, &state) == NULL) {
iscsi_set_error(iscsi, "Failed to send EXTENDED COPY"
" command");
return NULL;
}
event_loop(iscsi, &state);
return state.task;
}
struct scsi_task *
iscsi_scsi_command_sync(struct iscsi_context *iscsi, int lun,
struct scsi_task *task, struct iscsi_data *data)