/* Copyright (c) 2015 Google, Inc.
 * Barret Rhoden <brho@cs.berkeley.edu>
 * See LICENSE for details.
 *
 * getaddrinfo/freeaddrinfo.
 *
 * Supports IPv4, TCP, UDP, and maybe a couple protocols/socktypes.
 *
 * Doesn't handle service resolution yet, and only returns one addrinfo.
 */

#include <netdb.h>
#include <malloc.h>
#include <string.h>
#include <stdlib.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <unistd.h>

/* Helper, given the serv string, figures out the port and protocol.  Returns 0
 * on success or an EAI_ error. */
static int serv_get_portprotocol(const char *serv, unsigned long *port_ret,
                                 int *protocol_ret, struct addrinfo *hints)
{
	char *strtoul_end = 0;
	unsigned long port = 0;	/* uninitialized, up to the main caller */
	int protocol = 0;		/* any protocol, will assume TCP and UDP later */
	if (serv) {
		if (serv[0] == '\0')
			return EAI_NONAME;
		port = strtoul(serv, &strtoul_end, 0);
		/* Already checked that serv != \0 */
		if (*strtoul_end != '\0') {
			if (hints->ai_flags & AI_NUMERICSERV)
				return EAI_NONAME;
			/* CS lookup */
			/* TODO: get a port, maybe a protocol.  If we have a restriction on
			 * the protocol from hints, check that here.  Probably need to
			 * rework this a bit if we have multiple protocols. */
			return EAI_NONAME;
		}
	}
	*port_ret = port;
	*protocol_ret = protocol;
	return 0;
}

/* Helper: fills in all of the addr related info in ai for an ipv4 addr/port.
 * addr is in network order.  port is in host order. */
static void addrinfo_filladdr_ipv4(struct addrinfo *ai, in_addr_t addr,
                                   uint16_t port)
{
	struct sockaddr_in *sa_in4 = (struct sockaddr_in*)ai->ai_addr;
	ai->ai_family = AF_INET;
	ai->ai_addrlen = sizeof(struct sockaddr_in);
	sa_in4->sin_family = AF_INET;
	sa_in4->sin_addr.s_addr = addr;
	sa_in4->sin_port = htons(port);
}

static int resolve_name_to_ipv4(const char *name, struct in_addr *hostaddr)
{
	struct hostent host, *result;
	char buf[1024];
	int _herrno;
	int ret;
	ret = gethostbyname2_r(name, AF_INET, &host, buf, sizeof(buf),
	                       &result, &_herrno);
	/* TODO: deal with the herrno errors and errno errors. */
	if (ret)
		return -1;
	assert(result == &host);
	memcpy(hostaddr, host.h_addr_list[0], host.h_length);
	return 0;
}

/* Given the node string, fills in the addr related info in ai: the ai_family,
 * ai_addr, and ai_addrlen.  The ai_addr needs the port too, though that's a big
 * ugly.  We only support ipv4, so there's just one of these.  Returns 0 on
 * success, EAI_ error o/w. */
static int node_fill_addrinfo(const char *node, struct addrinfo *ai,
                              uint16_t port, struct addrinfo *hints)
{
	struct in_addr local_addr;
	if (!node) {
		/* AI_PASSIVE only matters with no node name */
		if (hints->ai_flags & AI_PASSIVE) {
			/* Caller wants to bind */
			addrinfo_filladdr_ipv4(ai, INADDR_ANY, port);
		} else {
			/* Caller wants to send from localhost */
			addrinfo_filladdr_ipv4(ai, INADDR_LOOPBACK, port);
		}
	} else {
		if (inet_pton(AF_INET, node, &local_addr) == 1) {
			addrinfo_filladdr_ipv4(ai, local_addr.s_addr, port);
		} else {
			if (hints->ai_flags & AI_NUMERICHOST)
				return EAI_NONAME;
			if (resolve_name_to_ipv4(node, &local_addr))
				return EAI_FAIL;
			addrinfo_filladdr_ipv4(ai, local_addr.s_addr, port);
		}
	}
	return 0;
}

