From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1L00FZ-0008M9-2e for qemu-devel@nongnu.org; Tue, 11 Nov 2008 15:54:13 -0500 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1L00FY-0008La-4T for qemu-devel@nongnu.org; Tue, 11 Nov 2008 15:54:12 -0500 Received: from [199.232.76.173] (port=38116 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1L00FX-0008LR-OH for qemu-devel@nongnu.org; Tue, 11 Nov 2008 15:54:11 -0500 Received: from savannah.gnu.org ([199.232.41.3]:36472 helo=sv.gnu.org) by monty-python.gnu.org with esmtps (TLS-1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.60) (envelope-from ) id 1L00FX-0005Xg-Ee for qemu-devel@nongnu.org; Tue, 11 Nov 2008 15:54:11 -0500 Received: from cvs.savannah.gnu.org ([199.232.41.69]) by sv.gnu.org with esmtp (Exim 4.63) (envelope-from ) id 1L00FW-0004Kb-JW for qemu-devel@nongnu.org; Tue, 11 Nov 2008 20:54:10 +0000 Received: from aliguori by cvs.savannah.gnu.org with local (Exim 4.63) (envelope-from ) id 1L00FW-0004KX-BJ for qemu-devel@nongnu.org; Tue, 11 Nov 2008 20:54:10 +0000 MIME-Version: 1.0 Errors-To: aliguori Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit From: Anthony Liguori Message-Id: Date: Tue, 11 Nov 2008 20:54:10 +0000 Subject: [Qemu-devel] [5697] sockets: switch over tcp/telnet/ unix serial line to new helper functions (Gerd Hoffman) Reply-To: qemu-devel@nongnu.org List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Revision: 5697 http://svn.sv.gnu.org/viewvc/?view=rev&root=qemu&revision=5697 Author: aliguori Date: 2008-11-11 20:54:09 +0000 (Tue, 11 Nov 2008) Log Message: ----------- sockets: switch over tcp/telnet/unix serial line to new helper functions (Gerd Hoffman) 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 Signed-off-by: Anthony Liguori Modified Paths: -------------- trunk/qemu-char.c Modified: trunk/qemu-char.c =================================================================== --- trunk/qemu-char.c 2008-11-11 20:51:59 UTC (rev 5696) +++ trunk/qemu-char.c 2008-11-11 20:54:09 UTC (rev 5697) @@ -1957,33 +1957,12 @@ { 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,','))) { ptr++; @@ -1993,6 +1972,8 @@ 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; @@ -2008,13 +1989,31 @@ 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; @@ -2032,61 +2031,20 @@ 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); }