1
0
Fork 0

added srv://

This commit is contained in:
Frank Celler 2016-03-08 10:51:25 +01:00
parent 40f410b4c8
commit 785a970dec
10 changed files with 371 additions and 28 deletions

4
.clang-format Normal file
View File

@ -0,0 +1,4 @@
BasedOnStyle: Google
DerivePointerAlignment: false
PointerAlignment: Left
Standard: Cpp11

View File

@ -5,11 +5,14 @@ v2.8.5 (2016-03-XX)
and #1770 (Display ACTUAL query time in aardvark's AQL editor)
* Windows: the unhandled exception handler now calls the windows logging
facilities directly without locks.
facilities directly without locks.
This fixes lockups on crashes from the logging framework.
* improve nullptr handling in logger.
* added new endpoint "srv://" for DNS service records
v2.8.4 (2016-03-01)
-------------------

View File

@ -525,12 +525,12 @@ am__lib_libarango_a_SOURCES_DIST = lib/Basics/application-exit.cpp \
lib/Rest/EndpointList.cpp lib/Rest/Endpoint.cpp \
lib/Rest/EndpointIp.cpp lib/Rest/EndpointIpV4.cpp \
lib/Rest/EndpointIpV6.cpp lib/Rest/EndpointUnixDomain.cpp \
lib/Rest/HttpRequest.cpp lib/Rest/HttpResponse.cpp \
lib/Rest/InitializeRest.cpp lib/Rest/SslInterface.cpp \
lib/Rest/Version.cpp lib/Utilities/DummyShell.cpp \
lib/Utilities/LineEditor.cpp lib/Utilities/ScriptLoader.cpp \
lib/Utilities/ShellBase.cpp lib/Zip/ioapi.cpp \
lib/Zip/unzip.cpp lib/Zip/zip.cpp \
lib/Rest/EndpointSrv.cpp lib/Rest/HttpRequest.cpp \
lib/Rest/HttpResponse.cpp lib/Rest/InitializeRest.cpp \
lib/Rest/SslInterface.cpp lib/Rest/Version.cpp \
lib/Utilities/DummyShell.cpp lib/Utilities/LineEditor.cpp \
lib/Utilities/ScriptLoader.cpp lib/Utilities/ShellBase.cpp \
lib/Zip/ioapi.cpp lib/Zip/unzip.cpp lib/Zip/zip.cpp \
3rdParty/linenoise-ng/src/linenoise.cpp \
3rdParty/linenoise-ng/src/ConvertUTF.cpp \
3rdParty/linenoise-ng/src/wcwidth.cpp \
@ -623,6 +623,7 @@ am_lib_libarango_a_OBJECTS = \
lib/Rest/lib_libarango_a-EndpointIpV4.$(OBJEXT) \
lib/Rest/lib_libarango_a-EndpointIpV6.$(OBJEXT) \
lib/Rest/lib_libarango_a-EndpointUnixDomain.$(OBJEXT) \
lib/Rest/lib_libarango_a-EndpointSrv.$(OBJEXT) \
lib/Rest/lib_libarango_a-HttpRequest.$(OBJEXT) \
lib/Rest/lib_libarango_a-HttpResponse.$(OBJEXT) \
lib/Rest/lib_libarango_a-InitializeRest.$(OBJEXT) \
@ -1363,12 +1364,13 @@ lib_libarango_a_SOURCES = lib/Basics/application-exit.cpp \
lib/Rest/EndpointList.cpp lib/Rest/Endpoint.cpp \
lib/Rest/EndpointIp.cpp lib/Rest/EndpointIpV4.cpp \
lib/Rest/EndpointIpV6.cpp lib/Rest/EndpointUnixDomain.cpp \
lib/Rest/HttpRequest.cpp lib/Rest/HttpResponse.cpp \
lib/Rest/InitializeRest.cpp lib/Rest/SslInterface.cpp \
lib/Rest/Version.cpp lib/Utilities/DummyShell.cpp \
lib/Utilities/LineEditor.cpp lib/Utilities/ScriptLoader.cpp \
lib/Utilities/ShellBase.cpp lib/Zip/ioapi.cpp \
lib/Zip/unzip.cpp lib/Zip/zip.cpp $(am__append_3) \
lib/Rest/EndpointSrv.cpp lib/Rest/HttpRequest.cpp \
lib/Rest/HttpResponse.cpp lib/Rest/InitializeRest.cpp \
lib/Rest/SslInterface.cpp lib/Rest/Version.cpp \
lib/Utilities/DummyShell.cpp lib/Utilities/LineEditor.cpp \
lib/Utilities/ScriptLoader.cpp lib/Utilities/ShellBase.cpp \
lib/Zip/ioapi.cpp lib/Zip/unzip.cpp lib/Zip/zip.cpp \
$(am__append_3) \
3rdParty/velocypack/src/AttributeTranslator.cpp \
3rdParty/velocypack/src/Builder.cpp \
3rdParty/velocypack/src/Collection.cpp \
@ -3246,6 +3248,8 @@ lib/Rest/lib_libarango_a-EndpointIpV6.$(OBJEXT): \
lib/Rest/$(am__dirstamp) lib/Rest/$(DEPDIR)/$(am__dirstamp)
lib/Rest/lib_libarango_a-EndpointUnixDomain.$(OBJEXT): \
lib/Rest/$(am__dirstamp) lib/Rest/$(DEPDIR)/$(am__dirstamp)
lib/Rest/lib_libarango_a-EndpointSrv.$(OBJEXT): \
lib/Rest/$(am__dirstamp) lib/Rest/$(DEPDIR)/$(am__dirstamp)
lib/Rest/lib_libarango_a-HttpRequest.$(OBJEXT): \
lib/Rest/$(am__dirstamp) lib/Rest/$(DEPDIR)/$(am__dirstamp)
lib/Rest/lib_libarango_a-HttpResponse.$(OBJEXT): \
@ -4166,6 +4170,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@lib/Rest/$(DEPDIR)/lib_libarango_a-EndpointIpV4.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@lib/Rest/$(DEPDIR)/lib_libarango_a-EndpointIpV6.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@lib/Rest/$(DEPDIR)/lib_libarango_a-EndpointList.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@lib/Rest/$(DEPDIR)/lib_libarango_a-EndpointSrv.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@lib/Rest/$(DEPDIR)/lib_libarango_a-EndpointUnixDomain.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@lib/Rest/$(DEPDIR)/lib_libarango_a-HttpRequest.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@lib/Rest/$(DEPDIR)/lib_libarango_a-HttpResponse.Po@am__quote@
@ -8258,6 +8263,20 @@ lib/Rest/lib_libarango_a-EndpointUnixDomain.obj: lib/Rest/EndpointUnixDomain.cpp
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lib_libarango_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o lib/Rest/lib_libarango_a-EndpointUnixDomain.obj `if test -f 'lib/Rest/EndpointUnixDomain.cpp'; then $(CYGPATH_W) 'lib/Rest/EndpointUnixDomain.cpp'; else $(CYGPATH_W) '$(srcdir)/lib/Rest/EndpointUnixDomain.cpp'; fi`
lib/Rest/lib_libarango_a-EndpointSrv.o: lib/Rest/EndpointSrv.cpp
@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lib_libarango_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT lib/Rest/lib_libarango_a-EndpointSrv.o -MD -MP -MF lib/Rest/$(DEPDIR)/lib_libarango_a-EndpointSrv.Tpo -c -o lib/Rest/lib_libarango_a-EndpointSrv.o `test -f 'lib/Rest/EndpointSrv.cpp' || echo '$(srcdir)/'`lib/Rest/EndpointSrv.cpp
@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) lib/Rest/$(DEPDIR)/lib_libarango_a-EndpointSrv.Tpo lib/Rest/$(DEPDIR)/lib_libarango_a-EndpointSrv.Po
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='lib/Rest/EndpointSrv.cpp' object='lib/Rest/lib_libarango_a-EndpointSrv.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lib_libarango_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o lib/Rest/lib_libarango_a-EndpointSrv.o `test -f 'lib/Rest/EndpointSrv.cpp' || echo '$(srcdir)/'`lib/Rest/EndpointSrv.cpp
lib/Rest/lib_libarango_a-EndpointSrv.obj: lib/Rest/EndpointSrv.cpp
@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lib_libarango_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT lib/Rest/lib_libarango_a-EndpointSrv.obj -MD -MP -MF lib/Rest/$(DEPDIR)/lib_libarango_a-EndpointSrv.Tpo -c -o lib/Rest/lib_libarango_a-EndpointSrv.obj `if test -f 'lib/Rest/EndpointSrv.cpp'; then $(CYGPATH_W) 'lib/Rest/EndpointSrv.cpp'; else $(CYGPATH_W) '$(srcdir)/lib/Rest/EndpointSrv.cpp'; fi`
@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) lib/Rest/$(DEPDIR)/lib_libarango_a-EndpointSrv.Tpo lib/Rest/$(DEPDIR)/lib_libarango_a-EndpointSrv.Po
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='lib/Rest/EndpointSrv.cpp' object='lib/Rest/lib_libarango_a-EndpointSrv.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lib_libarango_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o lib/Rest/lib_libarango_a-EndpointSrv.obj `if test -f 'lib/Rest/EndpointSrv.cpp'; then $(CYGPATH_W) 'lib/Rest/EndpointSrv.cpp'; else $(CYGPATH_W) '$(srcdir)/lib/Rest/EndpointSrv.cpp'; fi`
lib/Rest/lib_libarango_a-HttpRequest.o: lib/Rest/HttpRequest.cpp
@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lib_libarango_a_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT lib/Rest/lib_libarango_a-HttpRequest.o -MD -MP -MF lib/Rest/$(DEPDIR)/lib_libarango_a-HttpRequest.Tpo -c -o lib/Rest/lib_libarango_a-HttpRequest.o `test -f 'lib/Rest/HttpRequest.cpp' || echo '$(srcdir)/'`lib/Rest/HttpRequest.cpp
@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) lib/Rest/$(DEPDIR)/lib_libarango_a-HttpRequest.Tpo lib/Rest/$(DEPDIR)/lib_libarango_a-HttpRequest.Po

