gms::inet_address: Make serialization ipv6 aware
Because inet_address was initially hardcoded to
ipv4, its wire format is not very forward compatible.
Since we potentially need to communicate with older version nodes, we
manually define the new serial format for inet_address to be:
ipv4: 4 bytes address
ipv6: 4 bytes marker 0xffffffff (invalid address)
16 bytes data -> address
This commit is contained in:
68
gms/inet_address_serializer.hh
Normal file
68
gms/inet_address_serializer.hh
Normal file
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* Copyright (C) 2019 ScyllaDB
|
||||
*/
|
||||
|
||||
/*
|
||||
* This file is part of Scylla.
|
||||
*
|
||||
* See the LICENSE.PROPRIETARY file in the top-level directory for licensing information.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "inet_address.hh"
|
||||
#include "serializer.hh"
|
||||
|
||||
namespace ser {
|
||||
|
||||
/**
|
||||
* Manual definition of inet_address serialization.
|
||||
* Because inet_address was initially hardcoded to
|
||||
* ipv4, its wire format is not very forward compatible.
|
||||
*
|
||||
* Since we potentially need to communicate with older
|
||||
* version nodes, we manually define the new serial format
|
||||
* for inet_address to be:
|
||||
*
|
||||
* ipv4: 4 bytes address
|
||||
* ipv6: 4 bytes marker 0xffffffff (invalid address)
|
||||
* 16 bytes data -> address
|
||||
*
|
||||
* As long as we are restricted to ipv4 (config/user responsibility)
|
||||
* we will be able to swap gossip with older nodes. Once the
|
||||
* cluster is fully updated, user can enable ipv6 and we will be
|
||||
* happy and addressing all the molecules.
|
||||
*
|
||||
*/
|
||||
template<>
|
||||
struct serializer<gms::inet_address> {
|
||||
template<typename Input>
|
||||
static gms::inet_address read(Input& in) {
|
||||
auto sz = deserialize(in, boost::type<uint32_t>());
|
||||
if (sz == std::numeric_limits<uint32_t>::max()) {
|
||||
seastar::net::ipv6_address addr(deserialize(in, boost::type<net::ipv6_address::ipv6_bytes>()));
|
||||
return gms::inet_address(addr);
|
||||
}
|
||||
return gms::inet_address(sz);
|
||||
}
|
||||
template<typename Output>
|
||||
static void write(Output& out, gms::inet_address v) {
|
||||
auto& addr = v.addr();
|
||||
if (addr.is_ipv6()) {
|
||||
serialize(out, std::numeric_limits<uint32_t>::max());
|
||||
auto bv = v.bytes();
|
||||
out.write(reinterpret_cast<const char *>(bv.data()), bv.size());
|
||||
} else {
|
||||
uint32_t ip = addr.as_ipv4_address().ip;
|
||||
// must write this little (or rather host) endian
|
||||
serialize(out, ip);
|
||||
}
|
||||
}
|
||||
template<typename Input>
|
||||
static void skip(Input& v) {
|
||||
read(v);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
@@ -38,10 +38,6 @@ enum class application_state:int {
|
||||
SUPPORTED_FEATURES
|
||||
};
|
||||
|
||||
class inet_address final {
|
||||
uint32_t raw_addr();
|
||||
};
|
||||
|
||||
class versioned_value {
|
||||
sstring value;
|
||||
int version;
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
#include <seastar/core/distributed.hh>
|
||||
#include "gms/failure_detector.hh"
|
||||
#include "gms/gossiper.hh"
|
||||
#include "gms/inet_address_serializer.hh"
|
||||
#include "service/storage_service.hh"
|
||||
#include "streaming/prepare_message.hh"
|
||||
#include "gms/gossip_digest_syn.hh"
|
||||
|
||||
Reference in New Issue
Block a user