/*
 * hdhomerun_sock_posix.c
 *
 * Copyright © 2010 Silicondust USA Inc. <www.silicondust.com>.
 *
 * This library is free software; you can redistribute it and/or 
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 3 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library.  If not, see <http://www.gnu.org/licenses/>.
 * 
 * As a special exception to the GNU Lesser General Public License,
 * you may link, statically or dynamically, an application with a
 * publicly distributed version of the Library to produce an
 * executable file containing portions of the Library, and
 * distribute that executable file under terms of your choice,
 * without any of the additional requirements listed in clause 4 of
 * the GNU Lesser General Public License.
 * 
 * By "a publicly distributed version of the Library", we mean
 * either the unmodified Library as distributed by Silicondust, or a
 * modified version of the Library that is distributed under the
 * conditions defined in the GNU Lesser General Public License.
 */

/*
 * Implementation notes:
 *
 * API specifies timeout for each operation (or zero for non-blocking).
 *
 * It is not possible to rely on the OS socket timeout as this will fail to
 * detect the command-response situation where data is sent successfully and
 * the other end chooses not to send a response (other than the TCP ack).
 *
 * The select() cannot be used with high socket numbers (typically max 1024)
 * so the code works as follows:
 * - Use non-blocking sockets to allow operation without select.
 * - Use select where safe (low socket numbers).
 * - Poll with short sleep when select cannot be used safely.
 */

#include "hdhomerun.h"

#include <net/if.h>
#include <sys/ioctl.h>
#ifndef SIOCGIFCONF
#include <sys/sockio.h>
#endif
#ifndef _SIZEOF_ADDR_IFREQ
#define _SIZEOF_ADDR_IFREQ(x) sizeof(x)
#endif

int hdhomerun_local_ip_info(struct hdhomerun_local_ip_info_t ip_info_list[], int max_count)
{
	int sock = socket(AF_INET, SOCK_DGRAM, 0);
	if (sock == HDHOMERUN_SOCK_INVALID) {
		return -1;
	}

	struct ifconf ifc;
	size_t ifreq_buffer_size = 1024;

	while (1) {
		ifc.ifc_len = ifreq_buffer_size;
		ifc.ifc_buf = (char *)malloc(ifreq_buffer_size);
		if (!ifc.ifc_buf) {
			close(sock);
			return -1;
		}

		memset(ifc.ifc_buf, 0, ifreq_buffer_size);

		if (ioctl(sock, SIOCGIFCONF, &ifc) != 0) {
			free(ifc.ifc_buf);
			close(sock);
			return -1;
		}

		if (ifc.ifc_len < ifreq_buffer_size) {
			break;
		}

		free(ifc.ifc_buf);
		ifreq_buffer_size += 1024;
	}

	char *ptr = ifc.ifc_buf;
	char *end = ifc.ifc_buf + ifc.ifc_len;

	int count = 0;
	while (ptr <= end) {
		struct ifreq *ifr = (struct ifreq *)ptr;
		ptr += _SIZEOF_ADDR_IFREQ(*ifr);

		if (ioctl(sock, SIOCGIFADDR, ifr) != 0) {
			continue;
		}

		struct sockaddr_in *ip_addr_in = (struct sockaddr_in *)&(ifr->ifr_addr);
		uint32_t ip_addr = ntohl(ip_addr_in->sin_addr.s_addr);
		if (ip_addr == 0) {
			continue;
		}

		if (ioctl(sock, SIOCGIFNETMASK, ifr) != 0) {
			continue;
		}

		struct sockaddr_in *subnet_mask_in = (struct sockaddr_in *)&(ifr->ifr_addr);
		uint32_t subnet_mask = ntohl(subnet_mask_in->sin_addr.s_addr);

		struct hdhomerun_local_ip_info_t *ip_info = &ip_info_list[count++];
		ip_info->ip_addr = ip_addr;
		ip_info->subnet_mask = subnet_mask;

		if (count >= max_count) {
			break;
		}
	}

	free(ifc.ifc_buf);
	close(sock);
	return count;
}

