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,32 +1957,11 @@ static CharDriverState *qemu_chr_open_tcp(const char *host_str,
1957 { 1957 {
1958 CharDriverState *chr = NULL; 1958 CharDriverState *chr = NULL;
1959 TCPCharDriver *s = NULL; 1959 TCPCharDriver *s = NULL;
1960 - int fd = -1, ret, err, val; 1960 + int fd = -1, offset = 0;
1961 int is_listen = 0; 1961 int is_listen = 0;
1962 int is_waitconnect = 1; 1962 int is_waitconnect = 1;
1963 int do_nodelay = 0; 1963 int do_nodelay = 0;
1964 const char *ptr; 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 ptr = host_str; 1966 ptr = host_str;
1988 while((ptr = strchr(ptr,','))) { 1967 while((ptr = strchr(ptr,','))) {
@@ -1993,6 +1972,8 @@ static CharDriverState *qemu_chr_open_tcp(const char *host_str, @@ -1993,6 +1972,8 @@ static CharDriverState *qemu_chr_open_tcp(const char *host_str,
1993 is_waitconnect = 0; 1972 is_waitconnect = 0;
1994 } else if (!strncmp(ptr,"nodelay",6)) { 1973 } else if (!strncmp(ptr,"nodelay",6)) {
1995 do_nodelay = 1; 1974 do_nodelay = 1;
  1975 + } else if (!strncmp(ptr,"to=",3)) {
  1976 + /* nothing, inet_listen() parses this one */;
1996 } else { 1977 } else {
1997 printf("Unknown option: %s\n", ptr); 1978 printf("Unknown option: %s\n", ptr);
1998 goto fail; 1979 goto fail;
@@ -2008,13 +1989,31 @@ static CharDriverState *qemu_chr_open_tcp(const char *host_str, @@ -2008,13 +1989,31 @@ static CharDriverState *qemu_chr_open_tcp(const char *host_str,
2008 if (!s) 1989 if (!s)
2009 goto fail; 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 if (fd < 0) 2017 if (fd < 0)
2019 goto fail; 2018 goto fail;
2020 2019
@@ -2032,61 +2031,20 @@ static CharDriverState *qemu_chr_open_tcp(const char *host_str, @@ -2032,61 +2031,20 @@ static CharDriverState *qemu_chr_open_tcp(const char *host_str,
2032 chr->chr_close = tcp_chr_close; 2031 chr->chr_close = tcp_chr_close;
2033 2032
2034 if (is_listen) { 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 s->listen_fd = fd; 2034 s->listen_fd = fd;
2057 qemu_set_fd_handler(s->listen_fd, tcp_chr_accept, NULL, chr); 2035 qemu_set_fd_handler(s->listen_fd, tcp_chr_accept, NULL, chr);
2058 if (is_telnet) 2036 if (is_telnet)
2059 s->do_telnetopt = 1; 2037 s->do_telnetopt = 1;
2060 } else { 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 s->fd = fd; 2040 s->fd = fd;
2081 socket_set_nodelay(fd); 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 if (is_listen && is_waitconnect) { 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 tcp_chr_accept(chr); 2048 tcp_chr_accept(chr);
2091 socket_set_nonblock(s->listen_fd); 2049 socket_set_nonblock(s->listen_fd);
2092 } 2050 }