summaryrefslogtreecommitdiffstats
path: root/lib/libfetch
diff options
context:
space:
mode:
authordes <des@FreeBSD.org>2002-10-27 16:11:21 +0000
committerdes <des@FreeBSD.org>2002-10-27 16:11:21 +0000
commit34e6c489c762ffd7ea3491b3cf85302c64a36b97 (patch)
treeeec6756c8581909e18114c1772d9c8ca0d67bbe0 /lib/libfetch
parente6f3037210bd2a8b2debfe2237120ff0c87b2566 (diff)
downloadFreeBSD-src-34e6c489c762ffd7ea3491b3cf85302c64a36b97.zip
FreeBSD-src-34e6c489c762ffd7ea3491b3cf85302c64a36b97.tar.gz
Introduce _fetch_writev(), which is the conn_t version of writev(2). In
the SSL case, it is no different from the old _fetch_write(), but in the non-SSL case it uses writev(2) to send the entire vector as a single packet (provided it can fit in one packet). Implement _fetch_write() and _fetch_putln() in terms of _fetch_writev(). This should improve performance in the non-SSL case (by reducing protocol overhead) and solve the problem where too-smart-for-their-own-good firewalls reject FTP packets that do not end in CRLF. PR: bin/44123 Submitted by: fenner
Diffstat (limited to 'lib/libfetch')
-rw-r--r--lib/libfetch/common.c41
-rw-r--r--lib/libfetch/common.h4
2 files changed, 38 insertions, 7 deletions
diff --git a/lib/libfetch/common.c b/lib/libfetch/common.c
index 48ac5d3..ab3f4ca 100644
--- a/lib/libfetch/common.c
+++ b/lib/libfetch/common.c
@@ -454,6 +454,20 @@ _fetch_getln(conn_t *conn)
ssize_t
_fetch_write(conn_t *conn, const char *buf, size_t len)
{
+ struct iovec iov;
+
+ iov.iov_base = (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)
+{
struct timeval now, timeout, wait;
fd_set writefds;
ssize_t wlen, total;
@@ -466,7 +480,7 @@ _fetch_write(conn_t *conn, const char *buf, size_t len)
}
total = 0;
- while (len > 0) {
+ while (iovcnt > 0) {
while (fetchTimeout && !FD_ISSET(conn->sd, &writefds)) {
FD_SET(conn->sd, &writefds);
gettimeofday(&now, NULL);
@@ -492,10 +506,11 @@ _fetch_write(conn_t *conn, const char *buf, size_t len)
errno = 0;
#ifdef WITH_SSL
if (conn->ssl != NULL)
- wlen = SSL_write(conn->ssl, buf, len);
+ wlen = SSL_write(conn->ssl,
+ iov->iov_base, iov->iov_len);
else
#endif
- wlen = write(conn->sd, buf, len);
+ wlen = writev(conn->sd, iov, iovcnt);
if (wlen == 0) {
/* we consider a short write a failure */
errno = EPIPE;
@@ -507,9 +522,17 @@ _fetch_write(conn_t *conn, const char *buf, size_t len)
continue;
return (-1);
}
- len -= wlen;
- buf += wlen;
total += wlen;
+ while (iovcnt > 0 && wlen > iov->iov_len) {
+ wlen -= iov->iov_len;
+ iov++;
+ iovcnt--;
+ }
+ if (iovcnt > 0) {
+ iov->iov_len -= wlen;
+ iov->iov_base += wlen;
+ wlen = 0;
+ }
}
return (total);
}
@@ -521,10 +544,14 @@ _fetch_write(conn_t *conn, const char *buf, size_t len)
int
_fetch_putln(conn_t *conn, const char *str, size_t len)
{
+ struct iovec iov[2];
DEBUG(fprintf(stderr, ">>> %s\n", str));
- if (_fetch_write(conn, str, len) == -1 ||
- _fetch_write(conn, ENDL, sizeof ENDL) == -1)
+ iov[0].iov_base = (char *)str;
+ iov[0].iov_len = len;
+ iov[1].iov_base = (char *)ENDL;
+ iov[1].iov_len = sizeof ENDL;
+ if (_fetch_writev(conn, iov, 2) == -1)
return (-1);
return (0);
}
diff --git a/lib/libfetch/common.h b/lib/libfetch/common.h
index 42f68a8..4b42bf2 100644
--- a/lib/libfetch/common.h
+++ b/lib/libfetch/common.h
@@ -68,6 +68,9 @@ struct fetcherr {
const char *string;
};
+/* for _fetch_writev */
+struct iovec;
+
void _fetch_seterr(struct fetcherr *, int);
void _fetch_syserr(void);
void _fetch_info(const char *, ...);
@@ -80,6 +83,7 @@ int _fetch_ssl(conn_t *, int);
ssize_t _fetch_read(conn_t *, char *, size_t);
int _fetch_getln(conn_t *);
ssize_t _fetch_write(conn_t *, const char *, size_t);
+ssize_t _fetch_writev(conn_t *, struct iovec *, int);
int _fetch_putln(conn_t *, const char *, size_t);
int _fetch_close(conn_t *);
int _fetch_add_entry(struct url_ent **, int *, int *,
OpenPOWER on IntegriCloud