/* Copyright (C) 2007-2008 The Android Open Source Project
**
** This software is licensed under the terms of the GNU General Public
** License version 2, as published by the Free Software Foundation, and
** may be copied, distributed, and modified under those terms.
**
** This program 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 General Public License for more details.
*/
#ifdef __linux__ /* Recent versions of glibc only define EAI_NODATA, which is an
                    extension to the POSIX standard, if _GNU_SOURCE is defined. */
#  define _GNU_SOURCE 1
#endif

#include "android/sockets.h"
#include <fcntl.h>
#include <stddef.h>
#include "android/qemu-debug.h"
#include "sysemu/char.h"
#include <stdlib.h>
#include <string.h>
#include "android/utils/debug.h"
#include "android/utils/eintr_wrapper.h"
#include "android/utils/misc.h"
#include "android/utils/path.h"
#include "android/utils/socket_drainer.h"
#include "android/utils/system.h"

#define  D(...) VERBOSE_PRINT(socket,__VA_ARGS__)

#ifdef _WIN32
#  define xxWIN32_LEAN_AND_MEAN
#  include <windows.h>
#  include <winsock2.h>
#  include <ws2tcpip.h>
#else /* !_WIN32 */
#  include <sys/ioctl.h>
#  include <sys/socket.h>
#  include <netinet/in.h>
#  include <netinet/tcp.h>
#  include <netdb.h>
#  if HAVE_UNIX_SOCKETS
#    include <sys/un.h>
#    ifndef UNIX_PATH_MAX
#      define  UNIX_PATH_MAX  (sizeof(((struct sockaddr_un*)0)->sun_path)-1)
#    endif
#  endif
#endif /* !_WIN32 */



/* QSOCKET_CALL is used to deal with the fact that EINTR happens pretty
 * easily in QEMU since we use SIGALRM to implement periodic timers
 */
#ifdef _WIN32
#  define  QSOCKET_CALL(_ret,_cmd)   \
    do { _ret = (_cmd); } while ( _ret < 0 && WSAGetLastError() == WSAEINTR )
#else
#  define  QSOCKET_CALL(_ret,_cmd)   \
    do { \
        errno = 0; \
        _ret = HANDLE_EINTR(_cmd); \
    } while (0);
#endif

#ifdef _WIN32

#include <errno.h>

static int  winsock_error;

#define  WINSOCK_ERRORS_LIST \
    EE(WSA_INVALID_HANDLE,EINVAL,"invalid handle") \
    EE(WSA_NOT_ENOUGH_MEMORY,ENOMEM,"not enough memory") \
    EE(WSA_INVALID_PARAMETER,EINVAL,"invalid parameter") \
    EE(WSAEINTR,EINTR,"interrupted function call") \
    EE(WSAEALREADY,EALREADY,"operation already in progress") \
    EE(WSAEBADF,EBADF,"bad file descriptor") \
    EE(WSAEACCES,EACCES,"permission denied") \
    EE(WSAEFAULT,EFAULT,"bad address") \
    EE(WSAEINVAL,EINVAL,"invalid argument") \
    EE(WSAEMFILE,EMFILE,"too many opened files") \
    EE(WSAEWOULDBLOCK,EWOULDBLOCK,"resource temporarily unavailable") \
    EE(WSAEINPROGRESS,EINPROGRESS,"operation now in progress") \
    EE(WSAEALREADY,EAGAIN,"operation already in progress") \
    EE(WSAENOTSOCK,EBADF,"socket operation not on socket") \
    EE(WSAEDESTADDRREQ,EDESTADDRREQ,"destination address required") \
    EE(WSAEMSGSIZE,EMSGSIZE,"message too long") \
    EE(WSAEPROTOTYPE,EPROTOTYPE,"wrong protocol type for socket") \
    EE(WSAENOPROTOOPT,ENOPROTOOPT,"bad protocol option") \
    EE(WSAEADDRINUSE,EADDRINUSE,"address already in use") \
    EE(WSAEADDRNOTAVAIL,EADDRNOTAVAIL,"cannot assign requested address") \
    EE(WSAENETDOWN,ENETDOWN,"network is down") \
    EE(WSAENETUNREACH,ENETUNREACH,"network unreachable") \
    EE(WSAENETRESET,ENETRESET,"network dropped connection on reset") \
    EE(WSAECONNABORTED,ECONNABORTED,"software caused connection abort") \
    EE(WSAECONNRESET,ECONNRESET,"connection reset by peer") \
    EE(WSAENOBUFS,ENOBUFS,"no buffer space available") \
    EE(WSAEISCONN,EISCONN,"socket is already connected") \
    EE(WSAENOTCONN,ENOTCONN,"socket is not connected") \
    EE(WSAESHUTDOWN,ESHUTDOWN,"cannot send after socket shutdown") \
    EE(WSAETOOMANYREFS,ETOOMANYREFS,"too many references") \
    EE(WSAETIMEDOUT,ETIMEDOUT,"connection timed out") \
    EE(WSAECONNREFUSED,ECONNREFUSED,"connection refused") \
    EE(WSAELOOP,ELOOP,"cannot translate name") \
    EE(WSAENAMETOOLONG,ENAMETOOLONG,"name too long") \
    EE(WSAEHOSTDOWN,EHOSTDOWN,"host is down") \
    EE(WSAEHOSTUNREACH,EHOSTUNREACH,"no route to host") \

typedef struct {
    int          winsock;
    int          unix;
    const char*  string;
} WinsockError;

static const WinsockError  _winsock_errors[] = {
#define  EE(w,u,s)   { w, u, s },
    WINSOCK_ERRORS_LIST
#undef   EE
    { -1, -1, NULL }
};

/* this function reads the latest winsock error code and updates
 * errno to a matching value. It also returns the new value of
 * errno.
 */
static int
fix_errno( void )
{
    const WinsockError*  werr = _winsock_errors;
    int                  unix = EINVAL;  /* generic error code */

    winsock_error = WSAGetLastError();

    for ( ; werr->string != NULL; werr++ ) {
        if (werr->winsock == winsock_error) {
            unix = werr->unix;
            break;
        }
    }
    errno = unix;
    return -1;
}

static int
set_errno( int  code )
{
    winsock_error = -1;
    errno         = code;
    return -1;
}

/* this function returns a string describing the latest Winsock error */
const char*
_errno_str(void)
{
    const WinsockError*  werr   = _winsock_errors;
    const char*          result = NULL;

    for ( ; werr->string; werr++ ) {
        if (werr->winsock == winsock_error) {
            result = werr->string;
            break;
        }
    }

    if (result == NULL) {
        result = tempstr_format(
                    "Unkown socket error (Winsock=0x%08x) errno=%d: %s",
                    winsock_error, errno, strerror(errno));
    }
    return result;
}
#else
static int
fix_errno( void )
{
    return -1;
}

static int
set_errno( int  code )
{
    errno = code;
    return -1;
}
#endif

/* socket types */

static int
socket_family_to_bsd( SocketFamily  family )
{
    switch (family) {
    case SOCKET_INET: return AF_INET;
    case SOCKET_IN6:  return AF_INET6;
#if HAVE_UNIX_SOCKETS
    case SOCKET_UNIX: return AF_LOCAL;
#endif
    default: return -1;
    }
}

static int
socket_type_to_bsd( SocketType  type )
{
    switch (type) {
        case SOCKET_DGRAM:  return SOCK_DGRAM;
        case SOCKET_STREAM: return SOCK_STREAM;
        default: return 0;
    }
}

static SocketType
socket_type_from_bsd( int  type )
{
    switch (type) {
        case SOCK_DGRAM:  return SOCKET_DGRAM;
        case SOCK_STREAM: return SOCKET_STREAM;
        default:          return (SocketType) SOCKET_UNSPEC;
    }
}

#if 0
static int
socket_type_check( SocketType  type )
{
    return (type == SOCKET_DGRAM || type == SOCKET_STREAM);
}
#endif

typedef union {
    struct sockaddr     sa[1];
    struct sockaddr_in  in[1];
#if HAVE_IN6_SOCKETS
    struct sockaddr_in6 in6[1];
#endif
#if HAVE_UNIX_SOCKETS
    struct sockaddr_un  un[1];
#endif
} sockaddr_storage;

/* socket addresses */

void
sock_address_init_inet( SockAddress*  a, uint32_t  ip, uint16_t  port )
{
    a->family         = SOCKET_INET;
    a->u.inet.port    = port;
    a->u.inet.address = ip;
}

void
sock_address_init_in6 ( SockAddress*  a, const uint8_t*  ip6[16], uint16_t  port )
{
    a->family = SOCKET_IN6;
    a->u.in6.port = port;
    memcpy( a->u.in6.address, ip6, sizeof(a->u.in6.address) );
}

void
sock_address_init_unix( SockAddress*  a, const char*  path )
{
    a->family       = SOCKET_UNIX;
    a->u._unix.path  = strdup(path ? path : "");
    a->u._unix.owner = 1;
}

void  sock_address_done( SockAddress*  a )
{
    if (a->family == SOCKET_UNIX && a->u._unix.owner) {
        a->u._unix.owner = 0;
        free((char*)a->u._unix.path);
    }
}

static char*
format_char( char*  buf, char*  end, int  c )
{
    if (buf < end) {
        if (buf+1 == end) {
            *buf++ = 0;
        } else {
            *buf++ = (char) c;
            *buf    = 0;
        }
    }
    return buf;
}

static char*
format_str( char*  buf, char*  end, const char*  str )
{
    int  len   = strlen(str);
    int  avail = end - buf;

    if (len > avail)
        len = avail;

    memcpy( buf, str, len );
    buf += len;

    if (buf == end)
        buf[-1] = 0;
    else
        buf[0] = 0;

    return buf;
}

static char*
format_unsigned( char*  buf, char*  end, unsigned  val )
{
    char  temp[16];
    int   nn;

    for ( nn = 0; val != 0; nn++ ) {
        int  rem = val % 10;
        temp[nn] = '0'+rem;
        val /= 10;
    }

    if (nn == 0)
        temp[nn++] = '0';

    while (nn > 0)
        buf = format_char(buf, end, temp[--nn]);

    return buf;
}

