aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorLars Ingebrigtsen2016-01-30 03:51:04 +0100
committerLars Ingebrigtsen2016-01-30 03:51:04 +0100
commit233e89cf2317a1df410fe01ce20d66293517b500 (patch)
tree23a961282e117c17f06fd2e15862ff8666e3a4c3 /src
parent0677d94e2d55d473e9bbacde009bfd83df0bc67e (diff)
downloademacs-233e89cf2317a1df410fe01ce20d66293517b500.tar.gz
emacs-233e89cf2317a1df410fe01ce20d66293517b500.zip
Avoid memory leaks in async DNS
* process.c (check_for_dns): Free async DNS resources after they've been used.
Diffstat (limited to 'src')
-rw-r--r--src/process.c43
-rw-r--r--src/process.h2
2 files changed, 22 insertions, 23 deletions
diff --git a/src/process.c b/src/process.c
index dafd5330d30..168d9255f1e 100644
--- a/src/process.c
+++ b/src/process.c
@@ -3489,7 +3489,7 @@ usage: (make-network-process &rest ARGS) */)
3489 int family = -1; 3489 int family = -1;
3490 int ai_protocol = 0; 3490 int ai_protocol = 0;
3491#ifdef HAVE_GETADDRINFO_A 3491#ifdef HAVE_GETADDRINFO_A
3492 struct gaicb *dns_request = NULL; 3492 struct gaicb **dns_requests;
3493#endif 3493#endif
3494 ptrdiff_t count = SPECPDL_INDEX (); 3494 ptrdiff_t count = SPECPDL_INDEX ();
3495 3495
@@ -3635,8 +3635,7 @@ usage: (make-network-process &rest ARGS) */)
3635 portstring = SSDATA (service); 3635 portstring = SSDATA (service);
3636 } 3636 }
3637 3637
3638 hints = xmalloc (sizeof (struct addrinfo)); 3638 hints = xzalloc (sizeof (struct addrinfo));
3639 memset (hints, 0, sizeof (struct addrinfo));
3640 hints->ai_flags = 0; 3639 hints->ai_flags = 0;
3641 hints->ai_family = family; 3640 hints->ai_family = family;
3642 hints->ai_socktype = socktype; 3641 hints->ai_socktype = socktype;
@@ -3649,17 +3648,15 @@ usage: (make-network-process &rest ARGS) */)
3649 if (!NILP (Fplist_get (contact, QCnowait)) && 3648 if (!NILP (Fplist_get (contact, QCnowait)) &&
3650 !NILP (host)) 3649 !NILP (host))
3651 { 3650 {
3652 struct gaicb **reqs = xmalloc (sizeof (struct gaicb*));
3653
3654 printf("Async DNS for '%s'\n", SSDATA (host)); 3651 printf("Async DNS for '%s'\n", SSDATA (host));
3655 dns_request = xmalloc (sizeof (struct gaicb)); 3652 dns_requests = xmalloc (sizeof (struct gaicb*));
3656 reqs[0] = dns_request; 3653 dns_requests[0] = xmalloc (sizeof (struct gaicb));
3657 dns_request->ar_name = strdup (SSDATA (host)); 3654 dns_requests[0]->ar_name = strdup (SSDATA (host));
3658 dns_request->ar_service = strdup (portstring); 3655 dns_requests[0]->ar_service = strdup (portstring);
3659 dns_request->ar_request = hints; 3656 dns_requests[0]->ar_request = hints;
3660 dns_request->ar_result = NULL; 3657 dns_requests[0]->ar_result = NULL;
3661 3658
3662 ret = getaddrinfo_a (GAI_NOWAIT, reqs, 1, NULL); 3659 ret = getaddrinfo_a (GAI_NOWAIT, dns_requests, 1, NULL);
3663 if (ret) 3660 if (ret)
3664 error ("%s/%s getaddrinfo_a error %d", SSDATA (host), portstring, ret); 3661 error ("%s/%s getaddrinfo_a error %d", SSDATA (host), portstring, ret);
3665 3662
@@ -3788,7 +3785,7 @@ usage: (make-network-process &rest ARGS) */)
3788 p->port = port; 3785 p->port = port;
3789 p->socktype = socktype; 3786 p->socktype = socktype;
3790 p->ai_protocol = ai_protocol; 3787 p->ai_protocol = ai_protocol;
3791 p->dns_request = NULL; 3788 p->dns_requests = NULL;
3792 3789
3793 unbind_to (count, Qnil); 3790 unbind_to (count, Qnil);
3794 3791
@@ -3820,7 +3817,7 @@ usage: (make-network-process &rest ARGS) */)
3820 { 3817 {
3821 int channel; 3818 int channel;
3822 3819
3823 p->dns_request = dns_request; 3820 p->dns_requests = dns_requests;
3824 p->status = Qconnect; 3821 p->status = Qconnect;
3825 for (channel = 0; channel < FD_SETSIZE; ++channel) 3822 for (channel = 0; channel < FD_SETSIZE; ++channel)
3826 if (NILP (dns_process[channel])) 3823 if (NILP (dns_process[channel]))
@@ -4546,7 +4543,7 @@ check_for_dns (Lisp_Object proc)
4546 Lisp_Object ip_addresses = Qnil; 4543 Lisp_Object ip_addresses = Qnil;
4547 int ret = 0; 4544 int ret = 0;
4548 4545
4549 ret = gai_error (p->dns_request); 4546 ret = gai_error (p->dns_requests[0]);
4550 if (ret == EAI_INPROGRESS) 4547 if (ret == EAI_INPROGRESS)
4551 return 0; 4548 return 0;
4552 4549
@@ -4555,7 +4552,7 @@ check_for_dns (Lisp_Object proc)
4555 { 4552 {
4556 struct addrinfo *res; 4553 struct addrinfo *res;
4557 4554
4558 for (res = p->dns_request->ar_result; res; res = res->ai_next) 4555 for (res = p->dns_requests[0]->ar_result; res; res = res->ai_next)
4559 { 4556 {
4560 ip_addresses = Fcons (conv_sockaddr_to_lisp 4557 ip_addresses = Fcons (conv_sockaddr_to_lisp
4561 (res->ai_addr, res->ai_addrlen), 4558 (res->ai_addr, res->ai_addrlen),
@@ -4563,13 +4560,15 @@ check_for_dns (Lisp_Object proc)
4563 } 4560 }
4564 4561
4565 ip_addresses = Fnreverse (ip_addresses); 4562 ip_addresses = Fnreverse (ip_addresses);
4566 freeaddrinfo (p->dns_request->ar_result); 4563 freeaddrinfo (p->dns_requests[0]->ar_result);
4567 /* Free the calling array, too? FIXME */
4568 connect_network_socket (proc, ip_addresses); 4564 connect_network_socket (proc, ip_addresses);
4569 return 1;
4570 } 4565 }
4566 else
4567 pset_status (p, Qfailed);
4571 4568
4572 pset_status (p, Qfailed); 4569 xfree ((void *)p->dns_requests[0]->ar_request);
4570 xfree (p->dns_requests[0]);
4571 xfree (p->dns_requests);
4573 return 1; 4572 return 1;
4574} 4573}
4575#endif /* HAVE_GETADDRINFO_A */ 4574#endif /* HAVE_GETADDRINFO_A */
@@ -4705,7 +4704,7 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd,
4705 if (! NILP (dns_process[channel])) 4704 if (! NILP (dns_process[channel]))
4706 { 4705 {
4707 struct Lisp_Process *p = XPROCESS (dns_process[channel]); 4706 struct Lisp_Process *p = XPROCESS (dns_process[channel]);
4708 if (p && p->dns_request && 4707 if (p && p->dns_requests &&
4709 (! wait_proc || p == wait_proc) && 4708 (! wait_proc || p == wait_proc) &&
4710 check_for_dns (dns_process[channel])) 4709 check_for_dns (dns_process[channel]))
4711 { 4710 {
diff --git a/src/process.h b/src/process.h
index 684434c1748..990bbd55e3a 100644
--- a/src/process.h
+++ b/src/process.h
@@ -178,7 +178,7 @@ struct Lisp_Process
178#ifdef HAVE_GETADDRINFO_A 178#ifdef HAVE_GETADDRINFO_A
179 /* Whether the socket is waiting for response from an asynchronous 179 /* Whether the socket is waiting for response from an asynchronous
180 DNS call. */ 180 DNS call. */
181 struct gaicb* dns_request; 181 struct gaicb **dns_requests;
182#endif 182#endif
183 183
184#ifdef HAVE_GNUTLS 184#ifdef HAVE_GNUTLS