aboutsummaryrefslogtreecommitdiffstats
path: root/qemu-sockets-android.c
diff options
context:
space:
mode:
authorDavid 'Digit' Turner <digit@android.com>2010-12-23 00:59:44 +0100
committerDavid 'Digit' Turner <digit@android.com>2011-01-02 22:09:05 +0100
commitca6a2e034bce665a08d9d748ac11d6a7cfcd7c48 (patch)
treeed261be80a75ad5c2508a154f27a3101a7752d16 /qemu-sockets-android.c
parent8423ffa1a8c56e65220e2a354cd62f71f99a7a06 (diff)
downloadexternal_qemu-ca6a2e034bce665a08d9d748ac11d6a7cfcd7c48.zip
external_qemu-ca6a2e034bce665a08d9d748ac11d6a7cfcd7c48.tar.gz
external_qemu-ca6a2e034bce665a08d9d748ac11d6a7cfcd7c48.tar.bz2
qemu-sockets-android.c: Add inet_dgram_opts
Change-Id: I30b3905332925d369481612a571342e21a5a7ed9
Diffstat (limited to 'qemu-sockets-android.c')
-rw-r--r--qemu-sockets-android.c112
1 files changed, 112 insertions, 0 deletions
diff --git a/qemu-sockets-android.c b/qemu-sockets-android.c
index e7d5e18..b07129b 100644
--- a/qemu-sockets-android.c
+++ b/qemu-sockets-android.c
@@ -26,6 +26,10 @@
# define AI_ADDRCONFIG 0
#endif
+#ifndef INET6_ADDRSTRLEN
+# define INET6_ADDRSTRLEN 46
+#endif
+
static int sockets_debug = 0;
static const int on=1, off=0;
@@ -252,6 +256,114 @@ EXIT:
return sock;
}
+int inet_dgram_opts(QemuOpts *opts)
+{
+ SockAddress** peer_list = NULL;
+ SockAddress** local_list = NULL;
+ SockAddress* e;
+ unsigned flags = 0;
+ const char *addr;
+ const char *port;
+ char uaddr[INET6_ADDRSTRLEN+1];
+ char uport[33];
+ int sock = -1;
+ int nn;
+
+ /* lookup peer addr */
+ addr = qemu_opt_get(opts, "host");
+ port = qemu_opt_get(opts, "port");
+ if (addr == NULL || strlen(addr) == 0) {
+ addr = "localhost";
+ }
+ if (port == NULL || strlen(port) == 0) {
+ fprintf(stderr, "inet_dgram: port not specified\n");
+ return -1;
+ }
+
+ flags = SOCKET_LIST_DGRAM;
+ if (qemu_opt_get_bool(opts, "ipv4", 0)) {
+ flags &= SOCKET_LIST_FORCE_IN6;
+ flags |= SOCKET_LIST_FORCE_INET;
+ }
+ if (qemu_opt_get_bool(opts, "ipv6", 0)) {
+ flags &= SOCKET_LIST_FORCE_INET;
+ flags |= SOCKET_LIST_FORCE_IN6;
+ }
+
+ peer_list = sock_address_list_create(addr, port, flags);
+ if (peer_list == NULL) {
+ fprintf(stderr,"getaddrinfo(%s,%s): %s\n",
+ addr, port, errno_str);
+ return -1;
+ }
+
+ /* lookup local addr */
+ addr = qemu_opt_get(opts, "localaddr");
+ port = qemu_opt_get(opts, "localport");
+ if (addr == NULL || strlen(addr) == 0) {
+ addr = NULL;
+ }
+ if (!port || strlen(port) == 0)
+ port = "0";
+
+ flags = SOCKET_LIST_DGRAM | SOCKET_LIST_PASSIVE;
+ local_list = sock_address_list_create(addr, port, flags);
+ if (local_list == NULL) {
+ fprintf(stderr,"getaddrinfo(%s,%s): %s\n",
+ addr, port, errno_str);
+ goto EXIT;
+ }
+
+ if (sock_address_get_numeric_info(local_list[0],
+ uaddr, INET6_ADDRSTRLEN,
+ uport, 32)) {
+ fprintf(stderr, "%s: getnameinfo: oops\n", __FUNCTION__);
+ goto EXIT;
+ }
+
+ for (nn = 0; peer_list[nn] != NULL; nn++) {
+ SockAddress *local = local_list[0];
+ e = peer_list[nn];
+ sock = socket_create(sock_address_get_family(e), SOCKET_DGRAM);
+ if (sock < 0) {
+ fprintf(stderr,"%s: socket(%s): %s\n", __FUNCTION__,
+ sock_address_strfamily(e), errno_str);
+ continue;
+ }
+ socket_set_xreuseaddr(sock);
+
+ /* bind socket */
+ if (socket_bind(sock, local) < 0) {
+ fprintf(stderr,"%s: bind(%s,%s,%s): OK\n", __FUNCTION__,
+ sock_address_strfamily(local), addr, port);
+ socket_close(sock);
+ continue;
+ }
+
+ /* connect to peer */
+ if (socket_connect(sock,e) < 0) {
+ if (sockets_debug)
+ fprintf(stderr, "%s: connect(%s,%s,%s,%s): %s\n", __FUNCTION__,
+ sock_address_strfamily(e),
+ sock_address_to_string(e), addr, port, strerror(errno));
+ socket_close(sock);
+ continue;
+ }
+ if (sockets_debug)
+ fprintf(stderr, "%s: connect(%s,%s,%s,%s): OK\n", __FUNCTION__,
+ sock_address_strfamily(e),
+ sock_address_to_string(e), addr, port);
+
+ goto EXIT;
+ }
+ sock = -1;
+EXIT:
+ if (local_list)
+ sock_address_list_free(local_list);
+ if (peer_list)
+ sock_address_list_free(peer_list);
+ return sock;
+}
/* compatibility wrapper */
static int inet_parse(QemuOpts *opts, const char *str)