mirror of
https://github.com/clearml/dropbear
synced 2025-02-07 13:21:15 +00:00
avoid malloc for iovec
This commit is contained in:
parent
dce384668b
commit
20f9683ae0
@ -482,7 +482,7 @@ static void writechannel(struct Channel* channel, int fd, circbuffer *cbuf,
|
|||||||
|
|
||||||
if (written < 0) {
|
if (written < 0) {
|
||||||
if (errno != EINTR && errno != EAGAIN) {
|
if (errno != EINTR && errno != EAGAIN) {
|
||||||
TRACE(("errno %d len %d", errno, len))
|
TRACE(("errno %d", errno))
|
||||||
close_chan_fd(channel, fd, SHUT_WR);
|
close_chan_fd(channel, fd, SHUT_WR);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
17
netio.c
17
netio.c
@ -72,6 +72,7 @@ static void connect_try_next(struct dropbear_progress_connection *c) {
|
|||||||
int fastopen = 0;
|
int fastopen = 0;
|
||||||
#ifdef DROPBEAR_TCP_FAST_OPEN
|
#ifdef DROPBEAR_TCP_FAST_OPEN
|
||||||
struct msghdr message;
|
struct msghdr message;
|
||||||
|
struct iovec message;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
for (r = c->res_iter; r; r = r->ai_next)
|
for (r = c->res_iter; r; r = r->ai_next)
|
||||||
@ -99,8 +100,11 @@ static void connect_try_next(struct dropbear_progress_connection *c) {
|
|||||||
message.msg_namelen = r->ai_addrlen;
|
message.msg_namelen = r->ai_addrlen;
|
||||||
|
|
||||||
if (c->writequeue) {
|
if (c->writequeue) {
|
||||||
int iovlen; /* Linux msg_iovlen is a size_t */
|
/* 6 is arbitrary, enough to hold initial packets */
|
||||||
message.msg_iov = packet_queue_to_iovec(c->writequeue, &iovlen);
|
int iovlen = 6; /* Linux msg_iovlen is a size_t */
|
||||||
|
struct iov[6];
|
||||||
|
packet_queue_to_iovec(c->writequeue, iov, &iovlen);
|
||||||
|
message.msg_iov = &iov;
|
||||||
message.msg_iovlen = iovlen;
|
message.msg_iovlen = iovlen;
|
||||||
res = sendmsg(c->sock, &message, MSG_FASTOPEN);
|
res = sendmsg(c->sock, &message, MSG_FASTOPEN);
|
||||||
if (res < 0 && errno != EINPROGRESS) {
|
if (res < 0 && errno != EINPROGRESS) {
|
||||||
@ -114,7 +118,6 @@ static void connect_try_next(struct dropbear_progress_connection *c) {
|
|||||||
/* Set to NULL to avoid trying again */
|
/* Set to NULL to avoid trying again */
|
||||||
c->writequeue = NULL;
|
c->writequeue = NULL;
|
||||||
}
|
}
|
||||||
m_free(message.msg_iov);
|
|
||||||
packet_queue_consume(c->writequeue, res);
|
packet_queue_consume(c->writequeue, res);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -258,8 +261,7 @@ void connect_set_writequeue(struct dropbear_progress_connection *c, struct Queue
|
|||||||
c->writequeue = writequeue;
|
c->writequeue = writequeue;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct iovec * packet_queue_to_iovec(struct Queue *queue, int *ret_iov_count) {
|
void packet_queue_to_iovec(struct Queue *queue, struct iovec *iov, unsigned int *iov_count) {
|
||||||
struct iovec *iov = NULL;
|
|
||||||
struct Link *l;
|
struct Link *l;
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
int len;
|
int len;
|
||||||
@ -269,9 +271,8 @@ struct iovec * packet_queue_to_iovec(struct Queue *queue, int *ret_iov_count) {
|
|||||||
#define IOV_MAX UIO_MAXIOV
|
#define IOV_MAX UIO_MAXIOV
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
*ret_iov_count = MIN(queue->count, IOV_MAX);
|
*iov_count = MIN(MIN(queue->count, IOV_MAX), *iov_count);
|
||||||
|
|
||||||
iov = m_malloc(sizeof(*iov) * *ret_iov_count);
|
|
||||||
for (l = queue->head, i = 0; l; l = l->link, i++)
|
for (l = queue->head, i = 0; l; l = l->link, i++)
|
||||||
{
|
{
|
||||||
writebuf = (buffer*)l->item;
|
writebuf = (buffer*)l->item;
|
||||||
@ -282,8 +283,6 @@ struct iovec * packet_queue_to_iovec(struct Queue *queue, int *ret_iov_count) {
|
|||||||
iov[i].iov_base = buf_getptr(writebuf, len);
|
iov[i].iov_base = buf_getptr(writebuf, len);
|
||||||
iov[i].iov_len = len;
|
iov[i].iov_len = len;
|
||||||
}
|
}
|
||||||
|
|
||||||
return iov;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void packet_queue_consume(struct Queue *queue, ssize_t written) {
|
void packet_queue_consume(struct Queue *queue, ssize_t written) {
|
||||||
|
3
netio.h
3
netio.h
@ -44,7 +44,8 @@ void cancel_connect(struct dropbear_progress_connection *c);
|
|||||||
void connect_set_writequeue(struct dropbear_progress_connection *c, struct Queue *writequeue);
|
void connect_set_writequeue(struct dropbear_progress_connection *c, struct Queue *writequeue);
|
||||||
|
|
||||||
/* TODO: writev #ifdef guard */
|
/* TODO: writev #ifdef guard */
|
||||||
struct iovec * packet_queue_to_iovec(struct Queue *queue, int *ret_iov_count);
|
/* Fills out iov which contains iov_count slots, returning the number filled in iov_count */
|
||||||
|
void packet_queue_to_iovec(struct Queue *queue, struct iovec *iov, unsigned int *iov_count);
|
||||||
void packet_queue_consume(struct Queue *queue, ssize_t written);
|
void packet_queue_consume(struct Queue *queue, ssize_t written);
|
||||||
|
|
||||||
#ifdef DROPBEAR_TCP_FAST_OPEN
|
#ifdef DROPBEAR_TCP_FAST_OPEN
|
||||||
|
9
packet.c
9
packet.c
@ -58,8 +58,9 @@ void write_packet() {
|
|||||||
|
|
||||||
ssize_t written;
|
ssize_t written;
|
||||||
#ifdef HAVE_WRITEV
|
#ifdef HAVE_WRITEV
|
||||||
struct iovec *iov = NULL;
|
/* 50 is somewhat arbitrary */
|
||||||
int iov_count;
|
int iov_count = 50;
|
||||||
|
struct iovec iov[50];
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
TRACE2(("enter write_packet"))
|
TRACE2(("enter write_packet"))
|
||||||
@ -67,7 +68,7 @@ void write_packet() {
|
|||||||
|
|
||||||
#if defined(HAVE_WRITEV) && (defined(IOV_MAX) || defined(UIO_MAXIOV))
|
#if defined(HAVE_WRITEV) && (defined(IOV_MAX) || defined(UIO_MAXIOV))
|
||||||
|
|
||||||
iov = packet_queue_to_iovec(&ses.writequeue, &iov_count);
|
packet_queue_to_iovec(&ses.writequeue, iov, &iov_count);
|
||||||
/* This may return EAGAIN. The main loop sometimes
|
/* This may return EAGAIN. The main loop sometimes
|
||||||
calls write_packet() without bothering to test with select() since
|
calls write_packet() without bothering to test with select() since
|
||||||
it's likely to be necessary */
|
it's likely to be necessary */
|
||||||
@ -75,13 +76,11 @@ void write_packet() {
|
|||||||
if (written < 0) {
|
if (written < 0) {
|
||||||
if (errno == EINTR || errno == EAGAIN) {
|
if (errno == EINTR || errno == EAGAIN) {
|
||||||
TRACE2(("leave write_packet: EINTR"))
|
TRACE2(("leave write_packet: EINTR"))
|
||||||
m_free(iov);
|
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
dropbear_exit("Error writing: %s", strerror(errno));
|
dropbear_exit("Error writing: %s", strerror(errno));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
m_free(iov);
|
|
||||||
|
|
||||||
packet_queue_consume(&ses.writequeue, written);
|
packet_queue_consume(&ses.writequeue, written);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user