summaryrefslogtreecommitdiffhomepage
path: root/packet.c
diff options
context:
space:
mode:
Diffstat (limited to 'packet.c')
-rw-r--r--packet.c39
1 files changed, 27 insertions, 12 deletions
diff --git a/packet.c b/packet.c
index 42bcc99..19b5759 100644
--- a/packet.c
+++ b/packet.c
@@ -58,8 +58,13 @@ void write_packet() {
ssize_t written;
#ifdef HAVE_WRITEV
- struct iovec *iov = NULL;
- int iov_count;
+ /* 50 is somewhat arbitrary */
+ unsigned int iov_count = 50;
+ struct iovec iov[50];
+#else
+ int len;
+ buffer* writebuf;
+ int packet_type;
#endif
TRACE2(("enter write_packet"))
@@ -67,7 +72,7 @@ void write_packet() {
#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
calls write_packet() without bothering to test with select() since
it's likely to be necessary */
@@ -75,15 +80,14 @@ void write_packet() {
if (written < 0) {
if (errno == EINTR || errno == EAGAIN) {
TRACE2(("leave write_packet: EINTR"))
- m_free(iov);
return;
} else {
dropbear_exit("Error writing: %s", strerror(errno));
}
}
- m_free(iov);
packet_queue_consume(&ses.writequeue, written);
+ ses.writequeue_len -= written;
if (written == 0) {
ses.remoteclosed();
@@ -97,6 +101,8 @@ void write_packet() {
* a cleartext packet_type indicator */
packet_type = writebuf->data[writebuf->len-1];
len = writebuf->len - 1 - writebuf->pos;
+ TRACE2(("write_packet type %d len %d/%d", packet_type,
+ len, writebuf->len-1))
dropbear_assert(len > 0);
/* Try to write as much as possible */
written = write(ses.sock_out, buf_getptr(writebuf, len), len);
@@ -114,6 +120,8 @@ void write_packet() {
ses.remoteclosed();
}
+ ses.writequeue_len -= written;
+
if (written == len) {
/* We've finished with the packet, free it */
dequeue(&ses.writequeue);
@@ -571,15 +579,12 @@ void encrypt_packet() {
/* stick the MAC on it */
buf_putbytes(writebuf, mac_bytes, mac_size);
- /* The last byte of the buffer stores the cleartext packet_type. It is not
- * transmitted but is used for transmit timeout purposes */
- buf_putbyte(writebuf, packet_type);
- /* enqueue the packet for sending. It will get freed after transmission. */
- buf_setpos(writebuf, 0);
- enqueue(&ses.writequeue, (void*)writebuf);
-
/* Update counts */
ses.kexstate.datatrans += writebuf->len;
+
+ writebuf_enqueue(writebuf, packet_type);
+
+ /* Update counts */
ses.transseq++;
now = monotonic_now();
@@ -597,6 +602,16 @@ void encrypt_packet() {
TRACE2(("leave encrypt_packet()"))
}
+void writebuf_enqueue(buffer * writebuf, unsigned char packet_type) {
+ /* The last byte of the buffer stores the cleartext packet_type. It is not
+ * transmitted but is used for transmit timeout purposes */
+ buf_putbyte(writebuf, packet_type);
+ /* enqueue the packet for sending. It will get freed after transmission. */
+ buf_setpos(writebuf, 0);
+ enqueue(&ses.writequeue, (void*)writebuf);
+ ses.writequeue_len += writebuf->len-1;
+}
+
/* Create the packet mac, and append H(seqno|clearbuf) to the output */
/* output_mac must have ses.keys->trans.algo_mac->hashsize bytes. */