aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/libs/c-ares/src/lib/ares_parse_mx_reply.c
diff options
context:
space:
mode:
authorthegeorg <thegeorg@yandex-team.com>2024-07-30 09:57:24 +0300
committerthegeorg <thegeorg@yandex-team.com>2024-07-30 10:08:52 +0300
commit5b405616d0467647cb365e71237976a9f3810b42 (patch)
treec35e742877f95ba2b9357f178197c755f121cb1a /contrib/libs/c-ares/src/lib/ares_parse_mx_reply.c
parent997c68115bc1c9dd2fce5a6a6f8eae92ad628df7 (diff)
downloadydb-5b405616d0467647cb365e71237976a9f3810b42.tar.gz
Update contrib/libs/c-ares to 1.28.1
db71d0a3bd9ec3cf1e1ccb5a9cfac8abfd43fdb7
Diffstat (limited to 'contrib/libs/c-ares/src/lib/ares_parse_mx_reply.c')
-rw-r--r--contrib/libs/c-ares/src/lib/ares_parse_mx_reply.c180
1 files changed, 59 insertions, 121 deletions
diff --git a/contrib/libs/c-ares/src/lib/ares_parse_mx_reply.c b/contrib/libs/c-ares/src/lib/ares_parse_mx_reply.c
index 36dfe3d933..db7155d2e8 100644
--- a/contrib/libs/c-ares/src/lib/ares_parse_mx_reply.c
+++ b/contrib/libs/c-ares/src/lib/ares_parse_mx_reply.c
@@ -1,7 +1,6 @@
/* MIT License
*
- * Copyright (c) 1998 Massachusetts Institute of Technology
- * Copyright (c) 2010 Jeremy Lal
+ * Copyright (c) 2023 Brad House
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -26,149 +25,88 @@
*/
#include "ares_setup.h"
-
-#ifdef HAVE_NETINET_IN_H
-# include <netinet/in.h>
-#endif
-#ifdef HAVE_NETDB_H
-# include <netdb.h>
-#endif
-#ifdef HAVE_ARPA_INET_H
-# include <arpa/inet.h>
-#endif
-
-#include "ares_nameser.h"
-
#include "ares.h"
-#include "ares_dns.h"
#include "ares_data.h"
#include "ares_private.h"
-int
-ares_parse_mx_reply (const unsigned char *abuf, int alen,
- struct ares_mx_reply **mx_out)
+int ares_parse_mx_reply(const unsigned char *abuf, int alen_int,
+ struct ares_mx_reply **mx_out)
{
- unsigned int qdcount, ancount, i;
- const unsigned char *aptr, *vptr;
- int status, rr_type, rr_class, rr_len;
- long len;
- char *hostname = NULL, *rr_name = NULL;
+ ares_status_t status;
+ size_t alen;
struct ares_mx_reply *mx_head = NULL;
struct ares_mx_reply *mx_last = NULL;
struct ares_mx_reply *mx_curr;
+ ares_dns_record_t *dnsrec = NULL;
+ size_t i;
- /* Set *mx_out to NULL for all failure cases. */
*mx_out = NULL;
- /* Give up if abuf doesn't have room for a header. */
- if (alen < HFIXEDSZ)
+ if (alen_int < 0) {
return ARES_EBADRESP;
+ }
- /* Fetch the question and answer count from the header. */
- qdcount = DNS_HEADER_QDCOUNT (abuf);
- ancount = DNS_HEADER_ANCOUNT (abuf);
- if (qdcount != 1)
- return ARES_EBADRESP;
- if (ancount == 0)
- return ARES_ENODATA;
+ alen = (size_t)alen_int;
- /* Expand the name from the question, and skip past the question. */
- aptr = abuf + HFIXEDSZ;
- status = ares_expand_name (aptr, abuf, alen, &hostname, &len);
- if (status != ARES_SUCCESS)
- return status;
+ status = ares_dns_parse(abuf, alen, 0, &dnsrec);
+ if (status != ARES_SUCCESS) {
+ goto done;
+ }
- if (aptr + len + QFIXEDSZ > abuf + alen)
- {
- ares_free (hostname);
- return ARES_EBADRESP;
- }
- aptr += len + QFIXEDSZ;
+ if (ares_dns_record_rr_cnt(dnsrec, ARES_SECTION_ANSWER) == 0) {
+ status = ARES_ENODATA;
+ goto done;
+ }
- /* Examine each answer resource record (RR) in turn. */
- for (i = 0; i < ancount; i++)
- {
- /* Decode the RR up to the data field. */
- status = ares_expand_name (aptr, abuf, alen, &rr_name, &len);
- if (status != ARES_SUCCESS)
- {
- break;
- }
- aptr += len;
- if (aptr + RRFIXEDSZ > abuf + alen)
- {
- status = ARES_EBADRESP;
- break;
- }
- rr_type = DNS_RR_TYPE (aptr);
- rr_class = DNS_RR_CLASS (aptr);
- rr_len = DNS_RR_LEN (aptr);
- aptr += RRFIXEDSZ;
- if (aptr + rr_len > abuf + alen)
- {
- status = ARES_EBADRESP;
- break;
- }
+ for (i = 0; i < ares_dns_record_rr_cnt(dnsrec, ARES_SECTION_ANSWER); i++) {
+ const ares_dns_rr_t *rr =
+ ares_dns_record_rr_get(dnsrec, ARES_SECTION_ANSWER, i);
- /* Check if we are really looking at a MX record */
- if (rr_class == C_IN && rr_type == T_MX)
- {
- /* parse the MX record itself */
- if (rr_len < 2)
- {
- status = ARES_EBADRESP;
- break;
- }
+ if (rr == NULL) {
+ /* Shouldn't be possible */
+ status = ARES_EBADRESP;
+ goto done;
+ }
- /* Allocate storage for this MX answer appending it to the list */
- mx_curr = ares_malloc_data(ARES_DATATYPE_MX_REPLY);
- if (!mx_curr)
- {
- status = ARES_ENOMEM;
- break;
- }
- if (mx_last)
- {
- mx_last->next = mx_curr;
- }
- else
- {
- mx_head = mx_curr;
- }
- mx_last = mx_curr;
+ if (ares_dns_rr_get_class(rr) != ARES_CLASS_IN ||
+ ares_dns_rr_get_type(rr) != ARES_REC_TYPE_MX) {
+ continue;
+ }
- vptr = aptr;
- mx_curr->priority = DNS__16BIT(vptr);
- vptr += sizeof(unsigned short);
+ /* Allocate storage for this MX answer appending it to the list */
+ mx_curr = ares_malloc_data(ARES_DATATYPE_MX_REPLY);
+ if (mx_curr == NULL) {
+ status = ARES_ENOMEM;
+ goto done;
+ }
- status = ares_expand_name (vptr, abuf, alen, &mx_curr->host, &len);
- if (status != ARES_SUCCESS)
- break;
- }
+ /* Link in the record */
+ if (mx_last) {
+ mx_last->next = mx_curr;
+ } else {
+ mx_head = mx_curr;
+ }
+ mx_last = mx_curr;
- /* Don't lose memory in the next iteration */
- ares_free (rr_name);
- rr_name = NULL;
+ mx_curr->priority = ares_dns_rr_get_u16(rr, ARES_RR_MX_PREFERENCE);
+ mx_curr->host = ares_strdup(ares_dns_rr_get_str(rr, ARES_RR_MX_EXCHANGE));
- /* Move on to the next record */
- aptr += rr_len;
+ if (mx_curr->host == NULL) {
+ status = ARES_ENOMEM;
+ goto done;
}
+ }
- if (hostname)
- ares_free (hostname);
- if (rr_name)
- ares_free (rr_name);
-
+done:
/* clean up on error */
- if (status != ARES_SUCCESS)
- {
- if (mx_head)
- ares_free_data (mx_head);
- return status;
+ if (status != ARES_SUCCESS) {
+ if (mx_head) {
+ ares_free_data(mx_head);
}
-
- /* everything looks fine, return the data */
- *mx_out = mx_head;
-
- return ARES_SUCCESS;
+ } else {
+ /* everything looks fine, return the data */
+ *mx_out = mx_head;
+ }
+ ares_dns_record_destroy(dnsrec);
+ return (int)status;
}