+ hlen = silc_buffer_headlen(sb);
+ dlen = silc_buffer_len(sb);
+ h = (unsigned char *)silc_realloc(sb->head, newsize);
+ if (!h)
+ return NULL;
+ sb->head = h;
+ sb->data = sb->head + hlen;
+ sb->tail = sb->data + dlen;
+ sb->end = sb->head + newsize;
+
+ return sb;
+}
+
+/****f* silcutil/SilcBufferAPI/silc_buffer_realloc_size
+ *
+ * SYNOPSIS
+ *
+ * static inline
+ * SilcBuffer silc_buffer_realloc_size(SilcBuffer sb, SilcUInt32 newsize);
+ *
+ * DESCRIPTION
+ *
+ * Same as silc_buffer_realloc but moves moves the tail area
+ * automatically so that the buffer is ready to use without calling the
+ * silc_buffer_pull_tail. Returns NULL on error.
+ *
+ ***/
+
+static inline
+SilcBuffer silc_buffer_realloc_size(SilcBuffer sb, SilcUInt32 newsize)
+{
+ sb = silc_buffer_realloc(sb, newsize);
+ if (!sb)
+ return NULL;
+ silc_buffer_pull_tail(sb, silc_buffer_taillen(sb));
+ return sb;
+}
+
+
+/* SilcStack aware SilcBuffer routines */
+
+/****f* silcutil/SilcBufferAPI/silc_buffer_salloc
+ *
+ * SYNOPSIS
+ *
+ * static inline
+ * SilcBuffer silc_buffer_salloc(SilcStack stack, SilcUInt32 len);
+ *
+ * DESCRIPTION
+ *
+ * Allocates new SilcBuffer and returns it.
+ *
+ * This routine use SilcStack are memory source.
+ *
+ ***/
+
+static inline
+SilcBuffer silc_buffer_salloc(SilcStack stack, SilcUInt32 len)
+{
+ SilcBuffer sb;
+
+ /* Allocate new SilcBuffer */
+ sb = (SilcBuffer)silc_scalloc(stack, 1, sizeof(*sb));
+ if (!sb)
+ return NULL;
+
+ /* Allocate the actual data area */
+ sb->head = (unsigned char *)silc_smalloc_ua(stack, len);
+ if (!sb->head)
+ return NULL;
+
+ /* Set pointers to the new buffer */
+ sb->data = sb->head;
+ sb->tail = sb->head;
+ sb->end = sb->head + len;
+
+ return sb;
+}
+
+/****f* silcutil/SilcBufferAPI/silc_buffer_salloc_size
+ *
+ * SYNOPSIS
+ *
+ * static inline
+ * SilcBuffer silc_buffer_salloc_size(SilcStack stack, SilcUInt32 len);
+ *
+ * DESCRIPTION
+ *
+ * Allocates `len' bytes size buffer and moves the tail area automatically
+ * `len' bytes so that the buffer is ready to use without calling the
+ * silc_buffer_pull_tail.
+ *
+ * This routine use SilcStack are memory source.
+ *
+ ***/
+
+static inline
+SilcBuffer silc_buffer_salloc_size(SilcStack stack, SilcUInt32 len)
+{
+ SilcBuffer sb = silc_buffer_salloc(stack, len);
+ if (!sb)
+ return NULL;
+ silc_buffer_pull_tail(sb, len);
+ return sb;
+}
+
+/****f* silcutil/SilcBufferAPI/silc_buffer_srealloc
+ *
+ * SYNOPSIS
+ *
+ * static inline
+ * SilcBuffer silc_buffer_srealloc(SilcStack stack,
+ * SilcBuffer sb, SilcUInt32 newsize);
+ *
+ * DESCRIPTION
+ *
+ * Reallocates buffer. Old data is saved into the new buffer. The buffer
+ * is exact clone of the old one except that there is now more space
+ * at the end of buffer.
+ *
+ * This routine use SilcStack are memory source.
+ *
+ ***/
+
+static inline
+SilcBuffer silc_buffer_srealloc(SilcStack stack,
+ SilcBuffer sb, SilcUInt32 newsize)
+{
+ SilcUInt32 hlen, dlen;
+ unsigned char *h;
+
+ if (!sb)
+ return silc_buffer_salloc(stack, newsize);
+
+ if (newsize <= silc_buffer_truelen(sb))
+ return sb;
+
+ hlen = silc_buffer_headlen(sb);
+ dlen = silc_buffer_len(sb);
+ h = (unsigned char *)silc_srealloc_ua(stack, silc_buffer_truelen(sb),
+ sb->head, newsize);
+ if (!h) {
+ /* Do slow and stack wasting realloc. The old sb->head is lost and
+ is freed eventually. */
+ h = silc_smalloc_ua(stack, newsize);
+ if (!h)
+ return NULL;
+ memcpy(h, sb->head, silc_buffer_truelen(sb));
+ }
+
+ sb->head = h;
+ sb->data = sb->head + hlen;
+ sb->tail = sb->data + dlen;
+ sb->end = sb->head + newsize;
+
+ return sb;
+}
+
+/****f* silcutil/SilcBufferAPI/silc_buffer_srealloc_size
+ *
+ * SYNOPSIS
+ *
+ * static inline
+ * SilcBuffer silc_buffer_srealloc_size(SilcStack stack,
+ * SilcBuffer sb, SilcUInt32 newsize);
+ *
+ * DESCRIPTION
+ *
+ * Same as silc_buffer_srealloc but moves moves the tail area
+ * automatically so that the buffer is ready to use without calling the
+ * silc_buffer_pull_tail.
+ *
+ * This routine use SilcStack are memory source.
+ *
+ ***/
+
+static inline
+SilcBuffer silc_buffer_srealloc_size(SilcStack stack,
+ SilcBuffer sb, SilcUInt32 newsize)
+{
+ sb = silc_buffer_srealloc(stack, sb, newsize);
+ if (!sb)
+ return NULL;
+ silc_buffer_pull_tail(sb, silc_buffer_taillen(sb));
+ return sb;
+}
+
+/****f* silcutil/SilcBufferAPI/silc_buffer_scopy
+ *
+ * SYNOPSIS
+ *
+ * static inline
+ * SilcBuffer silc_buffer_scopy(SilcStack stack, SilcBuffer sb);
+ *
+ * DESCRIPTION
+ *
+ * Generates copy of a SilcBuffer. This copies everything inside the
+ * currently valid data area, nothing more. Use silc_buffer_clone to
+ * copy entire buffer.
+ *
+ * This routine use SilcStack are memory source.
+ *
+ ***/
+
+static inline
+SilcBuffer silc_buffer_scopy(SilcStack stack, SilcBuffer sb)
+{
+ SilcBuffer sb_new;
+
+ sb_new = silc_buffer_salloc_size(stack, silc_buffer_len(sb));