hdhomerun_sock_t hdhomerun_sock_create_udp(void)
{
	/* Create socket. */
	hdhomerun_sock_t sock = (hdhomerun_sock_t)socket(AF_INET, SOCK_DGRAM, 0);
	if (sock == -1) {
		return HDHOMERUN_SOCK_INVALID;
	}

	/* Set non-blocking */
	if (fcntl(sock, F_SETFL, O_NONBLOCK) != 0) {
		close(sock);
		return HDHOMERUN_SOCK_INVALID;
	}

	/* Allow broadcast. */
	int sock_opt = 1;
	setsockopt(sock, SOL_SOCKET, SO_BROADCAST, (char *)&sock_opt, sizeof(sock_opt));

	/* Success. */
	return sock;
}

hdhomerun_sock_t hdhomerun_sock_create_tcp(void)
{
	/* Create socket. */
	hdhomerun_sock_t sock = (hdhomerun_sock_t)socket(AF_INET, SOCK_STREAM, 0);
	if (sock == -1) {
		return HDHOMERUN_SOCK_INVALID;
	}

	/* Set non-blocking */
	if (fcntl(sock, F_SETFL, O_NONBLOCK) != 0) {
		close(sock);
		return HDHOMERUN_SOCK_INVALID;
	}

	/* Success. */
	return sock;
}

void hdhomerun_sock_destroy(hdhomerun_sock_t sock)
{
	close(sock);
}

int hdhomerun_sock_getlasterror(void)
{
	return errno;
}

uint32_t hdhomerun_sock_getsockname_addr(hdhomerun_sock_t sock)
{
	struct sockaddr_in sock_addr;
	socklen_t sockaddr_size = sizeof(sock_addr);

	if (getsockname(sock, (struct sockaddr *)&sock_addr, &sockaddr_size) != 0) {
		return 0;
	}

	return ntohl(sock_addr.sin_addr.s_addr);
}

uint16_t hdhomerun_sock_getsockname_port(hdhomerun_sock_t sock)
{
	struct sockaddr_in sock_addr;
	socklen_t sockaddr_size = sizeof(sock_addr);

	if (getsockname(sock, (struct sockaddr *)&sock_addr, &sockaddr_size) != 0) {
		return 0;
	}

	return ntohs(sock_addr.sin_port);
}

uint32_t hdhomerun_sock_getpeername_addr(hdhomerun_sock_t sock)
{
	struct sockaddr_in sock_addr;
	socklen_t sockaddr_size = sizeof(sock_addr);

	if (getpeername(sock, (struct sockaddr *)&sock_addr, &sockaddr_size) != 0) {
		return 0;
	}

	return ntohl(sock_addr.sin_addr.s_addr);
}

uint32_t hdhomerun_sock_getaddrinfo_addr(hdhomerun_sock_t sock, const char *name)
{
	struct addrinfo hints;
	memset(&hints, 0, sizeof(hints));
	hints.ai_family = AF_INET;
	hints.ai_socktype = SOCK_STREAM;
	hints.ai_protocol = IPPROTO_TCP;

	struct addrinfo *sock_info;
	if (getaddrinfo(name, "", &hints, &sock_info) != 0) {
		return 0;
	}

	struct sockaddr_in *sock_addr = (struct sockaddr_in *)sock_info->ai_addr;
	uint32_t addr = ntohl(sock_addr->sin_addr.s_addr);

	freeaddrinfo(sock_info);
	return addr;
}

bool_t hdhomerun_sock_join_multicast_group(hdhomerun_sock_t sock, uint32_t multicast_ip, uint32_t local_ip)
{
	struct ip_mreq imr;
	memset(&imr, 0, sizeof(imr));
	imr.imr_multiaddr.s_addr  = htonl(multicast_ip);
	imr.imr_interface.s_addr  = htonl(local_ip);

	if (setsockopt(sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, (const char *)&imr, sizeof(imr)) != 0) {
		return FALSE;
	}

	return TRUE;
}

