From 34e6c489c762ffd7ea3491b3cf85302c64a36b97 Mon Sep 17 00:00:00 2001 From: des Date: Sun, 27 Oct 2002 16:11:21 +0000 Subject: 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 --- lib/libfetch/common.c | 41 ++++++++++++++++++++++++++++++++++------- 1 file changed, 34 insertions(+), 7 deletions(-) (limited to 'lib/libfetch/common.c') 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); } -- cgit v1.1