static char*
format_hex( char*  buf, char*  end, unsigned  val, int  ndigits )
{
    int   shift = 4*ndigits;
    static const char   hex[16] = "0123456789abcdef";

    while (shift >= 0) {
        buf = format_char(buf, end, hex[(val >> shift) & 15]);
        shift -= 4;
    }
    return buf;
}

static char*
format_ip4( char*  buf, char*  end, uint32_t  ip )
{
    buf = format_unsigned( buf, end, (unsigned)(ip >> 24) );
    buf = format_char( buf, end, '.');
    buf = format_unsigned( buf, end, (unsigned)((ip >> 16) & 255));
    buf = format_char( buf, end, '.');
    buf = format_unsigned( buf, end, (unsigned)((ip >> 8) & 255));
    buf = format_char( buf, end, '.');
    buf = format_unsigned( buf, end, (unsigned)(ip & 255));
    return buf;
}

static char*
format_ip6( char*  buf, char*  end, const uint8_t*  ip6 )
{
    int  nn;
    for (nn = 0; nn < 8; nn++) {
        int  val = (ip6[0] << 16) | ip6[1];
        ip6 += 2;
        if (nn > 0)
            buf = format_char(buf, end, ':');
        if (val == 0)
            continue;
        buf  = format_hex(buf, end, val, 4);
    }
    return buf;
}

const char*
sock_address_to_string( const SockAddress*  a )
{
    static char buf0[MAX_PATH];
    char *buf = buf0, *end = buf + sizeof(buf0);

    switch (a->family) {
    case SOCKET_INET:
        buf = format_ip4( buf, end, a->u.inet.address );
        buf = format_char( buf, end, ':' );
        buf = format_unsigned( buf, end, (unsigned) a->u.inet.port );
        break;

    case SOCKET_IN6:
        buf = format_ip6( buf, end, a->u.in6.address );
        buf = format_char( buf, end, ':' );
        buf = format_unsigned( buf, end, (unsigned) a->u.in6.port );
        break;

    case SOCKET_UNIX:
        buf = format_str( buf, end, a->u._unix.path );
        break;

    default:
        return NULL;
    }

    return buf0;
}

int
sock_address_equal( const SockAddress*  a, const SockAddress*  b )
{
    if (a->family != b->family)
        return 0;

    switch (a->family) {
    case SOCKET_INET:
        return (a->u.inet.address == b->u.inet.address &&
                a->u.inet.port    == b->u.inet.port);

    case SOCKET_IN6:
        return (!memcmp(a->u.in6.address, b->u.in6.address, 16) &&
                a->u.in6.port == b->u.in6.port);

    case SOCKET_UNIX:
        return (!strcmp(a->u._unix.path, b->u._unix.path));

    default:
        return 0;
    }
}

int
sock_address_get_port( const SockAddress*  a )
{
    switch (a->family) {
    case SOCKET_INET:
        return a->u.inet.port;
    case SOCKET_IN6:
        return a->u.in6.port;
    default:
        return -1;
    }
}

void
sock_address_set_port( SockAddress*  a, uint16_t  port )
{
    switch (a->family) {
    case SOCKET_INET:
        a->u.inet.port = port;
        break;
    case SOCKET_IN6:
        a->u.in6.port = port;
        break;
    default:
        ;
    }
}

const char*
sock_address_get_path( const SockAddress*  a )
{
    if (a->family == SOCKET_UNIX)
        return a->u._unix.path;
    else
        return NULL;
}

int
sock_address_get_ip( const SockAddress*  a )
{
    if (a->family == SOCKET_INET)
        return a->u.inet.address;

    return -1;
}

#if 0
char*
bufprint_sock_address( char*  p, char*  end, const SockAddress*  a )
{
    switch (a->family) {
    case SOCKET_INET:
        {
            uint32_t  ip = a->u.inet.address;

            return bufprint( p, end, "%d.%d.%d.%d:%d",
                         (ip >> 24) & 255, (ip >> 16) & 255,
                         (ip >> 8) & 255, ip & 255,
                         a->u.inet.port );
        }
    case SOCKET_IN6:
        {
            int             nn     = 0;
            const char*     column = "";
            const uint8_t*  tab    = a->u.in6.address;
            for (nn = 0; nn < 16; nn += 2) {
                p = bufprint(p, end, "%s%04x", column, (tab[n] << 8) | tab[n+1]);
                column = ":";
            }
            return bufprint(p, end, ":%d", a->u.in6.port);
        }
    case SOCKET_UNIX:
        {
            return bufprint(p, end, "%s", a->u._unix.path);
        }
    default:
        return p;
    }
}
#endif

