Move net.h to include/net/

+ Move net-android.c and net.c to net/
+ Rename net-checksum.c to net/checksum.c
+ Move sockets.h and shaper.h to include/android/
  and sockets.c + shaper.c to android/

+ Move vgafont.h to ui/

Change-Id: I2659a919a316d3f95aac0f9924833eeee4cb5592
diff --git a/android/adb-server.c b/android/adb-server.c
index 41b2ffd..bc7baa1 100644
--- a/android/adb-server.c
+++ b/android/adb-server.c
@@ -15,7 +15,7 @@
  */
 
 #include "qemu-common.h"
-#include "sockets.h"
+#include "android/sockets.h"
 #include "iolooper.h"
 #include "android/async-utils.h"
 #include "android/utils/debug.h"
diff --git a/android/async-utils.h b/android/async-utils.h
index 30dfbe3..da5e506 100644
--- a/android/async-utils.h
+++ b/android/async-utils.h
@@ -17,7 +17,7 @@
 #define ANDROID_ASYNC_UTILS_H
 
 #include "android/looper.h"
-#include "sockets.h"
+#include "android/sockets.h"
 
 /* A set of useful data types to perform asynchronous operations.
  *
diff --git a/android/console.c b/android/console.c
index 07a59d2..51209cf 100644
--- a/android/console.c
+++ b/android/console.c
@@ -21,14 +21,14 @@
  *
  */
 
-#include "sockets.h"
+#include "android/sockets.h"
 #include "qemu-char.h"
 #include "sysemu.h"
 #include "android/android.h"
 #include "cpu.h"
 #include "hw/goldfish_device.h"
 #include "hw/power_supply.h"
-#include "shaper.h"
+#include "android/shaper.h"
 #include "modem_driver.h"
 #include "android/gps.h"
 #include "android/globals.h"
@@ -37,7 +37,7 @@
 #include "android/utils/stralloc.h"
 #include "android/config/config.h"
 #include "tcpdump.h"
-#include "net.h"
+#include "net/net.h"
 #include "monitor.h"
 
 #include <stdlib.h>
diff --git a/android/core-init-utils.c b/android/core-init-utils.c
index 97d5f05..aa676f8 100644
--- a/android/core-init-utils.c
+++ b/android/core-init-utils.c
@@ -19,7 +19,7 @@
 #include <stdlib.h>
 #include <errno.h>
 #include "qemu-common.h"
-#include "sockets.h"
+#include "android/sockets.h"
 #include "android/android.h"
 #include "android/core-init-utils.h"
 #include "android/utils/bufprint.h"
diff --git a/android/hw-pipe-net.c b/android/hw-pipe-net.c
index 1c71f18..f1c1411 100644
--- a/android/hw-pipe-net.c
+++ b/android/hw-pipe-net.c
@@ -18,7 +18,7 @@
  * guest clients to directly connect to a TCP port through /dev/qemu_pipe.
  */
 
-#include "sockets.h"
+#include "android/sockets.h"
 #include "android/utils/assert.h"
 #include "android/utils/panic.h"
 #include "android/utils/system.h"
diff --git a/android/looper-generic.c b/android/looper-generic.c
index ddc0824..9fd4f0b 100644
--- a/android/looper-generic.c
+++ b/android/looper-generic.c
@@ -16,7 +16,7 @@
 #include "android/utils/system.h"
 #include "android/looper.h"
 #include "iolooper.h"
-#include "sockets.h"
+#include "android/sockets.h"
 #include <inttypes.h>
 #include <limits.h>
 #include <errno.h>
diff --git a/android/looper-qemu.c b/android/looper-qemu.c
index 6ea64ca..df40afe 100644
--- a/android/looper-qemu.c
+++ b/android/looper-qemu.c
@@ -17,7 +17,7 @@
 #include "qemu-common.h"
 #include "qemu/timer.h"
 #include "qemu-char.h"
