aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2017-07-17 10:02:22 +0100
committerPeter Maydell <peter.maydell@linaro.org>2017-07-17 10:02:22 +0100
commitacbaa0f4fd0491d222b718688244e629aa188b3c (patch)
tree59427d66b06bbef5003023e9579b02be84d79bce
parent2286468faceccb54a102e66331a40f7ab45f412c (diff)
parent75cb298d905030fca897ea1d80e409c7f7e3e5ea (diff)
Merge remote-tracking branch 'remotes/thibault/tags/samuel-thibault' into staging
slirp updates # gpg: Signature made Sat 15 Jul 2017 13:30:03 BST # gpg: using RSA key 0xB0A51BF58C9179C5 # gpg: Good signature from "Samuel Thibault <samuel.thibault@aquilenet.fr>" # gpg: aka "Samuel Thibault <sthibault@debian.org>" # gpg: aka "Samuel Thibault <samuel.thibault@gnu.org>" # gpg: aka "Samuel Thibault <samuel.thibault@inria.fr>" # gpg: aka "Samuel Thibault <samuel.thibault@labri.fr>" # gpg: aka "Samuel Thibault <samuel.thibault@ens-lyon.org>" # gpg: aka "Samuel Thibault <samuel.thibault@u-bordeaux.fr>" # gpg: WARNING: This key is not certified with a trusted signature! # gpg: There is no indication that the signature belongs to the owner. # Primary key fingerprint: 900C B024 B679 31D4 0F82 304B D017 8C76 7D06 9EE6 # Subkey fingerprint: AEBF 7448 FAB9 453A 4552 390E B0A5 1BF5 8C91 79C5 * remotes/thibault/tags/samuel-thibault: slirp: Handle error returns from sosendoob() slirp: Handle error returns from slirp_send() in sosendoob() slirp: fork_exec(): Don't close() a negative number in fork_exec() slirp: use DIV_ROUND_UP Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
-rw-r--r--slirp/ip6.h6
-rw-r--r--slirp/misc.c4
-rw-r--r--slirp/sbuf.c2
-rw-r--r--slirp/socket.c52
4 files changed, 42 insertions, 22 deletions
diff --git a/slirp/ip6.h b/slirp/ip6.h
index 0908855f0f..b1bea43b3c 100644
--- a/slirp/ip6.h
+++ b/slirp/ip6.h
@@ -57,9 +57,9 @@ static inline bool in6_equal_mach(const struct in6_addr *a,
const struct in6_addr *b,
int prefix_len)
{
- if (memcmp(&(a->s6_addr[(prefix_len + 7) / 8]),
- &(b->s6_addr[(prefix_len + 7) / 8]),
- 16 - (prefix_len + 7) / 8) != 0) {
+ if (memcmp(&(a->s6_addr[DIV_ROUND_UP(prefix_len, 8)]),
+ &(b->s6_addr[DIV_ROUND_UP(prefix_len, 8)]),
+ 16 - DIV_ROUND_UP(prefix_len, 8)) != 0) {
return 0;
}
diff --git a/slirp/misc.c b/slirp/misc.c
index 88e9d94197..260187b6b6 100644
--- a/slirp/misc.c
+++ b/slirp/misc.c
@@ -112,7 +112,9 @@ fork_exec(struct socket *so, const char *ex, int do_pty)
bind(s, (struct sockaddr *)&addr, addrlen) < 0 ||
listen(s, 1) < 0) {
error_report("Error: inet socket: %s", strerror(errno));
- closesocket(s);
+ if (s >= 0) {
+ closesocket(s);
+ }
return 0;
}
diff --git a/slirp/sbuf.c b/slirp/sbuf.c
index 10119d3ad5..912f235f65 100644
--- a/slirp/sbuf.c
+++ b/slirp/sbuf.c
@@ -91,7 +91,7 @@ sbappend(struct socket *so, struct mbuf *m)
if (so->so_urgc) {
sbappendsb(&so->so_rcv, m);
m_free(m);
- sosendoob(so);
+ (void)sosendoob(so);
return;
}
diff --git a/slirp/socket.c b/slirp/socket.c
index 3b49a69a93..ecec0295a9 100644
--- a/slirp/socket.c
+++ b/slirp/socket.c
@@ -345,33 +345,40 @@ sosendoob(struct socket *so)
if (sb->sb_rptr < sb->sb_wptr) {
/* We can send it directly */
n = slirp_send(so, sb->sb_rptr, so->so_urgc, (MSG_OOB)); /* |MSG_DONTWAIT)); */
- so->so_urgc -= n;
-
- DEBUG_MISC((dfd, " --- sent %d bytes urgent data, %d urgent bytes left\n", n, so->so_urgc));
} else {
/*
* Since there's no sendv or sendtov like writev,
* we must copy all data to a linear buffer then
* send it all
*/
+ uint32_t urgc = so->so_urgc;
len = (sb->sb_data + sb->sb_datalen) - sb->sb_rptr;
- if (len > so->so_urgc) len = so->so_urgc;
+ if (len > urgc) {
+ len = urgc;
+ }
memcpy(buff, sb->sb_rptr, len);
- so->so_urgc -= len;
- if (so->so_urgc) {
+ urgc -= len;
+ if (urgc) {
n = sb->sb_wptr - sb->sb_data;
- if (n > so->so_urgc) n = so->so_urgc;
+ if (n > urgc) {
+ n = urgc;
+ }
memcpy((buff + len), sb->sb_data, n);
- so->so_urgc -= n;
len += n;
}
n = slirp_send(so, buff, len, (MSG_OOB)); /* |MSG_DONTWAIT)); */
+ }
+
#ifdef DEBUG
- if (n != len)
- DEBUG_ERROR((dfd, "Didn't send all data urgently XXXXX\n"));
+ if (n != len) {
+ DEBUG_ERROR((dfd, "Didn't send all data urgently XXXXX\n"));
+ }
#endif
- DEBUG_MISC((dfd, " ---2 sent %d bytes urgent data, %d urgent bytes left\n", n, so->so_urgc));
+ if (n < 0) {
+ return n;
}
+ so->so_urgc -= n;
+ DEBUG_MISC((dfd, " ---2 sent %d bytes urgent data, %d urgent bytes left\n", n, so->so_urgc));
sb->sb_cc -= n;
sb->sb_rptr += n;
@@ -397,7 +404,15 @@ sowrite(struct socket *so)
DEBUG_ARG("so = %p", so);
if (so->so_urgc) {
- sosendoob(so);
+ uint32_t expected = so->so_urgc;
+ if (sosendoob(so) < expected) {
+ /* Treat a short write as a fatal error too,
+ * rather than continuing on and sending the urgent
+ * data as if it were non-urgent and leaving the
+ * so_urgc count wrong.
+ */
+ goto err_disconnected;
+ }
if (sb->sb_cc == 0)
return 0;
}
@@ -441,11 +456,7 @@ sowrite(struct socket *so)
return 0;
if (nn <= 0) {
- DEBUG_MISC((dfd, " --- sowrite disconnected, so->so_state = %x, errno = %d\n",
- so->so_state, errno));
- sofcantsendmore(so);
- tcp_sockclosed(sototcpcb(so));
- return -1;
+ goto err_disconnected;
}
#ifndef HAVE_READV
@@ -472,6 +483,13 @@ sowrite(struct socket *so)
sofcantsendmore(so);
return nn;
+
+err_disconnected:
+ DEBUG_MISC((dfd, " --- sowrite disconnected, so->so_state = %x, errno = %d\n",
+ so->so_state, errno));
+ sofcantsendmore(so);
+ tcp_sockclosed(sototcpcb(so));
+ return -1;
}
/*