static int
sock_address_to_bsd( const SockAddress*  a, sockaddr_storage*  paddress, socklen_t  *psize )
{
    switch (a->family) {
    case SOCKET_INET:
        {
            struct sockaddr_in*  dst = paddress->in;

            *psize = sizeof(*dst);

            memset( paddress, 0, *psize );

            dst->sin_family      = AF_INET;
            dst->sin_port        = htons(a->u.inet.port);
            dst->sin_addr.s_addr = htonl(a->u.inet.address);
        }
        break;

#if HAVE_IN6_SOCKETS
    case SOCKET_IN6:
        {
            struct sockaddr_in6*  dst = paddress->in6;

            *psize = sizeof(*dst);

            memset( paddress, 0, *psize );

            dst->sin6_family = AF_INET6;
            dst->sin6_port   = htons(a->u.in6.port);
            memcpy( dst->sin6_addr.s6_addr, a->u.in6.address, 16 );
        }
        break;
#endif /* HAVE_IN6_SOCKETS */

#if HAVE_UNIX_SOCKETS
    case SOCKET_UNIX:
        {
            int                  slen = strlen(a->u._unix.path);
            struct sockaddr_un*  dst = paddress->un;

            if (slen >= UNIX_PATH_MAX)
                return -1;

            memset( dst, 0, sizeof(*dst) );

            dst->sun_family = AF_LOCAL;
            memcpy( dst->sun_path, a->u._unix.path, slen );
            dst->sun_path[slen] = 0;

            *psize = (char*)&dst->sun_path[slen+1] - (char*)dst;
        }
        break;
#endif /* HAVE_UNIX_SOCKETS */

    default:
        return set_errno(EINVAL);
    }

    return 0;
}

static int
sock_address_from_bsd( SockAddress*  a, const void*  from, size_t  fromlen )
{
    switch (((struct sockaddr *)from)->sa_family) {
    case AF_INET:
        {
           const struct sockaddr_in*  src = from;

            if (fromlen < sizeof(*src))
                return set_errno(EINVAL);

            a->family         = SOCKET_INET;
            a->u.inet.port    = ntohs(src->sin_port);
            a->u.inet.address = ntohl(src->sin_addr.s_addr);
        }
        break;

#ifdef HAVE_IN6_SOCKETS
    case AF_INET6:
        {
            const struct sockaddr_in6*  src = from;

            if (fromlen < sizeof(*src))
                return set_errno(EINVAL);

            a->family     = SOCKET_IN6;
            a->u.in6.port = ntohs(src->sin6_port);
            memcpy(a->u.in6.address, src->sin6_addr.s6_addr, 16);
        }
        break;
#endif

#ifdef HAVE_UNIX_SOCKETS
    case AF_LOCAL:
        {
            const struct sockaddr_un*  src = from;
            char*                end;

            if (fromlen < sizeof(*src))
                return set_errno(EINVAL);

            /* check that the path is zero-terminated */
            end = memchr(src->sun_path, 0, UNIX_PATH_MAX);
            if (end == NULL)
                return set_errno(EINVAL);

            a->family = SOCKET_UNIX;
            a->u._unix.owner = 1;
            a->u._unix.path  = strdup(src->sun_path);
        }
        break;
#endif

    default:
        return set_errno(EINVAL);
    }
    return 0;
}


int
sock_address_init_resolve( SockAddress*  a, const char*  hostname, uint16_t  port, int  preferIn6 )
{
    struct addrinfo   hints[1];
    struct addrinfo*  res;
    int                ret;

    memset(hints, 0, sizeof(hints));
    hints->ai_family   = preferIn6 ? AF_INET6 : AF_UNSPEC;

    ret = getaddrinfo(hostname, NULL, hints, &res);
    if (ret != 0) {
        int  err;

        switch (ret) {
        case EAI_AGAIN:  /* server is down */
        case EAI_FAIL:   /* server is sick */
            err = EHOSTDOWN;
            break;

/* NOTE that in x86_64-w64-mingw32 both EAI_NODATA and EAI_NONAME are the same */
#if defined(EAI_NODATA) && (EAI_NODATA != EAI_NONAME)
        case EAI_NODATA:
#endif
        case EAI_NONAME:
            err = ENOENT;
            break;

        case EAI_MEMORY:
            err = ENOMEM;
            break;

        default:
            err = EINVAL;
        }
        return set_errno(err);
    }

    /* Parse the returned list of addresses. */
    {
        struct addrinfo*  res_ipv4 = NULL;
        struct addrinfo*  res_ipv6 = NULL;
        struct addrinfo*  r;

       /* If preferIn6 is false, we stop on the first IPv4 address,
        * otherwise, we stop on the first IPv6 one
        */
        for (r = res; r != NULL; r = r->ai_next) {
            if (r->ai_family == AF_INET && res_ipv4 == NULL) {
                res_ipv4 = r;
                if (!preferIn6)
                    break;
            }
            else if (r->ai_family == AF_INET6 && res_ipv6 == NULL) {
                res_ipv6 = r;
                if (preferIn6)
                    break;
            }
        }

        /* Select the best address in 'r', which will be NULL
         * if there is no corresponding address.
         */
        if (preferIn6) {
            r = res_ipv6;
            if (r == NULL)
                r = res_ipv4;
        } else {
            r = res_ipv4;
            if (r == NULL)
                r = res_ipv6;
        }

        if (r == NULL) {
            ret = set_errno(ENOENT);
            goto Exit;
        }

        /* Convert to a SockAddress */
        ret = sock_address_from_bsd( a, r->ai_addr, r->ai_addrlen );
        if (ret < 0)
            goto Exit;
    }

    /* need to set the port */
    switch (a->family) {
    case SOCKET_INET: a->u.inet.port = port; break;
    case SOCKET_IN6:  a->u.in6.port  = port; break;
    default: ;
    }

Exit:
    freeaddrinfo(res);
    return ret;
}