View File

@ -139,6 +139,7 @@ add_library(
Rest/EndpointIp.cpp
Rest/EndpointIpV4.cpp
Rest/EndpointIpV6.cpp
Rest/EndpointSrv.cpp
Rest/HttpRequest.cpp
Rest/HttpResponse.cpp
Rest/InitializeRest.cpp

View File

@ -80,6 +80,7 @@ lib_libarango_a_SOURCES = \
lib/Rest/EndpointIpV4.cpp \
lib/Rest/EndpointIpV6.cpp \
lib/Rest/EndpointUnixDomain.cpp \
lib/Rest/EndpointSrv.cpp \
lib/Rest/HttpRequest.cpp \
lib/Rest/HttpResponse.cpp \
lib/Rest/InitializeRest.cpp \

View File

@ -39,6 +39,7 @@
#endif
#include "Rest/EndpointIpV4.h"
#include "Rest/EndpointIpV6.h"
#include "Rest/EndpointSrv.h"
using namespace std;
using namespace triagens::basics;
@ -116,25 +117,19 @@ std::string Endpoint::getUnifiedForm (const std::string& specification) {
return "";
}
#endif
else if (StringUtils::isPrefix(copy, "srv://")) {
return copy;
}
else if (! StringUtils::isPrefix(copy, "ssl://") &&
! StringUtils::isPrefix(copy, "tcp://")) {
// invalid type
return "";
}
size_t found;
/*
// turn "localhost" into "127.0.0.1"
// technically this is not always correct, but circumvents obvious problems
// when the configuration contains both "127.0.0.1" and "localhost" endpoints
found = copy.find("localhost");
if (found != string::npos && found >= 6 && found < 10) {
copy = copy.replace(found, strlen("localhost"), "127.0.0.1");
}
*/
// tcp/ip or ssl
size_t found;
string temp = copy.substr(6, copy.length()); // strip tcp:// or ssl://
if (temp[0] == '[') {
// ipv6
found = temp.find("]:", 1);
@ -144,6 +139,7 @@ std::string Endpoint::getUnifiedForm (const std::string& specification) {
}
found = temp.find("]", 1);
if (found != string::npos && found > 2 && found + 1 == temp.size()) {
// hostname only (e.g. [address])
return copy + ":" + StringUtils::itoa(EndpointIp::_defaultPort);
@ -227,7 +223,6 @@ Endpoint* Endpoint::factory (const Endpoint::EndpointType type,
EncryptionType encryption = ENCRYPTION_NONE;
string domainType = StringUtils::tolower(copy.substr(0, 7));
if (StringUtils::isPrefix(domainType, "ssl://")) {
// ssl
encryption = ENCRYPTION_SSL;
@ -246,6 +241,14 @@ Endpoint* Endpoint::factory (const Endpoint::EndpointType type,
}
#endif
else if (StringUtils::isPrefix(domainType, "srv://")) {
if (type != ENDPOINT_CLIENT) {
return nullptr;
}
return new EndpointSrv(specification.substr(6));
}
else if (! StringUtils::isPrefix(domainType, "tcp://")) {
// invalid type
return nullptr;

View File

@ -88,7 +88,8 @@ namespace triagens {
DOMAIN_UNKNOWN = 0,
DOMAIN_UNIX,
DOMAIN_IPV4,
DOMAIN_IPV6
DOMAIN_IPV6,
DOMAIN_SRV
};
////////////////////////////////////////////////////////////////////////////////
@ -205,7 +206,7 @@ namespace triagens {
/// @brief return whether the endpoint is connected
////////////////////////////////////////////////////////////////////////////////
bool isConnected () const {
virtual bool isConnected () const {
return _connected;
}
@ -221,7 +222,7 @@ namespace triagens {
/// @brief get the domain type of an endpoint
////////////////////////////////////////////////////////////////////////////////
DomainType getDomainType () const {
virtual DomainType getDomainType () const {
return _domainType;
}

View File

@ -126,6 +126,7 @@ TRI_socket_t EndpointIp::connectSocket (const struct addrinfo* aip,
#ifdef _WIN32
char windowsErrorBuf[256];
#endif
// set address and port
char host[NI_MAXHOST];
char serv[NI_MAXSERV];

257
lib/Rest/EndpointSrv.cpp Normal file
View File

@ -0,0 +1,257 @@
////////////////////////////////////////////////////////////////////////////////
/// DISCLAIMER
///
/// Copyright 2016 ArangoDB GmbH, Cologne, Germany
///
/// Licensed 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.
///
/// Copyright holder is ArangoDB GmbH, Cologne, Germany
///
/// @author Dr. Frank Celler
/// @author Copyright 2016, ArangoDB GmbH, Cologne, Germany
////////////////////////////////////////////////////////////////////////////////
#include "EndpointSrv.h"
#ifndef _WIN32
#define BIND_4_COMPAT 1 // LINUX
#define BIND_8_COMPAT 1 // MACOSX
#include <netinet/in.h>
#include <arpa/inet.h>
#include <arpa/nameser.h>
#include <resolv.h>
#include "Basics/logging.h"
#include "Rest/EndpointIp.h"
using namespace triagens::basics;
using namespace triagens::rest;
#if PACKETSZ > 1024
#define MAXPACKET PACKETSZ
#else
#define MAXPACKET 1024
#endif
union QueryBuffer {
::HEADER header;
unsigned char buffer[MAXPACKET];
};
struct SrvRecord {
int priority;
int weight;
int port;
std::string name;
};
std::vector<SrvRecord> srvRecords(std::string specification) {
res_init();
char const* dname = specification.c_str();
int nclass = ns_c_in;
int type = ns_t_srv;
QueryBuffer answer;
int anslen = sizeof(answer);
int n = res_search(dname, nclass, type, answer.buffer, anslen);
std::vector<SrvRecord> services;
if (n != -1) {
HEADER* hp = &answer.header;
int qdcount = ntohs(hp->qdcount);
int ancount = ntohs(hp->ancount);
unsigned char* msg = answer.buffer;
unsigned char* eom = msg + n;
unsigned char* cp = msg + sizeof(HEADER);
unsigned char hostbuf[256];
while (0 < qdcount-- && cp < eom) {
n = dn_expand(msg, eom, cp, (char*)hostbuf, 256);
if (n < 0) {
LOG_WARNING("DNS record for '%s' is corrupt", specification.c_str());
return {};
}
cp += n + QFIXEDSZ;
}
// loop through the answer buffer and extract SRV records
while (0 < ancount-- && cp < eom) {
n = dn_expand(msg, eom, cp, (char*)hostbuf, 256);
if (n < 0) {
LOG_WARNING("DNS record for '%s' is corrupt", specification.c_str());
return {};
}
cp += n;
int type = _getshort(cp);
cp += 2;
int nclass = _getshort(cp);
cp += 2;
int ttl = _getlong(cp);
cp += 4;
int dlen = _getshort(cp);
cp += 2;
int priority = _getshort(cp);
cp += 2;
int weight = _getshort(cp);
cp += 2;
int port = _getshort(cp);
cp += 2;
n = dn_expand(msg, eom, cp, (char*)hostbuf, 256);
if (n < 0) {
LOG_WARNING("DNS record for '%s' is corrupt", specification.c_str());
break;
}
cp += n;
LOG_TRACE("DNS record for '%s': type %d, class %d, ttl %d, len %d, prio %d, "
" weight %d, port %d, host '%s'", specification.c_str(),
type, nclass, ttl, dlen, priority, weight, port, hostbuf);
if (type != T_SRV) {
continue;
}
SrvRecord srv;
srv.weight = weight;
srv.priority = priority;
srv.port = port;
srv.name = (char*)hostbuf;
services.push_back(srv);
}
} else {
LOG_WARNING("DNS record for '%s' not found", specification.c_str());
}
std::sort(services.begin(), services.end(),
[](SrvRecord const& lhs, SrvRecord const& rhs) {
if (lhs.priority != rhs.priority) {
return lhs.priority < rhs.priority;
}
return lhs.weight > rhs.weight;
});
return services;
}
#else
std::vector<SrvRecord> srvRecords(std::string specification) {
return {};
}
#endif
EndpointSrv::EndpointSrv(std::string const& specification)
: Endpoint(ENDPOINT_CLIENT, DOMAIN_SRV, ENCRYPTION_NONE, specification, 0) {
LOG_ERROR("%s", specification.c_str());
}
EndpointSrv::~EndpointSrv() {}
bool EndpointSrv::isConnected() const {
if (_endpoint != nullptr) {
return _endpoint->isConnected();
}
return false;
}
TRI_socket_t EndpointSrv::connect(double connectTimeout,
double requestTimeout) {
LOG_ERROR("connecting to ip endpoint '%s'", _specification.c_str());
auto services = srvRecords(_specification);
TRI_socket_t res;
for (auto service : services) {
std::string spec =
"tcp://" + service.name + ":" + StringUtils::itoa(service.port);
_endpoint.reset(Endpoint::clientFactory(spec));
res = _endpoint->connect(connectTimeout, requestTimeout);
if (_endpoint->isConnected()) {
return res;
}
}
TRI_invalidatesocket(&res);
return res;
}
void EndpointSrv::disconnect() {
if (_endpoint != nullptr) {
_endpoint->disconnect();
}
}
bool EndpointSrv::initIncoming(TRI_socket_t) { return false; }
int EndpointSrv::getDomain() const {
if (_endpoint != nullptr) {
return _endpoint->getDomain();
}
return -1;
}
int EndpointSrv::getPort() const {
if (_endpoint != nullptr) {
return _endpoint->getPort();
}
return -1;
}
std::string EndpointSrv::getHost() const {
if (_endpoint != nullptr) {
return _endpoint->getHost();
}
return "";
}
std::string EndpointSrv::getHostString() const {
if (_endpoint != nullptr) {
return _endpoint->getHostString();
}
return "";
}

53
lib/Rest/EndpointSrv.h Normal file
View File

@ -0,0 +1,53 @@
////////////////////////////////////////////////////////////////////////////////
/// DISCLAIMER
///
/// Copyright 2016 ArangoDB GmbH, Cologne, Germany
///
/// Licensed 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.
///
/// Copyright holder is ArangoDB GmbH, Cologne, Germany
///
/// @author Dr. Frank Celler
/// @author Copyright 2016, ArangoDB GmbH, Cologne, Germany
////////////////////////////////////////////////////////////////////////////////
#ifndef ARANGODB_REST_ENDPOINT_SRV_H
#define ARANGODB_REST_ENDPOINT_SRV_H 1
#include "Rest/Endpoint.h"
namespace triagens {
namespace rest {
class EndpointSrv final : public Endpoint {
public:
explicit EndpointSrv(std::string const&);
~EndpointSrv();
public:
bool isConnected() const override;
TRI_socket_t connect(double, double) override;
void disconnect() override;
bool initIncoming(TRI_socket_t) override;
int getDomain() const override;
int getPort() const override;
std::string getHost() const override;
std::string getHostString() const override;
private:
std::unique_ptr<Endpoint> _endpoint;
};
}
}
#endif