-#include "sockets.h"  /* for socket_set_nonblock() */
+#include "android/sockets.h"  /* for socket_set_nonblock() */
 
 /**********************************************************************
  **********************************************************************
diff --git a/android/main.c b/android/main.c
index 1ca94df..757a05f 100644
--- a/android/main.c
+++ b/android/main.c
@@ -18,7 +18,7 @@
 #include <process.h>
 #endif
 
-#include "sockets.h"
+#include "android/sockets.h"
 
 #include "android/android.h"
 #include "qemu-common.h"
diff --git a/android/protocol/attach-ui-impl.h b/android/protocol/attach-ui-impl.h
index 3adc83a..db63955 100644
--- a/android/protocol/attach-ui-impl.h
+++ b/android/protocol/attach-ui-impl.h
@@ -13,7 +13,7 @@
 #ifndef _ANDROID_PROTOCOL_ATTACH_UI_IMPL_H
 #define _ANDROID_PROTOCOL_ATTACH_UI_IMPL_H
 
-#include "sockets.h"
+#include "android/sockets.h"
 
 /*
  * Contains the UI-side implementation of the "attach-ui" service that is
diff --git a/android/protocol/core-commands-proxy.h b/android/protocol/core-commands-proxy.h
index 4283296..289421f 100644
--- a/android/protocol/core-commands-proxy.h
+++ b/android/protocol/core-commands-proxy.h
@@ -13,7 +13,7 @@
 #ifndef _ANDROID_PROTOCOL_CORE_COMMANDS_PROXY_H
 #define _ANDROID_PROTOCOL_CORE_COMMANDS_PROXY_H
 
-#include "sockets.h"
+#include "android/sockets.h"
 
 /*
  * Contains the UI-side implementation of the "ui-core-control" service that is
diff --git a/android/protocol/core-connection.c b/android/protocol/core-connection.c
index 6de5386..35f4d6a 100644
--- a/android/protocol/core-connection.c
+++ b/android/protocol/core-connection.c
@@ -12,7 +12,7 @@
 
 #include <unistd.h>
 
-#include "sockets.h"
+#include "android/sockets.h"
 #include "qemu-common.h"
 #include "errno.h"
 #include "iolooper.h"
diff --git a/android/protocol/ui-commands-impl.h b/android/protocol/ui-commands-impl.h
index f575bd0..717f6b6 100644
--- a/android/protocol/ui-commands-impl.h
+++ b/android/protocol/ui-commands-impl.h
@@ -13,7 +13,7 @@
 #ifndef _ANDROID_PROTOCOL_UI_COMMANDS_IMPL_H
 #define _ANDROID_PROTOCOL_UI_COMMANDS_IMPL_H
 
-#include "sockets.h"
+#include "android/sockets.h"
 #include "android/looper.h"
 #include "android/protocol/ui-commands.h"
 
diff --git a/android/shaper.c b/android/shaper.c
new file mode 100644
index 0000000..4dbb8ea
--- /dev/null
+++ b/android/shaper.c
@@ -0,0 +1,590 @@
+/* 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.
+*/
+#include "android/shaper.h"
+#include "qemu-common.h"
+#include "qemu/timer.h"
+#include <stdlib.h>
+
+#define  SHAPER_CLOCK        rt_clock
+#define  SHAPER_CLOCK_UNIT   1000.
+
+static int
+_packet_is_internal( const uint8_t*  data, size_t  size )
+{
+    const uint8_t*  end = data + size;
+
+    /* must have room for Mac + IP header */
+    if (data + 40 > end)
+        return 0;
+
+    if (data[12] != 0x08 || data[13] != 0x00 )
+        return 0;
+
+    /* must have valid IP header */
+    data += 14;
+    if ((data[0] >> 4) != 4 || (data[0] & 15) < 5)
+        return 0;
+
+    /* internal if both source and dest addresses are in 10.x.x.x */
+    return ( data[12] == 10 && data[16] == 10);
+}
+
+/* here's how we implement network shaping. we want to limit the network
+ * rate to a given constant MAX_RATE expressed as bits/second. this means
+ * that it takes 1/MAX_RATE seconds to send a single bit, and count*8/MAX_RATE
+ * seconds to send 'count' bytes.
+ *
+ * we're going to implement a scheme where, when we send a packet of
+ * 'count' bytes, no other packet will go through in the same direction for
+ * at least 'count*8/MAX_RATE' seconds. any successive packet that is "sent"
+ * in this interval is placed in a queue, associated to a timer
+ *
+ * there are different (queue/timer/rate) values for the input and output
+ * direction of the user vlan.
+ */
+typedef struct QueuedPacketRec_ {
+    int64_t                    expiration;
+    struct QueuedPacketRec_*   next;
+    size_t                     size;
+    void*                      opaque;
+    void*                      data;
+} QueuedPacketRec, *QueuedPacket;
+
+
+static QueuedPacket
+queued_packet_create( const void*   data,
+                      size_t        size,
+                      void*         opaque,
+                      int           do_copy )
+{
+    QueuedPacket   packet;
+    size_t         packet_size = sizeof(*packet);
+
+    if (do_copy)
+        packet_size += size;
+
+    packet = qemu_malloc(packet_size);
+    packet->next       = NULL;
+    packet->expiration = 0;
+    packet->size       = (size_t)size;
+    packet->opaque     = opaque;
+
+    if (do_copy) {
+        packet->data = (void*)(packet+1);
+        memcpy( (char*)packet->data, (char*)data, packet->size );
+    } else {
+        packet->data = (void*)data;
+    }
+    return packet;
+}
+
+static void
+queued_packet_free( QueuedPacket  packet )
+{
+    if (packet) {
+        qemu_free( packet );
+    }
+}
+
+typedef struct NetShaperRec_ {
+    QueuedPacket   packets;   /* list of queued packets, ordered by expiration date */
+    int            num_packets;
+    int            active;    /* is this shaper active ? */
+    int64_t        block_until;
+    double         max_rate;  /* max rate expressed in bytes/second */
+    double         inv_rate;  /* inverse of max rate                */
+    QEMUTimer*     timer;     /* QEMU timer */
+
+    int                do_copy;
+    NetShaperSendFunc  send_func;
+
+} NetShaperRec;
+
+
+void
+netshaper_destroy( NetShaper  shaper )
+{
+    if (shaper) {
+        shaper->active = 0;
+
+        while (shaper->packets) {
+            QueuedPacket  packet = shaper->packets;
+            shaper->packets = packet->next;
+            packet->next    = NULL;
+            queued_packet_free(packet);
+        }
+
+        qemu_del_timer(shaper->timer);
+        qemu_free_timer(shaper->timer);
+        shaper->timer = NULL;
+        qemu_free(shaper);
+    }
+}
+
+/* this function is called when the shaper's timer expires */
+static void
+netshaper_expires( NetShaper  shaper )
+{
+    QueuedPacket  packet;
+
+    while ((packet = shaper->packets) != NULL) {
+        int64_t   now = qemu_get_clock_ms( SHAPER_CLOCK );
+
+       if (packet->expiration > now)
+           break;
+
+       shaper->packets = packet->next;
+       shaper->send_func( packet->data, packet->size, packet->opaque );
+       queued_packet_free(packet);
+       shaper->num_packets--;
+   }
+
+   /* reprogram timer if needed */
+   if (shaper->packets) {
+       shaper->block_until = shaper->packets->expiration;
+       qemu_mod_timer( shaper->timer, shaper->block_until );
+   } else {
+       shaper->block_until = -1;
+   }
+}
+
+
+NetShaper
+netshaper_create( int                do_copy,
+                  NetShaperSendFunc  send_func )
+{
+    NetShaper  shaper = qemu_malloc(sizeof(*shaper));
+
+    shaper->active = 0;
+    shaper->packets = NULL;
+    shaper->num_packets = 0;
+    shaper->timer   = qemu_new_timer_ms( SHAPER_CLOCK,
+                                         (QEMUTimerCB*) netshaper_expires,
+                                         shaper );
+    shaper->send_func = send_func;
+    shaper->max_rate  = 1e6;
+    shaper->inv_rate  = 0.;
+
+    shaper->block_until = -1; /* magic value, means to not block */
+
+    return shaper;
+}
+
+void
+netshaper_set_rate( NetShaper  shaper,
+                    double     rate )
+{
+    /* send all current packets when changing the rate */
+    while (shaper->packets) {
+        QueuedPacket  packet = shaper->packets;
+        shaper->packets = packet->next;
+        shaper->send_func(packet->data, packet->size, packet->opaque);
+        qemu_free(packet);
+        shaper->num_packets = 0;
+    }
+
+    shaper->max_rate = rate;
+    if (rate > 1.) {
+        shaper->inv_rate = (8.*SHAPER_CLOCK_UNIT)/rate;  /* qemu_get_clock returns time in ms */
+        shaper->active   = 1;                            /* for the real-time clock           */
+    } else {
+        shaper->active = 0;
+    }
+
+    shaper->block_until = -1;
+}
+
+void
+netshaper_send_aux( NetShaper  shaper,
+                    void*      data,
+                    size_t     size,
+                    void*      opaque )
+{
+    int64_t   now;
+
+    if (!shaper->active || _packet_is_internal(data, size)) {
+        shaper->send_func( data, size, opaque );
+        return;
+    }
+
+    now = qemu_get_clock_ms( SHAPER_CLOCK );
+    if (now >= shaper->block_until) {
+        shaper->send_func( data, size, opaque );
+        shaper->block_until = now + size*shaper->inv_rate;
+        //fprintf(stderr, "NETSHAPER: block for %.2fms\n", (shaper->block_until - now)*1.0 );
+        return;
+    }
+
+    /* create new packet, add it to the queue */
+    {
+        QueuedPacket   packet;
+
+        packet = queued_packet_create( data, size, opaque, shaper->do_copy );
+
+        packet->expiration = shaper->block_until;
+
+        {
+            QueuedPacket  *pnode, node;
+
+            pnode = &shaper->packets;
+            for (;;) {
+                node = *pnode;
+                if (node == NULL || node->expiration > packet->expiration )
+                    break;
+                pnode = &node->next;
+            }
+            packet->next = *pnode;
+            *pnode       = packet;
+
+            if (packet == shaper->packets)
+                qemu_mod_timer( shaper->timer, packet->expiration );
+        }
+        shaper->num_packets += 1;
+    }
+    shaper->block_until += size*shaper->inv_rate;
+    //fprintf(stderr, "NETSHAPER: block2 for %.2fms\n", (shaper->block_until - now)*1.0 );
+}
+
+void
+netshaper_send( NetShaper  shaper,
+                void*      data,
+                size_t     size )
+{
+    netshaper_send_aux(shaper, data, size, NULL);
+}
+
+
+int
+netshaper_can_send( NetShaper  shaper )
+{
+    int64_t  now;
+
+    if (!shaper->active || shaper->block_until < 0)
+        return 1;
+
+    if (shaper->packets)
+        return 0;
+
+    now = qemu_get_clock_ms( SHAPER_CLOCK );
+    return (now >= shaper->block_until);
+}
+
+
+
+
+
+
+/* this type is used to model a session connection/state
+ * if session->packet is != NULL, then the connection is delayed
+ */
+typedef struct SessionRec_ {
+    int64_t               expiration;
+    struct SessionRec_*   next;
+    unsigned              src_ip;
+    unsigned              dst_ip;
+    unsigned short        src_port;
+    unsigned short        dst_port;
+    uint8_t               protocol;
+    QueuedPacket          packet;
+
+} SessionRec, *Session;
+
+#define  _PROTOCOL_TCP   6
+#define  _PROTOCOL_UDP   17
+
+
+
+static void
+session_free( Session  session )
+{
+    if (session) {
+        if (session->packet) {
+            queued_packet_free(session->packet);
+            session->packet = NULL;
+        }
+        qemu_free( session );
+    }
+}
+
+
+#if 0  /* useful for debugging */
+static const char*
+session_to_string( Session  session )
+{
+    static char  temp[256];
+    const char*  format = (session->protocol == _PROTOCOL_TCP) ? "TCP" : "UDP";
+    sprintf( temp, "%s[%d.%d.%d.%d:%d / %d.%d.%d.%d:%d]", format,
+             (session->src_ip >> 24) & 255, (session->src_ip >> 16) & 255,
+             (session->src_ip >> 8) & 255, (session->src_ip) & 255, session->src_port,
+             (session->dst_ip >> 24) & 255, (session->dst_ip >> 16) & 255,
+             (session->dst_ip >> 8) & 255, (session->dst_ip) & 255, session->dst_port);
+
+    return temp;
+}
+#endif
+
+/* returns TRUE if this corresponds to a SYN packet */
+int
+_packet_SYN_flags( const void*  _data, size_t   size, Session  info )
+{
+    const uint8_t*  data = (const uint8_t*)_data;
+    const uint8_t*  end  = data + size;
+
+    /* enough room for a Ethernet MAC packet ? */
+    if (data + 14 > end - 4)
+        return 0;
+
+    /* is it an IP packet ? */
+    if (data[12] != 0x8 || data[13] != 0)
+        return 0;
+
+    data += 14;
+    end  -= 4;
+
+    if (data + 20 > end)
+        return 0;
+
+    /* IP version must be 4, and the header length in words at least 5 */
+    if ((data[0] & 0xF) < 5 || (data[0] >> 4) != 4)
+        return 0;
+
+    /* time-to-live must be > 0 */
+    if (data[8] == 0)
+        return 0;
+
+    /* must be TCP or UDP packet */
+    if (data[9] != _PROTOCOL_TCP && data[9] != _PROTOCOL_UDP)
+        return 0;
+
+    info->protocol = data[9];
+    info->src_ip   = (data[12] << 24) | (data[13] << 16) | (data[14] << 8) | data[15];
+    info->dst_ip   = (data[16] << 24) | (data[17] << 16) | (data[18] << 8) | data[19];
+
+    data += 4*(data[0] & 15);
+    if (data + 20 > end)
+        return 0;
+
+    info->src_port = (unsigned short)((data[0] << 8) | data[1]);
+    info->dst_port = (unsigned short)((data[2] << 8) | data[3]);
+
+    return (data[13] & 0x1f);
+}
+
+
+typedef struct NetDelayRec_
+{
+    Session     sessions;
+    int         num_sessions;
+    QEMUTimer*  timer;
+    int         active;
+    int         min_ms;
+    int         max_ms;
+
+    NetShaperSendFunc  send_func;
+
+} NetDelayRec;
+
+
+static Session*
+netdelay_lookup_session( NetDelay  delay, Session  info )
+{
+    Session*  pnode = &delay->sessions;
+    Session   node;
+
+    for (;;) {
+        node = *pnode;
+        if (node == NULL)
+            break;
+
+        if (node->src_ip == info->src_ip &&
+            node->dst_ip == info->dst_ip &&
+            node->src_port == info->src_port &&
+            node->dst_port == info->dst_port &&
+            node->protocol == info->protocol )
+            break;
+
+        pnode = &node->next;
+    }
+    return pnode;
+}
+
+
+
+/* called by the delay's timer on expiration */
+static void
+netdelay_expires( NetDelay  delay )
+{
+    Session  session;
+    int64_t  now = qemu_get_clock_ms( SHAPER_CLOCK );
+    int      rearm = 0;
+    int64_t  rearm_time = 0;
+
+    for (session = delay->sessions; session != NULL; session = session->next)
+    {
+        QueuedPacket  packet = session->packet;
+
+        if (packet == NULL)
+            continue;
+
+        if (session->expiration <= now) {
+            /* send the SYN packet now */
+                    //fprintf(stderr, "NetDelay:RST: sending creation for %s\n", session_to_string(session) );
+            delay->send_func( packet->data, packet->size, packet->opaque );
+            session->packet = NULL;
+            queued_packet_free( packet );
+        } else {
+            if (!rearm) {
+                rearm      = 1;
+                rearm_time = session->expiration;
+            }
+            else if ( session->expiration < rearm_time )
+                rearm_time = session->expiration;
+        }
+    }
+
+    if (rearm)
+        qemu_mod_timer( delay->timer, rearm_time );
+}
+
+
+NetDelay
+netdelay_create( NetShaperSendFunc  send_func )
+{
+    NetDelay  delay = qemu_malloc(sizeof(*delay));
+
+    delay->sessions     = NULL;
+    delay->num_sessions = 0;
+    delay->timer        = qemu_new_timer_ms( SHAPER_CLOCK,
+                                             (QEMUTimerCB*) netdelay_expires,
+                                             delay );
+    delay->active = 0;
+    delay->min_ms = 0;
+    delay->max_ms = 0;
+
+    delay->send_func = send_func;
+
+    return delay;
+}
+
+
+void
+netdelay_set_latency( NetDelay  delay, int  min_ms, int  max_ms )
+{
+    /* when changing the latency, accept all sessions */
+    while (delay->sessions) {
+        Session  session = delay->sessions;
+        delay->sessions = session->next;
+        session->next = NULL;
+        if (session->packet) {
+            QueuedPacket  packet = session->packet;
+            delay->send_func( packet->data, packet->size, packet->opaque );
+        }
+        session_free(session);
+        delay->num_sessions--;
+    }
+
+    delay->min_ms = min_ms;
+    delay->max_ms = max_ms;
+    delay->active = (min_ms <= max_ms) && min_ms > 0;
+}
+
+void
+netdelay_send( NetDelay  delay, const void*  data, size_t  size )
+{
+    netdelay_send_aux(delay, data, size, NULL);
+}
+
+
+void
+netdelay_send_aux( NetDelay  delay, const void*  data, size_t  size, void* opaque )
+{
+    if (delay->active && !_packet_is_internal(data, size)) {
+        SessionRec  info[1];
+        int         flags;
+
+        flags = _packet_SYN_flags( data, size, info );
+        if ((flags & 0x05) != 0)
+        {  /* FIN or RST: drop connection */
+            Session*  lookup  = netdelay_lookup_session( delay, info );
+            Session   session = *lookup;
+            if (session != NULL) {
+                //fprintf(stderr, "NetDelay:RST: dropping %s\n", session_to_string(info) );
+
+                *lookup = session->next;
+                session_free( session );
+                delay->num_sessions -= 1;
+            }
+        }
+        else if ((flags & 0x12) == 0x02)
+        {
+            /* SYN: create connection */
+            Session*  lookup  = netdelay_lookup_session( delay, info );
+            Session   session = *lookup;
+
+            if (session != NULL) {
+                if (session->packet != NULL) {
+                   /* this is a SYN re-transmission, since we didn't
+                    * send the original SYN packet yet, just eat this one
+                    */
+                    //fprintf(stderr, "NetDelay:RST: swallow SYN re-send for %s\n", session_to_string(info) );
+                    return;
+                }
+            } else {
+                /* establish a new session slightly in the future */
+                int   latency = delay->min_ms;
+                int   range   = delay->max_ms - delay->min_ms;
+
+                 if (range > 0)
+                    latency += rand() % range;
+
+                    //fprintf(stderr, "NetDelay:RST: delay creation for %s\n", session_to_string(info) );
+                session = qemu_malloc( sizeof(*session) );
+
+                session->next        = delay->sessions;
+                delay->sessions      = session;
+                delay->num_sessions += 1;
+
+                session->expiration = qemu_get_clock_ms( SHAPER_CLOCK ) + latency;
+
+                session->src_ip   = info->src_ip;
+                session->dst_ip   = info->dst_ip;
+                session->src_port = info->src_port;
+                session->dst_port = info->dst_port;
+                session->protocol = info->protocol;
+
+                session->packet = queued_packet_create( data, size, opaque, 1 );
+
+                netdelay_expires(delay);
+                return;
+            }
+        }
+    }
+
+    delay->send_func( (void*)data, size, opaque );
+}
+
+
+void
+netdelay_destroy( NetDelay  delay )
+{
+    if (delay) {
+        while (delay->sessions) {
+            Session  session = delay->sessions;
+            delay->sessions = session->next;
+            session_free(session);
+            delay->num_sessions -= 1;
+        }
+        delay->active = 0;
+        qemu_free( delay );
+    }
+}
+
diff --git a/android/sockets.c b/android/sockets.c
new file mode 100644
index 0000000..2250ee8
--- /dev/null
+++ b/android/sockets.c
@@ -0,0 +1,1568 @@
+/* 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 "qemu_debug.h"
+#include "qemu-char.h"
+#include <stdlib.h>
+#include <string.h>
+#include "android/utils/path.h"
+#include "android/utils/debug.h"
+#include "android/utils/misc.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; \
+        do { _ret = (_cmd); } while ( _ret < 0 && errno == EINTR ); \
+    } 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( int  fd, const SockAddress*  address )
+{
+    sockaddr_storage  addr;
+    socklen_t         addrlen;
+
+    if (sock_address_to_bsd(address, &addr, &addrlen) < 0)
+        return -1;
+
+    SOCKET_CALL(connect(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 = getsockopt(fd, domain, option, (char*)&opt, &optlen);
+        if (ret == 0)
+            return (int)opt;
+        if (errno != EINTR)
+            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_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, err;
+
+    ret = WSAStartup(MAKEWORD(2,2), &Data);
+    if (ret != 0) {
+        err = WSAGetLastError();
+        return -1;
+    }
+    atexit(socket_cleanup);
+    return 0;
+}
+
+#else /* !_WIN32 */
+
+int socket_init(void)
+{
+   return 0;   /* nothing to do on Unix */
+}
+
+#endif /* !_WIN32 */
+
+#ifdef _WIN32
+
+static void
+socket_close_handler( void*  _fd )
+{
+    int   fd = (int)_fd;
+    int   ret;
+    char  buff[64];
+
+    /* we want to drain the read side of the socket before closing it */
+    do {
+        ret = recv( fd, buff, sizeof(buff), 0 );
+    } while (ret < 0 && WSAGetLastError() == WSAEINTR);
+
+    if (ret < 0 && WSAGetLastError() == EWOULDBLOCK)
+        return;
+
+    qemu_set_fd_handler( fd, NULL, NULL, NULL );
+    closesocket( fd );
+}
+
+void
+socket_close( int  fd )
+{
+    int  old_errno = errno;
+
+    shutdown( fd, SD_BOTH );
+    /* we want to drain the socket before closing it */
+    qemu_set_fd_handler( fd, socket_close_handler, NULL, (void*)fd );
+
+    errno = old_errno;
+}
+
+#else /* !_WIN32 */
+
+#include <unistd.h>
+
+void
+socket_close( int  fd )
+{
+    int  old_errno = errno;
+
+    shutdown( fd, SHUT_RDWR );
+    close( fd );
+
+    errno = old_errno;
+}
+
+#endif /* !_WIN32 */
+
+
+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 );
+
+    do {
+        ret = unlink( name );
+    } while (ret < 0 && errno == EINTR);
+
+    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;
+}
diff --git a/android/sync-utils.c b/android/sync-utils.c
index 617ba8b..cab0fa6 100644
--- a/android/sync-utils.c
+++ b/android/sync-utils.c
@@ -22,7 +22,7 @@
 #include "qemu-common.h"
 #include "errno.h"
 #include "iolooper.h"
-#include "sockets.h"
+#include "android/sockets.h"
 #include "android/utils/debug.h"
 #include "android/sync-utils.h"
 #include "android/utils/system.h"
diff --git a/android/sync-utils.h b/android/sync-utils.h
index bb54f3c..adb68a7 100644
--- a/android/sync-utils.h
+++ b/android/sync-utils.h
@@ -23,7 +23,7 @@
 #define ANDROID_SYNC_UTILS_H
 
 #include "android/android.h"
-#include "sockets.h"
+#include "android/sockets.h"
 
 /* Descriptor for a connected non-blocking socket providing synchronous I/O */
 typedef struct SyncSocket SyncSocket;