/* The Winsock headers for mingw lack some definitions */
#ifndef AI_ADDRCONFIG
#  define  AI_ADDRCONFIG  0
#endif

SockAddress**
sock_address_list_create( const char*  hostname,
                          const char*  port,
                          unsigned     flags )
{
    SockAddress**    list = NULL;
    SockAddress*     addr;
    int              nn, count, ret;
    struct addrinfo  ai, *res, *e;

    memset(&ai, 0, sizeof(ai));
    ai.ai_flags   |= AI_ADDRCONFIG;
    ai.ai_family   = PF_UNSPEC;

    if (flags & SOCKET_LIST_FORCE_INET)
        ai.ai_family = PF_INET;
    else if (flags & SOCKET_LIST_FORCE_IN6)
        ai.ai_family = PF_INET6;

    if (flags & SOCKET_LIST_PASSIVE)
        ai.ai_flags |= AI_PASSIVE;
    else
        ai.ai_flags |= AI_CANONNAME;

    if (flags & SOCKET_LIST_DGRAM)
        ai.ai_socktype = SOCK_DGRAM;

    while (1) {
        struct addrinfo  hints = ai;

        ret = getaddrinfo(hostname, port, &hints, &res);
        if (ret == 0)
            break;

        switch (ret) {
#ifdef EAI_ADDRFAMILY
        case EAI_ADDRFAMILY:
#endif
        case EAI_NODATA:
            set_errno(ENOENT);
            break;
        case EAI_FAMILY:
            set_errno(EAFNOSUPPORT);
            break;
        case EAI_AGAIN:
            set_errno(EAGAIN);
            break;
#ifdef EAI_SYSTEM
        case EAI_SYSTEM:
            if (errno == EINTR)
                continue;
            break;
#endif
        default:
            set_errno(EINVAL);
        }
        return NULL;
    }

    /* allocate result list */
    for (count = 0, e = res; e != NULL; e = e->ai_next)
        count += 1;

    AARRAY_NEW(list, count+1);
    AARRAY_NEW(addr, count);

    for (nn = 0, e = res; e != NULL; e = e->ai_next) {

        ret = sock_address_from_bsd(addr, e->ai_addr, e->ai_addrlen);
        if (ret < 0)
            continue;

        list[nn++] = addr++;
    }
    list[nn] = NULL;
    freeaddrinfo(res);
    return list;
}

SockAddress**
sock_address_list_create2(const char* host_and_port, unsigned flags )
{
    char host_name[512];
    const char* actual_host_name = "localhost";
    // Parse host and port name.
    const char* port_name = strchr(host_and_port, ':');
    if (port_name != NULL) {
        int to_copy = MIN(sizeof(host_name)-1, port_name - host_and_port);
        if (to_copy != 0) {
            memcpy(host_name, host_and_port, to_copy);
            host_name[to_copy] = '\0';
            actual_host_name = host_name;
            port_name++;
        } else {
            return NULL;
        }
    } else {
        port_name = host_and_port;
    }
    // Make sure that port_name is not empty.
    if (port_name[0] == '\0') {
        return NULL;
    }
    return sock_address_list_create(actual_host_name, port_name, flags);
}

void
sock_address_list_free( SockAddress**  list )
{
    int  nn;
    SockAddress*  addr;

    if (list == NULL)
        return;

    addr = list[0];
    for (nn = 0; list[nn] != NULL; nn++) {
        sock_address_done(list[nn]);
        list[nn] = NULL;
    }
    AFREE(addr);
    AFREE(list);
}

int
sock_address_get_numeric_info( SockAddress*  a,
                               char*         host,
                               size_t        hostlen,
                               char*         serv,
                               size_t        servlen )
{
    struct sockaddr*  saddr;
    socklen_t         slen;
    int               ret;

    switch (a->family) {
    case SOCKET_INET:
        saddr = (struct sockaddr*) &a->u.inet.address;
        slen  = sizeof(a->u.inet.address);
        break;

#if HAVE_IN6_SOCKET
    case SOCKET_IN6:
        saddr = (struct sockaddr*) &a->u.in6.address;
        slen  = sizeof(a->u.in6.address);
        break;
#endif
    default:
        return set_errno(EINVAL);
    }

    ret = getnameinfo( saddr, slen, host, hostlen, serv, servlen,
                       NI_NUMERICHOST | NI_NUMERICSERV );

    switch (ret) {
    case 0:
        break;
    case EAI_AGAIN:
        ret = EAGAIN;
        break;
    default:
        ret = EINVAL;
    }
    return ret;
}

int
socket_create( SocketFamily  family, SocketType  type )
{
    int   ret;
    int   sfamily = socket_family_to_bsd(family);
    int   stype   = socket_type_to_bsd(type);

    if (sfamily < 0 || stype < 0) {
        return set_errno(EINVAL);
    }

    QSOCKET_CALL(ret, socket(sfamily, stype, 0));
    if (ret < 0)
        return fix_errno();

    return ret;
}


int
socket_create_inet( SocketType  type )
{
    return socket_create( SOCKET_INET, type );
}

#if HAVE_IN6_SOCKETS
int
socket_create_in6 ( SocketType  type )
{
    return socket_create( SOCKET_IN6, type );
}
#endif