static int proto_to_socktype(int protocol)
{
	switch (protocol) {
		case IPPROTO_IP:
		case IPPROTO_TCP:
			return SOCK_STREAM;
		case IPPROTO_ICMP:
		case IPPROTO_UDP:
			return SOCK_DGRAM;
		case IPPROTO_RAW:
			return SOCK_RAW;
	}
	return -1;
}

static int socktype_to_proto(int socktype)
{
	switch (socktype) {
		case SOCK_STREAM:
			return IPPROTO_TCP;
		case SOCK_DGRAM:
			return IPPROTO_UDP;
		case SOCK_RAW:
			return IPPROTO_RAW;
	}
	return -1;
}

int getaddrinfo(const char *node, const char *serv,
                const struct addrinfo *hints, struct addrinfo **res)
{
	struct addrinfo *ai;
	struct addrinfo local_hints;

	local_hints.ai_socktype = 0;
	local_hints.ai_protocol = 0;
	local_hints.ai_family = AF_UNSPEC;
	local_hints.ai_flags = AI_V4MAPPED | AI_ADDRCONFIG;

	unsigned long port = 0;	/* AF agnostic, hope a long is enough */
	int protocol = 0;
	int ret;

	if (hints)
		local_hints = *hints;

	if (!node && !serv)
		return EAI_NONAME;

	/* Only support IPv4 for now */
	if ((local_hints.ai_family != AF_UNSPEC) &&
	    (local_hints.ai_family != AF_INET))
		return EAI_FAMILY;

	ai = malloc(sizeof(struct addrinfo));
	memset(ai, 0, sizeof(struct addrinfo));
	ai->ai_addr = malloc(sizeof(struct sockaddr_storage));
	memset(ai->ai_addr, 0, sizeof(struct sockaddr_storage));

	/* Only supporting TCP and UDP for now.  If protocol is 0, later we'll make
	 * addrinfos for both (TODO).  Likewise, we only support DGRAM or STREAM for
	 * socktype. */
	if ((ret = serv_get_portprotocol(serv, &port, &protocol, &local_hints))) {
		freeaddrinfo(ai);
		return ret;
	}
	if ((ret = node_fill_addrinfo(node, ai, port, &local_hints))) {
		freeaddrinfo(ai);
		return ret;
	}
	/* We have a mostly full addrinfo.  Still missing ai_protocol, socktype,
	 * flags (already 0) and canonname (already 0).
	 *
	 * We might have restrictions on our protocol from the hints or from what
	 * serv specifies.  If we don't have a protocol yet (== 0), that means we
	 * have no restrictions from serv. */
	if (local_hints.ai_protocol) {
		if (protocol && protocol != local_hints.ai_protocol) {
			/* requested protocol wasn't available */
			freeaddrinfo(ai);
			return EAI_SERVICE;
		}
		ai->ai_protocol = local_hints.ai_protocol;
	} else if (protocol) {
		ai->ai_protocol = protocol;
	} else if (local_hints.ai_socktype) {
		ai->ai_protocol = socktype_to_proto(local_hints.ai_socktype);
	} else {
		/* no serv restrictions, no preferences */
		ai->ai_protocol = IPPROTO_TCP;
		/* TODO: consider building a second addrinfo for UDP.  while you're at
		 * it, support IPv6 and a bunch of other options! */
	}
	if (ai->ai_protocol == -1) {
		freeaddrinfo(ai);
		return EAI_SERVICE;
	}
	ai->ai_socktype = proto_to_socktype(ai->ai_protocol);
	if (local_hints.ai_socktype &&
	    (local_hints.ai_socktype != ai->ai_socktype)) {
		/* they requested a socktype, but we can't handle it */
		freeaddrinfo(ai);
		return EAI_SOCKTYPE;
	}
	/* TODO: support AI_CANONNAME, only in the first ai */
	*res = ai;
	return 0;
}
libc_hidden_def(getaddrinfo)

void freeaddrinfo(struct addrinfo *ai)
{
	struct addrinfo *next;
	if (!ai)
		return;
	free(ai->ai_addr);
	free(ai->ai_canonname);
	next = ai->ai_next;
	free(ai);
	freeaddrinfo(next);
}
libc_hidden_def(freeaddrinfo)
