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>
63 static struct sockaddr_storage *
64 ldns_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);
103 struct 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);
113 ldns_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) {
133 ldns_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) {
153 ldns_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));
192 ldns_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);
336 ldns_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);
445 ldns_udp_send_from(uint8_t **result,
ldns_buffer *qbin,
446 const struct sockaddr_storage *to , socklen_t tolen,
447 const struct sockaddr_storage *from, socklen_t fromlen,
448 struct timeval timeout,
size_t *answer_size)
453 sockfd = ldns_udp_bgsend_from(qbin, to, tolen, from, fromlen, timeout);
460 if(!ldns_sock_wait(sockfd, timeout, 0)) {
468 ldns_sock_nonblock(sockfd);
484 const struct sockaddr_storage *to , socklen_t tolen,
485 struct timeval timeout,
size_t *answer_size)
487 return ldns_udp_send_from(result, qbin, to, tolen, NULL, 0,
488 timeout, answer_size);
496 struct sockaddr_storage *src = NULL;
498 struct sockaddr_storage *ns;
506 bool all_servers_rtt_inf;
509 uint8_t *reply_bytes = NULL;
510 size_t reply_size = 0;
521 all_servers_rtt_inf =
true;
528 src = ldns_rdf2native_sockaddr_storage_port(
549 if ((ns->ss_family == AF_INET) &&
556 if ((ns->ss_family == AF_INET6) &&
564 all_servers_rtt_inf =
false;
566 gettimeofday(&tv_s, NULL);
574 ldns_tcp_send_from(&reply_bytes, qb,
575 ns, (socklen_t)ns_len,
576 src, (socklen_t)src_len,
587 ldns_udp_send_from(&reply_bytes, qb,
588 ns, (socklen_t)ns_len,
589 src, (socklen_t)src_len,
600 status = send_status;
628 gettimeofday(&tv_e, NULL);
632 ((tv_e.tv_sec - tv_s.tv_sec) * 1000) +
633 (tv_e.tv_usec - tv_s.tv_usec) / 1000);
654 if (all_servers_rtt_inf) {
659 if (tsig_mac && reply && reply_bytes) {
682 const struct sockaddr_storage *to, socklen_t tolen)
688 sendbuf =
LDNS_XMALLOC(uint8_t, ldns_buffer_position(qbin) + 2);
689 if(!sendbuf)
return 0;
690 ldns_write_uint16(sendbuf, ldns_buffer_position(qbin));
691 memcpy(sendbuf + 2, ldns_buffer_begin(qbin), ldns_buffer_position(qbin));
693 bytes = sendto(sockfd, (
void*)sendbuf,
694 ldns_buffer_position(qbin) + 2, 0, (
struct sockaddr *)to, tolen);
698 if (bytes == -1 || (
size_t) bytes != ldns_buffer_position(qbin) + 2 ) {
711 bytes = sendto(sockfd, (
void*)ldns_buffer_begin(qbin),
712 ldns_buffer_position(qbin), 0, (
struct sockaddr *)to, tolen);
714 if (bytes == -1 || (
size_t)bytes != ldns_buffer_position(qbin)) {
724 uint8_t *wire, *wireout;
734 (
struct sockaddr *)from, fromlen);
737 if (wire_size == -1 || wire_size == 0) {
743 *size = (size_t)wire_size;
755 ssize_t bytes = 0, rc = 0;
764 if(!ldns_sock_wait(sockfd, timeout, 0)) {
769 rc = recv(sockfd, (
void*) (wire + bytes),
770 (
size_t) (2 - bytes), 0);
771 if (rc == -1 || rc == 0) {
779 wire_size = ldns_read_uint16(wire);
789 while (bytes < (ssize_t) wire_size) {
790 if(!ldns_sock_wait(sockfd, timeout, 0)) {
795 rc = recv(sockfd, (
void*) (wire + bytes),
796 (
size_t) (wire_size - bytes), 0);
797 if (rc == -1 || rc == 0) {
805 *size = (size_t) bytes;
814 ssize_t bytes = 0, rc = 0;
823 rc = recv(sockfd, (
void*) (wire + bytes),
824 (
size_t) (2 - bytes), 0);
825 if (rc == -1 || rc == 0) {
833 wire_size = ldns_read_uint16(wire);
843 while (bytes < (ssize_t) wire_size) {
844 rc = recv(sockfd, (
void*) (wire + bytes),
845 (
size_t) (wire_size - bytes), 0);
846 if (rc == -1 || rc == 0) {
854 *size = (size_t) bytes;
863 struct sockaddr_in *data_in;
864 struct sockaddr_in6 *data_in6;
866 switch(sock->ss_family) {
868 data_in = (
struct sockaddr_in*)sock;
870 *port = ntohs((uint16_t)data_in->sin_port);
876 data_in6 = (
struct sockaddr_in6*)sock;
878 *port = ntohs((uint16_t)data_in6->sin6_port);
900 struct sockaddr_storage *src = NULL;
902 struct sockaddr_storage *ns = NULL;
917 src = ldns_rdf2native_sockaddr_storage_port(
934 if ((ns->ss_family == AF_INET) &&
942 if ((ns->ss_family == AF_INET6) &&
951 resolver->
_socket = ldns_tcp_connect_from(
952 ns, (socklen_t)ns_len,
953 src, (socklen_t)src_len,
1013 (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_CRYPTO_TSIG_BOGUS
@ LDNS_STATUS_ADDRESS_ERR
@ LDNS_STATUS_CRYPTO_TSIG_ERR
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.
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.
int ldns_udp_connect(const struct sockaddr_storage *to, struct timeval timeout __attribute__((unused)))
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_...
uint8_t * ldns_tcp_read_wire(int sockfd, size_t *size)
This routine may block.
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_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.
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.
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 ...
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.
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.
ldns_rdf * ldns_sockaddr_storage2rdf(const struct sockaddr_storage *sock, uint16_t *port)
returns an rdf with the sockaddr info.
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.
ldns_rr * ldns_pkt_tsig(const ldns_pkt *p)
Return the packet's tsig pseudo rr's.
void ldns_pkt_set_answerfrom(ldns_pkt *p, ldns_rdf *r)
Set the packet's answering server.
void ldns_pkt_set_querytime(ldns_pkt *p, uint32_t t)
Set the packet's query time.
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.
ldns_rdf_type ldns_rdf_get_type(const ldns_rdf *rd)
returns the type of the rdf.
@ 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.
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 * ldns_rdf_new_frm_data(ldns_rdf_type type, size_t size, const void *data)
allocates a new rdf structure and fills it.
const char * ldns_resolver_tsig_algorithm(const ldns_resolver *r)
Return the tsig algorithm as used by the nameserver.
signed char ldns_resolver_fail(const ldns_resolver *r)
Does the resolver only try the first nameserver.
const char * ldns_resolver_tsig_keydata(const ldns_resolver *r)
Return the tsig keydata as used by the 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
size_t ldns_resolver_nameserver_count(const ldns_resolver *r)
How many nameserver are configured in the resolver.
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.
size_t * ldns_resolver_rtt(const ldns_resolver *r)
Return the used round trip times for the nameservers.
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.
const char * ldns_resolver_tsig_keyname(const ldns_resolver *r)
Return the tsig keyname as used by the nameserver.
ldns_rdf ** ldns_resolver_nameservers(const ldns_resolver *r)
Return the configured nameserver ip address.
signed char ldns_resolver_usevc(const ldns_resolver *r)
Does the resolver use tcp or udp.
ldns_rdf * ldns_resolver_source(const ldns_resolver *r)
Get the source address the resolver should use.
uint16_t ldns_resolver_port(const ldns_resolver *r)
Get the port the resolver should use.
#define LDNS_RESOLV_INET6
enum ldns_enum_rr_class ldns_rr_class
ldns_rdf * ldns_rr_rdf(const ldns_rr *rr, size_t nr)
returns the rdata field member counter.
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.