summaryrefslogtreecommitdiff
path: root/utils/open-isns/message.c
diff options
context:
space:
mode:
authorMike Christie <michaelc@cs.wisc.edu>2015-08-24 20:31:06 -0500
committerMike Christie <michaelc@cs.wisc.edu>2015-08-24 20:31:06 -0500
commitc6d1117bb6fc85d505b815c23a0190376354c3f2 (patch)
tree8ed087d4b95ccb31c231c27fc0333d14a71ed207 /utils/open-isns/message.c
parent768326624de9be7229980ceb7a35943b6fba1a6b (diff)
downloadopen-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.c681
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;
-}