Exemple #1
0
int
main(int argc, char **argv)
{
	const char	*opt_configfile = ISNS_DEFAULT_ISNSADM_CONFIG;
	isns_client_t	*clnt;
	isns_attr_list_t *attrs;
	isns_simple_t	*reg;
	isns_portal_info_t portal_info;
	uint32_t	status;
	int		opt_replace = 1;
	int		c, n, timeout;

	while ((c = getopt(argc, argv, "c:d:n")) != -1) {
		switch (c) {
		case 'c':
			opt_configfile = optarg;
			break;

		case 'd':
			isns_enable_debugging(optarg);
			break;

		case 'n':
			opt_replace = 0;
			break;

		default:
			isns_fatal("Unknown option\n");
		}
	}

	if (optind != argc - 1)
		isns_fatal("Need timeout argument\n");
	timeout = parse_timeout(argv[optind]);

	isns_read_config(opt_configfile);

	/*
	    ---DevAttrReg[REPLACE]---
	    Source:
	      0020  string      : iSCSI name = "iqn.2005-03.org.open-iscsi:blue"
	    Message attributes:
	      0001  string      : Entity identifier = "blue.pauw.homeunix.net"
	    Operating attributes:
	      0001  string      : Entity identifier = "blue.pauw.homeunix.net"
	      0002  uint32      : Entity protocol = iSCSI (2)
	      0010  ipaddr      : Portal IP address = 192.168.1.2
	      0011  uint32      : Portal TCP/UDP port = 33849/tcp
	      0014  uint32      : ESI port = 56288/tcp
	      0020  string      : iSCSI name = "iqn.2005-03.org.open-iscsi:blue"
	      0021  uint32      : iSCSI node type = Initiator
	      0022  string      : iSCSI alias = "blue.pauw.homeunix.net"

	      [...]
    	      response status 0x0003 (Invalid registration)

	   This would fail because we got confused about EID in
	   the replace case.
	 */
	isns_assign_string(&isns_config.ic_source_name,
			"iqn.2005-03.org.open-iscsi:blue");

	for (n = 0; n < 2; ++n) {
		clnt = isns_create_default_client(NULL);
		reg = isns_simple_create(ISNS_DEVICE_ATTRIBUTE_REGISTER,
				clnt->ic_source, NULL);
		reg->is_replace = opt_replace;

		/* Message attributes */
		attrs = &reg->is_message_attrs;
		STR(ENTITY_IDENTIFIER,	"blue.pauw.homeunix.net");

		/* Operating attributes */
		attrs = &reg->is_operating_attrs;

		STR(ENTITY_IDENTIFIER,	"blue.pauw.homeunix.net");
		U32(ENTITY_PROTOCOL,	2);

		isns_portal_parse(&portal_info, "192.168.1.2:33849/tcp", NULL);
		isns_portal_to_attr_list(&portal_info,
				ISNS_TAG_PORTAL_IP_ADDRESS,
				ISNS_TAG_PORTAL_TCP_UDP_PORT,
				attrs);

		U32(ESI_PORT,		56288);
		STR(ISCSI_NAME,		"iqn.2005-03.org.open-iscsi:blue");
		U32(ISCSI_NODE_TYPE,	ISNS_ISCSI_INITIATOR_MASK);
		STR(ISCSI_ALIAS,	"blue.pauw.homeunix.net");
		isns_simple_print(reg, isns_print_stdout);

		status = isns_client_call(clnt, &reg);

		if (status != ISNS_SUCCESS)
			isns_fatal("Unable to register object: %s\n",
					isns_strerror(status));

		printf("Successfully registered object\n");
		// isns_simple_print(reg, isns_print_stdout);
		isns_simple_free(reg);
		isns_client_destroy(clnt);

		if (n == 0) {
			printf("Sleeping for %d seconds\n", timeout);
			sleep(timeout);
		}
	}

	return 0;
}
Exemple #2
0
/*
 * Process an incoming message
 */
