| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: common.c,v 1.30 2016/10/20 21:22:18 joerg Exp $ */ | | 1 | /* $NetBSD: common.c,v 1.31 2016/10/20 21:25:57 joerg Exp $ */ |
2 | /*- | | 2 | /*- |
3 | * Copyright (c) 1998-2004 Dag-Erling Coïdan Smørgrav | | 3 | * Copyright (c) 1998-2004 Dag-Erling Coïdan Smørgrav |
4 | * Copyright (c) 2008, 2010 Joerg Sonnenberger <joerg@NetBSD.org> | | 4 | * Copyright (c) 2008, 2010 Joerg Sonnenberger <joerg@NetBSD.org> |
5 | * All rights reserved. | | 5 | * All rights reserved. |
6 | * | | 6 | * |
7 | * Redistribution and use in source and binary forms, with or without | | 7 | * Redistribution and use in source and binary forms, with or without |
8 | * modification, are permitted provided that the following conditions | | 8 | * modification, are permitted provided that the following conditions |
9 | * are met: | | 9 | * are met: |
10 | * 1. Redistributions of source code must retain the above copyright | | 10 | * 1. Redistributions of source code must retain the above copyright |
11 | * notice, this list of conditions and the following disclaimer | | 11 | * notice, this list of conditions and the following disclaimer |
12 | * in this position and unchanged. | | 12 | * in this position and unchanged. |
13 | * 2. Redistributions in binary form must reproduce the above copyright | | 13 | * 2. Redistributions in binary form must reproduce the above copyright |
14 | * notice, this list of conditions and the following disclaimer in the | | 14 | * notice, this list of conditions and the following disclaimer in the |
| @@ -230,26 +230,27 @@ fetch_default_proxy_port(const char *sch | | | @@ -230,26 +230,27 @@ fetch_default_proxy_port(const char *sch |
230 | conn_t * | | 230 | conn_t * |
231 | fetch_reopen(int sd) | | 231 | fetch_reopen(int sd) |
232 | { | | 232 | { |
233 | conn_t *conn; | | 233 | conn_t *conn; |
234 | | | 234 | |
235 | /* allocate and fill connection structure */ | | 235 | /* allocate and fill connection structure */ |
236 | if ((conn = calloc(1, sizeof(*conn))) == NULL) | | 236 | if ((conn = calloc(1, sizeof(*conn))) == NULL) |
237 | return (NULL); | | 237 | return (NULL); |
238 | conn->ftp_home = NULL; | | 238 | conn->ftp_home = NULL; |
239 | conn->cache_url = NULL; | | 239 | conn->cache_url = NULL; |
240 | conn->next_buf = NULL; | | 240 | conn->next_buf = NULL; |
241 | conn->next_len = 0; | | 241 | conn->next_len = 0; |
242 | conn->sd = sd; | | 242 | conn->sd = sd; |
| | | 243 | conn->buf_events = POLLIN; |
243 | return (conn); | | 244 | return (conn); |
244 | } | | 245 | } |
245 | | | 246 | |
246 | | | 247 | |
247 | /* | | 248 | /* |
248 | * Bind a socket to a specific local address | | 249 | * Bind a socket to a specific local address |
249 | */ | | 250 | */ |
250 | int | | 251 | int |
251 | fetch_bind(int sd, int af, const char *addr) | | 252 | fetch_bind(int sd, int af, const char *addr) |
252 | { | | 253 | { |
253 | struct addrinfo hints, *res, *res0; | | 254 | struct addrinfo hints, *res, *res0; |
254 | | | 255 | |
255 | memset(&hints, 0, sizeof(hints)); | | 256 | memset(&hints, 0, sizeof(hints)); |
| @@ -446,26 +447,27 @@ fetch_ssl(conn_t *conn, const struct url | | | @@ -446,26 +447,27 @@ fetch_ssl(conn_t *conn, const struct url |
446 | } | | 447 | } |
447 | | | 448 | |
448 | SSL_load_error_strings(); | | 449 | SSL_load_error_strings(); |
449 | | | 450 | |
450 | conn->ssl_meth = SSLv23_client_method(); | | 451 | conn->ssl_meth = SSLv23_client_method(); |
451 | conn->ssl_ctx = SSL_CTX_new(conn->ssl_meth); | | 452 | conn->ssl_ctx = SSL_CTX_new(conn->ssl_meth); |
452 | SSL_CTX_set_mode(conn->ssl_ctx, SSL_MODE_AUTO_RETRY); | | 453 | SSL_CTX_set_mode(conn->ssl_ctx, SSL_MODE_AUTO_RETRY); |
453 | | | 454 | |
454 | conn->ssl = SSL_new(conn->ssl_ctx); | | 455 | conn->ssl = SSL_new(conn->ssl_ctx); |
455 | if (conn->ssl == NULL){ | | 456 | if (conn->ssl == NULL){ |
456 | fprintf(stderr, "SSL context creation failed\n"); | | 457 | fprintf(stderr, "SSL context creation failed\n"); |
457 | return (-1); | | 458 | return (-1); |
458 | } | | 459 | } |
| | | 460 | conn->buf_events = 0; |
459 | SSL_set_fd(conn->ssl, conn->sd); | | 461 | SSL_set_fd(conn->ssl, conn->sd); |
460 | #if OPENSSL_VERSION_NUMBER >= 0x0090806fL && !defined(OPENSSL_NO_TLSEXT) | | 462 | #if OPENSSL_VERSION_NUMBER >= 0x0090806fL && !defined(OPENSSL_NO_TLSEXT) |
461 | if (!SSL_set_tlsext_host_name(conn->ssl, (char *)(uintptr_t)URL->host)) { | | 463 | if (!SSL_set_tlsext_host_name(conn->ssl, (char *)(uintptr_t)URL->host)) { |
462 | fprintf(stderr, | | 464 | fprintf(stderr, |
463 | "TLS server name indication extension failed for host %s\n", | | 465 | "TLS server name indication extension failed for host %s\n", |
464 | URL->host); | | 466 | URL->host); |
465 | return (-1); | | 467 | return (-1); |
466 | } | | 468 | } |
467 | #endif | | 469 | #endif |
468 | if (SSL_connect(conn->ssl) == -1){ | | 470 | if (SSL_connect(conn->ssl) == -1){ |
469 | ERR_print_errors_fp(stderr); | | 471 | ERR_print_errors_fp(stderr); |
470 | return (-1); | | 472 | return (-1); |
471 | } | | 473 | } |
| @@ -527,50 +529,67 @@ fetch_read(conn_t *conn, char *buf, size | | | @@ -527,50 +529,67 @@ fetch_read(conn_t *conn, char *buf, size |
527 | len = conn->next_len; | | 529 | len = conn->next_len; |
528 | memmove(buf, conn->next_buf, len); | | 530 | memmove(buf, conn->next_buf, len); |
529 | conn->next_len -= len; | | 531 | conn->next_len -= len; |
530 | conn->next_buf += len; | | 532 | conn->next_buf += len; |
531 | return len; | | 533 | return len; |
532 | } | | 534 | } |
533 | | | 535 | |
534 | if (fetchTimeout) { | | 536 | if (fetchTimeout) { |
535 | gettimeofday(&timeout_end, NULL); | | 537 | gettimeofday(&timeout_end, NULL); |
536 | timeout_end.tv_sec += fetchTimeout; | | 538 | timeout_end.tv_sec += fetchTimeout; |
537 | } | | 539 | } |
538 | | | 540 | |
539 | pfd.fd = conn->sd; | | 541 | pfd.fd = conn->sd; |
540 | pfd.events = POLLIN; | | | |
541 | for (;;) { | | 542 | for (;;) { |
542 | if (fetchTimeout) { | | 543 | pfd.events = conn->buf_events; |
| | | 544 | if (fetchTimeout && pfd.events) { |
543 | do { | | 545 | do { |
544 | timeout_cur = compute_timeout(&timeout_end); | | 546 | timeout_cur = compute_timeout(&timeout_end); |
545 | if (timeout_cur < 0) { | | 547 | if (timeout_cur < 0) { |
546 | errno = ETIMEDOUT; | | 548 | errno = ETIMEDOUT; |
547 | fetch_syserr(); | | 549 | fetch_syserr(); |
548 | return (-1); | | 550 | return (-1); |
549 | } | | 551 | } |
550 | errno = 0; | | 552 | errno = 0; |
551 | r = poll(&pfd, 1, timeout_cur); | | 553 | r = poll(&pfd, 1, timeout_cur); |
552 | if (r == -1) { | | 554 | if (r == -1) { |
553 | if (errno == EINTR && fetchRestartCalls) | | 555 | if (errno == EINTR && fetchRestartCalls) |
554 | continue; | | 556 | continue; |
555 | fetch_syserr(); | | 557 | fetch_syserr(); |
556 | return (-1); | | 558 | return (-1); |
557 | } | | 559 | } |
558 | } while (pfd.revents == 0); | | 560 | } while (pfd.revents == 0); |
559 | } | | 561 | } |
560 | #ifdef WITH_SSL | | 562 | #ifdef WITH_SSL |
561 | if (conn->ssl != NULL) | | 563 | if (conn->ssl != NULL) { |
562 | rlen = SSL_read(conn->ssl, buf, len); | | 564 | rlen = SSL_read(conn->ssl, buf, len); |
563 | else | | 565 | if (rlen == -1) { |
| | | 566 | switch (SSL_get_error(conn->ssl, rlen)) { |
| | | 567 | case SSL_ERROR_WANT_READ: |
| | | 568 | conn->buf_events = POLLIN; |
| | | 569 | break; |
| | | 570 | case SSL_ERROR_WANT_WRITE: |
| | | 571 | conn->buf_events = POLLOUT; |
| | | 572 | break; |
| | | 573 | default: |
| | | 574 | errno = EIO; |
| | | 575 | fetch_syserr(); |
| | | 576 | return -1; |
| | | 577 | } |
| | | 578 | } else { |
| | | 579 | /* Assume buffering on the SSL layer. */ |
| | | 580 | conn->buf_events = 0; |
| | | 581 | } |
| | | 582 | } else |
564 | #endif | | 583 | #endif |
565 | rlen = read(conn->sd, buf, len); | | 584 | rlen = read(conn->sd, buf, len); |
566 | if (rlen >= 0) | | 585 | if (rlen >= 0) |
567 | break; | | 586 | break; |
568 | | | 587 | |
569 | if (errno != EINTR || !fetchRestartCalls) | | 588 | if (errno != EINTR || !fetchRestartCalls) |
570 | return (-1); | | 589 | return (-1); |
571 | } | | 590 | } |
572 | return (rlen); | | 591 | return (rlen); |
573 | } | | 592 | } |
574 | | | 593 | |
575 | | | 594 | |
576 | /* | | 595 | /* |