GNUnet  0.10.x
Data Structures | Macros | Functions
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.

Referenced by GNUNET_SERVER_mst_receive().

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 86 of file tcp_server_mst_legacy.c.

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

Referenced by GNUNET_SERVER_connect_socket(), and LIBGNUNET_PLUGIN_TRANSPORT_INIT().

88 {
90 
94  ret->cb = cb;
95  ret->cb_cls = cb_cls;
96  return ret;
97 }
#define GNUNET_new(type)
Allocate a struct or union of the given type.
static int ret
Final status code.
Definition: gnunet-arm.c:89
Handle to a message stream tokenizer.
#define GNUNET_MIN_MESSAGE_SIZE
Smallest supported message.
struct GNUNET_MessageHeader * hdr
Beginning of the buffer.
GNUNET_SERVER_MessageTokenizerCallback cb
Function to call on completed messages.
size_t curr_buf
Size of the buffer (starting at hdr).
#define GNUNET_malloc(size)
Wrapper around malloc.
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 116 of file tcp_server_mst_legacy.c.

References ALIGN_FACTOR, 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, size, and GNUNET_MessageHeader::size.

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

120 {
121  const struct GNUNET_MessageHeader *hdr;
122  size_t delta;
123  uint16_t want;
124  char *ibuf;
125  int need_align;
126  unsigned long offset;
127  int ret;
128 
129  GNUNET_assert (mst->off <= mst->pos);
130  GNUNET_assert (mst->pos <= mst->curr_buf);
132  "Server-mst receives %u bytes with %u bytes already in private buffer\n",
133  (unsigned int) size, (unsigned int) (mst->pos - mst->off));
134  ret = GNUNET_OK;
135  ibuf = (char *) mst->hdr;
136  while (mst->pos > 0)
137  {
138 do_align:
139  GNUNET_assert (mst->pos >= mst->off);
140  if ((mst->curr_buf - mst->off < sizeof (struct GNUNET_MessageHeader)) ||
141  (0 != (mst->off % ALIGN_FACTOR)))
142  {
143  /* need to align or need more space */
144  mst->pos -= mst->off;
145  memmove (ibuf, &ibuf[mst->off], mst->pos);
146  mst->off = 0;
147  }
148  if (mst->pos - mst->off < sizeof (struct GNUNET_MessageHeader))
149  {
150  delta =
151  GNUNET_MIN (sizeof (struct GNUNET_MessageHeader) -
152  (mst->pos - mst->off), size);
153  GNUNET_memcpy (&ibuf[mst->pos], buf, delta);
154  mst->pos += delta;
155  buf += delta;
156  size -= delta;
157  }
158  if (mst->pos - mst->off < sizeof (struct GNUNET_MessageHeader))
159  {
160  if (purge)
161  {
162  mst->off = 0;
163  mst->pos = 0;
164  }
165  return GNUNET_OK;
166  }
167  hdr = (const struct GNUNET_MessageHeader *) &ibuf[mst->off];
168  want = ntohs (hdr->size);
169  if (want < sizeof (struct GNUNET_MessageHeader))
170  {
171  GNUNET_break_op (0);
172  return GNUNET_SYSERR;
173  }
174  if ( (mst->curr_buf - mst->off < want) &&
175  (mst->off > 0) )
176  {
177  /* can get more space by moving */
178  mst->pos -= mst->off;
179  memmove (ibuf, &ibuf[mst->off], mst->pos);
180  mst->off = 0;
181  }
182  if (mst->curr_buf < want)
183  {
184  /* need to get more space by growing buffer */
185  GNUNET_assert (0 == mst->off);
186  mst->hdr = GNUNET_realloc (mst->hdr, want);
187  ibuf = (char *) mst->hdr;
188  mst->curr_buf = want;
189  }
190  hdr = (const struct GNUNET_MessageHeader *) &ibuf[mst->off];
191  if (mst->pos - mst->off < want)
192  {
193  delta = GNUNET_MIN (want - (mst->pos - mst->off), size);
194  GNUNET_assert (mst->pos + delta <= mst->curr_buf);
195  GNUNET_memcpy (&ibuf[mst->pos], buf, delta);
196  mst->pos += delta;
197  buf += delta;
198  size -= delta;
199  }
200  if (mst->pos - mst->off < want)
201  {
202  if (purge)
203  {
204  mst->off = 0;
205  mst->pos = 0;
206  }
207  return GNUNET_OK;
208  }
209  if (one_shot == GNUNET_SYSERR)
210  {
211  /* cannot call callback again, but return value saying that
212  * we have another full message in the buffer */
213  ret = GNUNET_NO;
214  goto copy;
215  }
216  if (one_shot == GNUNET_YES)
217  one_shot = GNUNET_SYSERR;
218  mst->off += want;
219  if (GNUNET_SYSERR == mst->cb (mst->cb_cls, client_identity, hdr))
220  return GNUNET_SYSERR;
221  if (mst->off == mst->pos)
222  {
223  /* reset to beginning of buffer, it's free right now! */
224  mst->off = 0;
225  mst->pos = 0;
226  }
227  }
228  GNUNET_assert (0 == mst->pos);
229  while (size > 0)
230  {
232  "Server-mst has %u bytes left in inbound buffer\n",
233  (unsigned int) size);
234  if (size < sizeof (struct GNUNET_MessageHeader))
235  break;
236  offset = (unsigned long) buf;
237  need_align = (0 != (offset % ALIGN_FACTOR)) ? GNUNET_YES : GNUNET_NO;
238  if (GNUNET_NO == need_align)
239  {
240  /* can try to do zero-copy and process directly from original buffer */
241  hdr = (const struct GNUNET_MessageHeader *) buf;
242  want = ntohs (hdr->size);
243  if (want < sizeof (struct GNUNET_MessageHeader))
244  {
245  GNUNET_break_op (0);
246  mst->off = 0;
247  return GNUNET_SYSERR;
248  }
249  if (size < want)
250  break; /* or not: buffer incomplete, so copy to private buffer... */
251  if (one_shot == GNUNET_SYSERR)
252  {
253  /* cannot call callback again, but return value saying that
254  * we have another full message in the buffer */
255  ret = GNUNET_NO;
256  goto copy;
257  }
258  if (one_shot == GNUNET_YES)
259  one_shot = GNUNET_SYSERR;
260  if (GNUNET_SYSERR == mst->cb (mst->cb_cls, client_identity, hdr))
261  return GNUNET_SYSERR;
262  buf += want;
263  size -= want;
264  }
265  else
266  {
267  /* need to copy to private buffer to align;
268  * yes, we go a bit more spagetti than usual here */
269  goto do_align;
270  }
271  }
272 copy:
273  if ((size > 0) && (!purge))
274  {
275  if (size + mst->pos > mst->curr_buf)
276  {
277  mst->hdr = GNUNET_realloc (mst->hdr, size + mst->pos);
278  ibuf = (char *) mst->hdr;
279  mst->curr_buf = size + mst->pos;
280  }
281  GNUNET_assert (size + mst->pos <= mst->curr_buf);
282  GNUNET_memcpy (&ibuf[mst->pos], buf, size);
283  mst->pos += size;
284  }
285  if (purge)
286  {
287  mst->off = 0;
288  mst->pos = 0;
289  }
291  "Server-mst leaves %u bytes in private buffer\n",
292  (unsigned int) (mst->pos - mst->off));
293  return ret;
294 }
static struct GNUNET_TIME_Relative delta
Definition: speedup.c:35
#define ALIGN_FACTOR
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:484
#define LOG(kind,...)
Definition: arm_api.c:33
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
#define GNUNET_NO
Definition: gnunet_common.h:81
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:78
size_t pos
How many bytes in buffer are valid right now?
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format...
static int ret
Final status code.
Definition: gnunet-arm.c:89
size_t off
How many bytes in buffer have we already processed?
#define GNUNET_memcpy(dst, src, n)
#define GNUNET_break_op(cond)
Use this for assertion violations caused by other peers (i.e.
#define GNUNET_realloc(ptr, size)
Wrapper around realloc.
#define GNUNET_MIN(a, b)
Definition: gnunet_common.h:83
static char buf[2048]
#define GNUNET_SYSERR
Definition: gnunet_common.h:79
static unsigned int size
Size of the "table".
Definition: peer.c:67
struct GNUNET_MessageHeader * hdr
Beginning of the buffer.
GNUNET_SERVER_MessageTokenizerCallback cb
Function to call on completed messages.
size_t curr_buf
Size of the buffer (starting at hdr).
Header for all communications.
#define GNUNET_YES
Definition: gnunet_common.h:80
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 303 of file tcp_server_mst_legacy.c.

References GNUNET_free, and GNUNET_SERVER_MessageStreamTokenizer::hdr.

Referenced by GNUNET_SERVER_client_disconnect(), and LIBGNUNET_PLUGIN_TRANSPORT_DONE().

304 {
305  GNUNET_free (mst->hdr);
306  GNUNET_free (mst);
307 }
struct GNUNET_MessageHeader * hdr
Beginning of the buffer.
#define GNUNET_free(ptr)
Wrapper around free.
Here is the caller graph for this function: