diff options
author | Mike Christie <michaelc@cs.wisc.edu> | 2015-08-24 20:31:06 -0500 |
---|---|---|
committer | Mike Christie <michaelc@cs.wisc.edu> | 2015-08-24 20:31:06 -0500 |
commit | c6d1117bb6fc85d505b815c23a0190376354c3f2 (patch) | |
tree | 8ed087d4b95ccb31c231c27fc0333d14a71ed207 /utils/open-isns/message.c | |
parent | 768326624de9be7229980ceb7a35943b6fba1a6b (diff) | |
download | open-iscsi-c6d1117bb6fc85d505b815c23a0190376354c3f2.tar.gz |
iscsi: remove local copy of open-isns
This has open-iscsi stop shipping a copy of open-isns.
You can get the open-isns from the new isns maintainer, Lee Duncan,
from his github tree here:
https://github.com/gonzoleeman/open-isns/releases
Thanks to Lee and SUSE for taking this work on!
Diffstat (limited to 'utils/open-isns/message.c')
-rw-r--r-- | utils/open-isns/message.c | 681 |
1 files changed, 0 insertions, 681 deletions
diff --git a/utils/open-isns/message.c b/utils/open-isns/message.c deleted file mode 100644 index 4cd40c3..0000000 --- a/utils/open-isns/message.c +++ /dev/null @@ -1,681 +0,0 @@ -/* - * iSNS message handling functions - * - * Copyright (C) 2007 Olaf Kirch <olaf.kirch@oracle.com> - * - * - */ - -#include <stdlib.h> -#include <string.h> -#include <sys/time.h> /* for timercmp */ -#include <unistd.h> /* gethostname */ -#include <ctype.h> -#include "isns.h" -#include "attrs.h" -#include "message.h" -#include "socket.h" -#include "util.h" - -/* iSCSI qualified names include the year and - * month in which the domain was assigned. - * See RFC 3720, section 3.2.6.3.1. - * That's one of these wonderful committee - * type of ideas that makes it hard for everyone, - * from coder to sysadmin. - * Since we have no way of finding out here, - * we fake it by assigning a date before the - * dawn of time. - */ -#define DUMMY_IQN_PREFIX "iqn.1967-12." - -static uint32_t isns_xid = 1; - -/* - * Initialize a message object - */ -isns_message_t * -__isns_alloc_message(uint32_t xid, size_t size, void (*destroy)(isns_message_t *)) -{ - isns_message_t *msg; - - isns_assert(size >= sizeof(*msg)); - msg = isns_calloc(1, size); - - isns_list_init(&msg->im_list); - msg->im_users = 1; - msg->im_xid = xid; - msg->im_destroy = destroy; - - return msg; -} - -static int -__isns_message_init(isns_message_t *msg, - uint16_t function, uint16_t flags, - size_t payload_len) -{ - struct isns_hdr *hdr = &msg->im_header; - - /* Pad to multiple of 4 octets */ - payload_len = (payload_len + 3) & ~3UL; - - /* For now, we don't do segmentation */ - if (payload_len > ISNS_MAX_PDU_SIZE) - return 0; - - /* msg->im_header is in host byte order */ - hdr->i_version = ISNS_VERSION; - hdr->i_function = function; - hdr->i_flags = flags; - hdr->i_length = payload_len; - hdr->i_xid = msg->im_xid; - hdr->i_seq = 0; - - /* Allocate buffer and reserve room for header */ - msg->im_payload = buf_alloc(sizeof(*hdr) + payload_len); - buf_push(msg->im_payload, sizeof(*hdr)); - - return 1; -} - -/* - * Allocate a message object. - */ -static isns_message_t * -__isns_create_message(uint32_t xid, uint16_t function, uint16_t flags) -{ - isns_message_t *msg; - - msg = __isns_alloc_message(xid, sizeof(*msg), NULL); - __isns_message_init(msg, function, flags, ISNS_MAX_MESSAGE); - - return msg; -} - -/* - * Allocate a request message - */ -isns_message_t * -isns_create_message(uint16_t function, uint16_t flags) -{ - return __isns_create_message(isns_xid++, function, flags); -} - -/* - * Allocate a response message - */ -isns_message_t * -isns_create_reply(const isns_message_t *msg) -{ - uint16_t function = msg->im_header.i_function;; - isns_message_t *resp; - - resp = __isns_create_message(msg->im_xid, function | 0x8000, ISNS_F_SERVER); - resp->im_addr = msg->im_addr; - resp->im_addrlen = msg->im_addrlen; - - /* Default to ISNS_SUCCESS */ - buf_put32(resp->im_payload, ISNS_SUCCESS); - - return resp; -} - -/* - * Delete a message - */ -void -isns_message_release(isns_message_t *msg) -{ - if (msg == NULL) - return; - - isns_assert(msg->im_users); - if (--(msg->im_users)) - return; - - if (msg->im_destroy) - msg->im_destroy(msg); - if (msg->im_payload) - buf_free(msg->im_payload); - isns_principal_free(msg->im_security); - - isns_list_del(&msg->im_list); - isns_free(msg); -} - -/* - * Extract the status from a reply message - */ -int -isns_message_status(isns_message_t *msg) -{ - uint32_t status; - - if (!(msg->im_header.i_function & 0x8000) - || !buf_get32(msg->im_payload, &status)) - return ISNS_MESSAGE_FORMAT_ERROR; - return status; -} - -/* - * Obtain the socket on which the message was received. - */ -isns_socket_t * -isns_message_socket(const isns_message_t *msg) -{ - return msg->im_socket; -} - -/* - * Obtain the message's security context - */ -isns_security_t * -isns_message_security(const isns_message_t *msg) -{ - if (!msg->im_socket) - return NULL; - return msg->im_socket->is_security; -} - -unsigned int -isns_message_function(const isns_message_t *msg) -{ - return msg->im_header.i_function; -} - -/* - * Reset the response message, and encode isns_error - * status - */ -void -isns_message_set_error(isns_message_t *msg, uint32_t status) -{ - /* Clear the buffer. This just resets head + tail */ - buf_clear(msg->im_payload); - - /* Now move past the header, and overwrite the - * status word. */ - buf_push(msg->im_payload, sizeof(struct isns_hdr)); - buf_put32(msg->im_payload, status); -} - -/* - * Message queue handling. Most related functions are - * in message.h - */ -void -isns_message_queue_move(isns_message_queue_t *dstq, - isns_message_t *msg) -{ - unsigned int src_ref = 0; - - /* If the message was on a different queue, - * the source queue will hold a reference - * to it. Account for that and fix up the - * refcount after we've appended it to the - * destination queue. */ - if (isns_message_unlink(msg)) - src_ref = 1; - - isns_message_queue_append(dstq, msg); - msg->im_users -= src_ref; -} - -/* - * Insert a messsage into a queue sorted by resend timeout - */ -void -isns_message_queue_insert_sorted(isns_message_queue_t *q, - int sort, isns_message_t *msg) -{ - isns_list_t *pos; - isns_message_t *__m; - - isns_assert(msg->im_queue == NULL); - if (sort == ISNS_MQ_SORT_RESEND_TIMEOUT) { - isns_message_queue_foreach(q, pos, __m) { - if (timercmp(&msg->im_resend_timeout, - &__m->im_resend_timeout, <)) - break; - } - } else { - isns_message_queue_append(q, msg); - return; - } - - /* Insert before pos */ - __isns_list_insert(pos->prev, &msg->im_list, pos); - q->imq_count++; - - msg->im_queue = q; - msg->im_users++; -} - -/* - * Message queue handling - */ -void -isns_message_queue_destroy(isns_message_queue_t *q) -{ - isns_message_t *msg; - - while ((msg = isns_message_dequeue(q)) != NULL) - isns_message_release(msg); -} - -/* - * Find a message with matching xid and address. - * (address, alen) may be NULL. - */ -isns_message_t * -isns_message_queue_find(isns_message_queue_t *q, uint32_t xid, - const struct sockaddr_storage *addr, socklen_t alen) -{ - isns_message_t *msg; - isns_list_t *pos; - - isns_message_queue_foreach(q, pos, msg) { - if (msg->im_xid != xid) - continue; - if (alen == 0) - return msg; - - if (msg->im_addrlen == alen - && !memcmp(&msg->im_addr, addr, alen)) - return msg; - } - - return NULL; -} - -/* - * Convert a hostname into an iSCSI qualified name - * We omit the dismbiguating YYYY-MM infix because - * we have no way of finding out, short of bothering - * whois. - */ -static char * -__revert_fqdn(const char *prefix, const char *__fqdn, const char *suffix) -{ - static char namebuf[1024] = { '\0' }; - char *fqdn, *result = NULL; - int pos, count = 0; - - if (prefix) - strcpy(namebuf, prefix); - pos = strlen(namebuf); - - fqdn = isns_strdup(__fqdn); - while (1) { - char *dot, *comp; - int comp_len; - - if ((dot = strrchr(fqdn, '.')) != NULL) { - *dot++ = '\0'; - comp = dot; - } else { - comp = fqdn; - } - - if (*comp == '\0') - continue; - comp_len = strlen(comp); - if (pos + comp_len + 2 > sizeof(namebuf)) { - isns_error("%s: FQDN too long\n", __FUNCTION__); - goto out; - } - if (count++) - namebuf[pos++] = '.'; - strcpy(namebuf + pos, comp); - pos += comp_len; - - if (dot == NULL) - break; - } - - if (suffix) { - int sfx_len = strlen(suffix); - - if (pos + sfx_len + 2 > sizeof(namebuf)) { - isns_error("%s: name too long\n", __FUNCTION__); - goto out; - } - namebuf[pos++] = ':'; - strcpy(namebuf + pos, suffix); - pos += sfx_len; - } - - result = isns_strdup(namebuf); - -out: isns_free(fqdn); - return result; -} - -/* - * Initialize all names - */ -int -isns_init_names(void) -{ - if (isns_config.ic_host_name == NULL) { - char namebuf[1024], *fqdn; - - if (gethostname(namebuf, sizeof(namebuf)) < 0) { - isns_error("gehostname: %m\n"); - return 0; - } - fqdn = isns_get_canon_name(namebuf); - if (fqdn == NULL) { - /* FIXME: we could get some unique value here - * such as the IP address, and concat that - * with iqn.2005-01.org.open-iscsi.ip for the - * source name. - */ - isns_error("Unable to get fully qualified hostname\n"); - return 0; - } - isns_config.ic_host_name = fqdn; - } - - if (isns_config.ic_auth_name == NULL) { - isns_config.ic_auth_name = isns_config.ic_host_name; - } - - if (isns_config.ic_entity_name == NULL) { - isns_config.ic_entity_name = isns_config.ic_auth_name; - } - - if (isns_config.ic_source_name == NULL) { - isns_config.ic_source_name = __revert_fqdn(DUMMY_IQN_PREFIX, - isns_config.ic_host_name, - isns_config.ic_source_suffix); - if (isns_config.ic_source_name == NULL) { - isns_error("Unable to build source name\n"); - return 0; - } - } - - return 1; -} - -/* - * Match a source name to a pattern (which is really just - * the entity identifier, usually). - * - * If the pattern is of the form "match:rev-fqdn", the - * source name must match - * iqn.[YYYY-MM.]<rev-fqdn> - * optionally followed by dot, colon or hyphen and arbitrary - * text. - * - * If the pattern does not start with "match:", the source name - * must match the pattern literally (case insensitively). - */ -int -isns_source_pattern_match(const char *pattern, const char *source) -{ - unsigned int rev_len; - - isns_debug_message("%s(%s, %s)\n", - __FUNCTION__, pattern, source); - - if (!strcmp(pattern, "*")) - return 1; - - if (strncmp(pattern, "match:", 6)) - return !strcasecmp(pattern, source); - pattern += 6; - - if (strncasecmp(source, "iqn.", 4)) - return 0; - source += 4; - - rev_len = strlen(pattern); - if (strncasecmp(source, pattern, rev_len)) { - /* See if the next component is YYYY-MM */ - if (!(isdigit(source[0]) - && isdigit(source[1]) - && isdigit(source[2]) - && isdigit(source[3]) - && source[4] == '-' - && isdigit(source[5]) - && isdigit(source[6]) - && source[7] == '.')) - return 0; - source += 8; - - if (strncasecmp(source, pattern, rev_len)) - return 0; - } - - source += rev_len; - if (source[0] != '.' - && source[0] != ':' - && source[0] != '-' - && source[0] != '\0') - return 0; - - return 1; -} - -/* - * This really just reverts the FQDN so it can - * be used in isns_source_entity_match - */ -char * -isns_build_source_pattern(const char *fqdn) -{ - return __revert_fqdn("match:", fqdn, NULL); -} - -/* - * Manage source objects - */ -static isns_source_t * -__isns_source_create(isns_attr_t *name_attr) -{ - isns_source_t *source = isns_calloc(1, sizeof(*source)); - - source->is_users = 1; - source->is_attr = name_attr; - return source; -} - -isns_source_t * -isns_source_create(isns_attr_t *name_attr) -{ - if (name_attr->ia_tag_id != ISNS_TAG_ISCSI_NAME - && name_attr->ia_tag_id != ISNS_TAG_FC_PORT_NAME_WWPN) - return NULL; - - name_attr->ia_users++; - return __isns_source_create(name_attr); -} - -isns_source_t * -isns_source_from_object(const isns_object_t *node) -{ - isns_attr_t *attr; - - if (!(attr = isns_storage_node_key_attr(node))) - return NULL; - return isns_source_create(attr); -} - -isns_source_t * -isns_source_create_iscsi(const char *name) -{ - isns_value_t var = ISNS_VALUE_INIT(string, (char *) name); - isns_attr_t *attr; - - attr = isns_attr_alloc(ISNS_TAG_ISCSI_NAME, NULL, &var); - return __isns_source_create(attr); -} - -/* - * This is used to attach a dummy source to iSNS responses - * until I fixed up all the code that relies on msg->is_source - * to be valid all the time. - */ -isns_source_t * -isns_source_dummy(void) -{ - static isns_source_t *dummy = NULL; - - if (!dummy) - dummy = isns_source_create_iscsi(".dummy."); - return isns_source_get(dummy); -} - -uint32_t -isns_source_type(const isns_source_t *source) -{ - return source->is_attr->ia_tag_id; -} - -const char * -isns_source_name(const isns_source_t *source) -{ - return source->is_attr->ia_value.iv_string; -} - -isns_attr_t * -isns_source_attr(const isns_source_t *source) -{ - return source->is_attr; -} - -/* - * Obtain an additional reference on the source object - */ -isns_source_t * -isns_source_get(isns_source_t *source) -{ - if (source) - source->is_users++; - return source; -} - -/* - * Look up the node corresponding to this source name - * When we get here, we have already verified that the - * client is permitted (by policy) to use this source node. - */ -int -isns_source_set_node(isns_source_t *source, isns_db_t *db) -{ - isns_object_t *node, *entity; - uint32_t node_type; - - if (source->is_node) - return 1; - - if (db == NULL) - return 0; - - node = isns_db_lookup_source_node(db, source); - if (node == NULL) - return 0; - - if (!isns_object_get_uint32(node, ISNS_TAG_ISCSI_NODE_TYPE, &node_type)) - node_type = 0; - - source->is_node = node; - source->is_node_type = node_type; - - if ((entity = isns_object_get_entity(node)) != NULL) - source->is_entity = isns_object_get(entity); - return 1; -} - -void -isns_source_set_entity(isns_source_t *source, isns_object_t *obj) -{ - if (obj) - isns_object_get(obj); - isns_object_release(source->is_entity); - source->is_entity = obj; -} - -/* - * Release a reference on the source object - */ -void -isns_source_release(isns_source_t *source) -{ - if (source && --source->is_users == 0) { - isns_attr_release(source->is_attr); - isns_object_release(source->is_node); - isns_object_release(source->is_entity); - memset(source, 0xa5, sizeof(*source)); - isns_free(source); - } -} - -/* - * Compare two source objects - */ -int -isns_source_match(const isns_source_t *a, - const isns_source_t *b) -{ - if (a && b) - return isns_attr_match(a->is_attr, b->is_attr); - return 0; -} - -/* - * Encode/decode source object - */ -int -isns_source_encode(buf_t *bp, const isns_source_t *source) -{ - if (source == NULL) { - isns_attr_t nil = ISNS_ATTR_INIT(ISNS_TAG_DELIMITER, nil, 0); - - return isns_attr_encode(bp, &nil); - } - return isns_attr_encode(bp, source->is_attr); -} - -int -isns_source_decode(buf_t *bp, isns_source_t **result) -{ - isns_attr_t *attr; - int status; - - status = isns_attr_decode(bp, &attr); - if (status == ISNS_SUCCESS) { - /* - * 5.6.1 - * The Source Attribute uniquely identifies the source of the - * message. Valid Source Attribute types are shown below. - * - * Valid Source Attributes - * ----------------------- - * iSCSI Name - * FC Port Name WWPN - */ - switch (attr->ia_tag_id) { -#if 0 - case ISNS_TAG_DELIMITER: - *result = NULL; - break; -#endif - - case ISNS_TAG_ISCSI_NAME: - *result = __isns_source_create(attr); - break; - - case ISNS_TAG_FC_PORT_NAME_WWPN: - *result = __isns_source_create(attr); - break; - - default: - isns_attr_release(attr); - return ISNS_SOURCE_UNKNOWN; - } - } - return status; -} |