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
This commit is contained in:
Dag-Erling Smørgrav 2002-10-27 16:11:21 +00:00
parent 9e913ebd0a
commit 2761348f78
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=106046
2 changed files with 38 additions and 7 deletions

View File

@ -453,6 +453,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;
@ -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);
}

View File

@ -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 *,