/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 * 
 *   http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

/*-------------------------------------------------------------------------
 *
 * netcheck.c
 *	  Implementation of network checking utilities
 *
 *-------------------------------------------------------------------------
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <netdb.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <net/if.h>
#include <net/route.h>
#include <netinet/in.h>
#include <sys/ioctl.h>
#include <sys/socket.h>

#include "postgres.h"
#include "utils/netcheck.h"
#include "utils/simex.h"
#include "utils/timestamp.h"

#if defined(__darwin__) || defined(sun)
#include <sys/sockio.h>
#endif /* defined(__darwin__) || defined(sun) */

/*
 * ifaddrs.h is not present in Solaris;
 * need to provide partial implementation
 */
#if defined(__darwin__) || defined(__linux__)
#define HAVE_IFADDRS	1
#endif /* defined(__darwin__) || defined(linux) */

#ifdef HAVE_IFADDRS
#include <ifaddrs.h>
#endif /* HAVE_IFADDRS */


/*
 * CONSTANTS
 */

#define NET_RETRIES             (5)
#define IF_CONFIG_BUFFER_SIZE   (32 * 1024)


/*
 * STRUCTS
 */

#ifndef HAVE_IFADDRS

struct ifaddrs
{
	struct ifaddrs *ifa_next;
	char ifa_name[32];
	uint64_t ifa_flags;
	struct sockaddr	*ifa_addr;
	struct sockaddr	*ifa_netmask;
	union
	{
		struct sockaddr ifa_addr_alloc;
		struct sockaddr_in ifa_addr_v4;
		struct sockaddr_in6 ifa_addr_v6;
	};
	union
	{
		struct sockaddr ifa_netmask_alloc;
		struct sockaddr_in ifa_netmask_v4;
		struct sockaddr_in6 ifa_netmask_v6;
	};
};

#endif /* HAVE_IFADDRS */


/*
 * STATIC VARIABLES
 */

/* flag indicating if NIC is running */
static bool running = false;

/* host name to be matched to NIC */
static const char *hostTarget = NULL;

/* IPv4 and IPv6 addresses for host */
static struct sockaddr_in hostAddrV4;
static struct sockaddr_in6 hostAddrV6;

/* list of interface address descriptors */
static struct ifaddrs *ifAddresses;


#ifndef HAVE_IFADDRS

/* socket used for retrieving NIC state */
static int sock = -1;

/* interface configuration */
static struct ifconf ifconfig;

/* buffers used for storing configuration */
static char ifBuffer[IF_CONFIG_BUFFER_SIZE];
static char ifaBuffer[IF_CONFIG_BUFFER_SIZE];

/* iterator for interface address descriptors */
static struct ifaddrs *ifAddrIter;

#endif /* HAVE_IFADDRS */


/*
 * FUNCTION PROTOTYPES
 */

static void Init(const char *hostname);
static bool GetHost(void);
static bool GetIfAddresses(void);
static bool CompareIP(char *ipaddr1, char *ipaddr2, char *mask, int length);
static bool CheckRunning(void);
static void FindMatchingIf(void);
static void Release(void);


#ifndef HAVE_IFADDRS

/* provide functions from ifaddrs.h */
static int getifaddrs(struct ifaddrs **ifAddrsPtr);
static void freeifaddrs(struct ifaddrs *ifAddrStruct);

static bool OpenSocket(bool useIPv6);
static bool CloseSocket(void);
static bool GetIFConfig(void);
static bool RetrieveIfInfo(bool useIPv6);
static bool CloseSocket();

#endif /* HAVE_IFADDRS */


/*
 * check if the NIC used for routing to the given host is running
 */
bool
NetCheckNIC(const char *hostname)
{
	/* open a socket */
	for (int i = 0; i < NET_RETRIES; i++)
	{
		Init(hostname);

		if (GetHost() && GetIfAddresses())
		{
			FindMatchingIf();
			Release();

			return CheckRunning();
		}

		elog(LOG, "Retry %d to check NIC status.", i + 1);
		Release();

		/* sleep for 1 second to avoid tight loops */
		pg_usleep(USECS_PER_SEC);
	}

	elog(LOG, "Failed to check NIC status after trying %d times.", NET_RETRIES);

	return false;
}


