summaryrefslogtreecommitdiff
path: root/src/transport/tcp_server_mst_legacy.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/transport/tcp_server_mst_legacy.c')
-rw-r--r--src/transport/tcp_server_mst_legacy.c323
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 */
41struct GNUNET_SERVER_MessageStreamTokenizer { 41struct 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 */
82struct GNUNET_SERVER_MessageStreamTokenizer * 83struct GNUNET_SERVER_MessageStreamTokenizer *
83GNUNET_SERVER_mst_create(GNUNET_SERVER_MessageTokenizerCallback cb, 84GNUNET_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 */
112int 113int
113GNUNET_SERVER_mst_receive(struct GNUNET_SERVER_MessageStreamTokenizer *mst, 114GNUNET_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 {
135do_align: 136do_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 }
269copy: 270copy:
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 */
299void 300void
300GNUNET_SERVER_mst_destroy(struct GNUNET_SERVER_MessageStreamTokenizer *mst) 301GNUNET_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