Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/external/bsd/fetch/dist/libfetch libfetch-2.30:
details: https://anonhg.NetBSD.org/src/rev/79f690a83760
branches: trunk
changeset: 751267:79f690a83760
user: joerg <joerg%NetBSD.org@localhost>
date: Sat Jan 30 21:26:09 2010 +0000
description:
libfetch-2.30:
- Revamped connection cache, allowing more than one active session
- HTTP keep-alive support
diffstat:
external/bsd/fetch/dist/libfetch/common.c | 221 +++++++++++++++++++----------
external/bsd/fetch/dist/libfetch/common.h | 22 +-
external/bsd/fetch/dist/libfetch/fetch.3 | 20 ++-
external/bsd/fetch/dist/libfetch/fetch.h | 6 +-
external/bsd/fetch/dist/libfetch/ftp.c | 159 +++++++--------------
external/bsd/fetch/dist/libfetch/http.c | 105 +++++++++++---
6 files changed, 309 insertions(+), 224 deletions(-)
diffs (truncated from 1169 to 300 lines):
diff -r a04619177d37 -r 79f690a83760 external/bsd/fetch/dist/libfetch/common.c
--- a/external/bsd/fetch/dist/libfetch/common.c Sat Jan 30 21:23:46 2010 +0000
+++ b/external/bsd/fetch/dist/libfetch/common.c Sat Jan 30 21:26:09 2010 +0000
@@ -1,7 +1,7 @@
-/* $NetBSD: common.c,v 1.1.1.7 2009/10/15 12:59:57 joerg Exp $ */
+/* $NetBSD: common.c,v 1.1.1.8 2010/01/30 21:26:09 joerg Exp $ */
/*-
* Copyright (c) 1998-2004 Dag-Erling Coïdan Smørgrav
- * Copyright (c) 2008 Joerg Sonnenberger <joerg%NetBSD.org@localhost>
+ * Copyright (c) 2008, 2010 Joerg Sonnenberger <joerg%NetBSD.org@localhost>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -62,12 +62,13 @@
#include <string.h>
#include <unistd.h>
+#ifndef MSG_NOSIGNAL
+#include <signal.h>
+#endif
+
#include "fetch.h"
#include "common.h"
-#define DECONST(x,y) ((x)(uintptr_t)(y))
-
-
/*** Local data **************************************************************/
/*
@@ -83,10 +84,6 @@
{ -1, FETCH_UNKNOWN, "Unknown resolver error" }
};
-/* End-of-Line */
-static const char ENDL[2] = "\r\n";
-
-
/*** Error-reporting functions ***********************************************/
/*
@@ -234,23 +231,10 @@
/* allocate and fill connection structure */
if ((conn = calloc(1, sizeof(*conn))) == NULL)
return (NULL);
+ conn->cache_url = NULL;
conn->next_buf = NULL;
conn->next_len = 0;
conn->sd = sd;
- conn->is_active = 0;
- ++conn->ref;
- return (conn);
-}
-
-
-/*
- * Bump a connection's reference count.
- */
-conn_t *
-fetch_ref(conn_t *conn)
-{
-
- ++conn->ref;
return (conn);
}
@@ -281,7 +265,7 @@
* Establish a TCP connection to the specified port on the specified host.
*/
conn_t *
-fetch_connect(const char *host, int port, int af, int verbose)
+fetch_connect(struct url *url, int af, int verbose)
{
conn_t *conn;
char pbuf[10];
@@ -290,22 +274,22 @@
int sd, error;
if (verbose)
- fetch_info("looking up %s", host);
+ fetch_info("looking up %s", url->host);
/* look up host name and set up socket address structure */
- snprintf(pbuf, sizeof(pbuf), "%d", port);
+ snprintf(pbuf, sizeof(pbuf), "%d", url->port);
memset(&hints, 0, sizeof(hints));
hints.ai_family = af;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = 0;
- if ((error = getaddrinfo(host, pbuf, &hints, &res0)) != 0) {
+ if ((error = getaddrinfo(url->host, pbuf, &hints, &res0)) != 0) {
netdb_seterr(error);
return (NULL);
}
bindaddr = getenv("FETCH_BIND_ADDRESS");
if (verbose)
- fetch_info("connecting to %s:%d", host, port);
+ fetch_info("connecting to %s:%d", url->host, url->port);
/* try to connect */
for (sd = -1, res = res0; res; sd = -1, res = res->ai_next) {
@@ -332,9 +316,114 @@
fetch_syserr();
close(sd);
}
+ conn->cache_url = fetchCopyURL(url);
+ conn->cache_af = af;
return (conn);
}
+static conn_t *connection_cache;
+static int cache_global_limit = 0;
+static int cache_per_host_limit = 0;
+
+/*
+ * Initialise cache with the given limits.
+ */
+void
+fetchConnectionCacheInit(int global_limit, int per_host_limit)
+{
+
+ if (global_limit < 0)
+ cache_global_limit = INT_MAX;
+ else if (per_host_limit > global_limit)
+ cache_global_limit = per_host_limit;
+ else
+ cache_global_limit = global_limit;
+ if (per_host_limit < 0)
+ cache_per_host_limit = INT_MAX;
+ else
+ cache_per_host_limit = per_host_limit;
+}
+
+/*
+ * Flush cache and free all associated resources.
+ */
+void
+fetchConnectionCacheClose(void)
+{
+ conn_t *conn;
+
+ while ((conn = connection_cache) != NULL) {
+ connection_cache = conn->next_cached;
+ (*conn->cache_close)(conn);
+ }
+}
+
+/*
+ * Check connection cache for an existing entry matching
+ * protocol/host/port/user/password/family.
+ */
+conn_t *
+fetch_cache_get(const struct url *url, int af)
+{
+ conn_t *conn, *last_conn = NULL;
+
+ for (conn = connection_cache; conn; conn = conn->next_cached) {
+ if (conn->cache_url->port == url->port &&
+ strcmp(conn->cache_url->scheme, url->scheme) == 0 &&
+ strcmp(conn->cache_url->host, url->host) == 0 &&
+ strcmp(conn->cache_url->user, url->user) == 0 &&
+ strcmp(conn->cache_url->pwd, url->pwd) == 0 &&
+ (conn->cache_af == AF_UNSPEC || af == AF_UNSPEC ||
+ conn->cache_af == af)) {
+ if (last_conn != NULL)
+ last_conn->next_cached = conn->next_cached;
+ else
+ connection_cache = conn->next_cached;
+ return conn;
+ }
+ }
+
+ return NULL;
+}
+
+/*
+ * Put the connection back into the cache for reuse.
+ * If the connection is freed due to LRU or if the cache
+ * is explicitly closed, the given callback is called.
+ */
+void
+fetch_cache_put(conn_t *conn, int (*closecb)(conn_t *))
+{
+ conn_t *iter, *last;
+ int global_count, host_count;
+
+ if (conn->cache_url == NULL || cache_global_limit == 0) {
+ (*closecb)(conn);
+ return;
+ }
+
+ global_count = host_count = 0;
+ last = NULL;
+ for (iter = connection_cache; iter;
+ last = iter, iter = iter->next_cached) {
+ ++global_count;
+ if (strcmp(conn->cache_url->host, iter->cache_url->host) == 0)
+ ++host_count;
+ if (global_count < cache_global_limit &&
+ host_count < cache_per_host_limit)
+ continue;
+ --global_count;
+ if (last != NULL)
+ last->next_cached = iter->next_cached;
+ else
+ connection_cache = iter->next_cached;
+ (*iter->cache_close)(iter);
+ }
+
+ conn->cache_close = closecb;
+ conn->next_cached = connection_cache;
+ connection_cache = conn;
+}
/*
* Enable SSL on a connection.
@@ -528,31 +617,28 @@
return (0);
}
-
-/*
- * Write to a connection w/ timeout
- */
-ssize_t
-fetch_write(conn_t *conn, const char *buf, size_t len)
-{
- struct iovec iov;
-
- iov.iov_base = DECONST(char *, buf);
- iov.iov_len = len;
- return fetch_writev(conn, &iov, 1);
-}
-
/*
* Write a vector to a connection w/ timeout
* Note: can modify the iovec.
*/
ssize_t
-fetch_writev(conn_t *conn, struct iovec *iov, int iovcnt)
+fetch_write(conn_t *conn, const void *buf, size_t len)
{
struct timeval now, timeout, waittv;
fd_set writefds;
ssize_t wlen, total;
int r;
+#ifndef MSG_NOSIGNAL
+ static int killed_sigpipe;
+#endif
+
+#ifndef MSG_NOSIGNAL
+ if (!killed_sigpipe) {
+ signal(SIGPIPE, SIG_IGN);
+ killed_sigpipe = 1;
+ }
+#endif
+
if (fetchTimeout) {
FD_ZERO(&writefds);
@@ -561,7 +647,7 @@
}
total = 0;
- while (iovcnt > 0) {
+ while (len) {
while (fetchTimeout && !FD_ISSET(conn->sd, &writefds)) {
FD_SET(conn->sd, &writefds);
gettimeofday(&now, NULL);
@@ -587,11 +673,14 @@
errno = 0;
#ifdef WITH_SSL
if (conn->ssl != NULL)
- wlen = SSL_write(conn->ssl,
- iov->iov_base, iov->iov_len);
+ wlen = SSL_write(conn->ssl, buf, len);
else
#endif
- wlen = writev(conn->sd, iov, iovcnt);
+#ifndef MSG_NOSIGNAL
+ wlen = send(conn->sd, buf, len, 0);
+#else
+ wlen = send(conn->sd, buf, len, MSG_NOSIGNAL);
+#endif
if (wlen == 0) {
/* we consider a short write a failure */
errno = EPIPE;
@@ -604,44 +693,14 @@
return (-1);
}
total += wlen;
- while (iovcnt > 0 && wlen >= (ssize_t)iov->iov_len) {
- wlen -= iov->iov_len;
- iov++;
- iovcnt--;
- }
- if (iovcnt > 0) {
- iov->iov_len -= wlen;
- iov->iov_base = DECONST(char *, iov->iov_base) + wlen;
Home |
Main Index |
Thread Index |
Old Index