bool_t hdhomerun_sock_leave_multicast_group(hdhomerun_sock_t sock, uint32_t multicast_ip, uint32_t local_ip)
{
	struct ip_mreq imr;
	memset(&imr, 0, sizeof(imr));
	imr.imr_multiaddr.s_addr  = htonl(multicast_ip);
	imr.imr_interface.s_addr  = htonl(local_ip);

	if (setsockopt(sock, IPPROTO_IP, IP_DROP_MEMBERSHIP, (const char *)&imr, sizeof(imr)) != 0) {
		return FALSE;
	}

	return TRUE;
}

bool_t hdhomerun_sock_bind(hdhomerun_sock_t sock, uint32_t local_addr, uint16_t local_port, bool_t allow_reuse)
{
	int sock_opt = allow_reuse;
	setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *)&sock_opt, sizeof(sock_opt));

	struct sockaddr_in sock_addr;
	memset(&sock_addr, 0, sizeof(sock_addr));
	sock_addr.sin_family = AF_INET;
	sock_addr.sin_addr.s_addr = htonl(local_addr);
	sock_addr.sin_port = htons(local_port);

	if (bind(sock, (struct sockaddr *)&sock_addr, sizeof(sock_addr)) != 0) {
		return FALSE;
	}

	return TRUE;
}

static bool_t hdhomerun_sock_wait_for_read_event(hdhomerun_sock_t sock, uint64_t stop_time)
{
	uint64_t current_time = getcurrenttime();
	if (current_time >= stop_time) {
		return FALSE;
	}

	if (sock < FD_SETSIZE) {
		uint64_t timeout = stop_time - current_time;
		struct timeval t;
		t.tv_sec = timeout / 1000;
		t.tv_usec = (timeout % 1000) * 1000;

		fd_set readfds;
		FD_ZERO(&readfds);
		FD_SET(sock, &readfds);

		fd_set errorfds;
		FD_ZERO(&errorfds);
		FD_SET(sock, &errorfds);

		if (select(sock + 1, &readfds, NULL, &errorfds, &t) <= 0) {
			return FALSE;
		}
		if (!FD_ISSET(sock, &readfds)) {
			return FALSE;
		}
	} else {
		uint64_t delay = stop_time - current_time;
		if (delay > 5) {
			delay = 5;
		}

		msleep_approx(delay);
	}

	return TRUE;
}

static bool_t hdhomerun_sock_wait_for_write_event(hdhomerun_sock_t sock, uint64_t stop_time)
{
	uint64_t current_time = getcurrenttime();
	if (current_time >= stop_time) {
		return FALSE;
	}

	if (sock < FD_SETSIZE) {
		uint64_t timeout = stop_time - current_time;
		struct timeval t;
		t.tv_sec = timeout / 1000;
		t.tv_usec = (timeout % 1000) * 1000;

		fd_set writefds;
		FD_ZERO(&writefds);
		FD_SET(sock, &writefds);

		fd_set errorfds;
		FD_ZERO(&errorfds);
		FD_SET(sock, &errorfds);

		if (select(sock + 1, NULL, &writefds, &errorfds, &t) <= 0) {
			return FALSE;
		}
		if (!FD_ISSET(sock, &writefds)) {
			return FALSE;
		}
	} else {
		uint64_t delay = stop_time - current_time;
		if (delay > 5) {
			delay = 5;
		}

		msleep_approx(delay);
	}

	return TRUE;
}

bool_t hdhomerun_sock_connect(hdhomerun_sock_t sock, uint32_t remote_addr, uint16_t remote_port, uint64_t timeout)
{
	struct sockaddr_in sock_addr;
	memset(&sock_addr, 0, sizeof(sock_addr));
	sock_addr.sin_family = AF_INET;
	sock_addr.sin_addr.s_addr = htonl(remote_addr);
	sock_addr.sin_port = htons(remote_port);

	if (connect(sock, (struct sockaddr *)&sock_addr, sizeof(sock_addr)) == 0) {
		return TRUE;
	}

	uint64_t stop_time = getcurrenttime() + timeout;

	/*
	 * getpeername() is used to detect if connect succeeded. Bug - cygwin
	 * will return getpeername success even if the connect process hasn't
	 * completed. This first call to select is used to work around the
	 * problem (at least for low numbered sockets where select is used).
	 */
	if (!hdhomerun_sock_wait_for_write_event(sock, stop_time)) {
		return FALSE;
	}

	while (1) {
		struct sockaddr_in sock_addr;
		socklen_t sockaddr_size = sizeof(sock_addr);
		if (getpeername(sock, (struct sockaddr *)&sock_addr, &sockaddr_size) == 0) {
			return TRUE;
		}

		if (errno != ENOTCONN) {
			return FALSE;
		}

		if (!hdhomerun_sock_wait_for_write_event(sock, stop_time)) {
			return FALSE;
		}
	}
}

