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 28 #include <arpa/inet.h> 60 static struct sockaddr_storage *
61 ldns_rdf2native_sockaddr_storage_port(
62 const ldns_rdf *rd, uint16_t port,
size_t *size)
64 struct sockaddr_storage *data;
65 struct sockaddr_in *data_in;
66 struct sockaddr_in6 *data_in6;
73 memset(data, 0,
sizeof(
struct sockaddr_storage));
78 data->ss_family = AF_INET;
80 data_in = (
struct sockaddr_in*) data;
81 data_in->sin_port = (in_port_t)htons(port);
83 *size =
sizeof(
struct sockaddr_in);
87 data->ss_family = AF_INET6;
89 data_in6 = (
struct sockaddr_in6*) data;
90 data_in6->sin6_port = (in_port_t)htons(port);
92 *size =
sizeof(
struct sockaddr_in6);
100 struct sockaddr_storage *
102 const ldns_rdf *rd, uint16_t port,
size_t *size)
104 return ldns_rdf2native_sockaddr_storage_port(
105 rd, (port == 0 ? (uint16_t)
LDNS_PORT : port), size);
110 ldns_sock_nonblock(
int sockfd)
114 if((flag = fcntl(sockfd, F_GETFL)) != -1) {
116 if(fcntl(sockfd, F_SETFL, flag) == -1) {
120 #elif defined(HAVE_IOCTLSOCKET) 121 unsigned long on = 1;
122 if(ioctlsocket(sockfd, FIONBIO, &on) != 0) {
130 ldns_sock_block(
int sockfd)
134 if((flag = fcntl(sockfd, F_GETFL)) != -1) {
136 if(fcntl(sockfd, F_SETFL, flag) == -1) {
140 #elif defined(HAVE_IOCTLSOCKET) 141 unsigned long off = 0;
142 if(ioctlsocket(sockfd, FIONBIO, &off) != 0) {
150 ldns_sock_wait(
int sockfd,
struct timeval timeout,
int write)
158 ret = select(sockfd+1, NULL, &fds, NULL, &timeout);
160 ret = select(sockfd+1, &fds, NULL, NULL, &timeout);
173 ldns_tcp_connect_from(
const struct sockaddr_storage *to, socklen_t tolen,
174 const struct sockaddr_storage *from, socklen_t fromlen,
175 struct timeval timeout)
180 if ((sockfd = socket((
int)((
struct sockaddr*)to)->sa_family, SOCK_STREAM,
181 IPPROTO_TCP)) == -1) {
185 if (from && bind(sockfd, (
const struct sockaddr*)from, fromlen) == -1){
190 ldns_sock_nonblock(sockfd);
191 if (connect(sockfd, (
struct sockaddr*)to, tolen) == -1) {
194 if(errno != EINPROGRESS) {
202 if(WSAGetLastError() != WSAEINPROGRESS &&
203 WSAGetLastError() != WSAEWOULDBLOCK) {
214 socklen_t len = (socklen_t)
sizeof(error);
216 if(!ldns_sock_wait(sockfd, timeout, 1)) {
226 if(getsockopt(sockfd, SOL_SOCKET, SO_ERROR, (
void*)&error,
231 error = WSAGetLastError();
235 #if defined(EINPROGRESS) && defined(EWOULDBLOCK) 236 if(error == EINPROGRESS || error == EWOULDBLOCK)
239 else if(error != 0) {
246 if(error == WSAEINPROGRESS)
248 else if(error == WSAEWOULDBLOCK)
250 else if(error != 0) {
261 ldns_sock_block(sockfd);
268 struct timeval timeout)
270 return ldns_tcp_connect_from(to, tolen, NULL, 0, timeout);
275 const struct sockaddr_storage *to, socklen_t tolen,
276 const struct sockaddr_storage *from, socklen_t fromlen,
277 struct timeval timeout)
281 sockfd = ldns_tcp_connect_from(to, tolen, from, fromlen, timeout);
301 const struct sockaddr_storage *to, socklen_t tolen,
302 struct timeval timeout)
304 return ldns_tcp_bgsend_from(qbin, to, tolen, NULL, 0, timeout);
312 ldns_tcp_send_from(uint8_t **result,
ldns_buffer *qbin,
313 const struct sockaddr_storage *to, socklen_t tolen,
314 const struct sockaddr_storage *from, socklen_t fromlen,
315 struct timeval timeout,
size_t *answer_size)
320 sockfd = ldns_tcp_bgsend_from(qbin, to, tolen, from, fromlen, timeout);
333 if (*answer_size == 0) {
339 *result =
LDNS_XREALLOC(answer, uint8_t, (
size_t)*answer_size);
349 const struct sockaddr_storage *to, socklen_t tolen,
350 struct timeval timeout,
size_t *answer_size)
352 return ldns_tcp_send_from(result, qbin,
353 to, tolen, NULL, 0, timeout, answer_size);
362 if ((sockfd = socket((
int)((
struct sockaddr*)to)->sa_family, SOCK_DGRAM,
373 const struct sockaddr_storage *to , socklen_t tolen,
374 const struct sockaddr_storage *from, socklen_t fromlen,
375 struct timeval timeout)
385 if (from && bind(sockfd, (
const struct sockaddr*)from, fromlen) == -1){
402 const struct sockaddr_storage *to , socklen_t tolen,
403 struct timeval timeout)
405 return ldns_udp_bgsend_from(qbin, to, tolen, NULL, 0, timeout);
409 ldns_udp_send_from(uint8_t **result,
ldns_buffer *qbin,
410 const struct sockaddr_storage *to , socklen_t tolen,
411 const struct sockaddr_storage *from, socklen_t fromlen,
412 struct timeval timeout,
size_t *answer_size)
417 sockfd = ldns_udp_bgsend_from(qbin, to, tolen, from, fromlen, timeout);
424 if(!ldns_sock_wait(sockfd, timeout, 0)) {
436 ldns_sock_nonblock(sockfd);
445 if (*answer_size == 0) {
456 const struct sockaddr_storage *to , socklen_t tolen,
457 struct timeval timeout,
size_t *answer_size)
459 return ldns_udp_send_from(result, qbin, to, tolen, NULL, 0,
460 timeout, answer_size);
468 struct sockaddr_storage *src = NULL;
470 struct sockaddr_storage *ns;
478 bool all_servers_rtt_inf;
481 uint8_t *reply_bytes = NULL;
482 size_t reply_size = 0;
493 all_servers_rtt_inf =
true;
500 src = ldns_rdf2native_sockaddr_storage_port(
521 if ((ns->ss_family == AF_INET) &&
528 if ((ns->ss_family == AF_INET6) &&
536 all_servers_rtt_inf =
false;
538 gettimeofday(&tv_s, NULL);
546 ldns_tcp_send_from(&reply_bytes, qb,
547 ns, (socklen_t)ns_len,
548 src, (socklen_t)src_len,
559 ldns_udp_send_from(&reply_bytes, qb,
560 ns, (socklen_t)ns_len,
561 src, (socklen_t)src_len,
572 status = send_status;
595 gettimeofday(&tv_e, NULL);
599 ((tv_e.tv_sec - tv_s.tv_sec) * 1000) +
600 (tv_e.tv_usec - tv_s.tv_usec) / 1000);
621 if (all_servers_rtt_inf) {
626 if (tsig_mac && reply && reply_bytes) {
649 const struct sockaddr_storage *to, socklen_t tolen)
655 sendbuf =
LDNS_XMALLOC(uint8_t, ldns_buffer_position(qbin) + 2);
656 if(!sendbuf)
return 0;
657 ldns_write_uint16(sendbuf, ldns_buffer_position(qbin));
658 memcpy(sendbuf + 2, ldns_buffer_begin(qbin), ldns_buffer_position(qbin));
660 bytes = sendto(sockfd, (
void*)sendbuf,
661 ldns_buffer_position(qbin) + 2, 0, (
struct sockaddr *)to, tolen);
665 if (bytes == -1 || (
size_t) bytes != ldns_buffer_position(qbin) + 2 ) {
678 bytes = sendto(sockfd, (
void*)ldns_buffer_begin(qbin),
679 ldns_buffer_position(qbin), 0, (
struct sockaddr *)to, tolen);
681 if (bytes == -1 || (
size_t)bytes != ldns_buffer_position(qbin)) {
684 if ((
size_t) bytes != ldns_buffer_position(qbin)) {
694 uint8_t *wire, *wireout;
704 (
struct sockaddr *)from, fromlen);
707 if (wire_size == -1 || wire_size == 0) {
713 *size = (size_t)wire_size;
725 ssize_t bytes = 0, rc = 0;
734 if(!ldns_sock_wait(sockfd, timeout, 0)) {
739 rc = recv(sockfd, (
void*) (wire + bytes),
740 (
size_t) (2 - bytes), 0);
741 if (rc == -1 || rc == 0) {
749 wire_size = ldns_read_uint16(wire);
759 while (bytes < (ssize_t) wire_size) {
760 if(!ldns_sock_wait(sockfd, timeout, 0)) {
765 rc = recv(sockfd, (
void*) (wire + bytes),
766 (
size_t) (wire_size - bytes), 0);
767 if (rc == -1 || rc == 0) {
775 *size = (size_t) bytes;
784 ssize_t bytes = 0, rc = 0;
793 rc = recv(sockfd, (
void*) (wire + bytes),
794 (
size_t) (2 - bytes), 0);
795 if (rc == -1 || rc == 0) {
803 wire_size = ldns_read_uint16(wire);
813 while (bytes < (ssize_t) wire_size) {
814 rc = recv(sockfd, (
void*) (wire + bytes),
815 (
size_t) (wire_size - bytes), 0);
816 if (rc == -1 || rc == 0) {
824 *size = (size_t) bytes;
833 struct sockaddr_in *data_in;
834 struct sockaddr_in6 *data_in6;
836 switch(sock->ss_family) {
838 data_in = (
struct sockaddr_in*)sock;
840 *port = ntohs((uint16_t)data_in->sin_port);
846 data_in6 = (
struct sockaddr_in6*)sock;
848 *port = ntohs((uint16_t)data_in6->sin6_port);
870 struct sockaddr_storage *src = NULL;
872 struct sockaddr_storage *ns = NULL;
887 src = ldns_rdf2native_sockaddr_storage_port(
904 resolver->
_socket = ldns_tcp_connect_from(
905 ns, (socklen_t)ns_len,
906 src, (socklen_t)src_len,
928 closesocket(resolver->
_socket);
950 closesocket(resolver->
_socket);
967 closesocket(resolver->
_socket);
975 (socklen_t)ns_len) == 0) {
986 closesocket(resolver->
_socket);
ldns_rdf * ldns_rr_rdf(const ldns_rr *rr, size_t nr)
returns the rdata field member counter.
uint8_t ldns_resolver_ip6(const ldns_resolver *r)
Does the resolver use ip6 or ip4.
implementation of buffers to ease operations
char * ldns_resolver_tsig_algorithm(const ldns_resolver *r)
Return the tsig algorithm as used by the nameserver.
uint8_t ldns_resolver_retry(const ldns_resolver *r)
Get the number of retries.
DNS stub resolver structure.
enum ldns_enum_rr_class ldns_rr_class
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_INET6
#define LDNS_XMALLOC(type, count)
#define LDNS_MIN_BUFLEN
number of initial bytes in buffer of which we cannot tell the size before hand
size_t ldns_rdf_size(const ldns_rdf *rd)
returns the size of the rdf.
void ldns_buffer_free(ldns_buffer *buffer)
frees the buffer.
ldns_rdf * ldns_rdf_clone(const ldns_rdf *rd)
clones a rdf structure.
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.
bool ldns_pkt_tsig_verify(ldns_pkt *pkt, uint8_t *wire, size_t wirelen, const char *key_name, const char *key_data, ldns_rdf *orig_mac_rdf)
verifies the tsig rr for the given packet and key.
#define LDNS_MAX_PACKETLEN
uint16_t ldns_resolver_port(const ldns_resolver *r)
Get the port the resolver should use.
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.
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.
#define LDNS_XREALLOC(ptr, type, count)
void ldns_pkt_set_size(ldns_pkt *packet, size_t s)
Set the packet's size.
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.
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_rdf_data(const ldns_rdf *rd)
returns the data of the rdf.
ldns_status ldns_pkt2buffer_wire(ldns_buffer *buffer, const ldns_pkt *packet)
Copies the packet data to the buffer in wire format.
ldns_status ldns_wire2pkt(ldns_pkt **packet_p, const uint8_t *wire, size_t max)
converts the data on the uint8_t bytearray (in wire format) to a DNS packet.
void ldns_resolver_nameservers_randomize(ldns_resolver *r)
Randomize the nameserver list in the resolver.
bool ldns_resolver_usevc(const ldns_resolver *r)
Does the resolver use tcp or udp.
size_t ldns_resolver_nameserver_count(const ldns_resolver *r)
How many nameserver are configured in the resolver.
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...
ldns_rdf * ldns_sockaddr_storage2rdf(struct sockaddr_storage *sock, uint16_t *port)
returns an rdf with the sockaddr info.
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...
ldns_rdf ** _nameservers
Array of nameservers to query (IP addresses or dnames)
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.
void ldns_pkt_set_answerfrom(ldns_pkt *packet, ldns_rdf *answerfrom)
Set the packet's answering server.
ldns_rdf_type ldns_rdf_get_type(const ldns_rdf *rd)
returns the type of the rdf.
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.
char * ldns_resolver_tsig_keydata(const ldns_resolver *r)
Return the tsig keydata as used by the nameserver.
uint8_t * ldns_tcp_read_wire(int sockfd, size_t *size)
This routine may block.
bool ldns_resolver_random(const ldns_resolver *r)
Does the resolver randomize the nameserver before usage.
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.
enum ldns_enum_status ldns_status
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.
#define LDNS_MALLOC(type)
Memory management macros.
void ldns_pkt_set_querytime(ldns_pkt *packet, uint32_t time)
Set the packet's query time.
ldns_buffer * ldns_buffer_new(size_t capacity)
creates a new buffer with the specified capacity.
uint8_t ldns_resolver_retrans(const ldns_resolver *r)
Get the retransmit interval.
ldns_status ldns_pkt_tsig_sign(ldns_pkt *pkt, const char *key_name, const char *key_data, uint16_t fudge, const char *algorithm_name, ldns_rdf *query_mac)
creates a tsig rr for the given packet and key.
int ldns_tcp_connect(const struct sockaddr_storage *to, socklen_t tolen, struct timeval timeout)
Create a tcp socket to the specified address.
size_t * ldns_resolver_rtt(const ldns_resolver *r)
Return the used round trip times for the nameservers.
bool ldns_resolver_fail(const ldns_resolver *r)
Does the resolver only try the first nameserver.
ldns_rdf * ldns_resolver_source(const ldns_resolver *r)
Get the source address the resolver should use.
ldns_rdf ** ldns_resolver_nameservers(const ldns_resolver *r)
Return the configured nameserver ip address.
char * ldns_resolver_tsig_keyname(const ldns_resolver *r)
Return the tsig keyname as used by the nameserver.
Resource record data field.
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.
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 respons as a ldns_pkt.
ldns_rr * ldns_pkt_tsig(const ldns_pkt *pkt)
Return the packet's tsig pseudo rr's.
ldns_status ldns_axfr_start(ldns_resolver *resolver, 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_...
#define LDNS_RESOLV_RTT_INF
int _socket
Keep some things to make AXFR possible.
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 respons as a ldns_pkt.
void ldns_pkt_free(ldns_pkt *packet)
frees the packet structure and all data that it contains.
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.
struct timeval ldns_resolver_timeout(const ldns_resolver *r)
What is the timeout on socket connections.
void ldns_pkt_set_timestamp(ldns_pkt *packet, struct timeval timeval)
Set the packet's timestamp.