qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Gerd Hoffmann <kraxel@redhat.com>
To: qemu-devel@nongnu.org
Cc: Gerd Hoffmann <kraxel@redhat.com>
Subject: [Qemu-devel] [PATCH 3/3] sockets: switch over tcp/telnet/unix serial line to new helper functions.
Date: Mon,  3 Nov 2008 17:42:30 +0100	[thread overview]
Message-ID: <1225730550-31941-4-git-send-email-kraxel@redhat.com> (raw)
In-Reply-To: <1225730550-31941-1-git-send-email-kraxel@redhat.com>

This switches the tcp, telnet and unix socket support for character
devices (serial/parallel, ...) to the new socket helpers.  Thereby they
gain IPv6 support and also get ability to search for a free tcp port.
Syntax is the same as for vnc, using a to= option, like this:

	-serial tcp:localhost:5000,to=5099,server

This will check the 5000 -> 5099 port range (inclusive) for a free tcp
port.  Likewise you can get auto-allocated unix sockets by specifying an
empty path:

	-serial unix:,server

qemu will create a randomly named socket in $TMPDIR then.

tcp also got new "ipv4" and "ipv6" options to make qemu try only the
specified internet protocol version.

You can use the "info chardev" command added by the first patch in this
series to figure the tcp port / unix socket actually allocated.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 qemu-char.c |  106 ++++++++++++++++++-----------------------------------------
 1 files changed, 32 insertions(+), 74 deletions(-)

