Commit f07b6003b6cebaa5404d702ad8aca181580e4d6c

Authored by aliguori
1 parent 9712ecaf

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 <kraxel@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>



git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@5697 c046a42c-6fe2-441c-8c8c-71466251a162
Showing 1 changed file with 32 additions and 74 deletions
qemu-char.c
... ... @@ -1957,32 +1957,11 @@ static CharDriverState *qemu_chr_open_tcp(const char *host_str,
1957 1957 {
1958 1958 CharDriverState *chr = NULL;
1959 1959 TCPCharDriver *s = NULL;
1960   - int fd = -1, ret, err, val;
  1960 + int fd = -1, offset = 0;
1961 1961 int is_listen = 0;
1962 1962 int is_waitconnect = 1;
1963 1963 int do_nodelay = 0;
1964 1964 const char *ptr;
1965   - struct sockaddr_in saddr;
1966   -#ifndef _WIN32
1967   - struct sockaddr_un uaddr;
1968   -#endif
1969   - struct sockaddr *addr;
1970   - socklen_t addrlen;
1971   -
1972   -#ifndef _WIN32
1973   - if (is_unix) {
1974   - addr = (struct sockaddr *)&uaddr;
1975   - addrlen = sizeof(uaddr);
1976   - if (parse_unix_path(&uaddr, host_str) < 0)
1977   - goto fail;
1978   - } else
1979   -#endif
1980   - {
1981   - addr = (struct sockaddr *)&saddr;
1982   - addrlen = sizeof(saddr);
1983   - if (parse_host_port(&saddr, host_str) < 0)
1984   - goto fail;
1985   - }
1986 1965  
1987 1966 ptr = host_str;
1988 1967 while((ptr = strchr(ptr,','))) {
... ... @@ -1993,6 +1972,8 @@ static CharDriverState *qemu_chr_open_tcp(const char *host_str,
1993 1972 is_waitconnect = 0;
1994 1973 } else if (!strncmp(ptr,"nodelay",6)) {
1995 1974 do_nodelay = 1;
  1975 + } else if (!strncmp(ptr,"to=",3)) {
  1976 + /* nothing, inet_listen() parses this one */;
1996 1977 } else {
1997 1978 printf("Unknown option: %s\n", ptr);
1998 1979 goto fail;
... ... @@ -2008,13 +1989,31 @@ static CharDriverState *qemu_chr_open_tcp(const char *host_str,
2008 1989 if (!s)
2009 1990 goto fail;
2010 1991  
2011   -#ifndef _WIN32
2012   - if (is_unix)
2013   - fd = socket(PF_UNIX, SOCK_STREAM, 0);
2014   - else
2015   -#endif
2016   - fd = socket(PF_INET, SOCK_STREAM, 0);
2017   -
  1992 + if (is_listen) {
  1993 + chr->filename = qemu_malloc(256);
  1994 + if (is_unix) {
  1995 + strcpy(chr->filename, "unix:");
  1996 + } else if (is_telnet) {
  1997 + strcpy(chr->filename, "telnet:");
  1998 + } else {
  1999 + strcpy(chr->filename, "tcp:");
  2000 + }
  2001 + offset = strlen(chr->filename);
  2002 + }
  2003 + if (is_unix) {
  2004 + if (is_listen) {
  2005 + fd = unix_listen(host_str, chr->filename + offset, 256 - offset);
  2006 + } else {
  2007 + fd = unix_connect(host_str);
  2008 + }
  2009 + } else {
  2010 + if (is_listen) {
  2011 + fd = inet_listen(host_str, chr->filename + offset, 256 - offset,
  2012 + SOCK_STREAM, 0);
  2013 + } else {
  2014 + fd = inet_connect(host_str, SOCK_STREAM);
  2015 + }
  2016 + }
2018 2017 if (fd < 0)
2019 2018 goto fail;
2020 2019  
... ... @@ -2032,61 +2031,20 @@ static CharDriverState *qemu_chr_open_tcp(const char *host_str,
2032 2031 chr->chr_close = tcp_chr_close;
2033 2032  
2034 2033 if (is_listen) {
2035   - /* allow fast reuse */
2036   -#ifndef _WIN32
2037   - if (is_unix) {
2038   - char path[109];
2039   - pstrcpy(path, sizeof(path), uaddr.sun_path);
2040   - unlink(path);
2041   - } else
2042   -#endif
2043   - {
2044   - val = 1;
2045   - setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (const char *)&val, sizeof(val));
2046   - }
2047   -
2048   - ret = bind(fd, addr, addrlen);
2049   - if (ret < 0)
2050   - goto fail;
2051   -
2052   - ret = listen(fd, 0);
2053   - if (ret < 0)
2054   - goto fail;
2055   -
2056 2034 s->listen_fd = fd;
2057 2035 qemu_set_fd_handler(s->listen_fd, tcp_chr_accept, NULL, chr);
2058 2036 if (is_telnet)
2059 2037 s->do_telnetopt = 1;
2060 2038 } else {
2061   - for(;;) {
2062   - ret = connect(fd, addr, addrlen);
2063   - if (ret < 0) {
2064   - err = socket_error();
2065   - if (err == EINTR || err == EWOULDBLOCK) {
2066   - } else if (err == EINPROGRESS) {
2067   - break;
2068   -#ifdef _WIN32
2069   - } else if (err == WSAEALREADY) {
2070   - break;
2071   -#endif
2072   - } else {
2073   - goto fail;
2074   - }
2075   - } else {
2076   - s->connected = 1;
2077   - break;
2078   - }
2079   - }
  2039 + s->connected = 1;
2080 2040 s->fd = fd;
2081 2041 socket_set_nodelay(fd);
2082   - if (s->connected)
2083   - tcp_chr_connect(chr);
2084   - else
2085   - qemu_set_fd_handler(s->fd, NULL, tcp_chr_connect, chr);
  2042 + tcp_chr_connect(chr);
2086 2043 }
2087 2044  
2088 2045 if (is_listen && is_waitconnect) {
2089   - printf("QEMU waiting for connection on: %s\n", host_str);
  2046 + printf("QEMU waiting for connection on: %s\n",
  2047 + chr->filename ? chr->filename : host_str);
2090 2048 tcp_chr_accept(chr);
2091 2049 socket_set_nonblock(s->listen_fd);
2092 2050 }
... ...