summaryrefslogtreecommitdiffstats
path: root/lib/libfetch/common.c
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/common.c
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/common.c')
-rw-r--r--lib/libfetch/common.c41
1 files changed, 34 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);
}
OpenPOWER on IntegriCloud