sssd/0007-iobuf-add-more-iobuf-f...

266 lines
7.6 KiB
Diff

From 51c8dda998c5b7bfa08362a13915fcff265a6f8f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <pbrezina@redhat.com>
Date: Fri, 23 Oct 2020 13:10:13 +0200
Subject: [PATCH 07/19] iobuf: add more iobuf functions
These will be used in later patches.
---
src/shared/safealign.h | 4 ++
src/util/sss_iobuf.c | 141 +++++++++++++++++++++++++++++++++++++++++
src/util/sss_iobuf.h | 46 ++++++++++++++
3 files changed, 191 insertions(+)
diff --git a/src/shared/safealign.h b/src/shared/safealign.h
index b00c37f5b98bd4bf7ff6cea8e1208d80c77f0228..35909faa25967cefd296808431620f51232f67e2 100644
--- a/src/shared/safealign.h
+++ b/src/shared/safealign.h
@@ -97,6 +97,10 @@ safealign_memcpy(void *dest, const void *src, size_t n, size_t *counter)
#define SAFEALIGN_SETMEM_UINT16(dest, value, pctr) \
SAFEALIGN_SETMEM_VALUE(dest, value, uint16_t, pctr)
+/* SAFEALIGN_SETMEM_UINT8(void *dest, uint8_t value, size_t *pctr) */
+#define SAFEALIGN_SETMEM_UINT8(dest, value, pctr) \
+ SAFEALIGN_SETMEM_VALUE(dest, value, uint8_t, pctr)
+
/* These macros are the same as their equivalents without _CHECK suffix,
* but additionally make the caller return EINVAL immediately if *pctr
* would exceed len. */
diff --git a/src/util/sss_iobuf.c b/src/util/sss_iobuf.c
index 518713e4cc3dd99627a3a4450f235cbbc69ed3a2..3056a7b0db38746cfed154179787e53622e1a041 100644
--- a/src/util/sss_iobuf.c
+++ b/src/util/sss_iobuf.c
@@ -66,6 +66,30 @@ struct sss_iobuf *sss_iobuf_init_readonly(TALLOC_CTX *mem_ctx,
return iobuf;
}
+struct sss_iobuf *sss_iobuf_init_steal(TALLOC_CTX *mem_ctx,
+ uint8_t *data,
+ size_t size)
+{
+ struct sss_iobuf *iobuf;
+
+ iobuf = talloc_zero(mem_ctx, struct sss_iobuf);
+ if (iobuf == NULL) {
+ return NULL;
+ }
+
+ iobuf->data = talloc_steal(iobuf, data);
+ iobuf->size = size;
+ iobuf->capacity = size;
+ iobuf->dp = 0;
+
+ return iobuf;
+}
+
+void sss_iobuf_cursor_reset(struct sss_iobuf *iobuf)
+{
+ iobuf->dp = 0;
+}
+
size_t sss_iobuf_get_len(struct sss_iobuf *iobuf)
{
if (iobuf == NULL) {
@@ -223,6 +247,109 @@ errno_t sss_iobuf_write_len(struct sss_iobuf *iobuf,
return EOK;
}
+errno_t sss_iobuf_read_varlen(TALLOC_CTX *mem_ctx,
+ struct sss_iobuf *iobuf,
+ uint8_t **_out,
+ size_t *_len)
+{
+ uint8_t *out;
+ uint32_t len;
+ size_t slen;
+ errno_t ret;
+
+ if (iobuf == NULL || _out == NULL || _len == NULL) {
+ return EINVAL;
+ }
+
+ ret = sss_iobuf_read_uint32(iobuf, &len);
+ if (ret != EOK) {
+ return ret;
+ }
+
+ if (len == 0) {
+ *_out = NULL;
+ *_len = 0;
+ return EOK;
+ }
+
+ out = talloc_array(mem_ctx, uint8_t, len);
+ if (out == NULL) {
+ return ENOMEM;
+ }
+
+ slen = len;
+ ret = sss_iobuf_read_len(iobuf, slen, out);
+ if (ret != EOK) {
+ talloc_free(out);
+ return ret;
+ }
+
+ *_out = out;
+ *_len = slen;
+
+ return EOK;
+}
+
+errno_t sss_iobuf_write_varlen(struct sss_iobuf *iobuf,
+ uint8_t *data,
+ size_t len)
+{
+ errno_t ret;
+
+ if (iobuf == NULL || (data == NULL && len != 0)) {
+ return EINVAL;
+ }
+
+ ret = sss_iobuf_write_uint32(iobuf, len);
+ if (ret != EOK) {
+ return ret;
+ }
+
+ if (len == 0) {
+ return EOK;
+ }
+
+ return sss_iobuf_write_len(iobuf, data, len);
+}
+
+errno_t sss_iobuf_read_iobuf(TALLOC_CTX *mem_ctx,
+ struct sss_iobuf *iobuf,
+ struct sss_iobuf **_out)
+{
+ struct sss_iobuf *out;
+ uint8_t *data;
+ size_t len;
+ errno_t ret;
+
+ ret = sss_iobuf_read_varlen(NULL, iobuf, &data, &len);
+ if (ret != EOK) {
+ return ret;
+ }
+
+ out = sss_iobuf_init_steal(mem_ctx, data, len);
+ if (out == NULL) {
+ return ENOMEM;
+ }
+
+ *_out = out;
+
+ return EOK;
+}
+
+errno_t sss_iobuf_write_iobuf(struct sss_iobuf *iobuf,
+ struct sss_iobuf *data)
+{
+ return sss_iobuf_write_varlen(iobuf, data->data, data->size);
+}
+
+errno_t sss_iobuf_read_uint8(struct sss_iobuf *iobuf,
+ uint8_t *_val)
+{
+ SAFEALIGN_COPY_UINT8_CHECK(_val, iobuf_ptr(iobuf),
+ iobuf->capacity, &iobuf->dp);
+ return EOK;
+}
+
errno_t sss_iobuf_read_uint32(struct sss_iobuf *iobuf,
uint32_t *_val)
{
@@ -239,6 +366,20 @@ errno_t sss_iobuf_read_int32(struct sss_iobuf *iobuf,
return EOK;
}
+errno_t sss_iobuf_write_uint8(struct sss_iobuf *iobuf,
+ uint8_t val)
+{
+ errno_t ret;
+
+ ret = ensure_bytes(iobuf, sizeof(uint8_t));
+ if (ret != EOK) {
+ return ret;
+ }
+
+ SAFEALIGN_SETMEM_UINT8(iobuf_ptr(iobuf), val, &iobuf->dp);
+ return EOK;
+}
+
errno_t sss_iobuf_write_uint32(struct sss_iobuf *iobuf,
uint32_t val)
{
diff --git a/src/util/sss_iobuf.h b/src/util/sss_iobuf.h
index cc3dfd1e98eeb49b979ac321bd0253bffa8a6dff..159fbc0b9ff756ca996722a84a1a13635d1aa8de 100644
--- a/src/util/sss_iobuf.h
+++ b/src/util/sss_iobuf.h
@@ -50,6 +50,29 @@ struct sss_iobuf *sss_iobuf_init_readonly(TALLOC_CTX *mem_ctx,
const uint8_t *data,
size_t size);
+/*
+ * @brief Allocate an IO buffer with a fixed size, stealing input data.
+ *
+ * This function is useful for parsing an input buffer from an existing
+ * buffer pointed to by data.
+ *
+ * The iobuf assumes ownership of the data buffer.
+ *
+ * @param[in] mem_ctx The talloc context that owns the iobuf
+ * @param[in] data The data to initialize the IO buffer with.
+ * @param[in] size The size of the data buffer
+ *
+ * @return The newly created buffer on success or NULL on an error.
+ */
+struct sss_iobuf *sss_iobuf_init_steal(TALLOC_CTX *mem_ctx,
+ uint8_t *data,
+ size_t size);
+
+/*
+ * @brief Reset internal cursor of the IO buffer (seek to the start)
+ */
+void sss_iobuf_cursor_reset(struct sss_iobuf *iobuf);
+
/*
* @brief Returns the number of bytes currently stored in the iobuf
*
@@ -131,6 +154,28 @@ errno_t sss_iobuf_write_len(struct sss_iobuf *iobuf,
uint8_t *buf,
size_t len);
+errno_t sss_iobuf_read_varlen(TALLOC_CTX *mem_ctx,
+ struct sss_iobuf *iobuf,
+ uint8_t **_out,
+ size_t *_len);
+
+errno_t sss_iobuf_write_varlen(struct sss_iobuf *iobuf,
+ uint8_t *data,
+ size_t len);
+
+errno_t sss_iobuf_read_iobuf(TALLOC_CTX *mem_ctx,
+ struct sss_iobuf *iobuf,
+ struct sss_iobuf **_out);
+
+errno_t sss_iobuf_write_iobuf(struct sss_iobuf *iobuf,
+ struct sss_iobuf *data);
+
+errno_t sss_iobuf_read_uint8(struct sss_iobuf *iobuf,
+ uint8_t *_val);
+
+errno_t sss_iobuf_write_uint8(struct sss_iobuf *iobuf,
+ uint8_t val);
+
errno_t sss_iobuf_read_uint32(struct sss_iobuf *iobuf,
uint32_t *_val);
@@ -148,4 +193,5 @@ errno_t sss_iobuf_read_stringz(struct sss_iobuf *iobuf,
errno_t sss_iobuf_write_stringz(struct sss_iobuf *iobuf,
const char *str);
+
#endif /* __SSS_IOBUF_H_ */
--
2.25.4