Mercurial > dropbear
comparison packet.c @ 728:f27058078d61
Try using writev() for writing packets out to tcp
author | Matt Johnston <matt@ucc.asn.au> |
---|---|
date | Sun, 31 Mar 2013 23:15:35 +0800 |
parents | f4232b65b316 |
children | 9a5438271556 |
comparison
equal
deleted
inserted
replaced
727:00bc3df3a9c3 | 728:f27058078d61 |
---|---|
53 | 53 |
54 int len, written; | 54 int len, written; |
55 buffer * writebuf = NULL; | 55 buffer * writebuf = NULL; |
56 time_t now; | 56 time_t now; |
57 unsigned packet_type; | 57 unsigned packet_type; |
58 int all_ignore = 1; | |
59 #ifdef HAVE_WRITEV | |
60 struct iovec *iov = NULL; | |
61 int i; | |
62 struct Link *l; | |
63 #endif | |
58 | 64 |
59 TRACE(("enter write_packet")) | 65 TRACE(("enter write_packet")) |
60 dropbear_assert(!isempty(&ses.writequeue)); | 66 dropbear_assert(!isempty(&ses.writequeue)); |
61 | 67 |
68 #ifdef HAVE_WRITEV | |
69 iov = m_malloc(sizeof(*iov) * ses.writequeue.count); | |
70 for (l = ses.writequeue.head, i = 0; l; l = l->link, i++) | |
71 { | |
72 writebuf = (buffer*)l->item; | |
73 packet_type = writebuf->data[writebuf->len-1]; | |
74 len = writebuf->len - 1 - writebuf->pos; | |
75 dropbear_assert(len > 0); | |
76 all_ignore &= (packet_type == SSH_MSG_IGNORE); | |
77 iov[i].iov_base = buf_getptr(writebuf, len); | |
78 iov[i].iov_len = len; | |
79 } | |
80 written = writev(ses.sock_out, iov, ses.writequeue.count); | |
81 if (written < 0) { | |
82 if (errno == EINTR) { | |
83 m_free(iov); | |
84 TRACE(("leave writepacket: EINTR")) | |
85 return; | |
86 } else { | |
87 dropbear_exit("Error writing"); | |
88 } | |
89 } | |
90 | |
91 if (written == 0) { | |
92 ses.remoteclosed(); | |
93 } | |
94 | |
95 while (written > 0) { | |
96 writebuf = (buffer*)examine(&ses.writequeue); | |
97 len = writebuf->len - 1 - writebuf->pos; | |
98 if (len > written) { | |
99 // partial buffer write | |
100 buf_incrpos(writebuf, written); | |
101 written = 0; | |
102 } else { | |
103 written -= len; | |
104 dequeue(&ses.writequeue); | |
105 buf_free(writebuf); | |
106 } | |
107 } | |
108 | |
109 m_free(iov); | |
110 | |
111 #else | |
62 /* Get the next buffer in the queue of encrypted packets to write*/ | 112 /* Get the next buffer in the queue of encrypted packets to write*/ |
63 writebuf = (buffer*)examine(&ses.writequeue); | 113 writebuf = (buffer*)examine(&ses.writequeue); |
64 | 114 |
65 /* The last byte of the buffer is not to be transmitted, but is | 115 /* The last byte of the buffer is not to be transmitted, but is |
66 * a cleartext packet_type indicator */ | 116 * a cleartext packet_type indicator */ |
76 return; | 126 return; |
77 } else { | 127 } else { |
78 dropbear_exit("Error writing"); | 128 dropbear_exit("Error writing"); |
79 } | 129 } |
80 } | 130 } |
81 | 131 all_ignore = (packet_type == SSH_MSG_IGNORE); |
82 now = time(NULL); | |
83 ses.last_trx_packet_time = now; | |
84 | |
85 if (packet_type != SSH_MSG_IGNORE) { | |
86 ses.last_packet_time = now; | |
87 } | |
88 | 132 |
89 if (written == 0) { | 133 if (written == 0) { |
90 ses.remoteclosed(); | 134 ses.remoteclosed(); |
91 } | 135 } |
92 | 136 |
96 buf_free(writebuf); | 140 buf_free(writebuf); |
97 writebuf = NULL; | 141 writebuf = NULL; |
98 } else { | 142 } else { |
99 /* More packet left to write, leave it in the queue for later */ | 143 /* More packet left to write, leave it in the queue for later */ |
100 buf_incrpos(writebuf, written); | 144 buf_incrpos(writebuf, written); |
145 } | |
146 | |
147 #endif | |
148 now = time(NULL); | |
149 ses.last_trx_packet_time = now; | |
150 | |
151 if (!all_ignore) { | |
152 ses.last_packet_time = now; | |
101 } | 153 } |
102 | 154 |
103 TRACE(("leave write_packet")) | 155 TRACE(("leave write_packet")) |
104 } | 156 } |
105 | 157 |