Author: des
Date: Sun May 25 16:20:53 2014
New Revision: 266654
URL: http://svnweb.freebsd.org/changeset/base/266654

Log:
  MFH (r260904): fix format string
  MFH (r261230,r261263): fix issues with buffering / stalling
  MFH (r261284): bump copyright dates
  MFH (r266291): look for root certs in /usr/local first
  
  Approved by:  re (gjb)

Modified:
  stable/9/lib/libfetch/common.c
  stable/9/lib/libfetch/common.h
  stable/9/lib/libfetch/http.c
Directory Properties:
  stable/9/lib/libfetch/   (props changed)

Modified: stable/9/lib/libfetch/common.c
==============================================================================
--- stable/9/lib/libfetch/common.c      Sun May 25 16:17:41 2014        
(r266653)
+++ stable/9/lib/libfetch/common.c      Sun May 25 16:20:53 2014        
(r266654)
@@ -1,5 +1,5 @@
 /*-
- * Copyright (c) 1998-2011 Dag-Erling Smørgrav
+ * Copyright (c) 1998-2014 Dag-Erling Smørgrav
  * Copyright (c) 2013 Michael Gmelin <free...@grem.de>
  * All rights reserved.
  *
@@ -41,6 +41,7 @@ __FBSDID("$FreeBSD$");
 #include <errno.h>
 #include <fcntl.h>
 #include <netdb.h>
+#include <poll.h>
 #include <pwd.h>
 #include <stdarg.h>
 #include <stdlib.h>
@@ -641,7 +642,7 @@ fetch_ssl_verify_hname(X509 *cert, const
        struct addrinfo *ip;
        STACK_OF(GENERAL_NAME) *altnames;
        X509_NAME *subject;
-       int ret;        
+       int ret;
 
        ret = 0;
        ip = fetch_ssl_get_numeric_addrinfo(host, strlen(host));
@@ -679,7 +680,7 @@ fetch_ssl_setup_transport_layer(SSL_CTX 
        if (getenv("SSL_NO_TLS1") != NULL)
                ssl_ctx_options |= SSL_OP_NO_TLSv1;
        if (verbose)
-               fetch_info("SSL options: %x", ssl_ctx_options);
+               fetch_info("SSL options: %lx", ssl_ctx_options);
        SSL_CTX_set_options(ctx, ssl_ctx_options);
 }
 
@@ -687,6 +688,8 @@ fetch_ssl_setup_transport_layer(SSL_CTX 
 /*
  * Configure peer verification based on environment.
  */