#if HAVE_UNIX_SOCKETS
int
socket_create_unix( SocketType  type )
{
    return socket_create( SOCKET_UNIX, type );
}
#endif

int  socket_can_read(int  fd)
{
#ifdef _WIN32
    unsigned long  opt;

    if (ioctlsocket(fd, FIONREAD, &opt) < 0)
        return 0;

    return opt;
#else
    int  opt;

    if (ioctl(fd, FIONREAD, &opt) < 0)
        return 0;

    return opt;
#endif
}

#define   SOCKET_CALL(cmd)  \
    int  ret; \
    QSOCKET_CALL(ret, (cmd)); \
    if (ret < 0) \
        return fix_errno(); \
    return ret; \

int
socket_send(int  fd, const void*  buf, int  buflen)
{
    SOCKET_CALL(send(fd, buf, buflen, 0))
}

int
socket_send_oob( int  fd, const void*  buf, int  buflen )
{
    SOCKET_CALL(send(fd, buf, buflen, MSG_OOB));
}

int
socket_sendto(int  fd, const void*  buf, int  buflen, const SockAddress*  to)
{
    sockaddr_storage  sa;
    socklen_t         salen;

    if (sock_address_to_bsd(to, &sa, &salen) < 0)
        return -1;

    SOCKET_CALL(sendto(fd, buf, buflen, 0, sa.sa, salen));
}

int
socket_recv(int  fd, void*  buf, int  len)
{
    SOCKET_CALL(recv(fd, buf, len, 0));
}

int
socket_recvfrom(int  fd, void*  buf, int  len, SockAddress*  from)
{
    sockaddr_storage  sa;
    socklen_t         salen = sizeof(sa);
    int               ret;

    QSOCKET_CALL(ret,recvfrom(fd,buf,len,0,sa.sa,&salen));
    if (ret < 0)
        return fix_errno();

    if (sock_address_from_bsd(from, &sa, salen) < 0)
        return -1;

    return ret;
}

int
socket_connect_no_sigalrm(int socket, const struct sockaddr *address, socklen_t address_len)
{
    int ret;
    BEGIN_NOSIGALRM
    ret = connect(socket, address, address_len);
    END_NOSIGALRM
    return ret;
}

int
socket_connect( int  fd, const SockAddress*  address )
{
    sockaddr_storage  addr;
    socklen_t         addrlen;

    if (sock_address_to_bsd(address, &addr, &addrlen) < 0)
        return -1;

    SOCKET_CALL(socket_connect_no_sigalrm(fd,addr.sa,addrlen));
}

int
socket_bind( int  fd, const SockAddress*  address )
{
    sockaddr_storage  addr;
    socklen_t         addrlen;

    if (sock_address_to_bsd(address, &addr, &addrlen) < 0)
        return -1;

    SOCKET_CALL(bind(fd, addr.sa, addrlen));
}

int
socket_get_address( int  fd, SockAddress*  address )
{
    sockaddr_storage  addr;
    socklen_t         addrlen = sizeof(addr);
    int               ret;

    QSOCKET_CALL(ret, getsockname(fd, addr.sa, &addrlen));
    if (ret < 0)
        return fix_errno();

    return sock_address_from_bsd(address, &addr, addrlen);
}

int
socket_get_peer_address( int  fd, SockAddress*  address )
{
    sockaddr_storage  addr;
    socklen_t         addrlen = sizeof(addr);
    int               ret;

    QSOCKET_CALL(ret, getpeername(fd, addr.sa, &addrlen));
    if (ret < 0)
        return fix_errno();

    return sock_address_from_bsd(address, &addr, addrlen);
}

int
socket_listen( int  fd, int  backlog )
{
    SOCKET_CALL(listen(fd, backlog));
}

int
socket_accept( int  fd, SockAddress*  address )
{
    sockaddr_storage  addr;
    socklen_t         addrlen = sizeof(addr);
    int               ret;

    QSOCKET_CALL(ret, accept(fd, addr.sa, &addrlen));
    if (ret < 0)
        return fix_errno();

    if (address) {
        if (sock_address_from_bsd(address, &addr, addrlen) < 0) {
            socket_close(ret);
            return -1;
        }
    }
    return ret;
}

static int
socket_getoption(int  fd, int  domain, int  option, int  defaut)
{
    int  ret;
    while (1) {
#ifdef _WIN32
        DWORD opt = (DWORD)-1;
#else
        int  opt  = -1;
#endif
        socklen_t  optlen = sizeof(opt);
        ret = HANDLE_EINTR(
                getsockopt(fd, domain, option, (char*)&opt, &optlen));
        if (ret == 0)
            return (int)opt;
        else
            return defaut;
    }
#undef OPT_CAST
}


SocketType socket_get_type(int fd)
{
    int   so_type = socket_getoption(fd, SOL_SOCKET, SO_TYPE, -1);
    return socket_type_from_bsd(so_type);
}

int socket_set_nonblock(int fd)
{
#ifdef _WIN32
    unsigned long opt = 1;
    return ioctlsocket(fd, FIONBIO, &opt);
#else
    int   flags = fcntl(fd, F_GETFL);
    return fcntl(fd, F_SETFL, flags | O_NONBLOCK);
#endif
}

