GNUnet  0.20.0
tcp_server_mst_legacy.c File Reference
#include "platform.h"
#include "gnunet_util_lib.h"
Include dependency graph for tcp_server_mst_legacy.c:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  GNUNET_SERVER_MessageStreamTokenizer
 Handle to a message stream tokenizer. More...
 

Macros

#define ALIGN_FACTOR   8
 

Functions

struct GNUNET_SERVER_MessageStreamTokenizerGNUNET_SERVER_mst_create (GNUNET_SERVER_MessageTokenizerCallback cb, void *cb_cls)
 Create a message stream tokenizer. More...
 
int GNUNET_SERVER_mst_receive (struct GNUNET_SERVER_MessageStreamTokenizer *mst, void *client_identity, const char *buf, size_t size, int purge, int one_shot)
 Add incoming data to the receive buffer and call the callback for all complete messages. More...
 
void GNUNET_SERVER_mst_destroy (struct GNUNET_SERVER_MessageStreamTokenizer *mst)
 Destroys a tokenizer. More...
 

Macro Definition Documentation

◆ ALIGN_FACTOR

#define ALIGN_FACTOR   8

Definition at line 34 of file tcp_server_mst_legacy.c.

Function Documentation

◆ GNUNET_SERVER_mst_create()

struct GNUNET_SERVER_MessageStreamTokenizer* GNUNET_SERVER_mst_create ( GNUNET_SERVER_MessageTokenizerCallback  cb,
void *  cb_cls 
)

Create a message stream tokenizer.

Parameters
cbfunction to call on completed messages
cb_clsclosure for cb
Returns
handle to tokenizer

Definition at line 83 of file tcp_server_mst_legacy.c.

85 {
87 
90  ret->curr_buf = GNUNET_MIN_MESSAGE_SIZE;
91  ret->cb = cb;
92  ret->cb_cls = cb_cls;
93  return ret;
94 }
static int ret
Return value of the commandline.
Definition: gnunet-abd.c:81
#define GNUNET_MIN_MESSAGE_SIZE
Smallest supported message.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
#define GNUNET_malloc(size)
Wrapper around malloc.
Handle to a message stream tokenizer.
GNUNET_SERVER_MessageTokenizerCallback cb
Function to call on completed messages.

References GNUNET_SERVER_MessageStreamTokenizer::cb, GNUNET_SERVER_MessageStreamTokenizer::cb_cls, GNUNET_malloc, GNUNET_MIN_MESSAGE_SIZE, GNUNET_new, and ret.

Referenced by GNUNET_SERVER_connect_socket().

Here is the caller graph for this function:

◆ GNUNET_SERVER_mst_receive()

int GNUNET_SERVER_mst_receive ( struct GNUNET_SERVER_MessageStreamTokenizer mst,
void *  client_identity,
const char *  buf,
size_t  size,
int  purge,
int  one_shot 
)

Add incoming data to the receive buffer and call the callback for all complete messages.

Parameters
msttokenizer to use
client_identityID of client for which this is a buffer
bufinput data to add
sizenumber of bytes in buf
purgeshould any excess bytes in the buffer be discarded (i.e. for packet-based services like UDP)
one_shotonly call callback once, keep rest of message in buffer
Returns
GNUNET_OK if we are done processing (need more data) GNUNET_NO if one_shot was set and we have another message ready GNUNET_SYSERR if the data stream is corrupt

Definition at line 113 of file tcp_server_mst_legacy.c.