bool_t hdhomerun_sock_send(hdhomerun_sock_t sock, const void *data, size_t length, uint64_t timeout)
{
	uint64_t stop_time = getcurrenttime() + timeout;
	const uint8_t *ptr = (const uint8_t *)data;

	while (1) {
		int ret = send(sock, ptr, length, 0);
		if (ret >= (int)length) {
			return TRUE;
		}

		if (ret > 0) {
			ptr += ret;
			length -= ret;
		}

		if (errno == EINPROGRESS) {
			errno = EWOULDBLOCK;
		}
		if (errno != EWOULDBLOCK) {
			return FALSE;
		}

		if (!hdhomerun_sock_wait_for_write_event(sock, stop_time)) {
			return FALSE;
		}
	}
}

bool_t hdhomerun_sock_sendto(hdhomerun_sock_t sock, uint32_t remote_addr, uint16_t remote_port, const void *data, size_t length, uint64_t timeout)
{
	uint64_t stop_time = getcurrenttime() + timeout;
	const uint8_t *ptr = (const uint8_t *)data;

	while (1) {
		struct sockaddr_in sock_addr;
		memset(&sock_addr, 0, sizeof(sock_addr));
		sock_addr.sin_family = AF_INET;
		sock_addr.sin_addr.s_addr = htonl(remote_addr);
		sock_addr.sin_port = htons(remote_port);

		int ret = sendto(sock, ptr, length, 0, (struct sockaddr *)&sock_addr, sizeof(sock_addr));
		if (ret >= (int)length) {
			return TRUE;
		}

		if (ret > 0) {
			ptr += ret;
			length -= ret;
		}

		if (errno == EINPROGRESS) {
			errno = EWOULDBLOCK;
		}
		if (errno != EWOULDBLOCK) {
			return FALSE;
		}

		if (!hdhomerun_sock_wait_for_write_event(sock, stop_time)) {
			return FALSE;
		}
	}
}

bool_t hdhomerun_sock_recv(hdhomerun_sock_t sock, void *data, size_t *length, uint64_t timeout)
{
	uint64_t stop_time = getcurrenttime() + timeout;

	while (1) {
		int ret = recv(sock, data, *length, 0);
		if (ret > 0) {
			*length = ret;
			return TRUE;
		}

		if (errno == EINPROGRESS) {
			errno = EWOULDBLOCK;
		}
		if (errno != EWOULDBLOCK) {
			return FALSE;
		}

		if (!hdhomerun_sock_wait_for_read_event(sock, stop_time)) {
			return FALSE;
		}
	}
}

bool_t hdhomerun_sock_recvfrom(hdhomerun_sock_t sock, uint32_t *remote_addr, uint16_t *remote_port, void *data, size_t *length, uint64_t timeout)
{
	uint64_t stop_time = getcurrenttime() + timeout;

	while (1) {
		struct sockaddr_in sock_addr;
		memset(&sock_addr, 0, sizeof(sock_addr));
		socklen_t sockaddr_size = sizeof(sock_addr);

		int ret = recvfrom(sock, data, *length, 0, (struct sockaddr *)&sock_addr, &sockaddr_size);
		if (ret > 0) {
			*remote_addr = ntohl(sock_addr.sin_addr.s_addr);
			*remote_port = ntohs(sock_addr.sin_port);
			*length = ret;
			return TRUE;
		}

		if (errno == EINPROGRESS) {
			errno = EWOULDBLOCK;
		}
		if (errno != EWOULDBLOCK) {
			return FALSE;
		}

		if (!hdhomerun_sock_wait_for_read_event(sock, stop_time)) {
			return FALSE;
		}
	}
}