/*
 * Initialize static variables.
 */
static void
Init(const char *hostname)
{
	hostTarget = hostname;
	running = false;

	ifAddresses = NULL;
}


/*
 * Retrieve IP address for the target host name.
 */
static bool
GetHost()
{
	struct addrinfo *hostAddresses = NULL;
	struct addrinfo *hostAddrIter = NULL;
	struct addrinfo hints;

	MemSet(&hints, 0, sizeof(hints));
	hints.ai_family = AF_UNSPEC;
	hints.ai_socktype = SOCK_STREAM;
	bool foundV4 = false;
	bool foundV6 = false;

	int ret = getaddrinfo(hostTarget, NULL /*service*/, &hints, &hostAddresses);

	if (0 != ret)
	{
		elog(LOG, "Failed to lookup host name to retrieve NIC configuration: %s",
		     gai_strerror(ret));

		return false;
	}

	for (hostAddrIter = hostAddresses; hostAddrIter != NULL; hostAddrIter = hostAddrIter->ai_next)
	{
		if (AF_INET == hostAddrIter->ai_family)
		{
			Assert(!foundV4 && "expected no more than one IPv4 address for host");
			memcpy(&hostAddrV4, hostAddrIter->ai_addr->sa_data, sizeof(hostAddrIter->ai_addr->sa_data)<sizeof(hostAddrV4)?sizeof(hostAddrIter->ai_addr->sa_data):sizeof(hostAddrV4));
			foundV4 = true;
		}
		else if (AF_INET6 == hostAddrIter->ai_family)
		{
			Assert(!foundV6 && "expected no more than one IPv6 address for host");
			memcpy(&hostAddrV6, hostAddrIter->ai_addr->sa_data, sizeof(hostAddrIter->ai_addr->sa_data)<sizeof(hostAddrV6)?sizeof(hostAddrIter->ai_addr->sa_data):sizeof(hostAddrV6));
			foundV6 = true;
		}
	}

	/* release allocated resources */
	freeaddrinfo(hostAddresses);

	return true;
}


/*
 * Retrieve NIC configuration.
 */
static bool
GetIfAddresses()
{
	int ret = getifaddrs(&ifAddresses);

	if (0 != ret || NULL == ifAddresses)
	{
		elog(LOG, "Failed to retrieve NIC configuration.");
		return false;
	}

	return true;
}


/*
 * Iterate over interfaces to find the one used for routing to host address.
 */
