[tarantool-patches] [PATCH 2/4] swim: extract binary ip/port into a separate struct
Vladislav Shpilevoy
v.shpilevoy at tarantool.org
Wed Apr 17 22:56:35 MSK 2019
At this moment there are two binary structures in the SWIM
protocol carrying an address: swim_member_passport and
swim_meta_header_bin - one address in each. This code duplication
was not formidable enough to stimulate creation of a separate
address structure.
But forthcoming indirect messages protocol extensions will add 2
new cases of encoding a binary address. It triggered this patch
to reduce code duplication.
Part of #3234
---
src/lib/swim/swim_proto.c | 51 ++++++++++++++++++++++++++----------
src/lib/swim/swim_proto.h | 55 +++++++++++++++++++++++----------------
2 files changed, 70 insertions(+), 36 deletions(-)
diff --git a/src/lib/swim/swim_proto.c b/src/lib/swim/swim_proto.c
index cd9dd195b..ce52faf1b 100644
--- a/src/lib/swim/swim_proto.c
+++ b/src/lib/swim/swim_proto.c
@@ -168,6 +168,31 @@ swim_check_inaddr_not_empty(const struct sockaddr_in *addr, const char *prefix,
return -1;
}
+/**
+ * Create a binary address structure. It requires explicit IP and
+ * port keys specification since the keys depend on the component
+ * employing the address.
+ */
+static inline void
+swim_inaddr_bin_create(struct swim_inaddr_bin *bin, uint8_t ip_key,
+ uint8_t port_key)
+{
+ assert(mp_sizeof_uint(ip_key) == 1 && mp_sizeof_uint(port_key) == 1);
+ bin->k_addr = ip_key;
+ bin->m_addr = 0xce;
+ bin->k_port = port_key;
+ bin->m_port = 0xcd;
+}
+
+/** Fill already created @a bin with a real inet address. */
+static inline void
+swim_inaddr_bin_fill(struct swim_inaddr_bin *bin,
+ const struct sockaddr_in *addr)
+{
+ bin->v_addr = mp_bswap_u32(ntohl(addr->sin_addr.s_addr));
+ bin->v_port = mp_bswap_u16(ntohs(addr->sin_port));
+}
+
void
swim_member_def_create(struct swim_member_def *def)
{
@@ -343,12 +368,12 @@ swim_anti_entropy_header_bin_create(struct swim_anti_entropy_header_bin *header,
void
swim_passport_bin_create(struct swim_passport_bin *passport)
{
- passport->m_header = 0x85;
+ int map_size = 3 + SWIM_INADDR_BIN_SIZE;
+ assert(mp_sizeof_map(map_size) == 1);
+ passport->m_header = 0x80 | map_size;
passport->k_status = SWIM_MEMBER_STATUS;
- passport->k_addr = SWIM_MEMBER_ADDRESS;
- passport->m_addr = 0xce;
- passport->k_port = SWIM_MEMBER_PORT;
- passport->m_port = 0xcd;
+ swim_inaddr_bin_create(&passport->addr, SWIM_MEMBER_ADDRESS,
+ SWIM_MEMBER_PORT);
passport->k_uuid = SWIM_MEMBER_UUID;
passport->m_uuid = 0xc4;
passport->m_uuid_len = UUID_LEN;
@@ -363,8 +388,7 @@ swim_passport_bin_fill(struct swim_passport_bin *passport,
enum swim_member_status status, uint64_t incarnation)
{
passport->v_status = status;
- passport->v_addr = mp_bswap_u32(ntohl(addr->sin_addr.s_addr));
- passport->v_port = mp_bswap_u16(ntohs(addr->sin_port));
+ swim_inaddr_bin_fill(&passport->addr, addr);
memcpy(passport->v_uuid, uuid, UUID_LEN);
passport->v_incarnation = mp_bswap_u64(incarnation);
}
@@ -382,16 +406,15 @@ void
swim_meta_header_bin_create(struct swim_meta_header_bin *header,
const struct sockaddr_in *src)
{
- header->m_header = 0x83;
+ int map_size = 1 + SWIM_INADDR_BIN_SIZE;
+ assert(mp_sizeof_map(map_size) == 1);
+ header->m_header = 0x80 | map_size;
header->k_version = SWIM_META_TARANTOOL_VERSION;
header->m_version = 0xce;
header->v_version = mp_bswap_u32(tarantool_version_id());
- header->k_addr = SWIM_META_SRC_ADDRESS;
- header->m_addr = 0xce;
- header->v_addr = mp_bswap_u32(ntohl(src->sin_addr.s_addr));
- header->k_port = SWIM_META_SRC_PORT;
- header->m_port = 0xcd;
- header->v_port = mp_bswap_u16(ntohs(src->sin_port));
+ swim_inaddr_bin_create(&header->src_addr, SWIM_META_SRC_ADDRESS,
+ SWIM_META_SRC_PORT);
+ swim_inaddr_bin_fill(&header->src_addr, src);
}
int
diff --git a/src/lib/swim/swim_proto.h b/src/lib/swim/swim_proto.h
index c6ff4539d..db366f729 100644
--- a/src/lib/swim/swim_proto.h
+++ b/src/lib/swim/swim_proto.h
@@ -232,6 +232,35 @@ swim_failure_detection_def_decode(struct swim_failure_detection_def *def,
/** {{{ Anti-entropy component */
+enum {
+ /**
+ * Number of keys in the address binary structure.
+ * Structures storing an address should use this size so
+ * as to correctly encode MessagePack map header.
+ */
+ SWIM_INADDR_BIN_SIZE = 2,
+};
+
+/**
+ * Binary inet address structure. It contains two fields at this
+ * moment - IP and port encoded as usual numbers. It means that
+ * after mp_decode_uint() it is necessary to use htonl/htons()
+ * functions to assign the values to struct sockaddr_in.
+ */
+struct PACKED swim_inaddr_bin {
+ /** mp_encode_uint(address key) */
+ uint8_t k_addr;
+ /** mp_encode_uint(ntohl(addr.sin_addr.s_addr)) */
+ uint8_t m_addr;
+ uint32_t v_addr;
+
+ /** mp_encode_uint(port key) */
+ uint8_t k_port;
+ /** mp_encode_uint(ntohs(addr.sin_port)) */
+ uint8_t m_port;
+ uint16_t v_port;
+};
+
/**
* Attributes of each record of a broadcasted member table. Just
* the same as some of struct swim_member attributes.
@@ -279,17 +308,8 @@ struct PACKED swim_passport_bin {
/** mp_encode_uint(enum member_status) */
uint8_t v_status;
- /** mp_encode_uint(SWIM_MEMBER_ADDRESS) */
- uint8_t k_addr;
- /** mp_encode_uint(addr.sin_addr.s_addr) */
- uint8_t m_addr;
- uint32_t v_addr;
-
- /** mp_encode_uint(SWIM_MEMBER_PORT) */
- uint8_t k_port;
- /** mp_encode_uint(addr.sin_port) */
- uint8_t m_port;
- uint16_t v_port;
+ /** SWIM_MEMBER_ADDRESS and SWIM_MEMBER_PORT. */
+ struct swim_inaddr_bin addr;
/** mp_encode_uint(SWIM_MEMBER_UUID) */
uint8_t k_uuid;
@@ -386,17 +406,8 @@ struct PACKED swim_meta_header_bin {
uint8_t m_version;
uint32_t v_version;
- /** mp_encode_uint(SWIM_META_SRC_ADDRESS) */
- uint8_t k_addr;
- /** mp_encode_uint(addr.sin_addr.s_addr) */
- uint8_t m_addr;
- uint32_t v_addr;
-
- /** mp_encode_uint(SWIM_META_SRC_PORT) */
- uint8_t k_port;
- /** mp_encode_uint(addr.sin_port) */
- uint8_t m_port;
- uint16_t v_port;
+ /** SWIM_META_SRC_ADDRESS and SWIM_META_SRC_PORT. */
+ struct swim_inaddr_bin src_addr;
};
/** Initialize meta section. */
--
2.17.2 (Apple Git-113)
More information about the Tarantool-patches
mailing list