From b72210568ef0c0fb141a01cffb71a09c4efa0364 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Thu, 22 Mar 2012 01:02:51 +0100 Subject: [PATCH 1/4] slirp: clean up conflicts with system headers Right now, slirp/slirp.h cannot include some system headers and, indirectly, qemu_socket.h. Clean this up, and remove a duplicate prototype that was introduced because of that. Signed-off-by: Paolo Bonzini Signed-off-by: Jan Kiszka --- slirp/slirp.h | 8 +------- slirp/tcp.h | 21 +++++++++++++++------ 2 files changed, 16 insertions(+), 13 deletions(-) diff --git a/slirp/slirp.h b/slirp/slirp.h index 5033ee3118..2098b20e39 100644 --- a/slirp/slirp.h +++ b/slirp/slirp.h @@ -88,10 +88,6 @@ void *malloc(size_t arg); void free(void *ptr); #endif -#ifndef HAVE_INET_ATON -int inet_aton(const char *cp, struct in_addr *ia); -#endif - #include #ifndef NO_UNIX_SOCKETS #include @@ -144,6 +140,7 @@ int inet_aton(const char *cp, struct in_addr *ia); #include "debug.h" #include "qemu-queue.h" +#include "qemu_socket.h" #include "libslirp.h" #include "ip.h" @@ -167,9 +164,6 @@ int inet_aton(const char *cp, struct in_addr *ia); #include "bootp.h" #include "tftp.h" -/* osdep.c */ -int qemu_socket(int domain, int type, int protocol); - #define ETH_ALEN 6 #define ETH_HLEN 14 diff --git a/slirp/tcp.h b/slirp/tcp.h index b3817cb13c..82996031e0 100644 --- a/slirp/tcp.h +++ b/slirp/tcp.h @@ -45,6 +45,7 @@ typedef uint32_t tcp_seq; * TCP header. * Per RFC 793, September, 1981. */ +#define tcphdr slirp_tcphdr struct tcphdr { uint16_t th_sport; /* source port */ uint16_t th_dport; /* destination port */ @@ -58,12 +59,6 @@ struct tcphdr { th_off:4; /* data offset */ #endif uint8_t th_flags; -#define TH_FIN 0x01 -#define TH_SYN 0x02 -#define TH_RST 0x04 -#define TH_PUSH 0x08 -#define TH_ACK 0x10 -#define TH_URG 0x20 uint16_t th_win; /* window */ uint16_t th_sum; /* checksum */ uint16_t th_urp; /* urgent pointer */ @@ -71,6 +66,16 @@ struct tcphdr { #include "tcp_var.h" +#ifndef TH_FIN +#define TH_FIN 0x01 +#define TH_SYN 0x02 +#define TH_RST 0x04 +#define TH_PUSH 0x08 +#define TH_ACK 0x10 +#define TH_URG 0x20 +#endif + +#ifndef TCPOPT_EOL #define TCPOPT_EOL 0 #define TCPOPT_NOP 1 #define TCPOPT_MAXSEG 2 @@ -86,6 +91,7 @@ struct tcphdr { #define TCPOPT_TSTAMP_HDR \ (TCPOPT_NOP<<24|TCPOPT_NOP<<16|TCPOPT_TIMESTAMP<<8|TCPOLEN_TIMESTAMP) +#endif /* * Default maximum segment size for TCP. @@ -95,10 +101,13 @@ struct tcphdr { * * We make this 1460 because we only care about Ethernet in the qemu context. */ +#undef TCP_MSS #define TCP_MSS 1460 +#undef TCP_MAXWIN #define TCP_MAXWIN 65535 /* largest value for (unscaled) window */ +#undef TCP_MAX_WINSHIFT #define TCP_MAX_WINSHIFT 14 /* maximum window shift */ /* From 1c5970a8b8ed79334e8ab303fec7287442538c3c Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Thu, 22 Mar 2012 01:02:52 +0100 Subject: [PATCH 2/4] slirp: use socket_set_nonblock Signed-off-by: Paolo Bonzini Signed-off-by: Jan Kiszka --- slirp/misc.c | 46 +--------------------------------------------- slirp/tcp_subr.c | 4 ++-- 2 files changed, 3 insertions(+), 47 deletions(-) diff --git a/slirp/misc.c b/slirp/misc.c index 0308a62fac..0bee864337 100644 --- a/slirp/misc.c +++ b/slirp/misc.c @@ -215,7 +215,7 @@ fork_exec(struct socket *so, const char *ex, int do_pty) setsockopt(so->s, SOL_SOCKET, SO_REUSEADDR, (char *)&opt, sizeof(int)); opt = 1; setsockopt(so->s, SOL_SOCKET, SO_OOBINLINE, (char *)&opt, sizeof(int)); - fd_nonblock(so->s); + socket_set_nonblock(so->s); /* Append the telnet options now */ if (so->so_m != NULL && do_pty == 1) { @@ -267,50 +267,6 @@ u_sleep(int usec) select(0, &fdset, &fdset, &fdset, &t); } -/* - * Set fd blocking and non-blocking - */ - -void -fd_nonblock(int fd) -{ -#ifdef FIONBIO -#ifdef _WIN32 - unsigned long opt = 1; -#else - int opt = 1; -#endif - - ioctlsocket(fd, FIONBIO, &opt); -#else - int opt; - - opt = fcntl(fd, F_GETFL, 0); - opt |= O_NONBLOCK; - fcntl(fd, F_SETFL, opt); -#endif -} - -void -fd_block(int fd) -{ -#ifdef FIONBIO -#ifdef _WIN32 - unsigned long opt = 0; -#else - int opt = 0; -#endif - - ioctlsocket(fd, FIONBIO, &opt); -#else - int opt; - - opt = fcntl(fd, F_GETFL, 0); - opt &= ~O_NONBLOCK; - fcntl(fd, F_SETFL, opt); -#endif -} - void slirp_connection_info(Slirp *slirp, Monitor *mon) { const char * const tcpstates[] = { diff --git a/slirp/tcp_subr.c b/slirp/tcp_subr.c index 6f6585a10f..0a545c41e7 100644 --- a/slirp/tcp_subr.c +++ b/slirp/tcp_subr.c @@ -336,7 +336,7 @@ int tcp_fconnect(struct socket *so) int opt, s=so->s; struct sockaddr_in addr; - fd_nonblock(s); + socket_set_nonblock(s); opt = 1; setsockopt(s,SOL_SOCKET,SO_REUSEADDR,(char *)&opt,sizeof(opt )); opt = 1; @@ -424,7 +424,7 @@ tcp_connect(struct socket *inso) tcp_close(sototcpcb(so)); /* This will sofree() as well */ return; } - fd_nonblock(s); + socket_set_nonblock(s); opt = 1; setsockopt(s,SOL_SOCKET,SO_REUSEADDR,(char *)&opt,sizeof(int)); opt = 1; From 56688961634a2d05fb5841a149bb5c1a17239e4c Mon Sep 17 00:00:00 2001 From: Jan Kiszka Date: Wed, 28 Mar 2012 21:03:42 +0200 Subject: [PATCH 3/4] w32/slirp: Undefine error constants before their redefinition Less warnings for your console. Signed-off-by: Jan Kiszka --- slirp/slirp.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/slirp/slirp.h b/slirp/slirp.h index 2098b20e39..46bfe4636d 100644 --- a/slirp/slirp.h +++ b/slirp/slirp.h @@ -15,6 +15,12 @@ typedef char *caddr_t; # include # include +# undef EWOULDBLOCK +# undef EINPROGRESS +# undef ENOTCONN +# undef EHOSTUNREACH +# undef ENETUNREACH +# undef ECONNREFUSED # define EWOULDBLOCK WSAEWOULDBLOCK # define EINPROGRESS WSAEINPROGRESS # define ENOTCONN WSAENOTCONN From 86073017e384b65a4b568da25e5873fd2e5e4db5 Mon Sep 17 00:00:00 2001 From: Jan Kiszka Date: Fri, 30 Mar 2012 19:29:08 +0200 Subject: [PATCH 4/4] slirp: Signal free input buffer space to io-thread This massively accelerates slirp reception speed: If data arrives faster than the guest can read it from the input buffer, the file descriptor for the corresponding socket was taken out of the fdset for select. However, the event of the guest reading enough data from the buffer was not signaled. Thus, the io-thread only noticed this change on the next time-driven poll. Fix this by kicking the io-thread as required. Signed-off-by: Jan Kiszka --- slirp/sbuf.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/slirp/sbuf.c b/slirp/sbuf.c index 5a1ccbfadf..637f8fea3d 100644 --- a/slirp/sbuf.c +++ b/slirp/sbuf.c @@ -6,6 +6,7 @@ */ #include +#include static void sbappendsb(struct sbuf *sb, struct mbuf *m); @@ -18,6 +19,8 @@ sbfree(struct sbuf *sb) void sbdrop(struct sbuf *sb, int num) { + int limit = sb->sb_datalen / 2; + /* * We can only drop how much we have * This should never succeed @@ -29,6 +32,9 @@ sbdrop(struct sbuf *sb, int num) if(sb->sb_rptr >= sb->sb_data + sb->sb_datalen) sb->sb_rptr -= sb->sb_datalen; + if (sb->sb_cc < limit && sb->sb_cc + num >= limit) { + qemu_notify_event(); + } } void