Example #1
0
/* si_addrinfo_list_from_hostent
 * Returns an addrinfo list from IPv4 and IPv6 hostent entries
 */
si_list_t *
si_addrinfo_list_from_hostent(si_mod_t *si, uint32_t flags, uint32_t socktype, uint32_t proto, uint16_t port, uint16_t scope, const struct hostent *h4, const struct hostent *h6)
{
	int i;
	si_list_t *out = NULL;
	si_list_t *list;

	if ((h6 != NULL) && (h6->h_addr_list != NULL))
	{
		for (i = 0; h6->h_addr_list[i] != NULL; i++)
		{
			struct in6_addr a6;
			memcpy(&a6, h6->h_addr_list[i], h6->h_length);
			list = si_addrinfo_list(si, flags, socktype, proto, NULL, &a6, port, scope, NULL, h6->h_name);
			out = si_list_concat(out, list);
			si_list_release(list);
		}
	}

	if ((h4 != NULL) && (h4->h_addr_list != NULL))
	{
		for (i = 0; h4->h_addr_list[i] != NULL; i++)
		{
			struct in_addr a4;
			memcpy(&a4, h4->h_addr_list[i], h4->h_length);
			list = si_addrinfo_list(si, flags, socktype, proto, &a4, NULL, port, 0, h4->h_name, NULL);
			out = si_list_concat(out, list);
			si_list_release(list);
		}
	}

	return out;
}
static void
si_async_workunit_release(si_async_workunit_t *r)
{
	if (r == NULL) return;

	if (OSAtomicDecrement32Barrier(&(r->refcount)) != 0) return;

#ifdef CALL_TRACE
	fprintf(stderr, "** %s freeing worklist item %p\n", __func__, r);
#endif

	si_async_worklist_remove_unit(r);

	if (r->resitem != NULL) si_item_release(r->resitem);
	if (r->reslist != NULL) si_list_release(r->reslist);

	if (r->str1 != NULL) free(r->str1);
	if (r->str2 != NULL) free(r->str2);
	if (r->str3 != NULL) free(r->str3);

	/* release send-once right if it has not been used */
	if (r->send != MACH_PORT_NULL) mach_port_deallocate(mach_task_self(), r->send);

	/* release receive right */
	mach_port_mod_refs(mach_task_self(), r->port, MACH_PORT_RIGHT_RECEIVE, -1);

	free(r);
}
Example #3
0
static void
_LI_thread_info_free(void *x)
{
	li_thread_data_t *tdata;

	if (x == NULL) return;

	tdata = (li_thread_data_t *)x;
	si_item_release(tdata->thread_item);
	si_list_release(tdata->thread_list);

	free(tdata);
}
Example #4
0
void
LI_set_thread_list(uint32_t key, si_list_t *list)
{
	li_thread_data_t *tdata;

	tdata = LI_get_thread_info(key);
	if (tdata == NULL) return;

	si_list_release(tdata->thread_list);

	si_list_reset(list);
	tdata->thread_list = list;
}
Example #5
0
static si_list_t *
_gai_srv(si_mod_t *si, const char *node, const char *serv, uint32_t family, uint32_t socktype, uint32_t proto, uint32_t flags, const char *interface, uint32_t *err)
{
	int i;
	char *qname;
	si_srv_t *srv;
	si_item_t *item;

	si_list_t *list = NULL;
	si_list_t *result = NULL;

	/* Minimum SRV priority is zero. Start below that. */
	int lastprio = -1;
	int currprio;

	if (node == NULL || serv == NULL) return NULL;

	asprintf(&qname, "%s.%s", serv, node);
	list = si_srv_byname(si, qname, interface, err);
	free(qname);

	/* Iterate the SRV records starting at lowest priority and attempt to
	 * lookup the target host name. Returns the first successful lookup.
	 * It's an O(n^2) algorithm but data sets are small (less than 100) and
	 * sorting overhead is dwarfed by network I/O for each element.
	 */
	while (list != NULL && result == NULL)
	{
		/* Find the next lowest priority level. */
		/* Maximum SRV priority is UINT16_MAX. Start above that. */
		currprio = INT_MAX;

		for (i = 0; i < list->count; ++i)
		{
			item = list->entry[i];
			srv = (si_srv_t *)((uintptr_t)item + sizeof(si_item_t));

			if (srv->priority > lastprio && srv->priority < currprio)
			{
				currprio = srv->priority;
			}
		}

		if (currprio == INT_MAX)
		{
			/* All priorities have been evaluated. Done. */
			break;
		}
		else
		{
			lastprio = currprio;
		}

		/* Lookup hosts at the current priority level. Return first match. */
		for (i = 0; i < list->count; ++i)
		{
			item = list->entry[i];
			srv = (si_srv_t *)((uintptr_t)item + sizeof(si_item_t));

			if (srv->priority == currprio)
			{
				/* So that _gai_simple expects an integer service. */
				flags |= AI_NUMERICSERV;

				result = _gai_simple(si, srv->target, &srv->port, family, socktype, proto, flags, interface, err);
				if (result)
				{
					break;
				}
			}
		}
	}

	if (list != NULL)
	{
		si_list_release(list);
	}

	return result;
}
Example #6
0
si_list_t *
si_addrinfo_list(si_mod_t *si, uint32_t flags, int socktype, int proto, struct in_addr *a4, struct in6_addr *a6, int port, int scopeid, const char *cname4, const char *cname6)
{
	int do_map = 0;
	si_item_t *item = NULL;
	si_list_t *out4 = NULL, *out6 = NULL;

	if ((flags & AI_V4MAPPED) && ((flags & AI_ALL) || (a6 == NULL))) do_map = 1;

	if (a6 != NULL)
	{
		if ((proto == IPPROTO_UNSPEC) || (proto == IPPROTO_UDP))
		{
			item = si_addrinfo_v6(si, 0, SOCK_DGRAM, IPPROTO_UDP, port, a6, scopeid, cname6);
			out6 = si_list_add(out6, item);
			si_item_release(item);
		}

		if ((proto == IPPROTO_UNSPEC) || (proto == IPPROTO_TCP))
		{
			item = si_addrinfo_v6(si, 0, SOCK_STREAM, IPPROTO_TCP, port, a6, scopeid, cname6);
			out6 = si_list_add(out6, item);
			si_item_release(item);
		}

		if (proto == IPPROTO_ICMPV6)
		{
			item = si_addrinfo_v6(si, 0, SOCK_RAW, IPPROTO_ICMPV6, port, a6, scopeid, cname6);
			out6 = si_list_add(out6, item);
			si_item_release(item);
		}
	}

	if (a4 != NULL)
	{
		if ((proto == IPPROTO_UNSPEC) || (proto == IPPROTO_UDP))
		{
			if (do_map == 0)
			{
				item = si_addrinfo_v4(si, 0, SOCK_DGRAM, IPPROTO_UDP, port, a4, 0, cname4);
				out4 = si_list_add(out4, item);
			}
			else
			{
				item = si_addrinfo_v4_mapped(si, 0, SOCK_DGRAM, IPPROTO_UDP, port, a4, 0, cname4);
				out6 = si_list_add(out6, item);
			}

			si_item_release(item);
		}

		if ((proto == IPPROTO_UNSPEC) || (proto == IPPROTO_TCP))
		{
			if (do_map == 0)
			{
				item = si_addrinfo_v4(si, 0, SOCK_STREAM, IPPROTO_TCP, port, a4, 0, cname4);
				out4 = si_list_add(out4, item);
			}
			else
			{
				item = si_addrinfo_v4_mapped(si, 0, SOCK_STREAM, IPPROTO_TCP, port, a4, 0, cname4);
				out6 = si_list_add(out6, item);
			}

			si_item_release(item);
		}

		if (proto == IPPROTO_ICMP)
		{
			if (do_map == 0)
			{
				item = si_addrinfo_v4(si, 0, SOCK_RAW, IPPROTO_ICMP, port, a4, 0, cname4);
				out4 = si_list_add(out4, item);
			}
			else
			{
				item = si_addrinfo_v4_mapped(si, 0, SOCK_RAW, IPPROTO_ICMP, port, a4, 0, cname4);
				out6 = si_list_add(out6, item);
			}

			si_item_release(item);
		}
	}

	out6 = si_list_concat(out6, out4);
	si_list_release(out4);

	return out6;
}