isns_message_t *
isns_process_message(isns_server_t *srv, isns_message_t *msg)
{
	struct isns_service_ops *ops = srv->is_ops;
	uint16_t	function = msg->im_header.i_function;
	int		status = ISNS_SUCCESS;
	isns_simple_t	*call = NULL, *reply = NULL;
	isns_message_t	*res_msg = NULL;
	isns_db_t	*db = srv->is_db;

	status = isns_simple_decode(msg, &call);
	if (status) {
		isns_debug_message("Failed to decode %s request: %s\n",
				isns_function_name(msg->im_header.i_function),
				isns_strerror(status));
		goto reply;
	}

	isns_simple_print(call, isns_debug_message);

	/* Set policy and privileges based on the
	 * sender's identity. */
	if (!(call->is_policy = isns_policy_bind(msg))) 
		goto err_unauthorized;

	if (!isns_policy_validate_function(call->is_policy, msg))
		goto err_unauthorized;

	/* Checks related to the message source.
	 * Note - some messages do not use a source.
	 */
	if (call->is_source) {
		/* Validate the message source. This checks whether the client
		 * is permitted to use this source node name.
		 * Beware - not all messages include a source.
		 */
		if (!isns_policy_validate_source(call->is_policy, call->is_source))
			goto err_unauthorized;

		/* This may fail if the source node isn't in the DB yet. */
		isns_source_set_node(call->is_source, db);

		/*
		 * 6.2.6.  Registration Period
		 *
		 * The registration SHALL be removed from the iSNS database
		 * if an iSNS Protocol message is not received from the
		 * iSNS client before the registration period has expired.
		 * Receipt of any iSNS Protocol message from the iSNS client
		 * automatically refreshes the Entity Registration Period and
		 * Entity Registration Timestamp.  To prevent a registration
		 * from expiring, the iSNS client should send an iSNS Protocol
		 * message to the iSNS server at intervals shorter than the
		 * registration period.  Such a message can be as simple as a
		 * query for one of its own attributes, using its associated
		 * iSCSI Name or FC Port Name WWPN as the Source attribute.
		 */
		/* Thusly, we update the timestamps of all entities
		 * registered by this source. */
		isns_entity_touch(call->is_source->is_entity);
	}

	/* Handle the requested function. If the function vector is
	 * NULL, silently discard the message. */
	switch (function) {
#define DO(rw, FUNCTION, __function) \
	case FUNCTION:						\
		if (!ops->__function)				\
			goto no_reply;				\
								\
		if (!isns_begin_##rw##_operation(srv, call, &status)) \
			break;					\
		status = ops->__function(srv, call, &reply);	\
		isns_end_##rw##_operation(srv, call, &status);	\
		break

	DO(write, ISNS_DEVICE_ATTRIBUTE_REGISTER, process_registration);
	DO(read,  ISNS_DEVICE_ATTRIBUTE_QUERY, process_query);
	DO(read,  ISNS_DEVICE_GET_NEXT, process_getnext);
	DO(write, ISNS_DEVICE_DEREGISTER, process_deregistration);
	DO(write, ISNS_DD_REGISTER, process_dd_registration);
	DO(write, ISNS_DD_DEREGISTER, process_dd_deregistration);
	DO(read,  ISNS_SCN_REGISTER, process_scn_registration);
	DO(read,  ISNS_SCN_DEREGISTER, process_scn_deregistration);
	DO(read,  ISNS_SCN_EVENT, process_scn_event);
	DO(read,  ISNS_STATE_CHANGE_NOTIFICATION, process_scn);
	DO(read,  ISNS_ENTITY_STATUS_INQUIRY, process_esi);
	DO(read,  ISNS_HEARTBEAT, process_heartbeat);
#undef DO

	default:
		isns_error("Function %s not supported\n",
				isns_function_name(function));
		status = ISNS_MESSAGE_NOT_SUPPORTED;
		break;
	}

reply:
	/* Commit any changes to the DB before we reply */
	if (db)
		isns_db_sync(db);

	/* Send out SCN notifications */
	isns_flush_events();

	if (reply != NULL) {
		reply->is_function |= 0x8000;
		isns_simple_print(reply, isns_debug_message);

		/* Encode the whole thing */
		status = isns_simple_encode_response(reply, msg, &res_msg);
	}

	/* No reply, or error when encoding it:
	 * just send the error, nothing else. */
	if (res_msg == NULL) {
		res_msg = isns_create_reply(msg);
		if (status == ISNS_SUCCESS)
			status = ISNS_INTERNAL_ERROR;
	}

	isns_debug_message("response status 0x%04x (%s)\n",
			status, isns_strerror(status));

	if (status != ISNS_SUCCESS)
		isns_message_set_error(res_msg, status);

no_reply:
	isns_simple_free(call);
	if (reply)
		isns_simple_free(reply);
	return res_msg;

err_unauthorized:
	status = ISNS_SOURCE_UNAUTHORIZED;
	goto reply;
}