diff --git a/gms/inet_address_serializer.hh b/gms/inet_address_serializer.hh new file mode 100644 index 0000000000..695203f924 --- /dev/null +++ b/gms/inet_address_serializer.hh @@ -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 { + template + static gms::inet_address read(Input& in) { + auto sz = deserialize(in, boost::type()); + if (sz == std::numeric_limits::max()) { + seastar::net::ipv6_address addr(deserialize(in, boost::type())); + return gms::inet_address(addr); + } + return gms::inet_address(sz); + } + template + static void write(Output& out, gms::inet_address v) { + auto& addr = v.addr(); + if (addr.is_ipv6()) { + serialize(out, std::numeric_limits::max()); + auto bv = v.bytes(); + out.write(reinterpret_cast(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 + static void skip(Input& v) { + read(v); + } +}; + + +} diff --git a/idl/gossip_digest.idl.hh b/idl/gossip_digest.idl.hh index a57ae6c980..c82928c804 100644 --- a/idl/gossip_digest.idl.hh +++ b/idl/gossip_digest.idl.hh @@ -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; diff --git a/message/messaging_service.cc b/message/messaging_service.cc index add6e70e3d..6dcdee7a5f 100644 --- a/message/messaging_service.cc +++ b/message/messaging_service.cc @@ -23,6 +23,7 @@ #include #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"