blob: 0ff75ac84fbc709f87a597f92af2ca3f4a726420 [file] [log] [blame]
/*
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#ifndef DATASTAX_INTERNAL_ADDRESS_HPP
#define DATASTAX_INTERNAL_ADDRESS_HPP
#include "allocated.hpp"
#include "callback.hpp"
#include "dense_hash_set.hpp"
#include "external.hpp"
#include "string.hpp"
#include "vector.hpp"
#include <uv.h>
namespace datastax { namespace internal { namespace core {
class Row;
class Address : public Allocated {
public:
static const Address EMPTY_KEY;
static const Address DELETED_KEY;
enum Family { UNRESOLVED, IPv4, IPv6 };
#ifdef _WIN32
struct SocketStorage {
struct sockaddr* addr() {
return reinterpret_cast<struct sockaddr*>(&storage);
}
struct sockaddr_in* addr_in() {
return reinterpret_cast<struct sockaddr_in*>(&storage);
}
struct sockaddr_in6* addr_in6() {
return reinterpret_cast<struct sockaddr_in6*>(&storage);
}
struct sockaddr_storage storage;
};
#else
struct SocketStorage {
struct sockaddr* addr() {
return &storage.addr;
}
struct sockaddr_in* addr_in() {
return &storage.addr_in;
}
struct sockaddr_in6* addr_in6() {
return &storage.addr_in6;
}
union {
struct sockaddr addr;
struct sockaddr_in addr_in;
struct sockaddr_in6 addr_in6;
} storage;
};
#endif
Address();
Address(const Address& other, const String& server_name);
Address(const String& hostname_or_address, int port, const String& server_name = String());
Address(const uint8_t* address, uint8_t address_length, int port);
Address(const struct sockaddr* addr);
bool equals(const Address& other, bool with_port = true) const;
bool operator==(const Address& other) const { return equals(other); }
bool operator!=(const Address& other) const { return !equals(other); }
bool operator<(const Address& other) const;
public:
String hostname_or_address() const;
const String& server_name() const { return server_name_; }
Family family() const { return family_; }
int port() const { return port_; }
bool is_valid() const { return !hostname_or_address_.empty(); }
bool is_resolved() const { return family_ == IPv4 || family_ == IPv6; }
bool is_valid_and_resolved() const { return is_valid() && is_resolved(); }
public:
size_t hash_code() const;
uint8_t to_inet(void* address) const;
const struct sockaddr* to_sockaddr(SocketStorage* storage) const;
String to_string(bool with_port = false) const;
private:
String hostname_or_address_;
String server_name_;
Family family_;
int port_;
};
String determine_listen_address(const Address& address, const Row* row);
}}} // namespace datastax::internal::core
namespace std {
#if defined(HASH_IN_TR1) && !defined(_WIN32)
namespace tr1 {
#endif
template <>
struct hash<datastax::internal::core::Address> {
size_t operator()(const datastax::internal::core::Address& address) const {
return address.hash_code();
}
};
template <>
struct hash<datastax::internal::core::Address::Family> {
size_t operator()(datastax::internal::core::Address::Family family) const {
return hasher(static_cast<int>(family));
}
SPARSEHASH_HASH<int> hasher;
};
#if defined(HASH_IN_TR1) && !defined(_WIN32)
} // namespace tr1
#endif
} // namespace std
namespace datastax { namespace internal { namespace core {
class AddressSet : public DenseHashSet<Address> {
public:
AddressSet() {
set_empty_key(Address::EMPTY_KEY);
set_deleted_key(Address::DELETED_KEY);
}
};
typedef Vector<Address> AddressVec;
}}} // namespace datastax::internal::core
namespace std {
inline std::ostream& operator<<(std::ostream& os, const datastax::internal::core::Address& a) {
return os << a.to_string();
}
inline std::ostream& operator<<(std::ostream& os, const datastax::internal::core::AddressVec& v) {
os << "[";
bool first = true;
for (datastax::internal::core::AddressVec::const_iterator it = v.begin(), end = v.end();
it != end; ++it) {
if (!first) os << ", ";
first = false;
os << *it;
}
os << "]";
return os;
}
} // namespace std
EXTERNAL_TYPE(datastax::internal::core::Address, CassNode)
#endif