Mercurial > dropbear
comparison packet.c @ 1051:359fba4b1a49
merge tcp fastopen
author | Matt Johnston <matt@ucc.asn.au> |
---|---|
date | Sat, 28 Feb 2015 23:24:30 +0800 |
parents | 0da8ba489c23 |
children | 4d7b4c5526c5 |
comparison
equal
deleted
inserted
replaced
1045:31727a8abd4b | 1051:359fba4b1a49 |
---|---|
32 #include "kex.h" | 32 #include "kex.h" |
33 #include "dbrandom.h" | 33 #include "dbrandom.h" |
34 #include "service.h" | 34 #include "service.h" |
35 #include "auth.h" | 35 #include "auth.h" |
36 #include "channel.h" | 36 #include "channel.h" |
37 #include "netio.h" | |
37 | 38 |
38 static int read_packet_init(); | 39 static int read_packet_init(); |
39 static void make_mac(unsigned int seqno, const struct key_context_directional * key_state, | 40 static void make_mac(unsigned int seqno, const struct key_context_directional * key_state, |
40 buffer * clear_buf, unsigned int clear_len, | 41 buffer * clear_buf, unsigned int clear_len, |
41 unsigned char *output_mac); | 42 unsigned char *output_mac); |
53 #endif | 54 #endif |
54 | 55 |
55 /* non-blocking function writing out a current encrypted packet */ | 56 /* non-blocking function writing out a current encrypted packet */ |
56 void write_packet() { | 57 void write_packet() { |
57 | 58 |
58 int len, written; | 59 ssize_t written; |
59 buffer * writebuf = NULL; | |
60 unsigned packet_type; | |
61 #ifdef HAVE_WRITEV | 60 #ifdef HAVE_WRITEV |
62 struct iovec *iov = NULL; | 61 struct iovec *iov = NULL; |
63 int i; | 62 int iov_count; |
64 struct Link *l; | |
65 int iov_max_count; | |
66 #endif | 63 #endif |
67 | 64 |
68 TRACE2(("enter write_packet")) | 65 TRACE2(("enter write_packet")) |
69 dropbear_assert(!isempty(&ses.writequeue)); | 66 dropbear_assert(!isempty(&ses.writequeue)); |
70 | 67 |
71 #if defined(HAVE_WRITEV) && (defined(IOV_MAX) || defined(UIO_MAXIOV)) | 68 #if defined(HAVE_WRITEV) && (defined(IOV_MAX) || defined(UIO_MAXIOV)) |
72 | 69 |
73 #ifndef IOV_MAX | 70 iov = packet_queue_to_iovec(&ses.writequeue, &iov_count); |
74 #define IOV_MAX UIO_MAXIOV | |
75 #endif | |
76 | |
77 /* Make sure the size of the iov is below the maximum allowed by the OS. */ | |
78 iov_max_count = ses.writequeue.count; | |
79 if (iov_max_count > IOV_MAX) | |
80 { | |
81 iov_max_count = IOV_MAX; | |
82 } | |
83 | |
84 iov = m_malloc(sizeof(*iov) * iov_max_count); | |
85 for (l = ses.writequeue.head, i = 0; l; l = l->link, i++) | |
86 { | |
87 writebuf = (buffer*)l->item; | |
88 packet_type = writebuf->data[writebuf->len-1]; | |
89 len = writebuf->len - 1 - writebuf->pos; | |
90 dropbear_assert(len > 0); | |
91 TRACE2(("write_packet writev #%d type %d len %d/%d", i, packet_type, | |
92 len, writebuf->len-1)) | |
93 iov[i].iov_base = buf_getptr(writebuf, len); | |
94 iov[i].iov_len = len; | |
95 } | |
96 /* This may return EAGAIN. The main loop sometimes | 71 /* This may return EAGAIN. The main loop sometimes |
97 calls write_packet() without bothering to test with select() since | 72 calls write_packet() without bothering to test with select() since |
98 it's likely to be necessary */ | 73 it's likely to be necessary */ |
99 written = writev(ses.sock_out, iov, iov_max_count); | 74 written = writev(ses.sock_out, iov, iov_count); |
100 if (written < 0) { | 75 if (written < 0) { |
101 if (errno == EINTR || errno == EAGAIN) { | 76 if (errno == EINTR || errno == EAGAIN) { |
77 TRACE2(("leave write_packet: EINTR")) | |
102 m_free(iov); | 78 m_free(iov); |
103 TRACE2(("leave write_packet: EINTR")) | |
104 return; | 79 return; |
105 } else { | 80 } else { |
106 dropbear_exit("Error writing: %s", strerror(errno)); | 81 dropbear_exit("Error writing: %s", strerror(errno)); |
107 } | 82 } |
108 } | 83 } |
84 m_free(iov); | |
85 | |
86 packet_queue_consume(&ses.writequeue, written); | |
109 | 87 |
110 if (written == 0) { | 88 if (written == 0) { |
111 ses.remoteclosed(); | 89 ses.remoteclosed(); |
112 } | 90 } |
113 | 91 |
114 while (written > 0) { | |
115 writebuf = (buffer*)examine(&ses.writequeue); | |
116 len = writebuf->len - 1 - writebuf->pos; | |
117 if (len > written) { | |
118 /* partial buffer write */ | |
119 buf_incrpos(writebuf, written); | |
120 written = 0; | |
121 } else { | |
122 written -= len; | |
123 dequeue(&ses.writequeue); | |
124 buf_free(writebuf); | |
125 } | |
126 } | |
127 | |
128 m_free(iov); | |
129 #else /* No writev () */ | 92 #else /* No writev () */ |
130 /* Get the next buffer in the queue of encrypted packets to write*/ | 93 /* Get the next buffer in the queue of encrypted packets to write*/ |
131 writebuf = (buffer*)examine(&ses.writequeue); | 94 writebuf = (buffer*)examine(&ses.writequeue); |
132 | 95 |
133 /* The last byte of the buffer is not to be transmitted, but is | 96 /* The last byte of the buffer is not to be transmitted, but is |