svn commit: r266654 - stable/9/lib/libfetch
Dag-Erling Smørgrav
des at FreeBSD.org
Sun May 25 16:20:54 UTC 2014
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 <freebsd at 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);
}
/*
More information about the svn-src-stable-9
mailing list