diff options
Diffstat (limited to 'src/transport/tcp_server_mst_legacy.c')
-rw-r--r-- | src/transport/tcp_server_mst_legacy.c | 323 |
1 files changed, 162 insertions, 161 deletions
diff --git a/src/transport/tcp_server_mst_legacy.c b/src/transport/tcp_server_mst_legacy.c index 03c02ff75..b27590a6f 100644 --- a/src/transport/tcp_server_mst_legacy.c +++ b/src/transport/tcp_server_mst_legacy.c | |||
@@ -38,7 +38,8 @@ | |||
38 | /** | 38 | /** |
39 | * Handle to a message stream tokenizer. | 39 | * Handle to a message stream tokenizer. |
40 | */ | 40 | */ |
41 | struct GNUNET_SERVER_MessageStreamTokenizer { | 41 | struct GNUNET_SERVER_MessageStreamTokenizer |
42 | { | ||
42 | /** | 43 | /** |
43 | * Function to call on completed messages. | 44 | * Function to call on completed messages. |
44 | */ | 45 | */ |
@@ -80,13 +81,13 @@ struct GNUNET_SERVER_MessageStreamTokenizer { | |||
80 | * @return handle to tokenizer | 81 | * @return handle to tokenizer |
81 | */ | 82 | */ |
82 | struct GNUNET_SERVER_MessageStreamTokenizer * | 83 | struct GNUNET_SERVER_MessageStreamTokenizer * |
83 | GNUNET_SERVER_mst_create(GNUNET_SERVER_MessageTokenizerCallback cb, | 84 | GNUNET_SERVER_mst_create (GNUNET_SERVER_MessageTokenizerCallback cb, |
84 | void *cb_cls) | 85 | void *cb_cls) |
85 | { | 86 | { |
86 | struct GNUNET_SERVER_MessageStreamTokenizer *ret; | 87 | struct GNUNET_SERVER_MessageStreamTokenizer *ret; |
87 | 88 | ||
88 | ret = GNUNET_new(struct GNUNET_SERVER_MessageStreamTokenizer); | 89 | ret = GNUNET_new (struct GNUNET_SERVER_MessageStreamTokenizer); |
89 | ret->hdr = GNUNET_malloc(GNUNET_MIN_MESSAGE_SIZE); | 90 | ret->hdr = GNUNET_malloc (GNUNET_MIN_MESSAGE_SIZE); |
90 | ret->curr_buf = GNUNET_MIN_MESSAGE_SIZE; | 91 | ret->curr_buf = GNUNET_MIN_MESSAGE_SIZE; |
91 | ret->cb = cb; | 92 | ret->cb = cb; |
92 | ret->cb_cls = cb_cls; | 93 | ret->cb_cls = cb_cls; |
@@ -110,10 +111,10 @@ GNUNET_SERVER_mst_create(GNUNET_SERVER_MessageTokenizerCallback cb, | |||
110 | * #GNUNET_SYSERR if the data stream is corrupt | 111 | * #GNUNET_SYSERR if the data stream is corrupt |
111 | */ | 112 | */ |
112 | int | 113 | int |
113 | GNUNET_SERVER_mst_receive(struct GNUNET_SERVER_MessageStreamTokenizer *mst, | 114 | GNUNET_SERVER_mst_receive (struct GNUNET_SERVER_MessageStreamTokenizer *mst, |
114 | void *client_identity, | 115 | void *client_identity, |
115 | const char *buf, size_t size, | 116 | const char *buf, size_t size, |
116 | int purge, int one_shot) | 117 | int purge, int one_shot) |
117 | { | 118 | { |
118 | const struct GNUNET_MessageHeader *hdr; | 119 | const struct GNUNET_MessageHeader *hdr; |
119 | size_t delta; | 120 | size_t delta; |
@@ -123,170 +124,170 @@ GNUNET_SERVER_mst_receive(struct GNUNET_SERVER_MessageStreamTokenizer *mst, | |||
123 | unsigned long offset; | 124 | unsigned long offset; |
124 | int ret; | 125 | int ret; |
125 | 126 | ||
126 | GNUNET_assert(mst->off <= mst->pos); | 127 | GNUNET_assert (mst->off <= mst->pos); |
127 | GNUNET_assert(mst->pos <= mst->curr_buf); | 128 | GNUNET_assert (mst->pos <= mst->curr_buf); |
128 | LOG(GNUNET_ERROR_TYPE_DEBUG, | 129 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
129 | "Server-mst receives %u bytes with %u bytes already in private buffer\n", | 130 | "Server-mst receives %u bytes with %u bytes already in private buffer\n", |
130 | (unsigned int)size, (unsigned int)(mst->pos - mst->off)); | 131 | (unsigned int) size, (unsigned int) (mst->pos - mst->off)); |
131 | ret = GNUNET_OK; | 132 | ret = GNUNET_OK; |
132 | ibuf = (char *)mst->hdr; | 133 | ibuf = (char *) mst->hdr; |
133 | while (mst->pos > 0) | 134 | while (mst->pos > 0) |
134 | { | 135 | { |
135 | do_align: | 136 | do_align: |
136 | GNUNET_assert(mst->pos >= mst->off); | 137 | GNUNET_assert (mst->pos >= mst->off); |
137 | if ((mst->curr_buf - mst->off < sizeof(struct GNUNET_MessageHeader)) || | 138 | if ((mst->curr_buf - mst->off < sizeof(struct GNUNET_MessageHeader)) || |
138 | (0 != (mst->off % ALIGN_FACTOR))) | 139 | (0 != (mst->off % ALIGN_FACTOR))) |
139 | { | 140 | { |
140 | /* need to align or need more space */ | 141 | /* need to align or need more space */ |
141 | mst->pos -= mst->off; | 142 | mst->pos -= mst->off; |
142 | memmove(ibuf, &ibuf[mst->off], mst->pos); | 143 | memmove (ibuf, &ibuf[mst->off], mst->pos); |
143 | mst->off = 0; | 144 | mst->off = 0; |
144 | } | 145 | } |
145 | if (mst->pos - mst->off < sizeof(struct GNUNET_MessageHeader)) | 146 | if (mst->pos - mst->off < sizeof(struct GNUNET_MessageHeader)) |
146 | { | 147 | { |
147 | delta = | 148 | delta = |
148 | GNUNET_MIN(sizeof(struct GNUNET_MessageHeader) - | 149 | GNUNET_MIN (sizeof(struct GNUNET_MessageHeader) |
149 | (mst->pos - mst->off), size); | 150 | - (mst->pos - mst->off), size); |
150 | GNUNET_memcpy(&ibuf[mst->pos], buf, delta); | 151 | GNUNET_memcpy (&ibuf[mst->pos], buf, delta); |
151 | mst->pos += delta; | 152 | mst->pos += delta; |
152 | buf += delta; | 153 | buf += delta; |
153 | size -= delta; | 154 | size -= delta; |
154 | } | 155 | } |
155 | if (mst->pos - mst->off < sizeof(struct GNUNET_MessageHeader)) | 156 | if (mst->pos - mst->off < sizeof(struct GNUNET_MessageHeader)) |
156 | { | 157 | { |
157 | if (purge) | 158 | if (purge) |
158 | { | 159 | { |
159 | mst->off = 0; | 160 | mst->off = 0; |
160 | mst->pos = 0; | 161 | mst->pos = 0; |
161 | } | 162 | } |
162 | return GNUNET_OK; | 163 | return GNUNET_OK; |
163 | } | 164 | } |
164 | hdr = (const struct GNUNET_MessageHeader *)&ibuf[mst->off]; | 165 | hdr = (const struct GNUNET_MessageHeader *) &ibuf[mst->off]; |
165 | want = ntohs(hdr->size); | 166 | want = ntohs (hdr->size); |
167 | if (want < sizeof(struct GNUNET_MessageHeader)) | ||
168 | { | ||
169 | GNUNET_break_op (0); | ||
170 | return GNUNET_SYSERR; | ||
171 | } | ||
172 | if ((mst->curr_buf - mst->off < want) && | ||
173 | (mst->off > 0)) | ||
174 | { | ||
175 | /* can get more space by moving */ | ||
176 | mst->pos -= mst->off; | ||
177 | memmove (ibuf, &ibuf[mst->off], mst->pos); | ||
178 | mst->off = 0; | ||
179 | } | ||
180 | if (mst->curr_buf < want) | ||
181 | { | ||
182 | /* need to get more space by growing buffer */ | ||
183 | GNUNET_assert (0 == mst->off); | ||
184 | mst->hdr = GNUNET_realloc (mst->hdr, want); | ||
185 | ibuf = (char *) mst->hdr; | ||
186 | mst->curr_buf = want; | ||
187 | } | ||
188 | hdr = (const struct GNUNET_MessageHeader *) &ibuf[mst->off]; | ||
189 | if (mst->pos - mst->off < want) | ||
190 | { | ||
191 | delta = GNUNET_MIN (want - (mst->pos - mst->off), size); | ||
192 | GNUNET_assert (mst->pos + delta <= mst->curr_buf); | ||
193 | GNUNET_memcpy (&ibuf[mst->pos], buf, delta); | ||
194 | mst->pos += delta; | ||
195 | buf += delta; | ||
196 | size -= delta; | ||
197 | } | ||
198 | if (mst->pos - mst->off < want) | ||
199 | { | ||
200 | if (purge) | ||
201 | { | ||
202 | mst->off = 0; | ||
203 | mst->pos = 0; | ||
204 | } | ||
205 | return GNUNET_OK; | ||
206 | } | ||
207 | if (one_shot == GNUNET_SYSERR) | ||
208 | { | ||
209 | /* cannot call callback again, but return value saying that | ||
210 | * we have another full message in the buffer */ | ||
211 | ret = GNUNET_NO; | ||
212 | goto copy; | ||
213 | } | ||
214 | if (one_shot == GNUNET_YES) | ||
215 | one_shot = GNUNET_SYSERR; | ||
216 | mst->off += want; | ||
217 | if (GNUNET_SYSERR == mst->cb (mst->cb_cls, client_identity, hdr)) | ||
218 | return GNUNET_SYSERR; | ||
219 | if (mst->off == mst->pos) | ||
220 | { | ||
221 | /* reset to beginning of buffer, it's free right now! */ | ||
222 | mst->off = 0; | ||
223 | mst->pos = 0; | ||
224 | } | ||
225 | } | ||
226 | GNUNET_assert (0 == mst->pos); | ||
227 | while (size > 0) | ||
228 | { | ||
229 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
230 | "Server-mst has %u bytes left in inbound buffer\n", | ||
231 | (unsigned int) size); | ||
232 | if (size < sizeof(struct GNUNET_MessageHeader)) | ||
233 | break; | ||
234 | offset = (unsigned long) buf; | ||
235 | need_align = (0 != (offset % ALIGN_FACTOR)) ? GNUNET_YES : GNUNET_NO; | ||
236 | if (GNUNET_NO == need_align) | ||
237 | { | ||
238 | /* can try to do zero-copy and process directly from original buffer */ | ||
239 | hdr = (const struct GNUNET_MessageHeader *) buf; | ||
240 | want = ntohs (hdr->size); | ||
166 | if (want < sizeof(struct GNUNET_MessageHeader)) | 241 | if (want < sizeof(struct GNUNET_MessageHeader)) |
167 | { | 242 | { |
168 | GNUNET_break_op(0); | 243 | GNUNET_break_op (0); |
169 | return GNUNET_SYSERR; | 244 | mst->off = 0; |
170 | } | 245 | return GNUNET_SYSERR; |
171 | if ((mst->curr_buf - mst->off < want) && | 246 | } |
172 | (mst->off > 0)) | 247 | if (size < want) |
173 | { | 248 | break; /* or not: buffer incomplete, so copy to private buffer... */ |
174 | /* can get more space by moving */ | ||
175 | mst->pos -= mst->off; | ||
176 | memmove(ibuf, &ibuf[mst->off], mst->pos); | ||
177 | mst->off = 0; | ||
178 | } | ||
179 | if (mst->curr_buf < want) | ||
180 | { | ||
181 | /* need to get more space by growing buffer */ | ||
182 | GNUNET_assert(0 == mst->off); | ||
183 | mst->hdr = GNUNET_realloc(mst->hdr, want); | ||
184 | ibuf = (char *)mst->hdr; | ||
185 | mst->curr_buf = want; | ||
186 | } | ||
187 | hdr = (const struct GNUNET_MessageHeader *)&ibuf[mst->off]; | ||
188 | if (mst->pos - mst->off < want) | ||
189 | { | ||
190 | delta = GNUNET_MIN(want - (mst->pos - mst->off), size); | ||
191 | GNUNET_assert(mst->pos + delta <= mst->curr_buf); | ||
192 | GNUNET_memcpy(&ibuf[mst->pos], buf, delta); | ||
193 | mst->pos += delta; | ||
194 | buf += delta; | ||
195 | size -= delta; | ||
196 | } | ||
197 | if (mst->pos - mst->off < want) | ||
198 | { | ||
199 | if (purge) | ||
200 | { | ||
201 | mst->off = 0; | ||
202 | mst->pos = 0; | ||
203 | } | ||
204 | return GNUNET_OK; | ||
205 | } | ||
206 | if (one_shot == GNUNET_SYSERR) | 249 | if (one_shot == GNUNET_SYSERR) |
207 | { | 250 | { |
208 | /* cannot call callback again, but return value saying that | 251 | /* cannot call callback again, but return value saying that |
209 | * we have another full message in the buffer */ | 252 | * we have another full message in the buffer */ |
210 | ret = GNUNET_NO; | 253 | ret = GNUNET_NO; |
211 | goto copy; | 254 | goto copy; |
212 | } | 255 | } |
213 | if (one_shot == GNUNET_YES) | 256 | if (one_shot == GNUNET_YES) |
214 | one_shot = GNUNET_SYSERR; | 257 | one_shot = GNUNET_SYSERR; |
215 | mst->off += want; | 258 | if (GNUNET_SYSERR == mst->cb (mst->cb_cls, client_identity, hdr)) |
216 | if (GNUNET_SYSERR == mst->cb(mst->cb_cls, client_identity, hdr)) | ||
217 | return GNUNET_SYSERR; | 259 | return GNUNET_SYSERR; |
218 | if (mst->off == mst->pos) | 260 | buf += want; |
219 | { | 261 | size -= want; |
220 | /* reset to beginning of buffer, it's free right now! */ | ||
221 | mst->off = 0; | ||
222 | mst->pos = 0; | ||
223 | } | ||
224 | } | 262 | } |
225 | GNUNET_assert(0 == mst->pos); | 263 | else |
226 | while (size > 0) | ||
227 | { | 264 | { |
228 | LOG(GNUNET_ERROR_TYPE_DEBUG, | 265 | /* need to copy to private buffer to align; |
229 | "Server-mst has %u bytes left in inbound buffer\n", | 266 | * yes, we go a bit more spagetti than usual here */ |
230 | (unsigned int)size); | 267 | goto do_align; |
231 | if (size < sizeof(struct GNUNET_MessageHeader)) | ||
232 | break; | ||
233 | offset = (unsigned long)buf; | ||
234 | need_align = (0 != (offset % ALIGN_FACTOR)) ? GNUNET_YES : GNUNET_NO; | ||
235 | if (GNUNET_NO == need_align) | ||
236 | { | ||
237 | /* can try to do zero-copy and process directly from original buffer */ | ||
238 | hdr = (const struct GNUNET_MessageHeader *)buf; | ||
239 | want = ntohs(hdr->size); | ||
240 | if (want < sizeof(struct GNUNET_MessageHeader)) | ||
241 | { | ||
242 | GNUNET_break_op(0); | ||
243 | mst->off = 0; | ||
244 | return GNUNET_SYSERR; | ||
245 | } | ||
246 | if (size < want) | ||
247 | break; /* or not: buffer incomplete, so copy to private buffer... */ | ||
248 | if (one_shot == GNUNET_SYSERR) | ||
249 | { | ||
250 | /* cannot call callback again, but return value saying that | ||
251 | * we have another full message in the buffer */ | ||
252 | ret = GNUNET_NO; | ||
253 | goto copy; | ||
254 | } | ||
255 | if (one_shot == GNUNET_YES) | ||
256 | one_shot = GNUNET_SYSERR; | ||
257 | if (GNUNET_SYSERR == mst->cb(mst->cb_cls, client_identity, hdr)) | ||
258 | return GNUNET_SYSERR; | ||
259 | buf += want; | ||
260 | size -= want; | ||
261 | } | ||
262 | else | ||
263 | { | ||
264 | /* need to copy to private buffer to align; | ||
265 | * yes, we go a bit more spagetti than usual here */ | ||
266 | goto do_align; | ||
267 | } | ||
268 | } | 268 | } |
269 | } | ||
269 | copy: | 270 | copy: |
270 | if ((size > 0) && (!purge)) | 271 | if ((size > 0) && (! purge)) |
272 | { | ||
273 | if (size + mst->pos > mst->curr_buf) | ||
271 | { | 274 | { |
272 | if (size + mst->pos > mst->curr_buf) | 275 | mst->hdr = GNUNET_realloc (mst->hdr, size + mst->pos); |
273 | { | 276 | ibuf = (char *) mst->hdr; |
274 | mst->hdr = GNUNET_realloc(mst->hdr, size + mst->pos); | 277 | mst->curr_buf = size + mst->pos; |
275 | ibuf = (char *)mst->hdr; | ||
276 | mst->curr_buf = size + mst->pos; | ||
277 | } | ||
278 | GNUNET_assert(size + mst->pos <= mst->curr_buf); | ||
279 | GNUNET_memcpy(&ibuf[mst->pos], buf, size); | ||
280 | mst->pos += size; | ||
281 | } | 278 | } |
279 | GNUNET_assert (size + mst->pos <= mst->curr_buf); | ||
280 | GNUNET_memcpy (&ibuf[mst->pos], buf, size); | ||
281 | mst->pos += size; | ||
282 | } | ||
282 | if (purge) | 283 | if (purge) |
283 | { | 284 | { |
284 | mst->off = 0; | 285 | mst->off = 0; |
285 | mst->pos = 0; | 286 | mst->pos = 0; |
286 | } | 287 | } |
287 | LOG(GNUNET_ERROR_TYPE_DEBUG, | 288 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
288 | "Server-mst leaves %u bytes in private buffer\n", | 289 | "Server-mst leaves %u bytes in private buffer\n", |
289 | (unsigned int)(mst->pos - mst->off)); | 290 | (unsigned int) (mst->pos - mst->off)); |
290 | return ret; | 291 | return ret; |
291 | } | 292 | } |
292 | 293 | ||
@@ -297,10 +298,10 @@ copy: | |||
297 | * @param mst tokenizer to destroy | 298 | * @param mst tokenizer to destroy |
298 | */ | 299 | */ |
299 | void | 300 | void |
300 | GNUNET_SERVER_mst_destroy(struct GNUNET_SERVER_MessageStreamTokenizer *mst) | 301 | GNUNET_SERVER_mst_destroy (struct GNUNET_SERVER_MessageStreamTokenizer *mst) |
301 | { | 302 | { |
302 | GNUNET_free(mst->hdr); | 303 | GNUNET_free (mst->hdr); |
303 | GNUNET_free(mst); | 304 | GNUNET_free (mst); |
304 | } | 305 | } |
305 | 306 | ||
306 | 307 | ||