static void
FindMatchingIf()
{
	Assert(NULL != ifAddresses);

	struct ifaddrs *ifa = NULL;
	bool found = false;

	/* iterate NICs */
	for (ifa = ifAddresses; ifa != NULL; ifa = ifa->ifa_next)
	{
		/* check if the examined interface is a NIC */
		if ((ifa->ifa_flags &
			 (IFF_UP | IFF_BROADCAST | IFF_POINTOPOINT | IFF_LOOPBACK | IFF_NOARP))
			 != (IFF_UP | IFF_BROADCAST))
		{
			continue;
		}

		/* check if the examined interface supports IPv4 or IPv6 */
		if ((AF_INET != ifa ->ifa_addr->sa_family &&
		     AF_INET6 != ifa ->ifa_addr->sa_family) ||
			ifa->ifa_netmask == NULL)
		{
			continue;
		}

		if (ifa ->ifa_addr->sa_family == AF_INET)
		{
			char nicAddr[sizeof(hostAddrV4)];
			char maskAddr[sizeof(hostAddrV4)];
			(void) memcpy(nicAddr, ifa->ifa_addr->sa_data, sizeof(ifa->ifa_addr->sa_data)<sizeof(nicAddr)?sizeof(ifa->ifa_addr->sa_data):sizeof(nicAddr));
			(void) memcpy(maskAddr, ifa->ifa_netmask->sa_data,  sizeof(ifa->ifa_netmask->sa_data)<sizeof(maskAddr)?sizeof(ifa->ifa_netmask->sa_data):sizeof(maskAddr));

			found = CompareIP((char*) &hostAddrV4, nicAddr, maskAddr, sizeof(ifa->ifa_addr->sa_data)<sizeof(hostAddrV4)?sizeof(ifa->ifa_addr->sa_data):sizeof(hostAddrV4));
		}
		else
		{
			Assert(ifa->ifa_addr->sa_family == AF_INET6);

			char nicAddr[sizeof(hostAddrV6)];
			char maskAddr[sizeof(hostAddrV6)];
			(void) memcpy(nicAddr, ifa->ifa_addr->sa_data, sizeof(ifa->ifa_addr->sa_data)<sizeof(nicAddr)?sizeof(ifa->ifa_addr->sa_data):sizeof(nicAddr));
			(void) memcpy(maskAddr, ifa->ifa_netmask->sa_data, sizeof(ifa->ifa_netmask->sa_data)<sizeof(maskAddr)?sizeof(ifa->ifa_netmask->sa_data):sizeof(maskAddr));

			found = CompareIP((char*) &hostAddrV6, nicAddr, maskAddr, sizeof(ifa->ifa_addr->sa_data)<sizeof(hostAddrV6)?sizeof(ifa->ifa_addr->sa_data):sizeof(hostAddrV6));
		}

		if (found)
		{
			running = (ifa->ifa_flags & IFF_RUNNING) == IFF_RUNNING;
			return;
		}
	}

	Assert(!running);
	elog(LOG, "No NIC matches host name %s.", hostTarget);
}

/*
 * Compare IP addresses under mask.
 */
static bool
CompareIP(char *ipaddr1, char *ipaddr2, char *mask, int length)
{
	int i = 0;
	for (i = 0; i < length; i++)
	{
		if ((ipaddr1[i] & mask[i]) != (ipaddr2[i] & mask[i]))
		{
			return false;
		}
	}

	return true;
}

/*
 * Check if NIC is running.
 */
static bool
CheckRunning()
{
	return running;
}


/*
 * Release allocated resources.
 */
static void
Release()
{
	if (NULL != ifAddresses)
	{
		freeifaddrs(ifAddresses);
		ifAddresses = NULL;
	}
}


#ifndef HAVE_IFADDRS

/*
 * Build list of interface address descriptors
 */
int getifaddrs(struct ifaddrs **ifAddrsPtr)
{
	MemSet(ifaBuffer, 0, sizeof(ifaBuffer));
	ifAddrIter = (struct ifaddrs*) ifaBuffer;
	*ifAddrsPtr = NULL;

	if (OpenSocket(false /*useIPv6*/) &&
	    GetIFConfig() &&
	    RetrieveIfInfo(false /*useIPv6*/) &&
	    CloseSocket() &&

	    OpenSocket(true /*useIPv6*/) &&
	    GetIFConfig() &&
	    RetrieveIfInfo(true /*useIPv6*/) &&
	    CloseSocket())
	{
		*ifAddrsPtr = (struct ifaddrs*) ifaBuffer;

		return 0;
	}

	CloseSocket();

	return -1;
}


/*
 * Release list of interface address descriptors;
 * no-op since we use statically allocated buffers
 */
static void
freeifaddrs(struct ifaddrs *ifAddresses)
{}


/*
 * Open socket.
 */
static bool
OpenSocket(bool useIPv6)
{
	if (useIPv6)
	{
		sock = gp_socket(AF_INET6, SOCK_DGRAM, 0 /* protocol */);
	}
	else
	{
		sock = gp_socket(AF_INET, SOCK_DGRAM, 0 /* protocol */);
	}

	if (-1 == sock)
	{
		elog(LOG, "Failed to open socket to retrieve NIC configuration.");
		return false;
	}

	return true;
}


