summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorQian Wu <qianwu@meta.com>2023-02-16 01:56:40 +0000
committerSamuel Thibault <samuel.thibault@ens-lyon.org>2023-02-16 01:56:40 +0000
commitbbe0e841b025f52be69551cbbce13c79467852c1 (patch)
treeb974d126693730f6942130f9b133344a531a90fb
parent0dd7f05095c0a77d9d2ec4764e8617192b4fa6ec (diff)
downloadqemu-libslirp-bbe0e841b025f52be69551cbbce13c79467852c1.tar.gz
Detach UDP socket if errno is ENOTCONN (Socket is not connected)
-rw-r--r--src/socket.c66
1 files changed, 37 insertions, 29 deletions
diff --git a/src/socket.c b/src/socket.c
index 6a3ddb1..fb9c019 100644
--- a/src/socket.c
+++ b/src/socket.c
@@ -633,39 +633,47 @@ void sorecvfrom(struct socket *so)
&addrlen);
DEBUG_MISC(" did recvfrom %d, errno = %d-%s", m->m_len, errno,
strerror(errno));
- if (m->m_len < 0) {
- /* Report error as ICMP */
- switch (so->so_lfamily) {
- uint8_t code;
- case AF_INET:
- code = ICMP_UNREACH_PORT;
-
- if (errno == EHOSTUNREACH) {
- code = ICMP_UNREACH_HOST;
- } else if (errno == ENETUNREACH) {
- code = ICMP_UNREACH_NET;
- }
+ if (m->m_len < 0) {
+ if (errno == ENOTCONN) {
+ /*
+ * UDP socket got burnt, e.g. by suspend on iOS. Tear it down
+ * and let it get re-created if the guest still needs it
+ */
+ udp_detach(so);
+ } else {
+ /* Report error as ICMP */
+ switch (so->so_lfamily) {
+ uint8_t code;
+ case AF_INET:
+ code = ICMP_UNREACH_PORT;
+
+ if (errno == EHOSTUNREACH) {
+ code = ICMP_UNREACH_HOST;
+ } else if (errno == ENETUNREACH) {
+ code = ICMP_UNREACH_NET;
+ }
- DEBUG_MISC(" rx error, tx icmp ICMP_UNREACH:%i", code);
- icmp_send_error(so->so_m, ICMP_UNREACH, code, 0,
- strerror(errno));
- break;
- case AF_INET6:
- code = ICMP6_UNREACH_PORT;
+ DEBUG_MISC(" rx error, tx icmp ICMP_UNREACH:%i", code);
+ icmp_send_error(so->so_m, ICMP_UNREACH, code, 0,
+ strerror(errno));
+ break;
+ case AF_INET6:
+ code = ICMP6_UNREACH_PORT;
+
+ if (errno == EHOSTUNREACH) {
+ code = ICMP6_UNREACH_ADDRESS;
+ } else if (errno == ENETUNREACH) {
+ code = ICMP6_UNREACH_NO_ROUTE;
+ }
- if (errno == EHOSTUNREACH) {
- code = ICMP6_UNREACH_ADDRESS;
- } else if (errno == ENETUNREACH) {
- code = ICMP6_UNREACH_NO_ROUTE;
+ DEBUG_MISC(" rx error, tx icmp6 ICMP_UNREACH:%i", code);
+ icmp6_send_error(so->so_m, ICMP6_UNREACH, code);
+ break;
+ default:
+ g_assert_not_reached();
}
-
- DEBUG_MISC(" rx error, tx icmp6 ICMP_UNREACH:%i", code);
- icmp6_send_error(so->so_m, ICMP6_UNREACH, code);
- break;
- default:
- g_assert_not_reached();
+ m_free(m);
}
- m_free(m);
} else {
/*
* Hack: domain name lookup will be used the most for UDP,