int socket_set_blocking(int fd)
{
#ifdef _WIN32
    unsigned long opt = 0;
    return ioctlsocket(fd, FIONBIO, &opt);
#else
    int   flags = fcntl(fd, F_GETFL);
    return fcntl(fd, F_SETFL, flags & ~O_NONBLOCK);
#endif
}

static int
socket_setoption(int  fd, int  domain, int  option, int  _flag)
{
#ifdef _WIN32
    DWORD  flag = (DWORD) _flag;
#else
    int    flag = _flag;
#endif
    return setsockopt( fd, domain, option, (const char*)&flag, sizeof(flag) );
}

int socket_set_xreuseaddr(int  fd)
{
#ifdef _WIN32
   /* on Windows, SO_REUSEADDR is used to indicate that several programs can
    * bind to the same port. this is completely different from the Unix
    * semantics. instead of SO_EXCLUSIVEADDR to ensure that explicitely prevent
    * this.
    */
    return socket_setoption(fd, SOL_SOCKET, SO_EXCLUSIVEADDRUSE, 1);
#else
    return socket_setoption(fd, SOL_SOCKET, SO_REUSEADDR, 1);
#endif
}


int socket_set_oobinline(int  fd)
{
    return socket_setoption(fd, SOL_SOCKET, SO_OOBINLINE, 1);
}

int socket_set_cork(int fd, int v)
{
#if defined(SOL_TCP) && defined(TCP_CORK)
    return socket_setoption(fd, SOL_TCP, TCP_CORK, v);
#else
    return 0;
#endif
}

int  socket_set_nodelay(int  fd)
{
    return socket_setoption(fd, IPPROTO_TCP, TCP_NODELAY, 1);
}

int socket_set_ipv6only(int  fd)
{
/* IPV6_ONLY is only supported since Vista on Windows,
 * and the Mingw headers lack its definition anyway.
 */
#if defined(_WIN32) && !defined(IPV6_V6ONLY)
	return 0;
#else
    return socket_setoption(fd, IPPROTO_IPV6, IPV6_V6ONLY, 1);
#endif
}


int socket_get_error(int fd)
{
    return socket_getoption(fd, SOL_SOCKET, SO_ERROR, -1);
}

#ifdef _WIN32
#include <stdlib.h>

static void socket_cleanup(void)
{
    WSACleanup();
}

int socket_init(void)
{
    WSADATA Data;
    int ret;

    ret = WSAStartup(MAKEWORD(2,2), &Data);
    if (ret != 0) {
        (void) WSAGetLastError();
        return -1;
    }
    atexit(socket_cleanup);
    return 0;
}

#else /* !_WIN32 */

int socket_init(void)
{
   return 0;   /* nothing to do on Unix */
}

#endif /* !_WIN32 */


void
socket_close( int  fd ) {
    socket_drainer_drain_and_close(fd);
}

static int
socket_bind_server( int  s, const SockAddress*  to, SocketType  type )
{
    socket_set_xreuseaddr(s);

    if (socket_bind(s, to) < 0) {
        D("could not bind server socket address %s: %s",
          sock_address_to_string(to), errno_str);
        goto FAIL;
    }

    if (type == SOCKET_STREAM) {
        if (socket_listen(s, 4) < 0) {
            D("could not listen server socket %s: %s",
              sock_address_to_string(to), errno_str);
            goto FAIL;
        }
    }
    return  s;

FAIL:
    socket_close(s);
    return -1;
}


static int
socket_connect_client( int  s, const SockAddress*  to )
{
    if (socket_connect(s, to) < 0) {
        D( "could not connect client socket to %s: %s\n",
           sock_address_to_string(to), errno_str );
        socket_close(s);
        return -1;
    }

    socket_set_nonblock( s );
    return s;
}


static int
socket_in_server( int  address, int  port, SocketType  type )
{
    SockAddress  addr;
    int          s;

    sock_address_init_inet( &addr, address, port );
    s = socket_create_inet( type );
    if (s < 0)
        return -1;

    return socket_bind_server( s, &addr, type );
}


static int
socket_in_client( SockAddress*  to, SocketType  type )
{
    int  s;

    s = socket_create_inet( type );
    if (s < 0) return -1;

    return socket_connect_client( s, to );
}


int
socket_loopback_server( int  port, SocketType  type )
{
    return socket_in_server( SOCK_ADDRESS_INET_LOOPBACK, port, type );
}

int
socket_loopback_client( int  port, SocketType  type )
{
    SockAddress  addr;

    sock_address_init_inet( &addr, SOCK_ADDRESS_INET_LOOPBACK, port );
    return socket_in_client( &addr, type );
}


int
socket_network_client( const char*  host, int  port, SocketType  type )
{
    SockAddress  addr;

    if (sock_address_init_resolve( &addr, host, port, 0) < 0)
        return -1;

    return socket_in_client( &addr, type );
}


int
socket_anyaddr_server( int  port, SocketType  type )
{
    return socket_in_server( SOCK_ADDRESS_INET_ANY, port, type );
}

int
socket_accept_any( int  server_fd )
{
    int  fd;

    QSOCKET_CALL(fd, accept( server_fd, NULL, 0 ));
    if (fd < 0) {
        D( "could not accept client connection from fd %d: %s",
           server_fd, errno_str );
        return -1;
    }

    /* set to non-blocking */
    socket_set_nonblock( fd );
    return fd;
}