117 {
118  const struct GNUNET_MessageHeader *hdr;
119  size_t delta;
120  uint16_t want;
121  char *ibuf;
122  int need_align;
123  unsigned long offset;
124  int ret;
125 
126  GNUNET_assert (mst->off <= mst->pos);
127  GNUNET_assert (mst->pos <= mst->curr_buf);
129  "Server-mst receives %u bytes with %u bytes already in private buffer\n",
130  (unsigned int) size, (unsigned int) (mst->pos - mst->off));
131  ret = GNUNET_OK;
132  ibuf = (char *) mst->hdr;
133  while (mst->pos > 0)
134  {
135 do_align:
136  GNUNET_assert (mst->pos >= mst->off);
137  if ((mst->curr_buf - mst->off < sizeof(struct GNUNET_MessageHeader)) ||
138  (0 != (mst->off % ALIGN_FACTOR)))
139  {
140  /* need to align or need more space */
141  mst->pos -= mst->off;
142  memmove (ibuf, &ibuf[mst->off], mst->pos);
143  mst->off = 0;
144  }
145  if (mst->pos - mst->off < sizeof(struct GNUNET_MessageHeader))
146  {
147  delta =
148  GNUNET_MIN (sizeof(struct GNUNET_MessageHeader)
149  - (mst->pos - mst->off), size);
150  GNUNET_memcpy (&ibuf[mst->pos], buf, delta);
151  mst->pos += delta;
152  buf += delta;
153  size -= delta;
154  }
155  if (mst->pos - mst->off < sizeof(struct GNUNET_MessageHeader))
156  {
157  if (purge)
158  {
159  mst->off = 0;
160  mst->pos = 0;
161  }
162  return GNUNET_OK;
163  }
164  hdr = (const struct GNUNET_MessageHeader *) &ibuf[mst->off];
165  want = ntohs (hdr->size);
166  if (want < sizeof(struct GNUNET_MessageHeader))
167  {
168  GNUNET_break_op (0);
169  return GNUNET_SYSERR;
170  }
171  if ((mst->curr_buf - mst->off < want) &&
172  (mst->off > 0))
173  {
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)
207  {
208  /* cannot call callback again, but return value saying that
209  * we have another full message in the buffer */
210  ret = GNUNET_NO;
211  goto copy;
212  }
213  if (one_shot == GNUNET_YES)
214  one_shot = GNUNET_SYSERR;
215  mst->off += want;
216  if (GNUNET_SYSERR == mst->cb (mst->cb_cls, client_identity, hdr))
217  return GNUNET_SYSERR;
218  if (mst->off == mst->pos)
219  {
220  /* reset to beginning of buffer, it's free right now! */
221  mst->off = 0;
222  mst->pos = 0;
223  }
224  }
225  GNUNET_assert (0 == mst->pos);
226  while (size > 0)
227  {
229  "Server-mst has %u bytes left in inbound buffer\n",
230  (unsigned int) size);
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 spaghetti than usual here */
266  goto do_align;
267  }
268  }
269 copy:
270  if ((size > 0) && (! purge))
271  {
272  if (size + mst->pos > mst->curr_buf)
273  {
274  mst->hdr = GNUNET_realloc (mst->hdr, 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  }
282  if (purge)
283  {
284  mst->off = 0;
285  mst->pos = 0;
286  }
288  "Server-mst leaves %u bytes in private buffer\n",
289  (unsigned int) (mst->pos - mst->off));
290  return ret;
291 }
#define LOG(kind,...)
Definition: abd_api.c:38
static size_t do_align(size_t start_position, size_t end_position)
Given the start and end position of a block of data, return the end position of that data after align...
Definition: fs_directory.c:488
static char buf[2048]
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
#define GNUNET_MIN(a, b)
@ GNUNET_OK
@ GNUNET_YES
@ GNUNET_NO
@ GNUNET_SYSERR
#define GNUNET_break_op(cond)
Use this for assertion violations caused by other peers (i.e.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
@ GNUNET_ERROR_TYPE_DEBUG
#define GNUNET_realloc(ptr, size)
Wrapper around realloc.
static unsigned int size
Size of the "table".
Definition: peer.c:68
static struct GNUNET_TIME_Relative delta
Definition: speedup.c:36
Header for all communications.
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format.
size_t off
How many bytes in buffer have we already processed?
size_t curr_buf
Size of the buffer (starting at hdr).
size_t pos
How many bytes in buffer are valid right now?
struct GNUNET_MessageHeader * hdr
Beginning of the buffer.
#define ALIGN_FACTOR

References ALIGN_FACTOR, buf, GNUNET_SERVER_MessageStreamTokenizer::cb, GNUNET_SERVER_MessageStreamTokenizer::cb_cls, GNUNET_SERVER_MessageStreamTokenizer::curr_buf, delta, do_align(), GNUNET_assert, GNUNET_break_op, GNUNET_ERROR_TYPE_DEBUG, GNUNET_memcpy, GNUNET_MIN, GNUNET_NO, GNUNET_OK, GNUNET_realloc, GNUNET_SYSERR, GNUNET_YES, GNUNET_SERVER_MessageStreamTokenizer::hdr, LOG, GNUNET_SERVER_MessageStreamTokenizer::off, GNUNET_SERVER_MessageStreamTokenizer::pos, ret, GNUNET_MessageHeader::size, and size.

Referenced by handle_helper_message(), process_data(), process_incoming(), process_mst(), and wlan_data_message_handler().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ GNUNET_SERVER_mst_destroy()

void GNUNET_SERVER_mst_destroy ( struct GNUNET_SERVER_MessageStreamTokenizer mst)

Destroys a tokenizer.

Parameters
msttokenizer to destroy

Definition at line 300 of file tcp_server_mst_legacy.c.

301 {
302  GNUNET_free (mst->hdr);
303  GNUNET_free (mst);
304 }
#define GNUNET_free(ptr)
Wrapper around free.

References GNUNET_free, and GNUNET_SERVER_MessageStreamTokenizer::hdr.

Referenced by GNUNET_SERVER_client_disconnect(), and LIBGNUNET_PLUGIN_TRANSPORT_DONE().

Here is the caller graph for this function: