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:
parent
9e913ebd0a
commit
2761348f78
@ -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);
|
||||
}
|
||||
|
@ -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 *,
|
||||
|
Loading…
x
Reference in New Issue
Block a user