#if HAVE_UNIX_SOCKETS

int
socket_unix_server( const char*  name, SocketType  type )
{
    SockAddress   addr;
    int           s, ret;

    s = socket_create_unix( type );
    if (s < 0)
        return -1;

    sock_address_init_unix( &addr, name );

    HANDLE_EINTR(unlink(name));

    ret = socket_bind_server( s, &addr, type );

    sock_address_done( &addr );
    return ret;
}

int
socket_unix_client( const char*  name, SocketType  type )
{
    SockAddress   addr;
    int           s, ret;

    s = socket_create_unix(type);
    if (s < 0)
        return -1;

    sock_address_init_unix( &addr, name );

    ret =  socket_connect_client( s, &addr );

    sock_address_done( &addr );
    return ret;
}

#endif /* HAVE_UNIX_SOCKETS */



int
socket_pair(int *fd1, int *fd2)
{
#ifndef _WIN32
    int   fds[2];
    int   ret = socketpair(AF_UNIX, SOCK_STREAM, 0, fds);

    if (!ret) {
        socket_set_nonblock(fds[0]);
        socket_set_nonblock(fds[1]);
        *fd1 = fds[0];
        *fd2 = fds[1];
    }
    return ret;
#else /* _WIN32 */
    /* on Windows, select() only works with network sockets, which
     * means we absolutely cannot use Win32 PIPEs to implement
     * socket pairs with the current event loop implementation.
     * We're going to do like Cygwin: create a random pair
     * of localhost TCP sockets and connect them together
     */
    int                 s0, s1, s2, port;
    struct sockaddr_in  sockin;
    socklen_t           len;

    /* first, create the 'server' socket.
     * a port number of 0 means 'any port between 1024 and 5000.
     * see Winsock bind() documentation for details */
    s0 = socket_loopback_server( 0, SOCK_STREAM );
    if (s0 < 0)
        return -1;

    /* now connect a client socket to it, we first need to
     * extract the server socket's port number */
    len = sizeof sockin;
    if (getsockname(s0, (struct sockaddr*) &sockin, &len) < 0) {
        closesocket (s0);
        return -1;
    }

    port = ntohs(sockin.sin_port);
    s2   = socket_loopback_client( port, SOCK_STREAM );
    if (s2 < 0) {
        closesocket(s0);
        return -1;
    }

    /* we need to accept the connection on the server socket
     * this will create the second socket for the pair
     */
    len = sizeof sockin;
    s1  = accept(s0, (struct sockaddr*) &sockin, &len);
    if (s1 == INVALID_SOCKET) {
        closesocket (s0);
        closesocket (s2);
        return -1;
    }
    socket_set_nonblock(s1);

    /* close server socket */
    closesocket(s0);
    *fd1 = s1;
    *fd2 = s2;
    return 0;
#endif /* _WIN32 */
}



int
socket_mcast_inet_add_membership( int  s, uint32_t  ip )
{
    struct ip_mreq imr;

    imr.imr_multiaddr.s_addr = htonl(ip);
    imr.imr_interface.s_addr = htonl(INADDR_ANY);

    if ( setsockopt( s, IPPROTO_IP, IP_ADD_MEMBERSHIP,
                     (const char *)&imr,
                     sizeof(struct ip_mreq)) < 0 )
    {
        return fix_errno();
    }
    return 0;
}

int
socket_mcast_inet_drop_membership( int  s, uint32_t  ip )
{
    struct ip_mreq imr;

    imr.imr_multiaddr.s_addr = htonl(ip);
    imr.imr_interface.s_addr = htonl(INADDR_ANY);

    if ( setsockopt( s, IPPROTO_IP, IP_DROP_MEMBERSHIP,
                     (const char *)&imr,
                     sizeof(struct ip_mreq)) < 0 )
    {
        return fix_errno();
    }
    return 0;
}

int
socket_mcast_inet_set_loop( int  s, int  enabled )
{
    return socket_setoption( s, IPPROTO_IP, IP_MULTICAST_LOOP, !!enabled );
}

int
socket_mcast_inet_set_ttl( int  s, int  ttl )
{
    return socket_setoption( s, IPPROTO_IP, IP_MULTICAST_TTL, ttl );
}


char*
host_name( void )
{
    static char buf[256];  /* 255 is the max host name length supported by DNS */
    int         ret;

    QSOCKET_CALL(ret, gethostname(buf, sizeof(buf)));

    if (ret < 0)
        return "localhost";
    else
        return buf;
}


// Temporary work-arounds until we get rid of this source file.

int qemu_getsockopt(int sock, int level, int optname, void* optval,
                    size_t* optlen) {
    socklen_t len = (socklen_t) *optlen;
    int ret = getsockopt(sock, level, optname, (char*)optval, &len);
    *optlen = (size_t) len;
    return ret;
}

int qemu_setsockopt(int sock, int level, int optname, const void* optval,
                    size_t optlen) {
  return setsockopt(sock, level, optname, (const char*)optval,
                    (socklen_t)optlen);
}

int qemu_recv(int sock, void* buf, size_t len, int flags) {
  return recv(sock, buf, len, flags);
}
