18#ifdef HAVE_NETINET_IN_H
19#include <netinet/in.h>
21#ifdef HAVE_SYS_SOCKET_H
22#include <sys/socket.h>
27#ifdef HAVE_ARPA_INET_H
63static struct sockaddr_storage *
64ldns_rdf2native_sockaddr_storage_port(
65 const ldns_rdf *rd, uint16_t port,
size_t *size)
67 struct sockaddr_storage *data;
68 struct sockaddr_in *data_in;
69 struct sockaddr_in6 *data_in6;
76 memset(data, 0,
sizeof(
struct sockaddr_storage));
81 data->ss_family = AF_INET;
83 data_in = (
struct sockaddr_in*) data;
84 data_in->sin_port = (in_port_t)htons(port);
86 *size =
sizeof(
struct sockaddr_in);
90 data->ss_family = AF_INET6;
92 data_in6 = (
struct sockaddr_in6*) data;
93 data_in6->sin6_port = (in_port_t)htons(port);
95 *size =
sizeof(
struct sockaddr_in6);
103struct sockaddr_storage *
105 const ldns_rdf *rd, uint16_t port,
size_t *size)
107 return ldns_rdf2native_sockaddr_storage_port(
108 rd, (port == 0 ? (uint16_t)
LDNS_PORT : port), size);
113ldns_sock_nonblock(
int sockfd)
117 if((flag = fcntl(sockfd, F_GETFL)) != -1) {
119 if(fcntl(sockfd, F_SETFL, flag) == -1) {
123#elif defined(HAVE_IOCTLSOCKET)
124 unsigned long on = 1;
125 if(ioctlsocket(sockfd, FIONBIO, &on) != 0) {
133ldns_sock_block(
int sockfd)
137 if((flag = fcntl(sockfd, F_GETFL)) != -1) {
139 if(fcntl(sockfd, F_SETFL, flag) == -1) {
143#elif defined(HAVE_IOCTLSOCKET)
144 unsigned long off = 0;
145 if(ioctlsocket(sockfd, FIONBIO, &off) != 0) {
153ldns_sock_wait(
int sockfd,
struct timeval timeout,
int write)
162 ret = select(sockfd+1, NULL, &fds, NULL, &timeout);
164 ret = select(sockfd+1, &fds, NULL, NULL, &timeout);
167 struct pollfd pfds[2];
169 memset(&pfds[0], 0,
sizeof(pfds[0]) * 2);
172 pfds[0].events = POLLIN|POLLERR;
175 pfds[0].events |= POLLOUT;
178 ret = poll(pfds, 1, (
int)(timeout.tv_sec * 1000
179 + timeout.tv_usec / 1000));
192ldns_tcp_connect_from(
const struct sockaddr_storage *to, socklen_t tolen,
193 const struct sockaddr_storage *from, socklen_t fromlen,
194 struct timeval timeout)
199 if ((sockfd = socket((
int)((
struct sockaddr*)to)->sa_family, SOCK_STREAM,
204 if (from && bind(sockfd, (
const struct sockaddr*)from, fromlen) == -1){
210 ldns_sock_nonblock(sockfd);
211 if (connect(sockfd, (
struct sockaddr*)to, tolen) == -1) {
214 if(errno != EINPROGRESS) {
222 if(WSAGetLastError() != WSAEINPROGRESS &&
223 WSAGetLastError() != WSAEWOULDBLOCK) {
234 socklen_t len = (socklen_t)
sizeof(error);
236 if(!ldns_sock_wait(sockfd, timeout, 1)) {
242 if(getsockopt(sockfd, SOL_SOCKET, SO_ERROR, (
void*)&error,
247 error = WSAGetLastError();
251#if defined(EINPROGRESS) && defined(EWOULDBLOCK)
252 if(error == EINPROGRESS || error == EWOULDBLOCK)
255 else if(error != 0) {
262 if(error == WSAEINPROGRESS)
264 else if(error == WSAEWOULDBLOCK)
266 else if(error != 0) {
277 ldns_sock_block(sockfd);
284 struct timeval timeout)
286 int s = ldns_tcp_connect_from(to, tolen, NULL, 0, timeout);
287 return s > 0 ? s : 0;
292 struct timeval timeout)
294 return ldns_tcp_connect_from(to, tolen, NULL, 0, timeout);
299 const struct sockaddr_storage *to, socklen_t tolen,
300 const struct sockaddr_storage *from, socklen_t fromlen,
301 struct timeval timeout)
305 sockfd = ldns_tcp_connect_from(to, tolen, from, fromlen, timeout);
317 const struct sockaddr_storage *to, socklen_t tolen,
318 struct timeval timeout)
320 int s = ldns_tcp_bgsend_from(qbin, to, tolen, NULL, 0, timeout);
321 return s > 0 ? s : 0;
326 const struct sockaddr_storage *to, socklen_t tolen,
327 struct timeval timeout)
329 return ldns_tcp_bgsend_from(qbin, to, tolen, NULL, 0, timeout);
336ldns_tcp_send_from(uint8_t **result,
ldns_buffer *qbin,
337 const struct sockaddr_storage *to, socklen_t tolen,
338 const struct sockaddr_storage *from, socklen_t fromlen,
339 struct timeval timeout,
size_t *answer_size)
344 sockfd = ldns_tcp_bgsend_from(qbin, to, tolen, from, fromlen, timeout);
364 const struct sockaddr_storage *to, socklen_t tolen,
365 struct timeval timeout,
size_t *answer_size)
367 return ldns_tcp_send_from(result, qbin,
368 to, tolen, NULL, 0, timeout, answer_size);
377 if ((sockfd = socket((
int)((
struct sockaddr*)to)->sa_family, SOCK_DGRAM,
392 if ((sockfd = socket((
int)((
struct sockaddr*)to)->sa_family, SOCK_DGRAM,
403 const struct sockaddr_storage *to , socklen_t tolen,
404 const struct sockaddr_storage *from, socklen_t fromlen,
405 struct timeval timeout)
415 if (from && bind(sockfd, (
const struct sockaddr*)from, fromlen) == -1){
429 const struct sockaddr_storage *to , socklen_t tolen,
430 struct timeval timeout)
432 int s = ldns_udp_bgsend_from(qbin, to, tolen, NULL, 0, timeout);
433 return s > 0 ? s : 0;
438 const struct sockaddr_storage *to , socklen_t tolen,
439 struct timeval timeout)
441 return ldns_udp_bgsend_from(qbin, to, tolen, NULL, 0, timeout);
446ldns_sockaddr_cmp(
const struct sockaddr_storage* addr1, socklen_t len1,
447 const struct sockaddr_storage* addr2, socklen_t len2)
449 struct sockaddr_in* p1_in = (
struct sockaddr_in*)addr1;
450 struct sockaddr_in* p2_in = (
struct sockaddr_in*)addr2;
451 struct sockaddr_in6* p1_in6 = (
struct sockaddr_in6*)addr1;
452 struct sockaddr_in6* p2_in6 = (
struct sockaddr_in6*)addr2;
457 assert(len1 == len2);
458 if( p1_in->sin_family < p2_in->sin_family)
460 if( p1_in->sin_family > p2_in->sin_family)
462 assert( p1_in->sin_family == p2_in->sin_family );
464 if( p1_in->sin_family == AF_INET ) {
466 if(p1_in->sin_port < p2_in->sin_port)
468 if(p1_in->sin_port > p2_in->sin_port)
470 assert(p1_in->sin_port == p2_in->sin_port);
471 return memcmp(&p1_in->sin_addr, &p2_in->sin_addr,
472 sizeof(p1_in->sin_addr));
473 }
else if (p1_in6->sin6_family == AF_INET6) {
475 if(p1_in6->sin6_port < p2_in6->sin6_port)
477 if(p1_in6->sin6_port > p2_in6->sin6_port)
479 assert(p1_in6->sin6_port == p2_in6->sin6_port);
480 return memcmp(&p1_in6->sin6_addr, &p2_in6->sin6_addr,
481 sizeof(p1_in6->sin6_addr));
484 return memcmp(addr1, addr2, len1);
489ldns_udp_send_from(uint8_t **result,
ldns_buffer *qbin,
490 const struct sockaddr_storage *to , socklen_t tolen,
491 const struct sockaddr_storage *from, socklen_t fromlen,
492 struct timeval timeout,
size_t *answer_size)
496 struct sockaddr_storage reply_addr;
497 socklen_t reply_addr_len;
499 sockfd = ldns_udp_bgsend_from(qbin, to, tolen, from, fromlen, timeout);
506 if(!ldns_sock_wait(sockfd, timeout, 0)) {
514 ldns_sock_nonblock(sockfd);
516 reply_addr_len =
sizeof(reply_addr);
517 memset(&reply_addr, 0, reply_addr_len);
527 if(ldns_sockaddr_cmp(to, tolen, &reply_addr, reply_addr_len) != 0) {
538 const struct sockaddr_storage *to , socklen_t tolen,
539 struct timeval timeout,
size_t *answer_size)
541 return ldns_udp_send_from(result, qbin, to, tolen, NULL, 0,
542 timeout, answer_size);
550 struct sockaddr_storage *src = NULL;
552 struct sockaddr_storage *ns;
560 bool all_servers_rtt_inf;
563 uint8_t *reply_bytes = NULL;
564 size_t reply_size = 0;
570 if(ldns_buffer_limit(qb) < 6 || ldns_buffer_read_u16_at(qb, 4) != 1)
579 all_servers_rtt_inf =
true;
586 src = ldns_rdf2native_sockaddr_storage_port(
607 if ((ns->ss_family == AF_INET) &&
614 if ((ns->ss_family == AF_INET6) &&
622 all_servers_rtt_inf =
false;
624 gettimeofday(&tv_s, NULL);
632 ldns_tcp_send_from(&reply_bytes, qb,
633 ns, (socklen_t)ns_len,
634 src, (socklen_t)src_len,
645 ldns_udp_send_from(&reply_bytes, qb,
646 ns, (socklen_t)ns_len,
647 src, (socklen_t)src_len,
658 status = send_status;
660 if(reply_bytes && ldns_buffer_limit(qb) >= 2) {
661 uint16_t txid = ldns_buffer_read_u16_at(qb, 0);
663 ldns_read_uint16(reply_bytes) != txid) {
696 gettimeofday(&tv_e, NULL);
700 ((tv_e.tv_sec - tv_s.tv_sec) * 1000) +
701 (tv_e.tv_usec - tv_s.tv_usec) / 1000);
722 if (all_servers_rtt_inf) {
727 if (tsig_mac && reply && reply_bytes) {
750 , ldns_buffer_begin(qb)
770 const struct sockaddr_storage *to, socklen_t tolen)
776 sendbuf =
LDNS_XMALLOC(uint8_t, ldns_buffer_position(qbin) + 2);
777 if(!sendbuf)
return 0;
778 ldns_write_uint16(sendbuf, ldns_buffer_position(qbin));
779 memcpy(sendbuf + 2, ldns_buffer_begin(qbin), ldns_buffer_position(qbin));
781 bytes = sendto(sockfd, (
void*)sendbuf,
782 ldns_buffer_position(qbin) + 2, 0, (
struct sockaddr *)to, tolen);
786 if (bytes == -1 || (
size_t) bytes != ldns_buffer_position(qbin) + 2 ) {
799 bytes = sendto(sockfd, (
void*)ldns_buffer_begin(qbin),
800 ldns_buffer_position(qbin), 0, (
struct sockaddr *)to, tolen);
802 if (bytes == -1 || (
size_t)bytes != ldns_buffer_position(qbin)) {
812 uint8_t *wire, *wireout;
822 (
struct sockaddr *)from, fromlen);
825 if (wire_size == -1 || wire_size == 0) {
831 *size = (size_t)wire_size;
843 ssize_t bytes = 0, rc = 0;
854 if(!ldns_sock_wait(sockfd, timeout, 0)) {
859 rc = recv(sockfd, (
void*) (wire + bytes),
860 (
size_t) (2 - bytes), 0);
861 if (rc == -1 || rc == 0) {
869 wire_size = ldns_read_uint16(wire);
879 while (bytes < (ssize_t) wire_size) {
880 if(!ldns_sock_wait(sockfd, timeout, 0)) {
885 rc = recv(sockfd, (
void*) (wire + bytes),
886 (
size_t) (wire_size - bytes), 0);
887 if (rc == -1 || rc == 0) {
895 *size = (size_t) bytes;
904 ssize_t bytes = 0, rc = 0;
913 rc = recv(sockfd, (
void*) (wire + bytes),
914 (
size_t) (2 - bytes), 0);
915 if (rc == -1 || rc == 0) {
923 wire_size = ldns_read_uint16(wire);
933 while (bytes < (ssize_t) wire_size) {
934 rc = recv(sockfd, (
void*) (wire + bytes),
935 (
size_t) (wire_size - bytes), 0);
936 if (rc == -1 || rc == 0) {
944 *size = (size_t) bytes;
953 struct sockaddr_in *data_in;
954 struct sockaddr_in6 *data_in6;
956 switch(sock->ss_family) {
958 data_in = (
struct sockaddr_in*)sock;
960 *port = ntohs((uint16_t)data_in->sin_port);
966 data_in6 = (
struct sockaddr_in6*)sock;
968 *port = ntohs((uint16_t)data_in6->sin6_port);
990 struct sockaddr_storage *src = NULL;
992 struct sockaddr_storage *ns = NULL;
1007 src = ldns_rdf2native_sockaddr_storage_port(
1024 if ((ns->ss_family == AF_INET) &&
1032 if ((ns->ss_family == AF_INET6) &&
1041 resolver->
_socket = ldns_tcp_connect_from(
1042 ns, (socklen_t)ns_len,
1043 src, (socklen_t)src_len,
1103 (socklen_t)ns_len) == 0) {
void ldns_buffer_free(ldns_buffer *buffer)
frees the buffer.
ldns_buffer * ldns_buffer_new(size_t capacity)
creates a new buffer with the specified capacity.
#define LDNS_MIN_BUFLEN
number of initial bytes in buffer of which we cannot tell the size before hand
@ LDNS_STATUS_NETWORK_ERR
@ LDNS_STATUS_SOCKET_ERROR
@ LDNS_STATUS_QDCOUNT_MUST_BE_ONE
@ LDNS_STATUS_CRYPTO_TSIG_BOGUS
@ LDNS_STATUS_QUERY_DID_NOT_MATCH
@ LDNS_STATUS_ADDRESS_ERR
@ LDNS_STATUS_CRYPTO_TSIG_ERR
@ LDNS_STATUS_ID_DID_NOT_MATCH
enum ldns_enum_status ldns_status
ldns_status ldns_pkt2buffer_wire(ldns_buffer *output, const ldns_pkt *pkt)
Copies the packet data to the buffer in wire format.
Including this file will include all ldns files, and define some lookup tables.
int ldns_udp_connect(const struct sockaddr_storage *to, struct timeval timeout __attribute__((unused)))
uint8_t * ldns_udp_read_wire(int sockfd, size_t *size, struct sockaddr_storage *from, socklen_t *fromlen)
Gives back a raw packet from the wire and reads the header data from the given socket.
ldns_status ldns_axfr_start(ldns_resolver *resolver, const ldns_rdf *domain, ldns_rr_class class)
Prepares the resolver for an axfr query The query is sent and the answers can be read with ldns_axfr_...
ldns_status ldns_send(ldns_pkt **result_packet, ldns_resolver *r, const ldns_pkt *query_pkt)
Sends ptk to the nameserver at the resolver object.
uint8_t * ldns_tcp_read_wire_timeout(int sockfd, size_t *size, struct timeval timeout)
Gives back a raw packet from the wire and reads the header data from the given socket.
uint8_t * ldns_tcp_read_wire(int sockfd, size_t *size)
This routine may block.
struct sockaddr_storage * ldns_rdf2native_sockaddr_storage(const ldns_rdf *rd, uint16_t port, size_t *size)
returns the native sockaddr representation from the rdf.
ssize_t ldns_tcp_send_query(ldns_buffer *qbin, int sockfd, const struct sockaddr_storage *to, socklen_t tolen)
send a query via tcp to a server.
ldns_rdf * ldns_sockaddr_storage2rdf(const struct sockaddr_storage *sock, uint16_t *port)
returns an rdf with the sockaddr info.
int ldns_tcp_connect(const struct sockaddr_storage *to, socklen_t tolen, struct timeval timeout)
Create a tcp socket to the specified address This function has the flaw that it returns 0 on failure,...
int ldns_tcp_connect2(const struct sockaddr_storage *to, socklen_t tolen, struct timeval timeout)
Create a tcp socket to the specified address.
ldns_status ldns_send_buffer(ldns_pkt **result, ldns_resolver *r, ldns_buffer *qb, ldns_rdf *tsig_mac)
Sends and ldns_buffer (presumably containing a packet to the nameserver at the resolver object.
int ldns_udp_bgsend(ldns_buffer *qbin, const struct sockaddr_storage *to, socklen_t tolen, struct timeval timeout)
Send an udp query and don't wait for an answer but return the socket This function has the flaw that ...
int ldns_tcp_bgsend(ldns_buffer *qbin, const struct sockaddr_storage *to, socklen_t tolen, struct timeval timeout)
Send an tcp query and don't wait for an answer but return the socket This function has the flaw that ...
int ldns_tcp_bgsend2(ldns_buffer *qbin, const struct sockaddr_storage *to, socklen_t tolen, struct timeval timeout)
Send an tcp query and don't wait for an answer but return the socket.
int ldns_udp_bgsend2(ldns_buffer *qbin, const struct sockaddr_storage *to, socklen_t tolen, struct timeval timeout)
Send an udp query and don't wait for an answer but return the socket.
ldns_status ldns_udp_send(uint8_t **result, ldns_buffer *qbin, const struct sockaddr_storage *to, socklen_t tolen, struct timeval timeout, size_t *answer_size)
Sends a buffer to an ip using udp and return the response as a ldns_pkt.
ldns_status ldns_tcp_send(uint8_t **result, ldns_buffer *qbin, const struct sockaddr_storage *to, socklen_t tolen, struct timeval timeout, size_t *answer_size)
Sends a buffer to an ip using tcp and return the response as a ldns_pkt.
ssize_t ldns_udp_send_query(ldns_buffer *qbin, int sockfd, const struct sockaddr_storage *to, socklen_t tolen)
send a query via udp to a server.
int ldns_udp_connect2(const struct sockaddr_storage *to, struct timeval timeout __attribute__((unused)))
#define LDNS_MAX_PACKETLEN
void ldns_pkt_free(ldns_pkt *packet)
frees the packet structure and all data that it contains.
void ldns_pkt_set_timestamp(ldns_pkt *p, struct timeval timeval)
Set the packet's timestamp.
void ldns_pkt_set_size(ldns_pkt *p, size_t s)
Set the packet's size.
void ldns_pkt_set_answerfrom(ldns_pkt *p, ldns_rdf *r)
Set the packet's answering server.
ldns_rr_list * ldns_pkt_question(const ldns_pkt *p)
Return the packet's question section.
ldns_pkt * ldns_pkt_query_new(ldns_rdf *rr_name, ldns_rr_type rr_type, ldns_rr_class rr_class, uint16_t flags)
creates a packet with a query in it for the given name, type and class.
uint16_t ldns_pkt_qdcount(const ldns_pkt *p)
Return the packet's qd count.
ldns_rr * ldns_pkt_tsig(const ldns_pkt *p)
Return the packet's tsig pseudo rr's.
void ldns_pkt_set_querytime(ldns_pkt *p, uint32_t t)
Set the packet's query time.
uint8_t * ldns_rdf_data(const ldns_rdf *rd)
returns the data of the rdf.
ldns_rdf * ldns_rdf_clone(const ldns_rdf *rd)
clones a rdf structure.
ldns_rdf_type ldns_rdf_get_type(const ldns_rdf *rd)
returns the type of the rdf.
ldns_rdf * ldns_rdf_new_frm_data(ldns_rdf_type type, size_t size, const void *data)
allocates a new rdf structure and fills it.
@ LDNS_RDF_TYPE_AAAA
AAAA record.
@ LDNS_RDF_TYPE_A
A record.
size_t ldns_rdf_size(const ldns_rdf *rd)
returns the size of the rdf.
size_t * ldns_resolver_rtt(const ldns_resolver *r)
Return the used round trip times for the nameservers.
const char * ldns_resolver_tsig_keydata(const ldns_resolver *r)
Return the tsig keydata as used by the nameserver.
signed char ldns_resolver_fail(const ldns_resolver *r)
Does the resolver only try the first nameserver.
void ldns_resolver_set_nameserver_rtt(ldns_resolver *r, size_t pos, size_t value)
Set round trip time for a specific nameserver.
#define LDNS_RESOLV_RTT_INF
const char * ldns_resolver_tsig_keyname(const ldns_resolver *r)
Return the tsig keyname as used by the nameserver.
size_t ldns_resolver_nameserver_count(const ldns_resolver *r)
How many nameserver are configured in the resolver.
ldns_rdf ** ldns_resolver_nameservers(const ldns_resolver *r)
Return the configured nameserver ip address.
uint8_t ldns_resolver_retrans(const ldns_resolver *r)
Get the retransmit interval.
void ldns_resolver_nameservers_randomize(ldns_resolver *r)
Randomize the nameserver list in the resolver.
struct timeval ldns_resolver_timeout(const ldns_resolver *r)
What is the timeout on socket connections.
uint8_t ldns_resolver_ip6(const ldns_resolver *r)
Does the resolver use ip6 or ip4.
signed char ldns_resolver_random(const ldns_resolver *r)
Does the resolver randomize the nameserver before usage.
uint8_t ldns_resolver_retry(const ldns_resolver *r)
Get the number of retries.
ldns_rdf * ldns_resolver_source(const ldns_resolver *r)
Get the source address the resolver should use.
signed char ldns_resolver_usevc(const ldns_resolver *r)
Does the resolver use tcp or udp.
const char * ldns_resolver_tsig_algorithm(const ldns_resolver *r)
Return the tsig algorithm as used by the nameserver.
uint16_t ldns_resolver_port(const ldns_resolver *r)
Get the port the resolver should use.
#define LDNS_RESOLV_INET6
ldns_rdf * ldns_rr_rdf(const ldns_rr *rr, size_t nr)
returns the rdata field member counter.
enum ldns_enum_rr_class ldns_rr_class
ldns_rr * ldns_rr_list_rr(const ldns_rr_list *rr_list, size_t nr)
returns a specific rr of an rrlist.
int ldns_rr_compare(const ldns_rr *rr1, const ldns_rr *rr2)
compares two rrs.
implementation of buffers to ease operations
Resource record data field.
DNS stub resolver structure.
int _socket
Keep some things to make AXFR possible.
ldns_rdf ** _nameservers
Array of nameservers to query (IP addresses or dnames)
int _axfr_soa_count
Count the number of LDNS_RR_TYPE_SOA RRs we have seen so far (the second one signifies the end of the...
bool ldns_pkt_tsig_verify(ldns_pkt *pkt, const uint8_t *wire, size_t wire_size, const char *key_name, const char *key_data, const ldns_rdf *mac)
verifies the tsig rr for the given packet and key.
ldns_status ldns_pkt_tsig_sign(ldns_pkt *pkt, const char *key_name, const char *key_data, uint16_t fudge, const char *algorithm_name, const ldns_rdf *query_mac)
creates a tsig rr for the given packet and key.
#define LDNS_MALLOC(type)
Memory management macros.
#define LDNS_XMALLOC(type, count)
#define LDNS_XREALLOC(ptr, type, count)
ldns_status ldns_wire2pkt(ldns_pkt **packet, const uint8_t *data, size_t len)
converts the data on the uint8_t bytearray (in wire format) to a DNS packet.