mirror of
https://github.com/NLnetLabs/unbound.git
synced 2025-12-20 23:00:56 -05:00
test for msgparse.
git-svn-id: file:///svn/unbound/trunk@246 be551aaa-1e26-0410-a405-d3ace91eadb9
This commit is contained in:
parent
8bda1b6893
commit
1cb321662d
11 changed files with 328 additions and 11 deletions
|
|
@ -3,6 +3,10 @@
|
|||
- store calculated hash value too.
|
||||
- routine to create message out of stored information.
|
||||
- util/data/msgparse.c for message parsing code.
|
||||
- unit test, and first fixes because of test.
|
||||
* forgot rrset_count addition.
|
||||
* did & of ptr on stack for memory position calculation.
|
||||
* dname_pkt_copy forgot to read next label length.
|
||||
|
||||
16 April 2007: Wouter
|
||||
- following a small change in LDNS, parsing code calculates the
|
||||
|
|
|
|||
|
|
@ -47,6 +47,7 @@
|
|||
#include "config.h"
|
||||
#include "testcode/fake_event.h"
|
||||
#include "util/netevent.h"
|
||||
#include "util/net_help.h"
|
||||
#include "services/listen_dnsport.h"
|
||||
#include "services/outside_network.h"
|
||||
#include "testcode/replay.h"
|
||||
|
|
@ -613,12 +614,7 @@ void
|
|||
comm_point_send_reply_iov(struct comm_reply* repinfo, struct iovec* iov,
|
||||
size_t iovlen)
|
||||
{
|
||||
size_t i;
|
||||
ldns_buffer_clear(repinfo->c->buffer);
|
||||
for(i=1; i<iovlen; i++)
|
||||
ldns_buffer_write(repinfo->c->buffer, iov[i].iov_base,
|
||||
iov[i].iov_len);
|
||||
ldns_buffer_flip(repinfo->c->buffer);
|
||||
write_iov_buffer(repinfo->c->buffer, iov, iovlen);
|
||||
comm_point_send_reply(repinfo);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -216,6 +216,7 @@ main(int argc, char* argv[])
|
|||
msgreply_test();
|
||||
lruhash_test();
|
||||
slabhash_test();
|
||||
msgparse_test();
|
||||
checklock_stop();
|
||||
printf("%d tests succeeded\n", testcount);
|
||||
return 0;
|
||||
|
|
|
|||
|
|
@ -51,5 +51,7 @@ extern int testcount;
|
|||
void lruhash_test();
|
||||
/** unit test slabhashtable implementation */
|
||||
void slabhash_test();
|
||||
/** unit test for msgreply and msgparse */
|
||||
void msgparse_test();
|
||||
|
||||
#endif /* TESTCODE_UNITMAIN_H */
|
||||
|
|
|
|||
282
testcode/unitmsgparse.c
Normal file
282
testcode/unitmsgparse.c
Normal file
|
|
@ -0,0 +1,282 @@
|
|||
/*
|
||||
* testcode/unitmsgparse.c - unit test for msg parse routines.
|
||||
*
|
||||
* Copyright (c) 2007, NLnet Labs. All rights reserved.
|
||||
*
|
||||
* This software is open source.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* Neither the name of the NLNET LABS nor the names of its contributors may
|
||||
* be used to endorse or promote products derived from this software without
|
||||
* specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
/**
|
||||
* \file
|
||||
* Unit test main program. Calls all the other unit tests.
|
||||
* Exits with code 1 on a failure. 0 if all unit tests are successfull.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "util/log.h"
|
||||
#include "testcode/unitmain.h"
|
||||
#include "util/data/msgparse.h"
|
||||
#include "util/data/msgreply.h"
|
||||
#include "util/alloc.h"
|
||||
#include "util/region-allocator.h"
|
||||
#include "util/net_help.h"
|
||||
|
||||
/** skip whitespace */
|
||||
static void
|
||||
skip_whites(const char** p)
|
||||
{
|
||||
while(1) {
|
||||
while(isspace(**p))
|
||||
(*p)++;
|
||||
if(**p == ';') {
|
||||
/* comment, skip until newline */
|
||||
while(**p && **p != '\n')
|
||||
(*p)++;
|
||||
if(**p == '\n')
|
||||
(*p)++;
|
||||
} else return;
|
||||
}
|
||||
}
|
||||
|
||||
/** takes a hex string and puts into buffer */
|
||||
static void hex_to_buf(ldns_buffer* pkt, const char* hex)
|
||||
{
|
||||
const char* p = hex;
|
||||
int val;
|
||||
ldns_buffer_clear(pkt);
|
||||
while(*p) {
|
||||
skip_whites(&p);
|
||||
if(ldns_buffer_position(pkt) == ldns_buffer_limit(pkt))
|
||||
fatal_exit("hex_to_buf: buffer too small");
|
||||
if(!isalnum(*p))
|
||||
break;
|
||||
val = ldns_hexdigit_to_int(*p++) << 4;
|
||||
skip_whites(&p);
|
||||
log_assert(*p && isalnum(*p));
|
||||
val |= ldns_hexdigit_to_int(*p++);
|
||||
ldns_buffer_write_u8(pkt, (uint8_t)val);
|
||||
skip_whites(&p);
|
||||
}
|
||||
ldns_buffer_flip(pkt);
|
||||
if(0) printf("packet size %u\n", (unsigned)ldns_buffer_limit(pkt));
|
||||
}
|
||||
|
||||
/** match two rr lists */
|
||||
static int
|
||||
match_list(ldns_rr_list* q, ldns_rr_list *p)
|
||||
{
|
||||
size_t i;
|
||||
if(ldns_rr_list_rr_count(q) != ldns_rr_list_rr_count(p))
|
||||
return 0;
|
||||
for(i=0; i<ldns_rr_list_rr_count(q); i++)
|
||||
{
|
||||
if(ldns_rr_compare(ldns_rr_list_rr(q, i),
|
||||
ldns_rr_list_rr(p, i)) != 0) {
|
||||
verbose(3, "rr %d different", i);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/** compare two booleans */
|
||||
static int
|
||||
cmp_bool(int x, int y)
|
||||
{
|
||||
if(!x && !y) return 0;
|
||||
if(x && y) return 0;
|
||||
if(!x) return -1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/** match all of the packet */
|
||||
static int
|
||||
match_all(ldns_pkt* q, ldns_pkt* p)
|
||||
{
|
||||
if(ldns_pkt_get_opcode(q) != ldns_pkt_get_opcode(p))
|
||||
{ verbose(3, "allmatch: opcode different"); return 0;}
|
||||
if(ldns_pkt_get_rcode(q) != ldns_pkt_get_rcode(p))
|
||||
{ verbose(3, "allmatch: rcode different"); return 0;}
|
||||
if(ldns_pkt_id(q) != ldns_pkt_id(p))
|
||||
{ verbose(3, "allmatch: id different"); return 0;}
|
||||
if(cmp_bool(ldns_pkt_qr(q), ldns_pkt_qr(p)) != 0)
|
||||
{ verbose(3, "allmatch: qr different"); return 0;}
|
||||
if(cmp_bool(ldns_pkt_aa(q), ldns_pkt_aa(p)) != 0)
|
||||
{ verbose(3, "allmatch: aa different"); return 0;}
|
||||
if(cmp_bool(ldns_pkt_tc(q), ldns_pkt_tc(p)) != 0)
|
||||
{ verbose(3, "allmatch: tc different"); return 0;}
|
||||
if(cmp_bool(ldns_pkt_rd(q), ldns_pkt_rd(p)) != 0)
|
||||
{ verbose(3, "allmatch: rd different"); return 0;}
|
||||
if(cmp_bool(ldns_pkt_cd(q), ldns_pkt_cd(p)) != 0)
|
||||
{ verbose(3, "allmatch: cd different"); return 0;}
|
||||
if(cmp_bool(ldns_pkt_ra(q), ldns_pkt_ra(p)) != 0)
|
||||
{ verbose(3, "allmatch: ra different"); return 0;}
|
||||
if(cmp_bool(ldns_pkt_ad(q), ldns_pkt_ad(p)) != 0)
|
||||
{ verbose(3, "allmatch: ad different"); return 0;}
|
||||
if(ldns_pkt_qdcount(q) != ldns_pkt_qdcount(p))
|
||||
{ verbose(3, "allmatch: qdcount different"); return 0;}
|
||||
if(ldns_pkt_ancount(q) != ldns_pkt_ancount(p))
|
||||
{ verbose(3, "allmatch: ancount different"); return 0;}
|
||||
if(ldns_pkt_nscount(q) != ldns_pkt_nscount(p))
|
||||
{ verbose(3, "allmatch: nscount different"); return 0;}
|
||||
if(ldns_pkt_arcount(q) != ldns_pkt_arcount(p))
|
||||
{ verbose(3, "allmatch: arcount different"); return 0;}
|
||||
if(!match_list(ldns_pkt_question(q), ldns_pkt_question(p)))
|
||||
{ verbose(3, "allmatch: qd section different"); return 0;}
|
||||
if(!match_list(ldns_pkt_answer(q), ldns_pkt_answer(p)))
|
||||
{ verbose(3, "allmatch: an section different"); return 0;}
|
||||
if(!match_list(ldns_pkt_authority(q), ldns_pkt_authority(p)))
|
||||
{ verbose(3, "allmatch: ar section different"); return 0;}
|
||||
if(!match_list(ldns_pkt_additional(q), ldns_pkt_additional(p)))
|
||||
{ verbose(3, "allmatch: ns section different"); return 0;}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/** see if buffers contain the same packet */
|
||||
static int
|
||||
test_buffers(ldns_buffer* pkt, ldns_buffer* out)
|
||||
{
|
||||
ldns_pkt* p1=0, *p2=0;
|
||||
ldns_status s1, s2;
|
||||
/* check binary same */
|
||||
if(ldns_buffer_limit(pkt) == ldns_buffer_limit(out) &&
|
||||
memcmp(ldns_buffer_begin(pkt), ldns_buffer_begin(out),
|
||||
ldns_buffer_limit(pkt)) == 0)
|
||||
return 1;
|
||||
/* check if it 'means the same' */
|
||||
s1 = ldns_buffer2pkt_wire(&p1, pkt);
|
||||
s2 = ldns_buffer2pkt_wire(&p2, pkt);
|
||||
if(s1 != s2) {
|
||||
/* oops! */
|
||||
printf("input ldns parse: %s, output ldns parse: %s.\n",
|
||||
ldns_get_errorstr_by_id(s1),
|
||||
ldns_get_errorstr_by_id(s2));
|
||||
unit_assert(0);
|
||||
}
|
||||
/* compare packets */
|
||||
unit_assert(match_all(p1, p2));
|
||||
ldns_pkt_free(p1);
|
||||
ldns_pkt_free(p2);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** test a packet */
|
||||
static void
|
||||
testpkt(ldns_buffer* pkt, struct alloc_cache* alloc, ldns_buffer* out,
|
||||
const char* hex)
|
||||
{
|
||||
struct query_info qi;
|
||||
struct reply_info* rep = 0;
|
||||
size_t sz;
|
||||
int ret;
|
||||
uint16_t id;
|
||||
uint16_t flags;
|
||||
uint32_t timenow = 0;
|
||||
region_type *region = region_create(malloc, free);
|
||||
struct iovec iov[1024];
|
||||
size_t maxiov = 1024;
|
||||
|
||||
hex_to_buf(pkt, hex);
|
||||
memmove(&id, ldns_buffer_begin(pkt), sizeof(id));
|
||||
memmove(&flags, ldns_buffer_at(pkt, 2), sizeof(flags));
|
||||
ret = reply_info_parse(pkt, alloc, &qi, &rep);
|
||||
if(ret != 0) {
|
||||
printf("exit code %d: %s", ret,
|
||||
ldns_lookup_by_id(ldns_rcodes, ret)->name);
|
||||
unit_assert(ret == 0);
|
||||
}
|
||||
sz = reply_info_iov_regen(&qi, rep, id, flags, iov, maxiov,
|
||||
timenow, region);
|
||||
unit_assert(sz != 0); /* udp packets should fit in 1024 iov */
|
||||
write_iov_buffer(out, iov, sz);
|
||||
|
||||
test_buffers(pkt, out);
|
||||
|
||||
query_info_clear(&qi);
|
||||
reply_info_parsedelete(rep, alloc);
|
||||
region_destroy(region);
|
||||
}
|
||||
|
||||
/** simple test of parsing. */
|
||||
static void
|
||||
simpletest(ldns_buffer* pkt, struct alloc_cache* alloc, ldns_buffer* out)
|
||||
{
|
||||
/* a root query drill -q - */
|
||||
testpkt(pkt, alloc, out,
|
||||
" c5 40 01 00 00 01 00 00 00 00 00 00 00 00 02 00 01 ");
|
||||
|
||||
/* a root reply drill -w - */
|
||||
testpkt(pkt, alloc, out,
|
||||
" ; 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19\n"
|
||||
" ;-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --\n"
|
||||
" 97 3f 81 80 00 01 00 0d 00 00 00 02 00 00 02 00 01 00 00 02 ; 1- 20\n"
|
||||
" 00 01 00 06 6d 38 00 14 01 49 0c 52 4f 4f 54 2d 53 45 52 56 ; 21- 40\n"
|
||||
" 45 52 53 03 4e 45 54 00 00 00 02 00 01 00 06 6d 38 00 14 01 ; 41- 60\n"
|
||||
" 4a 0c 52 4f 4f 54 2d 53 45 52 56 45 52 53 03 4e 45 54 00 00 ; 61- 80\n"
|
||||
" 00 02 00 01 00 06 6d 38 00 14 01 4b 0c 52 4f 4f 54 2d 53 45 ; 81- 100\n"
|
||||
" 52 56 45 52 53 03 4e 45 54 00 00 00 02 00 01 00 06 6d 38 00 ; 101- 120\n"
|
||||
" 14 01 4c 0c 52 4f 4f 54 2d 53 45 52 56 45 52 53 03 4e 45 54 ; 121- 140\n"
|
||||
" 00 00 00 02 00 01 00 06 6d 38 00 14 01 4d 0c 52 4f 4f 54 2d ; 141- 160\n"
|
||||
" 53 45 52 56 45 52 53 03 4e 45 54 00 00 00 02 00 01 00 06 6d ; 161- 180\n"
|
||||
" 38 00 14 01 41 0c 52 4f 4f 54 2d 53 45 52 56 45 52 53 03 4e ; 181- 200\n"
|
||||
" 45 54 00 00 00 02 00 01 00 06 6d 38 00 14 01 42 0c 52 4f 4f ; 201- 220\n"
|
||||
" 54 2d 53 45 52 56 45 52 53 03 4e 45 54 00 00 00 02 00 01 00 ; 221- 240\n"
|
||||
" 06 6d 38 00 14 01 43 0c 52 4f 4f 54 2d 53 45 52 56 45 52 53 ; 241- 260\n"
|
||||
" 03 4e 45 54 00 00 00 02 00 01 00 06 6d 38 00 14 01 44 0c 52 ; 261- 280\n"
|
||||
" 4f 4f 54 2d 53 45 52 56 45 52 53 03 4e 45 54 00 00 00 02 00 ; 281- 300\n"
|
||||
" 01 00 06 6d 38 00 14 01 45 0c 52 4f 4f 54 2d 53 45 52 56 45 ; 301- 320\n"
|
||||
" 52 53 03 4e 45 54 00 00 00 02 00 01 00 06 6d 38 00 14 01 46 ; 321- 340\n"
|
||||
" 0c 52 4f 4f 54 2d 53 45 52 56 45 52 53 03 4e 45 54 00 00 00 ; 341- 360\n"
|
||||
" 02 00 01 00 06 6d 38 00 14 01 47 0c 52 4f 4f 54 2d 53 45 52 ; 361- 380\n"
|
||||
" 56 45 52 53 03 4e 45 54 00 00 00 02 00 01 00 06 6d 38 00 14 ; 381- 400\n"
|
||||
" 01 48 0c 52 4f 4f 54 2d 53 45 52 56 45 52 53 03 4e 45 54 00 ; 401- 420\n"
|
||||
" 01 41 0c 52 4f 4f 54 2d 53 45 52 56 45 52 53 03 4e 45 54 00 ; 421- 440\n"
|
||||
" 00 01 00 01 00 02 64 b9 00 04 c6 29 00 04 01 4a 0c 52 4f 4f ; 441- 460\n"
|
||||
" 54 2d 53 45 52 56 45 52 53 03 4e 45 54 00 00 01 00 01 00 02 ; 461- 480\n"
|
||||
" 64 b9 00 04 c0 3a 80 1e ");
|
||||
}
|
||||
|
||||
void msgparse_test()
|
||||
{
|
||||
ldns_buffer* pkt = ldns_buffer_new(65553);
|
||||
ldns_buffer* out = ldns_buffer_new(65553);
|
||||
struct alloc_cache super_a, alloc;
|
||||
/* init */
|
||||
alloc_init(&super_a, NULL, 0);
|
||||
alloc_init(&alloc, &super_a, 2);
|
||||
|
||||
simpletest(pkt, &alloc, out);
|
||||
|
||||
/* cleanup */
|
||||
alloc_clear(&alloc);
|
||||
alloc_clear(&super_a);
|
||||
ldns_buffer_free(pkt);
|
||||
ldns_buffer_free(out);
|
||||
}
|
||||
|
|
@ -296,6 +296,7 @@ void dname_pkt_copy(ldns_buffer* pkt, uint8_t* to, uint8_t* dname)
|
|||
memmove(to, dname, lablen);
|
||||
dname += lablen;
|
||||
to += lablen;
|
||||
lablen = *dname++;
|
||||
}
|
||||
/* copy last \0 */
|
||||
*to = 0;
|
||||
|
|
|
|||
|
|
@ -32,6 +32,10 @@
|
|||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
/**
|
||||
* \file
|
||||
* Routines for message parsing a packet buffer to a descriptive structure.
|
||||
*/
|
||||
#include "config.h"
|
||||
#include "util/data/msgparse.h"
|
||||
#include "util/net_help.h"
|
||||
|
|
@ -403,5 +407,6 @@ parse_packet(ldns_buffer* pkt, struct msg_parse* msg, region_type* region)
|
|||
/* spurious data at end of packet. ignore */
|
||||
verbose(VERB_DETAIL, "spurious data at end of packet ignored");
|
||||
}
|
||||
msg->rrset_count = msg->an_rrsets + msg->ns_rrsets + msg->ar_rrsets;
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -32,6 +32,11 @@
|
|||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
/**
|
||||
* \file
|
||||
* Contains message parsing data structures.
|
||||
* These point back into the packet buffer.
|
||||
*/
|
||||
|
||||
#ifndef UTIL_DATA_MSGPARSE_H
|
||||
#define UTIL_DATA_MSGPARSE_H
|
||||
|
|
|
|||
|
|
@ -93,8 +93,8 @@ parse_create_repinfo(struct msg_parse* msg, struct reply_info** rep)
|
|||
(*rep)->ar_numrrsets = msg->ar_rrsets;
|
||||
(*rep)->rrset_count = msg->rrset_count;
|
||||
/* array starts after the refs */
|
||||
(*rep)->rrsets = (struct ub_packed_rrset_key**)&
|
||||
((*rep)->ref[msg->rrset_count]);
|
||||
(*rep)->rrsets = (struct ub_packed_rrset_key**)
|
||||
&((*rep)->ref[msg->rrset_count]);
|
||||
/* zero the arrays to assist cleanup in case of malloc failure */
|
||||
memset( (*rep)->rrsets, 0,
|
||||
sizeof(struct ub_packed_rrset_key*) * msg->rrset_count);
|
||||
|
|
@ -308,10 +308,10 @@ parse_rr_copy(ldns_buffer* pkt, struct rrset_parse* pset,
|
|||
data->ttl = MAX_TTL;
|
||||
data->count = pset->rr_count;
|
||||
/* layout: struct - rr_len - rr_data - rdata - rrsig */
|
||||
data->rr_len = (size_t*)((uint8_t*)&data +
|
||||
data->rr_len = (size_t*)((uint8_t*)data +
|
||||
sizeof(struct packed_rrset_data));
|
||||
data->rr_data = (uint8_t**)(&data->rr_len[data->count]);
|
||||
nextrdata = (uint8_t*)(&data->rr_data[data->count]);
|
||||
data->rr_data = (uint8_t**)&(data->rr_len[data->count]);
|
||||
nextrdata = (uint8_t*)&(data->rr_data[data->count]);
|
||||
data->rrsig_data = 0;
|
||||
data->rrsig_len = 0;
|
||||
for(i=0; i<data->count; i++) {
|
||||
|
|
|
|||
|
|
@ -94,3 +94,16 @@ is_pow2(size_t num)
|
|||
if(num == 0) return 1;
|
||||
return (num & (num-1)) == 0;
|
||||
}
|
||||
|
||||
void
|
||||
write_iov_buffer(ldns_buffer* buffer, struct iovec* iov, size_t iovlen)
|
||||
{
|
||||
size_t i;
|
||||
ldns_buffer_clear(buffer);
|
||||
for(i=1; i<iovlen; i++) {
|
||||
log_assert(ldns_buffer_position(buffer)+iov[i].iov_len
|
||||
<= ldns_buffer_capacity(buffer));
|
||||
ldns_buffer_write(buffer, iov[i].iov_base, iov[i].iov_len);
|
||||
}
|
||||
ldns_buffer_flip(buffer);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -83,4 +83,12 @@ int fd_set_nonblock(int s);
|
|||
*/
|
||||
int is_pow2(size_t num);
|
||||
|
||||
/**
|
||||
* Write iov vector into a buffer.
|
||||
* @param buffer: to write data into.
|
||||
* @param iov: iov vector
|
||||
* @param iovlen: length of iov vector
|
||||
*/
|
||||
void write_iov_buffer(ldns_buffer* buffer, struct iovec* iov, size_t iovlen);
|
||||
|
||||
#endif /* NET_HELP_H */
|
||||
|
|
|
|||
Loading…
Reference in a new issue