Attention is currently required from: Arne Schwabe.
Hello Arne Schwabe,
I'd like you to do a code review.
Please visit
https://gerrit.openvpn.net/c/openvpn/+/2180?usp=email
to review the following change.
Change subject: Free address lists by DNS cache ownership, not --preresolve
......................................................................
Free address lists by DNS cache ownership, not --preresolve
With --preresolve, remote_list and bind_local were never freed on the
assumption that they came from the DNS cache, which is freed with the
context gc. Lookups that miss the cache leaked a getaddrinfo() list on
every restart. Meanwhile phase2_socks_client() freed remote_list
unconditionally, a double free once the cache hits.
Free a list unless the cache owns it.
Change-Id: I4b07dbc6ad1f29021e1be4766500f4d291bbadc6
Signed-off-by: Razvan Cojocaru <[email protected]>
---
M src/openvpn/init.c
M src/openvpn/resolve.c
M src/openvpn/resolve.h
M src/openvpn/socket.c
4 files changed, 29 insertions(+), 7 deletions(-)
git pull ssh://gerrit.openvpn.net:29418/openvpn refs/changes/80/2180/1
diff --git a/src/openvpn/init.c b/src/openvpn/init.c
index 3bc4de4..d40959e 100644
--- a/src/openvpn/init.c
+++ b/src/openvpn/init.c
@@ -495,9 +495,9 @@
* Clear the remote address list
*/
static void
-clear_remote_addrlist(struct link_socket_addr *lsa, bool free)
+clear_remote_addrlist(struct link_socket_addr *lsa, const struct
cached_dns_entry *dns_cache)
{
- if (lsa->remote_list && free)
+ if (lsa->remote_list && !dns_cache_owns(dns_cache, lsa->remote_list))
{
freeaddrinfo(lsa->remote_list);
}
@@ -550,8 +550,7 @@
*/
if (c->c1.link_socket_addrs[0].remote_list)
{
- clear_remote_addrlist(&c->c1.link_socket_addrs[0],
- !c->options.resolve_in_advance);
+ clear_remote_addrlist(&c->c1.link_socket_addrs[0],
c->c1.dns_cache);
}
/* close_instance should have cleared the addrinfo objects
*/
@@ -4011,7 +4010,7 @@
&& c->c1.link_socket_addrs[0].current_remote->ai_next)
|| c->options.no_advance)))))
{
- clear_remote_addrlist(&c->c1.link_socket_addrs[0],
!c->options.resolve_in_advance);
+ clear_remote_addrlist(&c->c1.link_socket_addrs[0], c->c1.dns_cache);
}
/* Clear the remote actual address when persist_remote_ip is not in use */
@@ -4027,7 +4026,8 @@
{
for (int i = 0; i < c->c1.link_sockets_num; i++)
{
- if (c->c1.link_socket_addrs[i].bind_local &&
!c->options.resolve_in_advance)
+ if (c->c1.link_socket_addrs[i].bind_local
+ && !dns_cache_owns(c->c1.dns_cache,
c->c1.link_socket_addrs[i].bind_local))
{
freeaddrinfo(c->c1.link_socket_addrs[i].bind_local);
}
diff --git a/src/openvpn/resolve.c b/src/openvpn/resolve.c
index b8d9899..46a7f7b 100644
--- a/src/openvpn/resolve.c
+++ b/src/openvpn/resolve.c
@@ -524,6 +524,19 @@
return -1;
}
+bool
+dns_cache_owns(const struct cached_dns_entry *dns_cache, const struct addrinfo
*ai)
+{
+ for (const struct cached_dns_entry *ph = dns_cache; ph; ph = ph->next)
+ {
+ if (ph->ai == ai)
+ {
+ return true;
+ }
+ }
+ return false;
+}
+
static int
do_preresolve_host(struct context *c, const char *hostname, const char
*servname, const int af,
diff --git a/src/openvpn/resolve.h b/src/openvpn/resolve.h
index 9069af7..30b1a7e 100644
--- a/src/openvpn/resolve.h
+++ b/src/openvpn/resolve.h
@@ -103,4 +103,10 @@
const char *servname, int ai_family,
unsigned int resolve_flags, struct addrinfo **ai);
+/**
+ * Returns true if \c ai is a cached entry. Those are freed with the
+ * context gc, never with freeaddrinfo().
+ */
+bool dns_cache_owns(const struct cached_dns_entry *dns_cache, const struct
addrinfo *ai);
+
#endif /* RESOLVE_H */
diff --git a/src/openvpn/socket.c b/src/openvpn/socket.c
index 1fbd07b..d7670ae 100644
--- a/src/openvpn/socket.c
+++ b/src/openvpn/socket.c
@@ -1266,7 +1266,10 @@
addr_zero_host(&sock->info.lsa->actual.dest);
if (sock->info.lsa->remote_list)
{
- freeaddrinfo(sock->info.lsa->remote_list);
+ if (!dns_cache_owns(sock->dns_cache, sock->info.lsa->remote_list))
+ {
+ freeaddrinfo(sock->info.lsa->remote_list);
+ }
sock->info.lsa->current_remote = NULL;
sock->info.lsa->remote_list = NULL;
}
--
To view, visit https://gerrit.openvpn.net/c/openvpn/+/2180?usp=email
To unsubscribe, or for help writing mail filters, visit
https://gerrit.openvpn.net/settings?usp=email
Gerrit-MessageType: newchange
Gerrit-Project: openvpn
Gerrit-Branch: master
Gerrit-Change-Id: I4b07dbc6ad1f29021e1be4766500f4d291bbadc6
Gerrit-Change-Number: 2180
Gerrit-PatchSet: 1
Gerrit-Owner: Răzvan Cojocaru <[email protected]>
Gerrit-Reviewer: Arne Schwabe <[email protected]>
Gerrit-CC: openvpn-devel <[email protected]>
Gerrit-Attention: Arne Schwabe <[email protected]>
_______________________________________________
Openvpn-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/openvpn-devel