diff options
| -rw-r--r-- | hw/net/rtl8139.c | 2 | ||||
| -rw-r--r-- | net/filter.c | 2 | ||||
| -rw-r--r-- | net/net.c | 44 | ||||
| -rw-r--r-- | qga/commands.c | 4 | ||||
| -rw-r--r-- | qga/installer/qemu-ga.wxs | 4 | ||||
| -rw-r--r-- | slirp/slirp.c | 12 | ||||
| -rw-r--r-- | slirp/socket.c | 34 | ||||
| -rw-r--r-- | slirp/socket.h | 2 | ||||
| -rw-r--r-- | slirp/tcp_input.c | 6 | ||||
| -rw-r--r-- | slirp/tcp_subr.c | 7 | ||||
| -rw-r--r-- | util/hexdump.c | 33 |
11 files changed, 91 insertions, 59 deletions
diff --git a/hw/net/rtl8139.c b/hw/net/rtl8139.c index fee97bf607..1e5ec149fa 100644 --- a/hw/net/rtl8139.c +++ b/hw/net/rtl8139.c @@ -2046,7 +2046,7 @@ static int rtl8139_cplus_transmit_one(RTL8139State *s) } /* transfer ownership to target */ - txdw0 &= ~CP_RX_OWN; + txdw0 &= ~CP_TX_OWN; /* reset error indicator bits */ txdw0 &= ~CP_TX_STATUS_UNF; diff --git a/net/filter.c b/net/filter.c index 1c4fc5a2c7..8ac79f3b7b 100644 --- a/net/filter.c +++ b/net/filter.c @@ -164,7 +164,7 @@ static void netfilter_set_status(Object *obj, const char *str, Error **errp) return; } nf->on = !nf->on; - if (nfc->status_changed) { + if (nf->netdev && nfc->status_changed) { nfc->status_changed(nf, errp); } } diff --git a/net/net.c b/net/net.c index 594c3b8b5d..0ad6217cb9 100644 --- a/net/net.c +++ b/net/net.c @@ -81,34 +81,6 @@ int default_net = 1; /***********************************************************/ /* network device redirectors */ -#if defined(DEBUG_NET) -static void hex_dump(FILE *f, const uint8_t *buf, int size) -{ - int len, i, j, c; - - for(i=0;i<size;i+=16) { - len = size - i; - if (len > 16) - len = 16; - fprintf(f, "%08x ", i); - for(j=0;j<16;j++) { - if (j < len) - fprintf(f, " %02x", buf[i+j]); - else - fprintf(f, " "); - } - fprintf(f, " "); - for(j=0;j<len;j++) { - c = buf[i+j]; - if (c < ' ' || c > '~') - c = '.'; - fprintf(f, "%c", c); - } - fprintf(f, "\n"); - } -} -#endif - static int get_str_sep(char *buf, int buf_size, const char **pp, int sep) { const char *p, *p1; @@ -664,7 +636,7 @@ static ssize_t qemu_send_packet_async_with_flags(NetClientState *sender, #ifdef DEBUG_NET printf("qemu_send_packet_async:\n"); - hex_dump(stdout, buf, size); + qemu_hexdump((const char *)buf, stdout, "net", size); #endif if (sender->link_down || !sender->peer) { @@ -711,23 +683,28 @@ ssize_t qemu_send_packet_raw(NetClientState *nc, const uint8_t *buf, int size) static ssize_t nc_sendv_compat(NetClientState *nc, const struct iovec *iov, int iovcnt, unsigned flags) { - uint8_t buf[NET_BUFSIZE]; + uint8_t *buf = NULL; uint8_t *buffer; size_t offset; + ssize_t ret; if (iovcnt == 1) { buffer = iov[0].iov_base; offset = iov[0].iov_len; } else { + buf = g_new(uint8_t, NET_BUFSIZE); buffer = buf; - offset = iov_to_buf(iov, iovcnt, 0, buf, sizeof(buf)); + offset = iov_to_buf(iov, iovcnt, 0, buf, NET_BUFSIZE); } if (flags & QEMU_NET_PACKET_FLAG_RAW && nc->info->receive_raw) { - return nc->info->receive_raw(nc, buffer, offset); + ret = nc->info->receive_raw(nc, buffer, offset); } else { - return nc->info->receive(nc, buffer, offset); + ret = nc->info->receive(nc, buffer, offset); } + + g_free(buf); + return ret; } ssize_t qemu_deliver_packet_iov(NetClientState *sender, @@ -1100,6 +1077,7 @@ int net_client_init(QemuOpts *opts, int is_netdev, Error **errp) } error_propagate(errp, err); + opts_visitor_cleanup(ov); return ret; } diff --git a/qga/commands.c b/qga/commands.c index 95d8b04a16..b653a460b9 100644 --- a/qga/commands.c +++ b/qga/commands.c @@ -373,6 +373,7 @@ static gboolean guest_exec_output_watch(GIOChannel *ch, return true; close: + g_io_channel_shutdown(ch, true, NULL); g_io_channel_unref(ch); g_atomic_int_set(&p->closed, 1); return false; @@ -447,6 +448,7 @@ GuestExec *qmp_guest_exec(const char *path, g_io_channel_set_encoding(in_ch, NULL, NULL); g_io_channel_set_buffered(in_ch, false); g_io_channel_set_flags(in_ch, G_IO_FLAG_NONBLOCK, NULL); + g_io_channel_set_close_on_unref(in_ch, true); g_io_add_watch(in_ch, G_IO_OUT, guest_exec_input_watch, &gei->in); } @@ -462,6 +464,8 @@ GuestExec *qmp_guest_exec(const char *path, g_io_channel_set_encoding(err_ch, NULL, NULL); g_io_channel_set_buffered(out_ch, false); g_io_channel_set_buffered(err_ch, false); + g_io_channel_set_close_on_unref(out_ch, true); + g_io_channel_set_close_on_unref(err_ch, true); g_io_add_watch(out_ch, G_IO_IN | G_IO_HUP, guest_exec_output_watch, &gei->out); g_io_add_watch(err_ch, G_IO_IN | G_IO_HUP, diff --git a/qga/installer/qemu-ga.wxs b/qga/installer/qemu-ga.wxs index 7f9289122f..fa2260cafa 100644 --- a/qga/installer/qemu-ga.wxs +++ b/qga/installer/qemu-ga.wxs @@ -96,7 +96,7 @@ <File Id="gspawn-win32-helper-console.exe" Name="gspawn-win32-helper-console.exe" Source="$(var.Mingw_bin)/gspawn-win32-helper-console.exe" KeyPath="yes" DiskId="1"/> </Component> <Component Id="gspawn-helper" Guid="{CD67A5A3-2DB1-4DA1-A67A-8D71E797B466}"> - <File Id="gspawn-win32-helper.exe" Name="gspawn-win32-helper.exe" Source="$(var.Mingw_bin)/gspawn-win32-helper.exe" KeyPath="yes" DiskId="1"/> + <File Id="gspawn-win32-helper.exe" Name="gspawn-win32-helper.exe" Source="$(var.Mingw_bin)/gspawn-win32-helper-console.exe" KeyPath="yes" DiskId="1"/> </Component> <?endif?> <?if $(var.Arch) = "64"?> @@ -104,7 +104,7 @@ <File Id="gspawn-win64-helper-console.exe" Name="gspawn-win64-helper-console.exe" Source="$(var.Mingw_bin)/gspawn-win64-helper-console.exe" KeyPath="yes" DiskId="1"/> </Component> <Component Id="gspawn-helper" Guid="{D201AD22-1846-4E4F-B6E1-C7A908ED2457}"> - <File Id="gspawn-win64-helper.exe" Name="gspawn-win64-helper.exe" Source="$(var.Mingw_bin)/gspawn-win64-helper.exe" KeyPath="yes" DiskId="1"/> + <File Id="gspawn-win64-helper.exe" Name="gspawn-win64-helper.exe" Source="$(var.Mingw_bin)/gspawn-win64-helper-console.exe" KeyPath="yes" DiskId="1"/> </Component> <?endif?> <Component Id="iconv" Guid="{35EE3558-D34B-4F0A-B8BD-430FF0775246}"> diff --git a/slirp/slirp.c b/slirp/slirp.c index fef526c5ad..9f4bea3d3b 100644 --- a/slirp/slirp.c +++ b/slirp/slirp.c @@ -534,7 +534,12 @@ void slirp_pollfds_poll(GArray *pollfds, int select_error) * test for G_IO_IN below if this succeeds */ if (revents & G_IO_PRI) { - sorecvoob(so); + ret = sorecvoob(so); + if (ret < 0) { + /* Socket error might have resulted in the socket being + * removed, do not try to do anything more with it. */ + continue; + } } /* * Check sockets for reading @@ -553,6 +558,11 @@ void slirp_pollfds_poll(GArray *pollfds, int select_error) if (ret > 0) { tcp_output(sototcpcb(so)); } + if (ret < 0) { + /* Socket error might have resulted in the socket being + * removed, do not try to do anything more with it. */ + continue; + } } /* diff --git a/slirp/socket.c b/slirp/socket.c index b836c42b8e..bd97b2d682 100644 --- a/slirp/socket.c +++ b/slirp/socket.c @@ -176,9 +176,24 @@ soread(struct socket *so) if (nn < 0 && (errno == EINTR || errno == EAGAIN)) return 0; else { + int err; + socklen_t slen = sizeof err; + + err = errno; + if (nn == 0) { + getsockopt(so->s, SOL_SOCKET, SO_ERROR, + &err, &slen); + } + DEBUG_MISC((dfd, " --- soread() disconnected, nn = %d, errno = %d-%s\n", nn, errno,strerror(errno))); sofcantrcvmore(so); - tcp_sockclosed(sototcpcb(so)); + + if (err == ECONNRESET || err == ECONNREFUSED + || err == ENOTCONN || err == EPIPE) { + tcp_drop(sototcpcb(so), err); + } else { + tcp_sockclosed(sototcpcb(so)); + } return -1; } } @@ -260,10 +275,11 @@ err: * so when OOB data arrives, we soread() it and everything * in the send buffer is sent as urgent data */ -void +int sorecvoob(struct socket *so) { struct tcpcb *tp = sototcpcb(so); + int ret; DEBUG_CALL("sorecvoob"); DEBUG_ARG("so = %p", so); @@ -276,11 +292,15 @@ sorecvoob(struct socket *so) * urgent data, or the read() doesn't return all the * urgent data. */ - soread(so); - tp->snd_up = tp->snd_una + so->so_snd.sb_cc; - tp->t_force = 1; - tcp_output(tp); - tp->t_force = 0; + ret = soread(so); + if (ret > 0) { + tp->snd_up = tp->snd_una + so->so_snd.sb_cc; + tp->t_force = 1; + tcp_output(tp); + tp->t_force = 0; + } + + return ret; } /* diff --git a/slirp/socket.h b/slirp/socket.h index e9c9b053dc..7dca506973 100644 --- a/slirp/socket.h +++ b/slirp/socket.h @@ -127,7 +127,7 @@ struct socket *solookup(struct socket **, struct socket *, struct socket *socreate(Slirp *); void sofree(struct socket *); int soread(struct socket *); -void sorecvoob(struct socket *); +int sorecvoob(struct socket *); int sosendoob(struct socket *); int sowrite(struct socket *); void sorecvfrom(struct socket *); diff --git a/slirp/tcp_input.c b/slirp/tcp_input.c index 1fcca3040e..5433e7fe9c 100644 --- a/slirp/tcp_input.c +++ b/slirp/tcp_input.c @@ -725,6 +725,12 @@ findso: so->so_ti = ti; tp->t_timer[TCPT_KEEP] = TCPTV_KEEP_INIT; tp->t_state = TCPS_SYN_RECEIVED; + /* + * Initialize receive sequence numbers now so that we can send a + * valid RST if the remote end rejects our connection. + */ + tp->irs = ti->ti_seq; + tcp_rcvseqinit(tp); tcp_template(tp); } return; diff --git a/slirp/tcp_subr.c b/slirp/tcp_subr.c index dbfd2c673b..32ff452e93 100644 --- a/slirp/tcp_subr.c +++ b/slirp/tcp_subr.c @@ -356,6 +356,10 @@ tcp_sockclosed(struct tcpcb *tp) DEBUG_CALL("tcp_sockclosed"); DEBUG_ARG("tp = %p", tp); + if (!tp) { + return; + } + switch (tp->t_state) { case TCPS_CLOSED: @@ -374,8 +378,7 @@ tcp_sockclosed(struct tcpcb *tp) tp->t_state = TCPS_LAST_ACK; break; } - if (tp) - tcp_output(tp); + tcp_output(tp); } /* diff --git a/util/hexdump.c b/util/hexdump.c index 1d9c12967b..f879ff0ad6 100644 --- a/util/hexdump.c +++ b/util/hexdump.c @@ -18,21 +18,32 @@ void qemu_hexdump(const char *buf, FILE *fp, const char *prefix, size_t size) { - unsigned int b; + unsigned int b, len, i, c; - for (b = 0; b < size; b++) { - if ((b % 16) == 0) { - fprintf(fp, "%s: %04x:", prefix, b); + for (b = 0; b < size; b += 16) { + len = size - b; + if (len > 16) { + len = 16; } - if ((b % 4) == 0) { - fprintf(fp, " "); + fprintf(fp, "%s: %04x:", prefix, b); + for (i = 0; i < 16; i++) { + if ((i % 4) == 0) { + fprintf(fp, " "); + } + if (i < len) { + fprintf(fp, " %02x", (unsigned char)buf[b + i]); + } else { + fprintf(fp, " "); + } } - fprintf(fp, " %02x", (unsigned char)buf[b]); - if ((b % 16) == 15) { - fprintf(fp, "\n"); + fprintf(fp, " "); + for (i = 0; i < len; i++) { + c = buf[b + i]; + if (c < ' ' || c > '~') { + c = '.'; + } + fprintf(fp, "%c", c); } - } - if ((b % 16) != 0) { fprintf(fp, "\n"); } } |