diff --git a/qemu-char.c b/qemu-char.c
index ceffbed..906e817 100644
--- a/qemu-char.c
+++ b/qemu-char.c
@@ -1951,32 +1951,11 @@ static CharDriverState *qemu_chr_open_tcp(const char *host_str,
 {
     CharDriverState *chr = NULL;
     TCPCharDriver *s = NULL;
-    int fd = -1, ret, err, val;
+    int fd = -1, offset = 0;
     int is_listen = 0;
     int is_waitconnect = 1;
     int do_nodelay = 0;
     const char *ptr;
-    struct sockaddr_in saddr;
-#ifndef _WIN32
-    struct sockaddr_un uaddr;
-#endif
-    struct sockaddr *addr;
-    socklen_t addrlen;
-
-#ifndef _WIN32
-    if (is_unix) {
-	addr = (struct sockaddr *)&uaddr;
-	addrlen = sizeof(uaddr);
-	if (parse_unix_path(&uaddr, host_str) < 0)
-	    goto fail;
-    } else
-#endif
-    {
-	addr = (struct sockaddr *)&saddr;
-	addrlen = sizeof(saddr);
-	if (parse_host_port(&saddr, host_str) < 0)
-	    goto fail;
-    }
 
     ptr = host_str;
     while((ptr = strchr(ptr,','))) {
@@ -1987,6 +1966,8 @@ static CharDriverState *qemu_chr_open_tcp(const char *host_str,
             is_waitconnect = 0;
         } else if (!strncmp(ptr,"nodelay",6)) {
             do_nodelay = 1;
+        } else if (!strncmp(ptr,"to=",3)) {
+            /* nothing, inet_listen() parses this one */;
         } else {
             printf("Unknown option: %s\n", ptr);
             goto fail;
@@ -2002,13 +1983,31 @@ static CharDriverState *qemu_chr_open_tcp(const char *host_str,
     if (!s)
         goto fail;
 
-#ifndef _WIN32
-    if (is_unix)
-	fd = socket(PF_UNIX, SOCK_STREAM, 0);
-    else
-#endif
-	fd = socket(PF_INET, SOCK_STREAM, 0);
-
+    if (is_listen) {
+        chr->filename = qemu_malloc(256);
+        if (is_unix) {
+            strcpy(chr->filename, "unix:");
+        } else if (is_telnet) {
+            strcpy(chr->filename, "telnet:");
+        } else {
+            strcpy(chr->filename, "tcp:");
+        }
+        offset = strlen(chr->filename);
+    }
+    if (is_unix) {
+        if (is_listen) {
+            fd = unix_listen(host_str, chr->filename + offset, 256 - offset);
+        } else {
+            fd = unix_connect(host_str);
+        }
+    } else {
+        if (is_listen) {
+            fd = inet_listen(host_str, chr->filename + offset, 256 - offset,
+                             SOCK_STREAM, 0);
+        } else {
+            fd = inet_connect(host_str, SOCK_STREAM);
+        }
+    }
     if (fd < 0)
         goto fail;
 
@@ -2026,61 +2025,20 @@ static CharDriverState *qemu_chr_open_tcp(const char *host_str,
     chr->chr_close = tcp_chr_close;
 
     if (is_listen) {
-        /* allow fast reuse */
-#ifndef _WIN32
-	if (is_unix) {
-	    char path[109];
-	    pstrcpy(path, sizeof(path), uaddr.sun_path);
-	    unlink(path);
-	} else
-#endif
-	{
-	    val = 1;
-	    setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (const char *)&val, sizeof(val));
-	}
-
-        ret = bind(fd, addr, addrlen);
-        if (ret < 0)
-            goto fail;
-
-        ret = listen(fd, 0);
-        if (ret < 0)
-            goto fail;
-
         s->listen_fd = fd;
         qemu_set_fd_handler(s->listen_fd, tcp_chr_accept, NULL, chr);
         if (is_telnet)
             s->do_telnetopt = 1;
     } else {
-        for(;;) {
-            ret = connect(fd, addr, addrlen);
-            if (ret < 0) {
-                err = socket_error();
-                if (err == EINTR || err == EWOULDBLOCK) {
-                } else if (err == EINPROGRESS) {
-                    break;
-#ifdef _WIN32
-                } else if (err == WSAEALREADY) {
-                    break;
-#endif
-                } else {
-                    goto fail;
-                }
-            } else {
-                s->connected = 1;
-                break;
-            }
-        }
+        s->connected = 1;
         s->fd = fd;
         socket_set_nodelay(fd);
-        if (s->connected)
-            tcp_chr_connect(chr);
-        else
-            qemu_set_fd_handler(s->fd, NULL, tcp_chr_connect, chr);
+        tcp_chr_connect(chr);
     }
 
     if (is_listen && is_waitconnect) {
-        printf("QEMU waiting for connection on: %s\n", host_str);
+        printf("QEMU waiting for connection on: %s\n",
+               chr->filename ? chr->filename : host_str);
         tcp_chr_accept(chr);
         socket_set_nonblock(s->listen_fd);
     }
-- 
1.5.6.5

  parent reply	other threads:[~2008-11-03 16:42 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-11-03 16:42 [Qemu-devel] [PATCH v3 0/3] ipv6 and autoport patches Gerd Hoffmann
2008-11-03 16:42 ` [Qemu-devel] [PATCH 1/3] sockets: helper functions for qemu Gerd Hoffmann
2008-11-04 12:42   ` [Qemu-devel] " Gerd Hoffmann
2008-11-11 20:41   ` [Qemu-devel] " Anthony Liguori
2008-11-11 21:14     ` Gerd Hoffmann
2008-11-11 20:47   ` Anthony Liguori
2008-11-03 16:42 ` [Qemu-devel] [PATCH 2/3] sockets: switch vnc to new code, support vnc port auto-allocation Gerd Hoffmann
2008-11-11 20:52   ` Anthony Liguori
2008-11-26 23:25   ` Ryan Harper
2008-11-27  9:11     ` Gerd Hoffmann
2008-11-03 16:42 ` Gerd Hoffmann [this message]
2008-11-11 20:54   ` [Qemu-devel] [PATCH 3/3] sockets: switch over tcp/telnet/unix serial line to new helper functions Anthony Liguori

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1225730550-31941-4-git-send-email-kraxel@redhat.com \
    --to=kraxel@redhat.com \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).