aboutsummaryrefslogtreecommitdiff
path: root/src/util/server_mst.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/util/server_mst.c')
-rw-r--r--src/util/server_mst.c34
1 files changed, 26 insertions, 8 deletions
diff --git a/src/util/server_mst.c b/src/util/server_mst.c
index 53cae7035..8df4e4b7d 100644
--- a/src/util/server_mst.c
+++ b/src/util/server_mst.c
@@ -92,14 +92,17 @@ GNUNET_SERVER_mst_create (size_t maxbuf,
92 * @param size number of bytes in buf 92 * @param size number of bytes in buf
93 * @param purge should any excess bytes in the buffer be discarded 93 * @param purge should any excess bytes in the buffer be discarded
94 * (i.e. for packet-based services like UDP) 94 * (i.e. for packet-based services like UDP)
95 * @return GNUNET_NO if the data stream is corrupt 95 * @param one_shot only call callback once, keep rest of message in buffer
96 * GNUNET_SYSERR if the data stream is corrupt beyond repair 96 * @return GNUNET_OK if we are done processing (need more data)
97 * GNUNET_NO if one_shot was set and we have another message ready
98 * GNUNET_SYSERR if the data stream is corrupt
97 */ 99 */
98int 100int
99GNUNET_SERVER_mst_receive (struct GNUNET_SERVER_MessageStreamTokenizer *mst, 101GNUNET_SERVER_mst_receive (struct GNUNET_SERVER_MessageStreamTokenizer *mst,
100 const char *buf, 102 const char *buf,
101 size_t size, 103 size_t size,
102 int purge) 104 int purge,
105 int one_shot)
103{ 106{
104 const struct GNUNET_MessageHeader *hdr; 107 const struct GNUNET_MessageHeader *hdr;
105 size_t delta; 108 size_t delta;
@@ -107,7 +110,9 @@ GNUNET_SERVER_mst_receive (struct GNUNET_SERVER_MessageStreamTokenizer *mst,
107 char *ibuf; 110 char *ibuf;
108 int need_align; 111 int need_align;
109 unsigned long offset; 112 unsigned long offset;
113 int ret;
110 114
115 ret = GNUNET_OK;
111 ibuf = (char*) &mst->hdr; 116 ibuf = (char*) &mst->hdr;
112 if (mst->off > 0) 117 if (mst->off > 0)
113 { 118 {
@@ -133,8 +138,6 @@ GNUNET_SERVER_mst_receive (struct GNUNET_SERVER_MessageStreamTokenizer *mst,
133 if (want < sizeof (struct GNUNET_MessageHeader)) 138 if (want < sizeof (struct GNUNET_MessageHeader))
134 { 139 {
135 GNUNET_break_op (0); 140 GNUNET_break_op (0);
136 if (purge)
137 return GNUNET_NO;
138 return GNUNET_SYSERR; 141 return GNUNET_SYSERR;
139 } 142 }
140 if (want < mst->off) 143 if (want < mst->off)
@@ -154,6 +157,13 @@ GNUNET_SERVER_mst_receive (struct GNUNET_SERVER_MessageStreamTokenizer *mst,
154 mst->off = 0; 157 mst->off = 0;
155 return GNUNET_OK; 158 return GNUNET_OK;
156 } 159 }
160 if (one_shot == GNUNET_SYSERR)
161 {
162 ret = GNUNET_NO;
163 goto copy;
164 }
165 if (one_shot == GNUNET_YES)
166 one_shot = GNUNET_SYSERR;
157 mst->cb (mst->cb_cls, mst->client_identity, &mst->hdr); 167 mst->cb (mst->cb_cls, mst->client_identity, &mst->hdr);
158 mst->off = 0; 168 mst->off = 0;
159 } 169 }
@@ -174,6 +184,13 @@ GNUNET_SERVER_mst_receive (struct GNUNET_SERVER_MessageStreamTokenizer *mst,
174 want = ntohs (hdr->size); 184 want = ntohs (hdr->size);
175 if (size < want) 185 if (size < want)
176 break; /* or not, buffer incomplete... */ 186 break; /* or not, buffer incomplete... */
187 if (one_shot == GNUNET_SYSERR)
188 {
189 ret = GNUNET_NO;
190 goto copy;
191 }
192 if (one_shot == GNUNET_YES)
193 one_shot = GNUNET_SYSERR;
177 mst->cb (mst->cb_cls, mst->client_identity, hdr); 194 mst->cb (mst->cb_cls, mst->client_identity, hdr);
178 buf += want; 195 buf += want;
179 size -= want; 196 size -= want;
@@ -184,15 +201,16 @@ GNUNET_SERVER_mst_receive (struct GNUNET_SERVER_MessageStreamTokenizer *mst,
184 goto do_align; 201 goto do_align;
185 } 202 }
186 } 203 }
204 copy:
187 if ( (size > 0) && (! purge) ) 205 if ( (size > 0) && (! purge) )
188 { 206 {
189 memcpy (&mst->hdr, buf, size); 207 memcpy (&ibuf[mst->off], buf, size);
190 mst->off = size; 208 mst->off += size;
191 size = 0; 209 size = 0;
192 } 210 }
193 if (purge) 211 if (purge)
194 mst->off = 0; 212 mst->off = 0;
195 return GNUNET_OK; 213 return ret;
196} 214}
197 215
198 216