Mercurial > dropbear
comparison packet.c @ 1026:59a1146e8b9d fastopen
generalise write iovec handling
author | Matt Johnston <matt@ucc.asn.au> |
---|---|
date | Wed, 18 Feb 2015 23:02:49 +0800 |
parents | 02baa0b334e8 |
children | daf21fd50abf |
comparison
equal
deleted
inserted
replaced
1025:02baa0b334e8 | 1026:59a1146e8b9d |
---|---|
50 #ifndef DISABLE_ZLIB | 50 #ifndef DISABLE_ZLIB |
51 static buffer* buf_decompress(buffer* buf, unsigned int len); | 51 static buffer* buf_decompress(buffer* buf, unsigned int len); |
52 static void buf_compress(buffer * dest, buffer * src, unsigned int len); | 52 static void buf_compress(buffer * dest, buffer * src, unsigned int len); |
53 #endif | 53 #endif |
54 | 54 |
55 #if 0 | 55 struct iovec * packet_queue_to_iovec(struct Queue *queue, int *ret_iov_count) { |
56 struct iovec * dropbear_queue_to_iovec(struct Queue *queue) { | |
57 | |
58 struct iovec *iov = NULL; | 56 struct iovec *iov = NULL; |
59 struct Link *l; | 57 struct Link *l; |
60 int iov_max_count; | 58 unsigned int i, packet_type; |
59 int len; | |
60 buffer *writebuf; | |
61 | 61 |
62 #ifndef IOV_MAX | 62 #ifndef IOV_MAX |
63 #define IOV_MAX UIO_MAXIOV | 63 #define IOV_MAX UIO_MAXIOV |
64 #endif | 64 #endif |
65 | 65 |
66 #error incomplete | 66 *ret_iov_count = MIN(queue->count, IOV_MAX); |
67 | 67 |
68 } | 68 iov = m_malloc(sizeof(*iov) * *ret_iov_count); |
69 | 69 for (l = queue->head, i = 0; l; l = l->link, i++) |
70 void dropbear_queue_consume(struct Queue *queue, ssize_t written) { | |
71 | |
72 } | |
73 #endif | |
74 | |
75 /* non-blocking function writing out a current encrypted packet */ | |
76 void write_packet() { | |
77 | |
78 ssize_t written; | |
79 int len; | |
80 buffer * writebuf = NULL; | |
81 unsigned packet_type; | |
82 #ifdef HAVE_WRITEV | |
83 struct iovec *iov = NULL; | |
84 int i; | |
85 struct Link *l; | |
86 int iov_max_count; | |
87 #endif | |
88 | |
89 TRACE2(("enter write_packet")) | |
90 dropbear_assert(!isempty(&ses.writequeue)); | |
91 | |
92 #if defined(HAVE_WRITEV) && (defined(IOV_MAX) || defined(UIO_MAXIOV)) | |
93 | |
94 #ifndef IOV_MAX | |
95 #define IOV_MAX UIO_MAXIOV | |
96 #endif | |
97 | |
98 /* Make sure the size of the iov is below the maximum allowed by the OS. */ | |
99 iov_max_count = ses.writequeue.count; | |
100 if (iov_max_count > IOV_MAX) | |
101 { | |
102 iov_max_count = IOV_MAX; | |
103 } | |
104 | |
105 iov = m_malloc(sizeof(*iov) * iov_max_count); | |
106 for (l = ses.writequeue.head, i = 0; l; l = l->link, i++) | |
107 { | 70 { |
108 writebuf = (buffer*)l->item; | 71 writebuf = (buffer*)l->item; |
109 packet_type = writebuf->data[writebuf->len-1]; | 72 packet_type = writebuf->data[writebuf->len-1]; |
110 len = writebuf->len - 1 - writebuf->pos; | 73 len = writebuf->len - 1 - writebuf->pos; |
111 dropbear_assert(len > 0); | 74 dropbear_assert(len > 0); |
112 TRACE2(("write_packet writev #%d type %d len %d/%d", i, packet_type, | 75 TRACE2(("write_packet writev #%d type %d len %d/%d", i, packet_type, |
113 len, writebuf->len-1)) | 76 len, writebuf->len-1)) |
114 iov[i].iov_base = buf_getptr(writebuf, len); | 77 iov[i].iov_base = buf_getptr(writebuf, len); |
115 iov[i].iov_len = len; | 78 iov[i].iov_len = len; |
116 } | 79 } |
117 /* This may return EAGAIN. The main loop sometimes | 80 |
118 calls write_packet() without bothering to test with select() since | 81 return iov; |
119 it's likely to be necessary */ | 82 } |
120 written = writev(ses.sock_out, iov, iov_max_count); | 83 |
121 if (written < 0) { | 84 void packet_queue_consume(struct Queue *queue, ssize_t written) { |
122 if (errno == EINTR || errno == EAGAIN) { | 85 buffer *writebuf; |
123 m_free(iov); | 86 int len; |
124 TRACE2(("leave write_packet: EINTR")) | |
125 return; | |
126 } else { | |
127 dropbear_exit("Error writing: %s", strerror(errno)); | |
128 } | |
129 } | |
130 | |
131 if (written == 0) { | |
132 ses.remoteclosed(); | |
133 } | |
134 | |
135 while (written > 0) { | 87 while (written > 0) { |
136 writebuf = (buffer*)examine(&ses.writequeue); | 88 writebuf = (buffer*)examine(queue); |
137 len = writebuf->len - 1 - writebuf->pos; | 89 len = writebuf->len - 1 - writebuf->pos; |
138 if (len > written) { | 90 if (len > written) { |
139 /* partial buffer write */ | 91 /* partial buffer write */ |
140 buf_incrpos(writebuf, written); | 92 buf_incrpos(writebuf, written); |
141 written = 0; | 93 written = 0; |
142 } else { | 94 } else { |
143 written -= len; | 95 written -= len; |
144 dequeue(&ses.writequeue); | 96 dequeue(queue); |
145 buf_free(writebuf); | 97 buf_free(writebuf); |
146 } | 98 } |
147 } | 99 } |
148 | 100 } |
101 | |
102 /* non-blocking function writing out a current encrypted packet */ | |
103 void write_packet() { | |
104 | |
105 ssize_t written; | |
106 int len; | |
107 buffer * writebuf = NULL; | |
108 unsigned packet_type; | |
109 #ifdef HAVE_WRITEV | |
110 struct iovec *iov = NULL; | |
111 int i; | |
112 struct Link *l; | |
113 int iov_count; | |
114 #endif | |
115 | |
116 TRACE2(("enter write_packet")) | |
117 dropbear_assert(!isempty(&ses.writequeue)); | |
118 | |
119 #if defined(HAVE_WRITEV) && (defined(IOV_MAX) || defined(UIO_MAXIOV)) | |
120 | |
121 iov = packet_queue_to_iovec(&ses.writequeue, &iov_count); | |
122 /* This may return EAGAIN. The main loop sometimes | |
123 calls write_packet() without bothering to test with select() since | |
124 it's likely to be necessary */ | |
125 written = writev(ses.sock_out, iov, iov_count); | |
126 if (written < 0) { | |
127 if (errno == EINTR || errno == EAGAIN) { | |
128 TRACE2(("leave write_packet: EINTR")) | |
129 m_free(iov); | |
130 return; | |
131 } else { | |
132 dropbear_exit("Error writing: %s", strerror(errno)); | |
133 } | |
134 } | |
149 m_free(iov); | 135 m_free(iov); |
136 | |
137 packet_queue_consume(&ses.writequeue, written); | |
138 | |
139 if (written == 0) { | |
140 ses.remoteclosed(); | |
141 } | |
142 | |
150 #else /* No writev () */ | 143 #else /* No writev () */ |
151 /* Get the next buffer in the queue of encrypted packets to write*/ | 144 /* Get the next buffer in the queue of encrypted packets to write*/ |
152 writebuf = (buffer*)examine(&ses.writequeue); | 145 writebuf = (buffer*)examine(&ses.writequeue); |
153 | 146 |
154 /* The last byte of the buffer is not to be transmitted, but is | 147 /* The last byte of the buffer is not to be transmitted, but is |