00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 #include <ldns/config.h>
00015
00016 #include <ldns/ldns.h>
00017
00018 #include <netinet/in.h>
00019 #include <sys/socket.h>
00020 #include <netdb.h>
00021 #include <arpa/inet.h>
00022 #include <sys/time.h>
00023 #include <errno.h>
00024
00025 ldns_status
00026 ldns_send(ldns_pkt **result_packet, ldns_resolver *r, const ldns_pkt *query_pkt)
00027 {
00028 ldns_buffer *qb;
00029 ldns_status result;
00030 ldns_rdf *tsig_mac = NULL;
00031
00032 qb = ldns_buffer_new(LDNS_MIN_BUFLEN);
00033
00034 if (ldns_pkt_tsig(query_pkt)) {
00035 tsig_mac = ldns_rr_rdf(ldns_pkt_tsig(query_pkt), 3);
00036 }
00037
00038
00039 if (!query_pkt ||
00040 ldns_pkt2buffer_wire(qb, query_pkt) != LDNS_STATUS_OK) {
00041 result = LDNS_STATUS_ERR;
00042 } else {
00043 result = ldns_send_buffer(result_packet, r, qb, tsig_mac);
00044 }
00045
00046 ldns_buffer_free(qb);
00047
00048 return result;
00049 }
00050
00051 ldns_status
00052 ldns_send_buffer(ldns_pkt **result, ldns_resolver *r, ldns_buffer *qb, ldns_rdf *tsig_mac)
00053 {
00054 uint8_t i;
00055
00056 struct sockaddr_storage *ns;
00057 size_t ns_len;
00058 struct timeval tv_s;
00059 struct timeval tv_e;
00060
00061 ldns_rdf **ns_array;
00062 size_t *rtt;
00063 ldns_pkt *reply;
00064 bool all_servers_rtt_inf;
00065 uint8_t retries;
00066
00067 uint8_t *reply_bytes = NULL;
00068 size_t reply_size = 0;
00069 ldns_status status, send_status;
00070
00071 assert(r != NULL);
00072
00073 status = LDNS_STATUS_OK;
00074 rtt = ldns_resolver_rtt(r);
00075 ns_array = ldns_resolver_nameservers(r);
00076 reply = NULL;
00077 ns_len = 0;
00078
00079 all_servers_rtt_inf = true;
00080
00081 if (ldns_resolver_random(r)) {
00082 ldns_resolver_nameservers_randomize(r);
00083 }
00084
00085
00086 for (i = 0; i < ldns_resolver_nameserver_count(r); i++) {
00087
00088 if (rtt[i] == LDNS_RESOLV_RTT_INF) {
00089
00090 continue;
00091 }
00092 all_servers_rtt_inf = false;
00093
00094
00095
00096
00097
00098
00099 ns = ldns_rdf2native_sockaddr_storage(ns_array[i],
00100 ldns_resolver_port(r), &ns_len);
00101
00102 if ((ns->ss_family == AF_INET) &&
00103 (ldns_resolver_ip6(r) == LDNS_RESOLV_INET6)) {
00104 continue;
00105 }
00106
00107 if ((ns->ss_family == AF_INET6) &&
00108 (ldns_resolver_ip6(r) == LDNS_RESOLV_INET)) {
00109 continue;
00110 }
00111
00112 gettimeofday(&tv_s, NULL);
00113
00114 send_status = LDNS_STATUS_ERR;
00115
00116 if (1 == ldns_resolver_usevc(r)) {
00117 for (retries = ldns_resolver_retry(r); retries > 0; retries--) {
00118 send_status =
00119 ldns_tcp_send(&reply_bytes, qb, ns,
00120 (socklen_t)ns_len, ldns_resolver_timeout(r),
00121 &reply_size);
00122 if (send_status == LDNS_STATUS_OK) {
00123 break;
00124 }
00125 }
00126 } else {
00127 for (retries = ldns_resolver_retry(r); retries > 0; retries--) {
00128
00129 send_status =
00130 ldns_udp_send(&reply_bytes, qb, ns,
00131 (socklen_t)ns_len, ldns_resolver_timeout(r),
00132 &reply_size);
00133
00134 if (send_status == LDNS_STATUS_OK) {
00135 break;
00136 }
00137 }
00138 }
00139
00140 if (send_status != LDNS_STATUS_OK) {
00141 ldns_resolver_set_nameserver_rtt(r, i, LDNS_RESOLV_RTT_INF);
00142 status = send_status;
00143 }
00144
00145
00146 if (!reply_bytes) {
00147
00148 if (ldns_resolver_fail(r)) {
00149 LDNS_FREE(ns);
00150 return LDNS_STATUS_ERR;
00151 } else {
00152 LDNS_FREE(ns);
00153 continue;
00154 }
00155 }
00156
00157 status = ldns_wire2pkt(&reply, reply_bytes, reply_size);
00158 if (status != LDNS_STATUS_OK) {
00159 LDNS_FREE(reply_bytes);
00160 LDNS_FREE(ns);
00161 return status;
00162 }
00163
00164 LDNS_FREE(ns);
00165 gettimeofday(&tv_e, NULL);
00166
00167 if (reply) {
00168 ldns_pkt_set_querytime(reply, (uint32_t)
00169 ((tv_e.tv_sec - tv_s.tv_sec) * 1000) +
00170 (tv_e.tv_usec - tv_s.tv_usec) / 1000);
00171 ldns_pkt_set_answerfrom(reply, ns_array[i]);
00172 ldns_pkt_set_timestamp(reply, tv_s);
00173 ldns_pkt_set_size(reply, reply_size);
00174 break;
00175 } else {
00176 if (ldns_resolver_fail(r)) {
00177
00178
00179 break;
00180 }
00181 }
00182
00183
00184 sleep((unsigned int) ldns_resolver_retrans(r));
00185 }
00186
00187 if (all_servers_rtt_inf) {
00188 LDNS_FREE(reply_bytes);
00189 return LDNS_STATUS_RES_NO_NS;
00190 }
00191 #ifdef HAVE_SSL
00192 if (tsig_mac && reply_bytes) {
00193 if (!ldns_pkt_tsig_verify(reply,
00194 reply_bytes,
00195 reply_size,
00196 ldns_resolver_tsig_keyname(r),
00197 ldns_resolver_tsig_keydata(r), tsig_mac)) {
00198 status = LDNS_STATUS_CRYPTO_TSIG_BOGUS;
00199 }
00200 }
00201 #else
00202 (void)tsig_mac;
00203 #endif
00204 LDNS_FREE(reply_bytes);
00205 if (result) {
00206 *result = reply;
00207 }
00208
00209 return status;
00210 }
00211
00212 ldns_status
00213 ldns_udp_send(uint8_t **result, ldns_buffer *qbin, const struct sockaddr_storage *to,
00214 socklen_t tolen, struct timeval timeout, size_t *answer_size)
00215 {
00216 int sockfd;
00217 uint8_t *answer;
00218
00219 sockfd = ldns_udp_bgsend(qbin, to, tolen, timeout);
00220
00221 if (sockfd == 0) {
00222 return LDNS_STATUS_SOCKET_ERROR;
00223 }
00224
00225
00226 answer = ldns_udp_read_wire(sockfd, answer_size, NULL, NULL);
00227 close(sockfd);
00228
00229 if (*answer_size == 0) {
00230
00231 return LDNS_STATUS_NETWORK_ERR;
00232 }
00233
00234 *result = answer;
00235 return LDNS_STATUS_OK;
00236 }
00237
00238 int
00239 ldns_udp_bgsend(ldns_buffer *qbin, const struct sockaddr_storage *to, socklen_t tolen,
00240 struct timeval timeout)
00241 {
00242 int sockfd;
00243
00244 sockfd = ldns_udp_connect(to, timeout);
00245
00246 if (sockfd == 0) {
00247 return 0;
00248 }
00249
00250 if (ldns_udp_send_query(qbin, sockfd, to, tolen) == 0) {
00251 return 0;
00252 }
00253 return sockfd;
00254 }
00255
00256 int
00257 ldns_udp_connect(const struct sockaddr_storage *to, struct timeval timeout)
00258 {
00259 int sockfd;
00260
00261 if ((sockfd = socket((int)((struct sockaddr*)to)->sa_family, SOCK_DGRAM,
00262 IPPROTO_UDP))
00263 == -1) {
00264 return 0;
00265 }
00266 if (setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, &timeout,
00267 (socklen_t)sizeof(timeout))) {
00268
00269
00270
00271
00272
00273 }
00274 return sockfd;
00275 }
00276
00277 int
00278 ldns_tcp_connect(const struct sockaddr_storage *to, socklen_t tolen,
00279 struct timeval timeout)
00280 {
00281 int sockfd;
00282
00283 if ((sockfd = socket((int)((struct sockaddr*)to)->sa_family, SOCK_STREAM,
00284 IPPROTO_TCP)) == -1) {
00285
00286 return 0;
00287 }
00288
00289 if (setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, &timeout,
00290 (socklen_t) sizeof(timeout))) {
00291
00292 close(sockfd);
00293 return 0;
00294 }
00295
00296 if (connect(sockfd, (struct sockaddr*)to, tolen) == -1) {
00297 close(sockfd);
00298
00299 return 0;
00300 }
00301 return sockfd;
00302 }
00303
00304 ssize_t
00305 ldns_tcp_send_query(ldns_buffer *qbin, int sockfd,
00306 const struct sockaddr_storage *to, socklen_t tolen)
00307 {
00308 uint8_t *sendbuf;
00309 ssize_t bytes;
00310
00311
00312 sendbuf = LDNS_XMALLOC(uint8_t, ldns_buffer_position(qbin) + 2);
00313 ldns_write_uint16(sendbuf, ldns_buffer_position(qbin));
00314 memcpy(sendbuf + 2, ldns_buffer_export(qbin), ldns_buffer_position(qbin));
00315
00316 bytes = sendto(sockfd, sendbuf,
00317 ldns_buffer_position(qbin) + 2, 0, (struct sockaddr *)to, tolen);
00318
00319 LDNS_FREE(sendbuf);
00320
00321 if (bytes == -1 || (size_t) bytes != ldns_buffer_position(qbin) + 2 ) {
00322 return 0;
00323 }
00324 return bytes;
00325 }
00326
00327
00328 ssize_t
00329 ldns_udp_send_query(ldns_buffer *qbin, int sockfd, const struct sockaddr_storage *to,
00330 socklen_t tolen)
00331 {
00332 ssize_t bytes;
00333
00334 bytes = sendto(sockfd, ldns_buffer_begin(qbin),
00335 ldns_buffer_position(qbin), 0, (struct sockaddr *)to, tolen);
00336
00337 if (bytes == -1 || (size_t)bytes != ldns_buffer_position(qbin)) {
00338 return 0;
00339 }
00340 if ((size_t) bytes != ldns_buffer_position(qbin)) {
00341 return 0;
00342 }
00343 return bytes;
00344 }
00345
00346 uint8_t *
00347 ldns_udp_read_wire(int sockfd, size_t *size, struct sockaddr_storage *from,
00348 socklen_t *fromlen)
00349 {
00350 uint8_t *wire;
00351 ssize_t wire_size;
00352 socklen_t flen;
00353
00354 wire = LDNS_XMALLOC(uint8_t, LDNS_MAX_PACKETLEN);
00355 if (!wire) {
00356 *size = 0;
00357 return NULL;
00358 }
00359
00360 wire_size = recvfrom(sockfd, wire, LDNS_MAX_PACKETLEN, 0,
00361 (struct sockaddr*) from, &flen);
00362
00363 if (from) {
00364 if (fromlen) {
00365 *fromlen = flen;
00366 }
00367 }
00368
00369
00370 if (wire_size == -1 || wire_size == 0) {
00371 *size = 0;
00372 LDNS_FREE(wire);
00373 return NULL;
00374 }
00375
00376 *size = (size_t)wire_size;
00377 wire = LDNS_XREALLOC(wire, uint8_t, (size_t)wire_size);
00378
00379 return wire;
00380 }
00381
00382 uint8_t *
00383 ldns_tcp_read_wire(int sockfd, size_t *size)
00384 {
00385 uint8_t *wire;
00386 uint16_t wire_size;
00387 ssize_t bytes = 0;
00388
00389 wire = LDNS_XMALLOC(uint8_t, 2);
00390 if (!wire) {
00391 *size = 0;
00392 return NULL;
00393 }
00394
00395 while (bytes < 2) {
00396 bytes = recv(sockfd, wire, 2, 0);
00397 if (bytes == -1 || bytes == 0) {
00398 *size = 0;
00399 LDNS_FREE(wire);
00400 return NULL;
00401 }
00402 }
00403
00404 wire_size = ldns_read_uint16(wire);
00405
00406 LDNS_FREE(wire);
00407 wire = LDNS_XMALLOC(uint8_t, wire_size);
00408 bytes = 0;
00409
00410 while (bytes < (ssize_t) wire_size) {
00411 bytes += recv(sockfd, wire + bytes, (size_t) (wire_size - bytes), 0);
00412 if (bytes == -1 || bytes == 0) {
00413 LDNS_FREE(wire);
00414 *size = 0;
00415 return NULL;
00416 }
00417 }
00418
00419 *size = (size_t) bytes;
00420 return wire;
00421 }
00422
00423
00424
00425
00426 ldns_status
00427 ldns_tcp_send(uint8_t **result, ldns_buffer *qbin, const struct sockaddr_storage *to,
00428 socklen_t tolen, struct timeval timeout, size_t *answer_size)
00429 {
00430 int sockfd;
00431 uint8_t *answer;
00432
00433 sockfd = ldns_tcp_bgsend(qbin, to, tolen, timeout);
00434
00435 if (sockfd == 0) {
00436 return LDNS_STATUS_ERR;
00437 }
00438
00439 answer = ldns_tcp_read_wire(sockfd, answer_size);
00440 close(sockfd);
00441
00442 if (*answer_size == 0) {
00443
00444 return LDNS_STATUS_NETWORK_ERR;
00445 }
00446
00447
00448 answer = (uint8_t*)LDNS_XREALLOC(answer, uint8_t *, (size_t)*answer_size);
00449 *result = answer;
00450 return LDNS_STATUS_OK;
00451 }
00452
00453 int
00454 ldns_tcp_bgsend(ldns_buffer *qbin, const struct sockaddr_storage *to, socklen_t tolen,
00455 struct timeval timeout)
00456 {
00457 int sockfd;
00458
00459 sockfd = ldns_tcp_connect(to, tolen, timeout);
00460
00461 if (sockfd == 0) {
00462 return 0;
00463 }
00464
00465 if (ldns_tcp_send_query(qbin, sockfd, to, tolen) == 0) {
00466 return 0;
00467 }
00468
00469 return sockfd;
00470 }
00471
00472
00473 struct sockaddr_storage *
00474 ldns_rdf2native_sockaddr_storage(const ldns_rdf *rd, uint16_t port, size_t *size)
00475 {
00476 struct sockaddr_storage *data;
00477 struct sockaddr_in *data_in;
00478 struct sockaddr_in6 *data_in6;
00479
00480 data = LDNS_MALLOC(struct sockaddr_storage);
00481 if (!data) {
00482 return NULL;
00483 }
00484 if (port == 0) {
00485 port = LDNS_PORT;
00486 }
00487
00488 switch(ldns_rdf_get_type(rd)) {
00489 case LDNS_RDF_TYPE_A:
00490 data->ss_family = AF_INET;
00491 data_in = (struct sockaddr_in*) data;
00492 data_in->sin_port = (in_port_t)htons(port);
00493 memcpy(&(data_in->sin_addr), ldns_rdf_data(rd), ldns_rdf_size(rd));
00494 *size = sizeof(struct sockaddr_in);
00495 return data;
00496 case LDNS_RDF_TYPE_AAAA:
00497 data->ss_family = AF_INET6;
00498 data_in6 = (struct sockaddr_in6*) data;
00499 data_in6->sin6_port = (in_port_t)htons(port);
00500 memcpy(&data_in6->sin6_addr, ldns_rdf_data(rd), ldns_rdf_size(rd));
00501 *size = sizeof(struct sockaddr_in6);
00502 return data;
00503 default:
00504 LDNS_FREE(data);
00505 return NULL;
00506 }
00507 }
00508
00509 ldns_rdf *
00510 ldns_sockaddr_storage2rdf(struct sockaddr_storage *sock, uint16_t *port)
00511 {
00512 ldns_rdf *addr;
00513 struct sockaddr_in *data_in;
00514 struct sockaddr_in6 *data_in6;
00515
00516 switch(sock->ss_family) {
00517 case AF_INET:
00518 data_in = (struct sockaddr_in*)sock;
00519 if (port) {
00520 *port = ntohs((uint16_t)data_in->sin_port);
00521 }
00522 addr = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_A,
00523 LDNS_IP4ADDRLEN, &data_in->sin_addr);
00524 break;
00525 case AF_INET6:
00526 data_in6 = (struct sockaddr_in6*)sock;
00527 if (port) {
00528 *port = ntohs((uint16_t)data_in6->sin6_port);
00529 }
00530 addr = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_AAAA,
00531 LDNS_IP6ADDRLEN, &data_in6->sin6_addr);
00532 break;
00533 default:
00534 if (port) {
00535 *port = 0;
00536 }
00537 return NULL;
00538 }
00539 return addr;
00540 }
00541
00542
00543 ldns_status
00544 ldns_axfr_start(ldns_resolver *resolver, ldns_rdf *domain, ldns_rr_class class)
00545 {
00546 ldns_pkt *query;
00547 ldns_buffer *query_wire;
00548
00549 struct sockaddr_storage *ns;
00550 size_t ns_len = 0;
00551 ldns_status status;
00552
00553 if (!resolver || ldns_resolver_nameserver_count(resolver) < 1) {
00554 return LDNS_STATUS_ERR;
00555 }
00556
00557 query = ldns_pkt_query_new(ldns_rdf_clone(domain), LDNS_RR_TYPE_AXFR, class, 0);
00558
00559 if (!query) {
00560 return LDNS_STATUS_ADDRESS_ERR;
00561 }
00562
00563 ns = ldns_rdf2native_sockaddr_storage(resolver->_nameservers[0],
00564 ldns_resolver_port(resolver), &ns_len);
00565
00566 resolver->_socket = ldns_tcp_connect(ns, (socklen_t)ns_len,
00567 ldns_resolver_timeout(resolver));
00568 if (resolver->_socket == 0) {
00569 ldns_pkt_free(query);
00570 LDNS_FREE(ns);
00571 return LDNS_STATUS_NETWORK_ERR;
00572 }
00573
00574 #ifdef HAVE_SSL
00575 if (ldns_resolver_tsig_keyname(resolver) && ldns_resolver_tsig_keydata(resolver)) {
00576 status = ldns_pkt_tsig_sign(query,
00577 ldns_resolver_tsig_keyname(resolver),
00578 ldns_resolver_tsig_keydata(resolver),
00579 300, ldns_resolver_tsig_algorithm(resolver), NULL);
00580 if (status != LDNS_STATUS_OK) {
00581 return LDNS_STATUS_CRYPTO_TSIG_ERR;
00582 }
00583 }
00584 #endif
00585
00586
00587
00588 query_wire = ldns_buffer_new(LDNS_MAX_PACKETLEN);
00589 status = ldns_pkt2buffer_wire(query_wire, query);
00590 if (status != LDNS_STATUS_OK) {
00591 ldns_pkt_free(query);
00592 LDNS_FREE(ns);
00593 return status;
00594 }
00595
00596 if (ldns_tcp_send_query(query_wire, resolver->_socket, ns,
00597 (socklen_t)ns_len) == 0) {
00598 ldns_pkt_free(query);
00599 ldns_buffer_free(query_wire);
00600 LDNS_FREE(ns);
00601 return LDNS_STATUS_NETWORK_ERR;
00602 }
00603
00604 ldns_pkt_free(query);
00605 ldns_buffer_free(query_wire);
00606 LDNS_FREE(ns);
00607
00608
00609
00610
00611 resolver->_axfr_soa_count = 0;
00612 return LDNS_STATUS_OK;
00613 }