/*
 * Close socket.
 */
static bool
CloseSocket()
{
	(void) close(sock);

	sock = -1;

	return true;
}


/*
 * Retrieve interface configuration.
 */
static bool
GetIFConfig()
{
	MemSet(ifBuffer, 0, sizeof(ifBuffer));
	MemSet(&ifconfig, 0, sizeof(ifconfig));
	ifconfig.ifc_buf = ifBuffer;
	ifconfig.ifc_len = sizeof(ifBuffer);

	if (-1 == ioctl(sock, SIOCGIFCONF, &ifconfig))
	{
		elog(LOG, "Failed to retrieve NIC configuration.");
		return false;
	}
	return true;
}


/*
 * Retrieve information for the available NICs.
 */
static bool
RetrieveIfInfo(bool useIPv6)
{
	/*
	 * ifreq structures may be variable length;
	 * we have to step along the structure by the size of
	 * the previous structure
	 */
	struct ifreq *ifr = (struct ifreq *) ifconfig.ifc_req;
	struct ifreq *end = (struct ifreq *) ((char *) ifr + ifconfig.ifc_len);
	const char *ipvName = (useIPv6) ? "IPv6" : "IPv4";

	if (ifr == end)
	{
		elog(LOG, "Failed to retrieve NIC configuration.");
		return false;
	}

	while (ifr < end)
	{
		struct ifreq *ifrCurrent = ifr;

#ifdef __darwin__
		/* step along the array by the size of the current structure */
		ifr = (struct ifreq *)((char *)ifr + ifr->ifr_addr.sa_len + IFNAMSIZ);
#else
		ifr++;
#endif /* __darwin__ */

		if (AF_INET != ifrCurrent->ifr_addr.sa_family &&
		    AF_INET6 != ifrCurrent->ifr_addr.sa_family)
		{
			continue;
		}

		int addrLen = (ifrCurrent->ifr_addr.sa_family == AF_INET6) ?
						sizeof(struct sockaddr_in6) : sizeof(struct sockaddr_in);

		ifAddrIter->ifa_next = (ifAddrIter + 1);
		(void) strncpy(ifAddrIter->ifa_name, ifrCurrent->ifr_name, sizeof(ifAddrIter->ifa_name));
		(void) memcpy(&ifAddrIter->ifa_addr_alloc, &ifrCurrent->ifr_addr, addrLen);
		ifAddrIter->ifa_addr = &ifAddrIter->ifa_addr_alloc;

		/* retrieve configuration flags */
		if (-1 == ioctl(sock, SIOCGIFFLAGS, ifrCurrent))
		{
			elog(LOG, "Failed to retrieve configuration flags for NIC %s using %s.",
			     ifrCurrent->ifr_name,
			     ipvName
			     );
			continue;
		}
		ifAddrIter->ifa_flags = ifrCurrent->ifr_flags;


		/* retrieve network mask */
		if (-1 == ioctl(sock, SIOCGIFNETMASK, ifrCurrent))
		{
			elog(LOG, "Failed to retrieve network mask for NIC %s using %s.",
			     ifrCurrent->ifr_name,
			     ipvName);
			continue;
		}
		(void) memcpy(&ifAddrIter->ifa_netmask_alloc, &ifrCurrent->ifr_addr, addrLen);
		ifAddrIter->ifa_netmask = &ifAddrIter->ifa_netmask_alloc;

		/* move to next descriptor */
		ifAddrIter++;

		if ((uintptr_t) sizeof(ifaBuffer) < (uintptr_t) ifAddrIter - (uintptr_t) ifaBuffer)
		{
			elog(LOG, "Failed to retrieve configuration for all NICs, buffer capacity reached.");
			return false;
		}
	}

	/* terminate address descriptor list */
	(ifAddrIter - 1)->ifa_next = NULL;

	return true;
}


#endif /* HAVE_IFADDRS */

/* EOF */
