diff options
| author | Lars Ingebrigtsen | 2016-01-30 03:51:04 +0100 |
|---|---|---|
| committer | Lars Ingebrigtsen | 2016-01-30 03:51:04 +0100 |
| commit | 233e89cf2317a1df410fe01ce20d66293517b500 (patch) | |
| tree | 23a961282e117c17f06fd2e15862ff8666e3a4c3 /src | |
| parent | 0677d94e2d55d473e9bbacde009bfd83df0bc67e (diff) | |
| download | emacs-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.c | 43 | ||||
| -rw-r--r-- | src/process.h | 2 |
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 |