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