+#define LOCAL_CERT_FILE        "/usr/local/etc/ssl/cert.pem"
+#define BASE_CERT_FILE "/etc/ssl/cert.pem"
 static int
 fetch_ssl_setup_peer_verification(SSL_CTX *ctx, int verbose)
 {
@@ -695,8 +698,12 @@ fetch_ssl_setup_peer_verification(SSL_CT
        const char *ca_cert_file, *ca_cert_path, *crl_file;
 
        if (getenv("SSL_NO_VERIFY_PEER") == NULL) {
-               ca_cert_file = getenv("SSL_CA_CERT_FILE") != NULL ?
-                   getenv("SSL_CA_CERT_FILE") : "/etc/ssl/cert.pem";
+               ca_cert_file = getenv("SSL_CA_CERT_FILE");
+               if (ca_cert_file == NULL &&
+                   access(LOCAL_CERT_FILE, R_OK) == 0)
+                       ca_cert_file = LOCAL_CERT_FILE;
+               if (ca_cert_file == NULL)
+                       ca_cert_file = BASE_CERT_FILE;
                ca_cert_path = getenv("SSL_CA_CERT_PATH");
                if (verbose) {
                        fetch_info("Peer verification enabled");
@@ -913,33 +920,6 @@ fetch_ssl_read(SSL *ssl, char *buf, size
 }
 #endif
 
-/*
- * Cache some data that was read from a socket but cannot be immediately
- * returned because of an interrupted system call.
- */
-static int
-fetch_cache_data(conn_t *conn, char *src, size_t nbytes)
-{
-       char *tmp;
-
-       if (conn->cache.size < nbytes) {
-               tmp = realloc(conn->cache.buf, nbytes);
-               if (tmp == NULL) {
-                       fetch_syserr();
-                       return (-1);
-               }
-               conn->cache.buf = tmp;
-               conn->cache.size = nbytes;
-       }
-
-       memcpy(conn->cache.buf, src, nbytes);
-       conn->cache.len = nbytes;
-       conn->cache.pos = 0;
-
-       return (0);
-}
-
-
 static ssize_t
 fetch_socket_read(int sd, char *buf, size_t len)
 {
@@ -962,46 +942,31 @@ ssize_t
 fetch_read(conn_t *conn, char *buf, size_t len)
 {
        struct timeval now, timeout, delta;
-       fd_set readfds;
-       ssize_t rlen, total;
-       char *start;
+       struct pollfd pfd;
+       ssize_t rlen;
+       int deltams;
 
        if (fetchTimeout > 0) {
                gettimeofday(&timeout, NULL);
                timeout.tv_sec += fetchTimeout;
        }
 
-       total = 0;
-       start = buf;
-
-       if (conn->cache.len > 0) {
-               /*
-                * The last invocation of fetch_read was interrupted by a
-                * signal after some data had been read from the socket. Copy
-                * the cached data into the supplied buffer before trying to
-                * read from the socket again.
-                */
-               total = (conn->cache.len < len) ? conn->cache.len : len;
-               memcpy(buf, conn->cache.buf, total);
-
-               conn->cache.len -= total;
-               conn->cache.pos += total;
-               len -= total;
-               buf += total;
-       }
+       deltams = INFTIM;
+       memset(&pfd, 0, sizeof pfd);
+       pfd.fd = conn->sd;
+       pfd.events = POLLIN | POLLERR;
 
-       while (len > 0) {
+       for (;;) {
                /*
                 * The socket is non-blocking.  Instead of the canonical
-                * select() -> read(), we do the following:
+                * poll() -> read(), we do the following:
                 *
                 * 1) call read() or SSL_read().
-                * 2) if an error occurred, return -1.
-                * 3) if we received data but we still expect more,
-                *    update our counters and loop.
+                * 2) if we received some data, return it.
+                * 3) if an error occurred, return -1.
                 * 4) if read() or SSL_read() signaled EOF, return.
                 * 5) if we did not receive any data but we're not at EOF,
-                *    call select().
+                *    call poll().
                 *
                 * In the SSL case, this is necessary because if we
                 * receive a close notification, we have to call
@@ -1017,46 +982,34 @@ fetch_read(conn_t *conn, char *buf, size
                else
 #endif
                        rlen = fetch_socket_read(conn->sd, buf, len);
-               if (rlen == 0) {
+               if (rlen >= 0) {
                        break;
-               } else if (rlen > 0) {
-                       len -= rlen;
-                       buf += rlen;
-                       total += rlen;
-                       continue;
                } else if (rlen == FETCH_READ_ERROR) {
-                       if (errno == EINTR)
-                               fetch_cache_data(conn, start, total);
+                       fetch_syserr();
                        return (-1);
                }
                // assert(rlen == FETCH_READ_WAIT);
-               FD_ZERO(&readfds);
-               while (!FD_ISSET(conn->sd, &readfds)) {
-                       FD_SET(conn->sd, &readfds);
-                       if (fetchTimeout > 0) {
-                               gettimeofday(&now, NULL);
-                               if (!timercmp(&timeout, &now, >)) {
-                                       errno = ETIMEDOUT;
-                                       fetch_syserr();
-                                       return (-1);
-                               }
-                               timersub(&timeout, &now, &delta);
-                       }
-                       errno = 0;
-                       if (select(conn->sd + 1, &readfds, NULL, NULL,
-                               fetchTimeout > 0 ? &delta : NULL) < 0) {
-                               if (errno == EINTR) {
-                                       if (fetchRestartCalls)
-                                               continue;
-                                       /* Save anything that was read. */
-                                       fetch_cache_data(conn, start, total);
-                               }
+               if (fetchTimeout > 0) {
+                       gettimeofday(&now, NULL);
+                       if (!timercmp(&timeout, &now, >)) {
+                               errno = ETIMEDOUT;
                                fetch_syserr();
                                return (-1);
                        }
+                       timersub(&timeout, &now, &delta);
+                       deltams = delta.tv_sec * 1000 +
+                           delta.tv_usec / 1000;;
+               }
+               errno = 0;
+               pfd.revents = 0;
+               if (poll(&pfd, 1, deltams) < 0) {
+                       if (errno == EINTR && fetchRestartCalls)
+                               continue;
+                       fetch_syserr();
+                       return (-1);
                }
        }
-       return (total);
+       return (rlen);
 }
 
 
@@ -1130,35 +1083,33 @@ ssize_t
 fetch_writev(conn_t *conn, struct iovec *iov, int iovcnt)
 {
        struct timeval now, timeout, delta;
-       fd_set writefds;
+       struct pollfd pfd;
        ssize_t wlen, total;
-       int r;
+       int deltams;
 
+       memset(&pfd, 0, sizeof pfd);
        if (fetchTimeout) {
-               FD_ZERO(&writefds);
+               pfd.fd = conn->sd;
+               pfd.events = POLLOUT | POLLERR;
                gettimeofday(&timeout, NULL);
                timeout.tv_sec += fetchTimeout;
        }
 
        total = 0;
        while (iovcnt > 0) {
-               while (fetchTimeout && !FD_ISSET(conn->sd, &writefds)) {
-                       FD_SET(conn->sd, &writefds);
+               while (fetchTimeout && pfd.revents == 0) {
                        gettimeofday(&now, NULL);
-                       delta.tv_sec = timeout.tv_sec - now.tv_sec;
-                       delta.tv_usec = timeout.tv_usec - now.tv_usec;
-                       if (delta.tv_usec < 0) {
-                               delta.tv_usec += 1000000;
-                               delta.tv_sec--;
-                       }
-                       if (delta.tv_sec < 0) {
+                       if (!timercmp(&timeout, &now, >)) {
                                errno = ETIMEDOUT;
                                fetch_syserr();
                                return (-1);
                        }
+                       timersub(&timeout, &now, &delta);
+                       deltams = delta.tv_sec * 1000 +
+                           delta.tv_usec / 1000;
                        errno = 0;
-                       r = select(conn->sd + 1, NULL, &writefds, NULL, &delta);
-                       if (r == -1) {
+                       pfd.revents = 0;
+                       if (poll(&pfd, 1, deltams) < 0) {
                                if (errno == EINTR && fetchRestartCalls)
                                        continue;
                                return (-1);
@@ -1250,7 +1201,6 @@ fetch_close(conn_t *conn)
        }
 #endif
        ret = close(conn->sd);
-       free(conn->cache.buf);
        free(conn->buf);
        free(conn);
        return (ret);

Modified: stable/9/lib/libfetch/common.h
==============================================================================
--- stable/9/lib/libfetch/common.h      Sun May 25 16:17:41 2014        
(r266653)
+++ stable/9/lib/libfetch/common.h      Sun May 25 16:20:53 2014        
(r266654)
@@ -1,5 +1,5 @@
 /*-
- * Copyright (c) 1998-2011 Dag-Erling Smørgrav
+ * Copyright (c) 1998-2014 Dag-Erling Smørgrav
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -52,13 +52,6 @@ struct fetchconn {
        size_t           bufsize;       /* buffer size */
        size_t           buflen;        /* length of buffer contents */
        int              err;           /* last protocol reply code */
-       struct {                        /* data cached after an interrupted
-                                          read */
-               char    *buf;
-               size_t   size;
-               size_t   pos;
-               size_t   len;
-       } cache;
 #ifdef WITH_SSL
        SSL             *ssl;           /* SSL handle */
        SSL_CTX         *ssl_ctx;       /* SSL context */

Modified: stable/9/lib/libfetch/http.c
==============================================================================
--- stable/9/lib/libfetch/http.c        Sun May 25 16:17:41 2014        
(r266653)
+++ stable/9/lib/libfetch/http.c        Sun May 25 16:20:53 2014        
(r266654)
@@ -1,5 +1,5 @@
 /*-
- * Copyright (c) 2000-2013 Dag-Erling Smørgrav
+ * Copyright (c) 2000-2014 Dag-Erling Smørgrav
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -204,10 +204,11 @@ http_growbuf(struct httpio *io, size_t l
 /*
  * Fill the input buffer, do chunk decoding on the fly
  */
-static int
+static ssize_t
 http_fillbuf(struct httpio *io, size_t len)
 {
        ssize_t nbytes;
+       char ch;
 
        if (io->error)
                return (-1);
@@ -229,7 +230,7 @@ http_fillbuf(struct httpio *io, size_t l
        if (io->chunksize == 0) {
                switch (http_new_chunk(io)) {
                case -1:
-                       io->error = 1;
+                       io->error = EPROTO;
                        return (-1);
                case 0:
                        io->eof = 1;
@@ -249,10 +250,8 @@ http_fillbuf(struct httpio *io, size_t l
        io->chunksize -= io->buflen;
 
        if (io->chunksize == 0) {
-               char endl[2];
-
-               if (fetch_read(io->conn, endl, 2) != 2 ||
-                   endl[0] != '\r' || endl[1] != '\n')
+               if (fetch_read(io->conn, &ch, 1) != 1 || ch != '\r' ||
+                   fetch_read(io->conn, &ch, 1) != 1 || ch != '\n')
                        return (-1);
        }
 
@@ -268,31 +267,30 @@ static int
 http_readfn(void *v, char *buf, int len)
 {
        struct httpio *io = (struct httpio *)v;
-       int l, pos;
+       int rlen;
 
        if (io->error)
                return (-1);
        if (io->eof)
                return (0);
 
-       for (pos = 0; len > 0; pos += l, len -= l) {
-               /* empty buffer */
-               if (!io->buf || io->bufpos == io->buflen)
-                       if (http_fillbuf(io, len) < 1)
-                               break;
-               l = io->buflen - io->bufpos;
-               if (len < l)
-                       l = len;
-               memcpy(buf + pos, io->buf + io->bufpos, l);
-               io->bufpos += l;
+       /* empty buffer */
+       if (!io->buf || io->bufpos == io->buflen) {
+               if ((rlen = http_fillbuf(io, len)) < 0) {
+                       if ((errno = io->error) == EINTR)
+                               io->error = 0;
+                       return (-1);
+               } else if (rlen == 0) {
+                       return (0);
+               }
        }
 
-       if (!pos && io->error) {
-               if (io->error == EINTR)
-                       io->error = 0;
-               return (-1);
-       }
-       return (pos);
+       rlen = io->buflen - io->bufpos;
+       if (len < rlen)
+               rlen = len;
+       memcpy(buf, io->buf + io->bufpos, rlen);
+       io->bufpos += rlen;
+       return (rlen);
 }
 
 /*
_______________________________________________
svn-src-stable-9@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-stable-9
To unsubscribe, send any mail to "svn-src-stable-9-unsubscr...@freebsd.org"

Reply via email to