コード例 #1
0
ファイル: scn.c プロジェクト: chris-se/open-isns
/*
 * Obtain a socket to talk to this guy.
 * Not entirely trivial - this can be both an established
 * (incoming) connection, or one that we should establish.
 *
 * Note, we do not support transmission on the incoming
 * connection yet.
 */
static isns_socket_t *
isns_scn_get_socket(isns_scn_t *scn)
{
	isns_scn_funnel_t *f, *best = NULL;
	isns_socket_t	*sock;
	unsigned int	worst = 0, loops = 0, nfunnels;

	/* Keep it simple for now */
	if ((f = scn->scn_current_funnel) != NULL && f->scn_socket) {
		if (!f->scn_bad)
			return f->scn_socket;
		/* Oops, we've seen timeouts on this socket. */
		isns_socket_free(f->scn_socket);
		f->scn_socket = NULL;
	}

again:
	nfunnels = 0;
	for (f = scn->scn_funnels; f; f = f->scn_next) {
		unsigned int	badness = f->scn_bad;

		if (!best || badness < best->scn_bad)
			best = f;
		if (badness > worst)
			worst = badness;
		nfunnels++;
	}

	if (!best)
		return NULL;

	sock = isns_connect_to_portal(&best->scn_portal);
	if (sock == NULL) {
		/* Make sure we try each funnel exactly once */
		best->scn_bad = worst + 1;
		if (++loops < nfunnels)
			goto again;
		return NULL;
	}

	/* Set the security context */
	isns_socket_set_security_ctx(sock,
			isns_default_security_context(1));

	isns_debug_scn("SCN: %s using portal %s\n",
			scn->scn_name,
			isns_portal_string(&best->scn_portal));
	scn->scn_current_funnel = best;
	best->scn_socket = sock;
	return sock;
}
コード例 #2
0
ファイル: sysdep-unix.c プロジェクト: MagicalTux/open-iscsi-1
int
isns_enumerate_portals(isns_portal_info_t *result, unsigned int max)
{
	char		buffer[8192], *end, *ptr;
	struct ifconf	ifc;
	unsigned int	nportals = 0;
	int		fd = -1;

	if ((fd = socket(PF_INET, SOCK_DGRAM, 0)) < 0) {
		isns_error("%s: no socket - %m\n", __FUNCTION__);
		return 0;
	}

	ifc.ifc_buf = buffer;
	ifc.ifc_len = sizeof(buffer);
	if (ioctl(fd, SIOCGIFCONF, &ifc) < 0) {
		isns_error("ioctl(SIOCGIFCONF): %m\n");
		goto out;
	}

	ptr = buffer;
	end = buffer + ifc.ifc_len;
	while (ptr < end) {
		struct ifreq	ifr;
		struct sockaddr_storage ifaddr;
		isns_portal_info_t portal;
		int		ifflags;

		memcpy(&ifr, ptr, sizeof(ifr));
		ptr += sizeof(ifr);

		/* Get the interface addr */
		memcpy(&ifaddr, &ifr.ifr_addr, sizeof(ifr.ifr_addr));

		if (ioctl(fd, SIOCGIFFLAGS, &ifr) < 0) {
			isns_error("ioctl(%s, SIOCGIFFLAGS): %m\n",
					ifr.ifr_name);
			continue;
		}
		ifflags = ifr.ifr_flags;

		if ((ifflags & IFF_UP) == 0)
			continue;
		if ((ifflags & IFF_LOOPBACK) != 0)
			continue;

		if (!isns_portal_from_sockaddr(&portal, &ifaddr))
			continue;

		isns_debug_socket("Got interface %u: %s %s\n",
				nportals, ifr.ifr_name,
				isns_portal_string(&portal));
		if (nportals < max)
			result[nportals++] = portal;
	}

out:
	if (fd >= 0)
		close(fd);
	return nportals;
}