txt: introduce `ares_parse_txt_reply_ext`
Introduce `ares_txt_ext` structure with an extra `record_start` field, which indicates a start of a new TXT record, thus allowing to differentiate the chunks in the same record, from a chunks in a different record. Introduce a new API method: `ares_parse_txt_reply_ext` that works with this kind of struct.
This commit is contained in:
parent
0c4c1ca9bc
commit
53c2186e18
15
ares.h
15
ares.h
|
@ -484,6 +484,17 @@ struct ares_txt_reply {
|
|||
size_t length; /* length excludes null termination */
|
||||
};
|
||||
|
||||
/* NOTE: This structure is a superset of ares_txt_reply
|
||||
*/
|
||||
struct ares_txt_ext {
|
||||
struct ares_txt_ext *next;
|
||||
unsigned char *txt;
|
||||
size_t length;
|
||||
/* 1 - if start of new record
|
||||
* 0 - if a chunk in the same record */
|
||||
unsigned char record_start;
|
||||
};
|
||||
|
||||
struct ares_naptr_reply {
|
||||
struct ares_naptr_reply *next;
|
||||
unsigned char *flags;
|
||||
|
@ -547,6 +558,10 @@ CARES_EXTERN int ares_parse_txt_reply(const unsigned char* abuf,
|
|||
int alen,
|
||||
struct ares_txt_reply** txt_out);
|
||||
|
||||
CARES_EXTERN int ares_parse_txt_reply_ext(const unsigned char* abuf,
|
||||
int alen,
|
||||
struct ares_txt_ext** txt_out);
|
||||
|
||||
CARES_EXTERN int ares_parse_naptr_reply(const unsigned char* abuf,
|
||||
int alen,
|
||||
struct ares_naptr_reply** naptr_out);
|
||||
|
|
|
@ -79,6 +79,7 @@ void ares_free_data(void *dataptr)
|
|||
break;
|
||||
|
||||
case ARES_DATATYPE_TXT_REPLY:
|
||||
case ARES_DATATYPE_TXT_EXT:
|
||||
|
||||
if (ptr->data.txt_reply.next)
|
||||
ares_free_data(ptr->data.txt_reply.next);
|
||||
|
@ -162,6 +163,10 @@ void *ares_malloc_data(ares_datatype type)
|
|||
ptr->data.srv_reply.port = 0;
|
||||
break;
|
||||
|
||||
case ARES_DATATYPE_TXT_EXT:
|
||||
ptr->data.txt_ext.record_start = 0;
|
||||
/* FALLTHROUGH */
|
||||
|
||||
case ARES_DATATYPE_TXT_REPLY:
|
||||
ptr->data.txt_reply.next = NULL;
|
||||
ptr->data.txt_reply.txt = NULL;
|
||||
|
|
14
ares_data.h
14
ares_data.h
|
@ -18,6 +18,7 @@ typedef enum {
|
|||
ARES_DATATYPE_UNKNOWN = 1, /* unknown data type - introduced in 1.7.0 */
|
||||
ARES_DATATYPE_SRV_REPLY, /* struct ares_srv_reply - introduced in 1.7.0 */
|
||||
ARES_DATATYPE_TXT_REPLY, /* struct ares_txt_reply - introduced in 1.7.0 */
|
||||
ARES_DATATYPE_TXT_EXT, /* struct ares_txt_ext - introduced in 1.11.0 */
|
||||
ARES_DATATYPE_ADDR_NODE, /* struct ares_addr_node - introduced in 1.7.1 */
|
||||
ARES_DATATYPE_MX_REPLY, /* struct ares_mx_reply - introduced in 1.7.2 */
|
||||
ARES_DATATYPE_NAPTR_REPLY,/* struct ares_naptr_reply - introduced in 1.7.6 */
|
||||
|
@ -56,13 +57,14 @@ struct ares_data {
|
|||
ares_datatype type; /* Actual data type identifier. */
|
||||
unsigned int mark; /* Private ares_data signature. */
|
||||
union {
|
||||
struct ares_txt_reply txt_reply;
|
||||
struct ares_srv_reply srv_reply;
|
||||
struct ares_addr_node addr_node;
|
||||
struct ares_txt_reply txt_reply;
|
||||
struct ares_txt_ext txt_ext;
|
||||
struct ares_srv_reply srv_reply;
|
||||
struct ares_addr_node addr_node;
|
||||
struct ares_addr_port_node addr_port_node;
|
||||
struct ares_mx_reply mx_reply;
|
||||
struct ares_naptr_reply naptr_reply;
|
||||
struct ares_soa_reply soa_reply;
|
||||
struct ares_mx_reply mx_reply;
|
||||
struct ares_naptr_reply naptr_reply;
|
||||
struct ares_soa_reply soa_reply;
|
||||
} data;
|
||||
};
|
||||
|
||||
|
|
|
@ -22,13 +22,16 @@ ares_parse_txt_reply \- Parse a reply to a DNS query of type TXT
|
|||
.PP
|
||||
.B int ares_parse_txt_reply(const unsigned char* \fIabuf\fP, int \fIalen\fP,
|
||||
.B struct ares_txt_reply **\fItxt_out\fP);
|
||||
.PP
|
||||
.B int ares_parse_txt_reply_ext(const unsigned char* \fIabuf\fP, int \fIalen\fP,
|
||||
.B struct ares_txt_ext **\fItxt_out\fP);
|
||||
.fi
|
||||
.SH DESCRIPTION
|
||||
The
|
||||
.B ares_parse_txt_reply
|
||||
.BR "ares_parse_txt_reply" " (" "ares_parse_txt_reply_ext" ")"
|
||||
function parses the response to a query of type TXT into a
|
||||
linked list (one element per sub-string) of
|
||||
.I struct ares_txt_reply
|
||||
.IR "struct ares_txt_reply" " (" "struct ares_txt_ext" ")"
|
||||
The parameters
|
||||
.I abuf
|
||||
and
|
||||
|
@ -55,8 +58,44 @@ struct ares_txt_reply {
|
|||
.fi
|
||||
.in
|
||||
.PP
|
||||
The structure
|
||||
.I ares_txt_ext
|
||||
contains the following fields:
|
||||
.sp
|
||||
.in +4n
|
||||
.nf
|
||||
struct ares_txt_ext {
|
||||
struct ares_txt_ext *next;
|
||||
unsigned int length;
|
||||
unsigned char *txt;
|
||||
unsigned char record_start;
|
||||
};
|
||||
.fi
|
||||
.in
|
||||
.PP
|
||||
The
|
||||
.I record_start
|
||||
field in
|
||||
.I struct ares_txt_ext
|
||||
is 1 if this structure is a start of a TXT record, and 0 if the structure is a
|
||||
continuation of a previous record. The linked list of the
|
||||
.I struct ares_txt_ext
|
||||
will have at least one item with
|
||||
.I record_start
|
||||
equal to 1, and may have some items with
|
||||
.I record_start
|
||||
equal to 0 between them.
|
||||
.PP
|
||||
These sequences of
|
||||
.I struct ares_txt_ext
|
||||
(starting from the item with
|
||||
.I record_start
|
||||
equal to 1, and ending right before the record start item) may be treated as
|
||||
either components of a single TXT record or as a multi-parted TXT record,
|
||||
depending on particular use case.
|
||||
.PP
|
||||
.SH RETURN VALUES
|
||||
.B ares_parse_txt_reply
|
||||
.BR "ares_parse_txt_reply" " (" "ares_parse_txt_reply_ext" ")"
|
||||
can return any of the following values:
|
||||
.TP 15
|
||||
.B ARES_SUCCESS
|
||||
|
@ -77,4 +116,5 @@ This function was first introduced in c-ares version 1.7.0.
|
|||
.BR ares_free_data (3)
|
||||
.SH AUTHOR
|
||||
Written by Jakub Hrozek <jhrozek@redhat.com>, on behalf of Red Hat, Inc http://www.redhat.com
|
||||
|
||||
.PP
|
||||
Amended by Fedor Indutny <fedor@indutny.com>, on behalf of PayPal, Inc https://www.paypal.com
|
||||
|
|
|
@ -44,9 +44,9 @@
|
|||
#include "ares_data.h"
|
||||
#include "ares_private.h"
|
||||
|
||||
int
|
||||
ares_parse_txt_reply (const unsigned char *abuf, int alen,
|
||||
struct ares_txt_reply **txt_out)
|
||||
static int
|
||||
ares__parse_txt_reply (const unsigned char *abuf, int alen,
|
||||
int ex, void **txt_out)
|
||||
{
|
||||
size_t substr_len;
|
||||
unsigned int qdcount, ancount, i;
|
||||
|
@ -55,9 +55,9 @@ ares_parse_txt_reply (const unsigned char *abuf, int alen,
|
|||
int status, rr_type, rr_class, rr_len;
|
||||
long len;
|
||||
char *hostname = NULL, *rr_name = NULL;
|
||||
struct ares_txt_reply *txt_head = NULL;
|
||||
struct ares_txt_reply *txt_last = NULL;
|
||||
struct ares_txt_reply *txt_curr;
|
||||
struct ares_txt_ext *txt_head = NULL;
|
||||
struct ares_txt_ext *txt_last = NULL;
|
||||
struct ares_txt_ext *txt_curr;
|
||||
|
||||
/* Set *txt_out to NULL for all failure cases. */
|
||||
*txt_out = NULL;
|
||||
|
@ -133,10 +133,9 @@ ares_parse_txt_reply (const unsigned char *abuf, int alen,
|
|||
break;
|
||||
}
|
||||
|
||||
++strptr;
|
||||
|
||||
/* Allocate storage for this TXT answer appending it to the list */
|
||||
txt_curr = ares_malloc_data(ARES_DATATYPE_TXT_REPLY);
|
||||
txt_curr = ares_malloc_data(ex ? ARES_DATATYPE_TXT_EXT :
|
||||
ARES_DATATYPE_TXT_REPLY);
|
||||
if (!txt_curr)
|
||||
{
|
||||
status = ARES_ENOMEM;
|
||||
|
@ -152,6 +151,8 @@ ares_parse_txt_reply (const unsigned char *abuf, int alen,
|
|||
}
|
||||
txt_last = txt_curr;
|
||||
|
||||
if (ex)
|
||||
txt_curr->record_start = (strptr == aptr);
|
||||
txt_curr->length = substr_len;
|
||||
txt_curr->txt = ares_malloc (substr_len + 1/* Including null byte */);
|
||||
if (txt_curr->txt == NULL)
|
||||
|
@ -159,6 +160,8 @@ ares_parse_txt_reply (const unsigned char *abuf, int alen,
|
|||
status = ARES_ENOMEM;
|
||||
break;
|
||||
}
|
||||
|
||||
++strptr;
|
||||
memcpy ((char *) txt_curr->txt, strptr, substr_len);
|
||||
|
||||
/* Make sure we NULL-terminate */
|
||||
|
@ -200,3 +203,18 @@ ares_parse_txt_reply (const unsigned char *abuf, int alen,
|
|||
|
||||
return ARES_SUCCESS;
|
||||
}
|
||||
|
||||
int
|
||||
ares_parse_txt_reply (const unsigned char *abuf, int alen,
|
||||
struct ares_txt_reply **txt_out)
|
||||
{
|
||||
return ares__parse_txt_reply(abuf, alen, 0, (void **) txt_out);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
ares_parse_txt_reply_ext (const unsigned char *abuf, int alen,
|
||||
struct ares_txt_ext **txt_out)
|
||||
{
|
||||
return ares__parse_txt_reply(abuf, alen, 1, (void **) txt_out);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue