mirror of https://gitee.com/bigwinds/arangodb
Merge branch 'devel' of ssh://github.com/arangodb/arangodb into devel
This commit is contained in:
commit
600cef8ec4
35
.travis.yml
35
.travis.yml
|
@ -1,3 +1,18 @@
|
|||
branches:
|
||||
only:
|
||||
- master
|
||||
- 1.0
|
||||
- 1.1
|
||||
- 1.2
|
||||
- 1.3
|
||||
- 1.4
|
||||
- 2.0
|
||||
- 2.1
|
||||
- 2.2
|
||||
- 2.3
|
||||
- 2.4
|
||||
- devel
|
||||
|
||||
language: cpp
|
||||
compiler: g++
|
||||
|
||||
|
@ -27,20 +42,8 @@ install:
|
|||
- sudo apt-get -y install gdb
|
||||
|
||||
before_script: "bash -c Installation/travisCI/before_script.sh"
|
||||
script: "bash -c Installation/travisCI/script.sh"
|
||||
script:
|
||||
- "bash -c Installation/travisCI/build.sh"
|
||||
- "bash -c Installation/travisCI/jslint.sh"
|
||||
- "bash -c Installation/travisCI/tests.sh"
|
||||
after_failure: "bash -c Installation/travisCI/after_failure.sh"
|
||||
branches:
|
||||
only:
|
||||
- master
|
||||
- 1.0
|
||||
- 1.1
|
||||
- 1.2
|
||||
- 1.3
|
||||
- 1.4
|
||||
- 2.0
|
||||
- 2.1
|
||||
- 2.2
|
||||
- 2.3
|
||||
- 2.4
|
||||
- devel
|
||||
|
||||
|
|
10
CHANGELOG
10
CHANGELOG
|
@ -29,10 +29,18 @@ v2.5.0 (XXXX-XX-XX)
|
|||
v2.4.2 (2015-XX-XX)
|
||||
-------------------
|
||||
|
||||
* added custom visitor functionality for AQL traversals
|
||||
|
||||
This allows more complex result processing in traversals triggered by AQL. A few examples
|
||||
are shown in [this article](http://jsteemann.github.io/blog/2015/01/28/using-custom-visitors-in-aql-graph-traversals/).
|
||||
|
||||
* improved number of results estimated for nodes of type EnumerateListNode and SubqueryNode
|
||||
in AQL explain output
|
||||
|
||||
* added AQL explain helper:
|
||||
* added AQL explain helper to explain arbitrary AQL queries
|
||||
|
||||
The helper function prints the query execution plan and the indexes to be used in the
|
||||
query. It can be invoked from the ArangoShell or the web interface as follows:
|
||||
|
||||
require("org/arangodb/aql/explainer").explain(query);
|
||||
|
||||
|
|
|
@ -18,8 +18,6 @@ following attribute naming constraints are not violated:
|
|||
end users should try to avoid using their own attribute names starting with
|
||||
underscores.
|
||||
|
||||
* Attribute names should not start with the at-mark (*@*). The at-mark
|
||||
at the start of attribute names is reserved in ArangoDB for future use cases.
|
||||
* Theoretically, attribute names can include punctuation and special characters
|
||||
as desired, provided the name is a valid UTF-8 string. For maximum
|
||||
portability, special characters should be avoided though. For example,
|
||||
|
@ -30,6 +28,10 @@ following attribute naming constraints are not violated:
|
|||
attribute names which don't require any quoting/escaping in all languages
|
||||
used. This includes languages used by the client (e.g. Ruby, PHP) if the
|
||||
attributes are mapped to object members there.
|
||||
* Attribute names starting with an at-mark (*@*) will need to be enclosed in
|
||||
backticks when used in an AQL query to tell them apart from bind variables.
|
||||
Therefore we do not encourage the use of attributes starting with at-marks,
|
||||
though they will work when used properly.
|
||||
* ArangoDB does not enforce a length limit for attribute names. However, long
|
||||
attribute names may use more memory in result sets etc. Therefore the use
|
||||
of long attribute names is discouraged.
|
||||
|
|
|
@ -436,9 +436,9 @@ SHELL_COMMON = \
|
|||
@top_srcdir@/js/common/tests/shell-errors.js \
|
||||
@top_srcdir@/js/common/tests/shell-fs.js \
|
||||
@top_srcdir@/js/common/tests/shell-general-graph.js \
|
||||
@top_srcdir@/js/common/tests/shell-graph-traversal.js \
|
||||
@top_srcdir@/js/common/tests/shell-graph-algorithms.js \
|
||||
@top_srcdir@/js/common/tests/shell-graph-measurement.js \
|
||||
@top_srcdir@/js/common/tests/shell-graph-traversal.js \
|
||||
@top_srcdir@/js/common/tests/shell-keygen.js \
|
||||
@top_srcdir@/js/common/tests/shell-keygen-noncluster.js \
|
||||
@top_srcdir@/js/common/tests/shell-index-ensure.js \
|
||||
|
@ -553,6 +553,7 @@ SHELL_SERVER_AQL = @top_srcdir@/js/server/tests/aql-arithmetic.js \
|
|||
@top_srcdir@/js/server/tests/aql-functions-types.js \
|
||||
@top_srcdir@/js/server/tests/aql-general-graph.js \
|
||||
@top_srcdir@/js/server/tests/aql-graph.js \
|
||||
@top_srcdir@/js/server/tests/aql-graph-visitors.js \
|
||||
@top_srcdir@/js/server/tests/aql-hash-noncluster.js \
|
||||
@top_srcdir@/js/server/tests/aql-is-in-polygon.js \
|
||||
@top_srcdir@/js/server/tests/aql-logical.js \
|
||||
|
|
|
@ -1578,6 +1578,7 @@ void RestReplicationHandler::handleCommandRestoreCollection () {
|
|||
TRI_Insert3ObjectJson(TRI_CORE_MEM_ZONE, &result, "result", TRI_CreateBooleanJson(TRI_CORE_MEM_ZONE, true));
|
||||
|
||||
generateResult(&result);
|
||||
TRI_DestroyJson(TRI_CORE_MEM_ZONE, &result);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1624,6 +1625,7 @@ void RestReplicationHandler::handleCommandRestoreIndexes () {
|
|||
TRI_Insert3ObjectJson(TRI_CORE_MEM_ZONE, &result, "result", TRI_CreateBooleanJson(TRI_CORE_MEM_ZONE, true));
|
||||
|
||||
generateResult(&result);
|
||||
TRI_DestroyJson(TRI_CORE_MEM_ZONE, &result);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2403,6 +2405,7 @@ void RestReplicationHandler::handleCommandRestoreData () {
|
|||
TRI_Insert3ObjectJson(TRI_CORE_MEM_ZONE, &result, "result", TRI_CreateBooleanJson(TRI_CORE_MEM_ZONE, true));
|
||||
|
||||
generateResult(&result);
|
||||
TRI_DestroyJson(TRI_CORE_MEM_ZONE, &result);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2693,6 +2696,7 @@ void RestReplicationHandler::handleCommandRestoreDataCoordinator () {
|
|||
TRI_Insert3ObjectJson(TRI_CORE_MEM_ZONE, &result, "result", TRI_CreateBooleanJson(TRI_CORE_MEM_ZONE, true));
|
||||
|
||||
generateResult(&result);
|
||||
TRI_DestroyJson(TRI_CORE_MEM_ZONE, &result);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -367,6 +367,25 @@ function startInstance (protocol, options, addArgs, testname) {
|
|||
return instanceInfo;
|
||||
}
|
||||
|
||||
function readImportantLogLines(logFilename) {
|
||||
var importantLines = [];
|
||||
var buf = fs.readBuffer(logFilename);
|
||||
var i;
|
||||
var lineStart = 0;
|
||||
var maxBuffer = buf.length;
|
||||
for (i = 0; i < maxBuffer; i++) {
|
||||
if (buf[i] === 10) { // \n
|
||||
var line = buf.asciiSlice(lineStart, i - 1);
|
||||
// filter out regular INFO lines, and test related messages
|
||||
if ((line.search(" INFO ") < 0) &&
|
||||
(line.search("WARNING about to execute:") < 0)) {
|
||||
importantLines.push(line);
|
||||
}
|
||||
lineStart = i + 1;
|
||||
}
|
||||
}
|
||||
return importantLines;
|
||||
}
|
||||
|
||||
function copy (src, dst) {
|
||||
var fs = require("fs");
|
||||
|
@ -503,6 +522,8 @@ function shutdownInstance (instanceInfo, options) {
|
|||
}
|
||||
|
||||
}
|
||||
instanceInfo.importantLogLines = readImportantLogLines(fs.join(instanceInfo.tmpDataDir, "log"));
|
||||
|
||||
cleanupDirectories = cleanupDirectories.concat([instanceInfo.tmpDataDir, instanceInfo.flatTmpDataDir]);
|
||||
}
|
||||
|
||||
|
@ -792,6 +813,9 @@ function performTests(options, testList, testname, remote) {
|
|||
shutdownInstance(instanceInfo,options);
|
||||
}
|
||||
print("done.");
|
||||
if (instanceInfo.hasOwnProperty('importantLogLines') && instanceInfo.importantLogLines.length > 0) {
|
||||
print("Found messages in the server logs: \n" + yaml.safeDump(instanceInfo.importantLogLines));
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
|
@ -828,6 +852,10 @@ testFuncs.single_server = function (options) {
|
|||
}
|
||||
shutdownInstance(instanceInfo,options);
|
||||
print("done.");
|
||||
|
||||
if (instanceInfo.hasOwnProperty('importantLogLines') && instanceInfo.importantLogLines.length > 0) {
|
||||
print("Found messages in the server logs: \n" + yaml.safeDump(instanceInfo.importantLogLines));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
else {
|
||||
|
@ -872,6 +900,9 @@ testFuncs.single_client = function (options) {
|
|||
}
|
||||
shutdownInstance(instanceInfo,options);
|
||||
print("done.");
|
||||
if (instanceInfo.hasOwnProperty('importantLogLines') && instanceInfo.importantLogLines.length > 0) {
|
||||
print("Found messages in the server logs: \n" + yaml.safeDump(instanceInfo.importantLogLines));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
else {
|
||||
|
@ -989,6 +1020,9 @@ testFuncs.shell_client = function(options) {
|
|||
print("Shutting down...");
|
||||
shutdownInstance(instanceInfo, options);
|
||||
print("done.");
|
||||
if (instanceInfo.hasOwnProperty('importantLogLines') && instanceInfo.importantLogLines.length > 0) {
|
||||
print("Found messages in the server logs: \n" + yaml.safeDump(instanceInfo.importantLogLines));
|
||||
}
|
||||
return results;
|
||||
};
|
||||
|
||||
|
@ -1114,6 +1148,9 @@ function rubyTests (options, ssl) {
|
|||
fs.remove(tmpname);
|
||||
shutdownInstance(instanceInfo,options);
|
||||
print("done.");
|
||||
if (instanceInfo.hasOwnProperty('importantLogLines') && instanceInfo.importantLogLines.length > 0) {
|
||||
print("Found messages in the server logs: \n" + yaml.safeDump(instanceInfo.importantLogLines));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -1256,6 +1293,9 @@ testFuncs.importing = function (options) {
|
|||
print("Shutting down...");
|
||||
shutdownInstance(instanceInfo,options);
|
||||
print("done.");
|
||||
if (instanceInfo.hasOwnProperty('importantLogLines') && instanceInfo.importantLogLines.length > 0) {
|
||||
print("Found messages in the server logs: \n" + yaml.safeDump(instanceInfo.importantLogLines));
|
||||
}
|
||||
return result;
|
||||
};
|
||||
|
||||
|
@ -1315,6 +1355,9 @@ testFuncs.foxx_manager = function (options) {
|
|||
print("Shutting down...");
|
||||
shutdownInstance(instanceInfo,options);
|
||||
print("done.");
|
||||
if (instanceInfo.hasOwnProperty('importantLogLines') && instanceInfo.importantLogLines.length > 0) {
|
||||
print("Found messages in the server logs: \n" + yaml.safeDump(instanceInfo.importantLogLines));
|
||||
}
|
||||
return results;
|
||||
};
|
||||
|
||||
|
@ -1349,6 +1392,9 @@ testFuncs.dump = function (options) {
|
|||
print("Shutting down...");
|
||||
shutdownInstance(instanceInfo,options);
|
||||
print("done.");
|
||||
if (instanceInfo.hasOwnProperty('importantLogLines') && instanceInfo.importantLogLines.length > 0) {
|
||||
print("Found messages in the server logs: \n" + yaml.safeDump(instanceInfo.importantLogLines));
|
||||
}
|
||||
return results;
|
||||
};
|
||||
|
||||
|
@ -1409,6 +1455,9 @@ testFuncs.arangob = function (options) {
|
|||
print("Shutting down...");
|
||||
shutdownInstance(instanceInfo,options);
|
||||
print("done.");
|
||||
if (instanceInfo.hasOwnProperty('importantLogLines') && instanceInfo.importantLogLines.length > 0) {
|
||||
print("Found messages in the server logs: \n" + yaml.safeDump(instanceInfo.importantLogLines));
|
||||
}
|
||||
return results;
|
||||
};
|
||||
|
||||
|
@ -1426,6 +1475,9 @@ testFuncs.authentication = function (options) {
|
|||
print("Shutting down...");
|
||||
shutdownInstance(instanceInfo,options);
|
||||
print("done.");
|
||||
if (instanceInfo.hasOwnProperty('importantLogLines') && instanceInfo.importantLogLines.length > 0) {
|
||||
print("Found messages in the server logs: \n" + yaml.safeDump(instanceInfo.importantLogLines));
|
||||
}
|
||||
return results;
|
||||
};
|
||||
|
||||
|
@ -1493,6 +1545,9 @@ testFuncs.authentication_parameters = function (options) {
|
|||
|
||||
print("Shutting down Full test...");
|
||||
shutdownInstance(instanceInfo,options);
|
||||
if (instanceInfo.hasOwnProperty('importantLogLines') && instanceInfo.importantLogLines.length > 0) {
|
||||
print("Found messages in the server logs: \n" + yaml.safeDump(instanceInfo.importantLogLines));
|
||||
}
|
||||
print("done with Full test.");
|
||||
// Only system authentication:
|
||||
continueTesting = true;
|
||||
|
@ -1533,6 +1588,9 @@ testFuncs.authentication_parameters = function (options) {
|
|||
|
||||
print("Shutting down System test...");
|
||||
shutdownInstance(instanceInfo,options);
|
||||
if (instanceInfo.hasOwnProperty('importantLogLines') && instanceInfo.importantLogLines.length > 0) {
|
||||
print("Found messages in the server logs: \n" + yaml.safeDump(instanceInfo.importantLogLines));
|
||||
}
|
||||
print("done with System test.");
|
||||
// No authentication:
|
||||
instanceInfo = startInstance("tcp", options,
|
||||
|
@ -1574,6 +1632,9 @@ testFuncs.authentication_parameters = function (options) {
|
|||
|
||||
print("Shutting down None test...");
|
||||
shutdownInstance(instanceInfo,options);
|
||||
if (instanceInfo.hasOwnProperty('importantLogLines') && instanceInfo.importantLogLines.length > 0) {
|
||||
print("Found messages in the server logs: \n" + yaml.safeDump(instanceInfo.importantLogLines));
|
||||
}
|
||||
print("done with None test.");
|
||||
return results;
|
||||
};
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -265,6 +265,16 @@ namespace triagens {
|
|||
|
||||
virtual std::string getHostString () const = 0;
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- protected variables
|
||||
// -----------------------------------------------------------------------------
|
||||
public:
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief error message if failure occured
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
std::string _errorMessage;
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- protected variables
|
||||
// -----------------------------------------------------------------------------
|
||||
|
|
|
@ -39,6 +39,23 @@
|
|||
using namespace triagens::basics;
|
||||
using namespace triagens::rest;
|
||||
|
||||
|
||||
#ifdef _WIN32
|
||||
#define STR_ERROR() \
|
||||
windowsErrorBuf; \
|
||||
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, \
|
||||
NULL, \
|
||||
GetLastError(), \
|
||||
0, \
|
||||
windowsErrorBuf, \
|
||||
sizeof(windowsErrorBuf), NULL); \
|
||||
errno = GetLastError();
|
||||
#else
|
||||
#define STR_ERROR() strerror(errno)
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- EndpointIp
|
||||
// -----------------------------------------------------------------------------
|
||||
|
@ -104,6 +121,11 @@ EndpointIp::~EndpointIp () {
|
|||
TRI_socket_t EndpointIp::connectSocket (const struct addrinfo* aip,
|
||||
double connectTimeout,
|
||||
double requestTimeout) {
|
||||
const char *pErr;
|
||||
char errBuf[256];
|
||||
#ifdef _WIN32
|
||||
char windowsErrorBuf[256];
|
||||
#endif
|
||||
// set address and port
|
||||
char host[NI_MAXHOST];
|
||||
char serv[NI_MAXSERV];
|
||||
|
@ -119,7 +141,13 @@ TRI_socket_t EndpointIp::connectSocket (const struct addrinfo* aip,
|
|||
listenSocket = TRI_socket(aip->ai_family, aip->ai_socktype, aip->ai_protocol);
|
||||
|
||||
if (! TRI_isvalidsocket(listenSocket)) {
|
||||
LOG_ERROR("socket() failed with %d (%s)", errno, strerror(errno));
|
||||
pErr = STR_ERROR();
|
||||
snprintf(errBuf, sizeof(errBuf),
|
||||
"socket() failed with %d - %s",
|
||||
errno, pErr);
|
||||
|
||||
LOG_ERROR("%s", errBuf);
|
||||
_errorMessage = errBuf;
|
||||
return listenSocket;
|
||||
}
|
||||
|
||||
|
@ -129,7 +157,14 @@ TRI_socket_t EndpointIp::connectSocket (const struct addrinfo* aip,
|
|||
int excl = 1;
|
||||
if (TRI_setsockopt(listenSocket, SOL_SOCKET, SO_EXCLUSIVEADDRUSE,
|
||||
reinterpret_cast<char*> (&excl), sizeof (excl)) == -1) {
|
||||
LOG_ERROR("setsockopt() failed with %d", WSAGetLastError());
|
||||
|
||||
pErr = STR_ERROR();
|
||||
snprintf(errBuf, sizeof(errBuf), "setsockopt() failed with #%d - %s",
|
||||
errno,
|
||||
pErr);
|
||||
|
||||
LOG_ERROR("%s", errBuf);
|
||||
_errorMessage = errBuf;
|
||||
|
||||
TRI_CLOSE_SOCKET(listenSocket);
|
||||
TRI_invalidatesocket(&listenSocket);
|
||||
|
@ -140,7 +175,14 @@ TRI_socket_t EndpointIp::connectSocket (const struct addrinfo* aip,
|
|||
if (_reuseAddress) {
|
||||
int opt = 1;
|
||||
if (TRI_setsockopt(listenSocket, SOL_SOCKET, SO_REUSEADDR, reinterpret_cast<char*> (&opt), sizeof (opt)) == -1) {
|
||||
LOG_ERROR("setsockopt() failed with %d (%s)", errno, strerror(errno));
|
||||
|
||||
pErr = STR_ERROR();
|
||||
snprintf(errBuf, sizeof(errBuf), "setsockopt() failed with #%d - %s",
|
||||
errno,
|
||||
pErr);
|
||||
|
||||
LOG_ERROR("%s", errBuf);
|
||||
_errorMessage = errBuf;
|
||||
|
||||
TRI_CLOSE_SOCKET(listenSocket);
|
||||
TRI_invalidatesocket(&listenSocket);
|
||||
|
@ -153,12 +195,16 @@ TRI_socket_t EndpointIp::connectSocket (const struct addrinfo* aip,
|
|||
int result = TRI_bind(listenSocket, aip->ai_addr, (int) aip->ai_addrlen);
|
||||
|
||||
if (result != 0) {
|
||||
// error
|
||||
#ifndef _WIN32
|
||||
LOG_ERROR("bind(address '%s', port %d) failed with %d (%s)", host, (int) _port, errno, strerror(errno));
|
||||
#else
|
||||
LOG_ERROR("bind(address '%s', port %d) failed with %d", host, (int) _port, WSAGetLastError());
|
||||
#endif
|
||||
pErr = STR_ERROR();
|
||||
snprintf(errBuf, sizeof(errBuf), "bind(address '%s', port %d) failed with #%d - %s",
|
||||
host,
|
||||
(int) _port,
|
||||
errno,
|
||||
pErr);
|
||||
|
||||
LOG_ERROR("%s", errBuf);
|
||||
_errorMessage = errBuf;
|
||||
|
||||
TRI_CLOSE_SOCKET(listenSocket);
|
||||
|
||||
TRI_invalidatesocket(&listenSocket);
|
||||
|
@ -170,8 +216,13 @@ TRI_socket_t EndpointIp::connectSocket (const struct addrinfo* aip,
|
|||
result = TRI_listen(listenSocket, _listenBacklog);
|
||||
|
||||
if (result != 0) {
|
||||
// todo: get the correct error code using WSAGetLastError for windows
|
||||
LOG_ERROR("listen() failed with %d (%s)", errno, strerror(errno));
|
||||
pErr = STR_ERROR();
|
||||
snprintf(errBuf, sizeof(errBuf),
|
||||
"listen() failed with #%d - %s",
|
||||
errno, pErr);
|
||||
|
||||
LOG_ERROR("%s", errBuf);
|
||||
_errorMessage = errBuf;
|
||||
|
||||
TRI_CLOSE_SOCKET(listenSocket);
|
||||
TRI_invalidatesocket(&listenSocket);
|
||||
|
@ -187,6 +238,14 @@ TRI_socket_t EndpointIp::connectSocket (const struct addrinfo* aip,
|
|||
int result = TRI_connect(listenSocket, (const struct sockaddr*) aip->ai_addr, (int) aip->ai_addrlen);
|
||||
|
||||
if (result != 0) {
|
||||
pErr = STR_ERROR();
|
||||
snprintf(errBuf, sizeof(errBuf),
|
||||
"connect() failed with #%d - %s",
|
||||
errno, pErr);
|
||||
|
||||
LOG_ERROR("%s", errBuf);
|
||||
_errorMessage = errBuf;
|
||||
|
||||
TRI_CLOSE_SOCKET(listenSocket);
|
||||
TRI_invalidatesocket(&listenSocket);
|
||||
return listenSocket;
|
||||
|
@ -256,10 +315,12 @@ TRI_socket_t EndpointIp::connect (double connectTimeout,
|
|||
switch (lastError) {
|
||||
case WSANOTINITIALISED: {
|
||||
LOG_ERROR("getaddrinfo for host '%s': WSAStartup was not called or not called successfully.", _host.c_str());
|
||||
_errorMessage = std::string("getaddrinfo for host '") + _host + std::string("': WSAStartup was not called or not called successfully.");
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
LOG_ERROR("getaddrinfo for host '%s': %s", _host.c_str(), gai_strerror(error));
|
||||
_errorMessage = std::string("getaddrinfo for host '") + _host + std::string("': ") + gai_strerror(error);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -313,6 +374,7 @@ TRI_socket_t EndpointIp::connect (double connectTimeout, double requestTimeout)
|
|||
|
||||
if (error != 0) {
|
||||
LOG_ERROR("getaddrinfo for host '%s': %s", _host.c_str(), gai_strerror(error));
|
||||
_errorMessage = std::string("getaddrinfo for host '") + _host + std::string("': ") + gai_strerror(error);
|
||||
|
||||
if (result != 0) {
|
||||
freeaddrinfo(result);
|
||||
|
@ -362,9 +424,19 @@ bool EndpointIp::initIncoming (TRI_socket_t incoming) {
|
|||
int res = TRI_setsockopt(incoming, IPPROTO_TCP, TCP_NODELAY, (char*) &n, sizeof(n));
|
||||
|
||||
if (res != 0 ) {
|
||||
// todo: get correct windows error code
|
||||
LOG_WARNING("setsockopt failed with %d (%s)", errno, strerror(errno));
|
||||
const char *pErr;
|
||||
char errBuf[256];
|
||||
#ifdef _WIN32
|
||||
char windowsErrorBuf[256];
|
||||
#endif
|
||||
|
||||
pErr = STR_ERROR();
|
||||
snprintf(errBuf, sizeof(errBuf), "setsockopt failed with #%d - %s",
|
||||
errno,
|
||||
pErr);
|
||||
|
||||
LOG_WARNING("%s", errBuf);
|
||||
_errorMessage = errBuf;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -122,7 +122,7 @@ bool ClientConnection::connectSocket () {
|
|||
_socket = _endpoint->connect(_connectTimeout, _requestTimeout);
|
||||
|
||||
if (! TRI_isvalidsocket(_socket)) {
|
||||
_errorDetails = std::string("failed to connect : ") + std::string(strerror(errno));
|
||||
_errorDetails = _endpoint->_errorMessage;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -162,10 +162,11 @@ namespace triagens {
|
|||
&bytesWritten);
|
||||
|
||||
if (! res) {
|
||||
if (TRI_errno() != TRI_ERROR_NO_ERROR) {
|
||||
setErrorMessage(TRI_last_error(), false);
|
||||
}
|
||||
|
||||
setErrorMessage("Error writing to '" +
|
||||
_connection->getEndpoint()->getSpecification() +
|
||||
"' '" +
|
||||
_connection->getErrorDetails() +
|
||||
"'");
|
||||
this->close(); // this sets _state to IN_CONNECT for a retry
|
||||
}
|
||||
else {
|
||||
|
@ -194,6 +195,11 @@ namespace triagens {
|
|||
|
||||
// If there was an error, then we are doomed:
|
||||
if (! res) {
|
||||
setErrorMessage("Error reading from: '" +
|
||||
_connection->getEndpoint()->getSpecification() +
|
||||
"' '" +
|
||||
_connection->getErrorDetails() +
|
||||
"'");
|
||||
this->close(); // this sets the state to IN_CONNECT for a retry
|
||||
break;
|
||||
}
|
||||
|
@ -292,7 +298,7 @@ namespace triagens {
|
|||
_connection->getEndpoint()->getSpecification() +
|
||||
"' '" +
|
||||
_connection->getErrorDetails() +
|
||||
"' '");
|
||||
"'");
|
||||
_state = DEAD;
|
||||
}
|
||||
else {
|
||||
|
|
|
@ -51,6 +51,19 @@
|
|||
|
||||
#include <openssl/ssl.h>
|
||||
|
||||
#ifdef _WIN32
|
||||
#define STR_ERROR() \
|
||||
windowsErrorBuf; \
|
||||
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, \
|
||||
NULL, \
|
||||
GetLastError(), \
|
||||
0, \
|
||||
windowsErrorBuf, \
|
||||
sizeof(windowsErrorBuf), NULL); \
|
||||
errno = GetLastError();
|
||||
#else
|
||||
#define STR_ERROR() strerror(errno)
|
||||
#endif
|
||||
|
||||
|
||||
using namespace triagens::basics;
|
||||
|
@ -137,6 +150,11 @@ SslClientConnection::~SslClientConnection () {
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool SslClientConnection::connectSocket () {
|
||||
const char *pErr;
|
||||
#ifdef _WIN32
|
||||
char windowsErrorBuf[256];
|
||||
#endif
|
||||
|
||||
TRI_ASSERT(_endpoint != nullptr);
|
||||
|
||||
if (_endpoint->isConnected()) {
|
||||
|
@ -146,7 +164,7 @@ bool SslClientConnection::connectSocket () {
|
|||
_socket = _endpoint->connect(_connectTimeout, _requestTimeout);
|
||||
|
||||
if (! TRI_isvalidsocket(_socket) || _ctx == nullptr) {
|
||||
_errorDetails = std::string("failed to connect : ") + std::string(strerror(errno));
|
||||
_errorDetails = _endpoint->_errorMessage;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -181,38 +199,43 @@ bool SslClientConnection::connectSocket () {
|
|||
(errorDetail == SSL_ERROR_WANT_WRITE)) {
|
||||
return true;
|
||||
}
|
||||
errorDetail = ERR_get_error(); /* Gets the earliest error code from the
|
||||
thread's error queue and removes the
|
||||
entry. */
|
||||
switch(errorDetail) {
|
||||
case 0x1407E086:
|
||||
/* 1407E086:
|
||||
SSL routines:
|
||||
SSL2_SET_CERTIFICATE:
|
||||
certificate verify failed */
|
||||
/* fall-through */
|
||||
case 0x14090086:
|
||||
/* 14090086:
|
||||
SSL routines:
|
||||
SSL3_GET_SERVER_CERTIFICATE:
|
||||
certificate verify failed */
|
||||
|
||||
certError = SSL_get_verify_result(_ssl);
|
||||
if(certError != X509_V_OK) {
|
||||
_errorDetails = std::string("SSL: certificate problem: ") +
|
||||
X509_verify_cert_error_string(certError);
|
||||
}
|
||||
else {
|
||||
_errorDetails = std::string("SSL: certificate problem, verify that the CA cert is OK.");
|
||||
}
|
||||
break;
|
||||
default:
|
||||
char errorBuffer[256];
|
||||
ERR_error_string_n(errorDetail, errorBuffer, sizeof(errorBuffer));
|
||||
_errorDetails = std::string("SSL: ") + errorBuffer;
|
||||
break;
|
||||
else if (errorDetail == SSL_ERROR_SYSCALL) {
|
||||
pErr = STR_ERROR();
|
||||
_errorDetails = std::string("SSL: during SSL_connect: ") + std::to_string(errno) + std::string(" - ") + pErr;
|
||||
}
|
||||
else {
|
||||
errorDetail = ERR_get_error(); /* Gets the earliest error code from the
|
||||
thread's error queue and removes the
|
||||
entry. */
|
||||
switch(errorDetail) {
|
||||
case 0x1407E086:
|
||||
/* 1407E086:
|
||||
SSL routines:
|
||||
SSL2_SET_CERTIFICATE:
|
||||
certificate verify failed */
|
||||
/* fall-through */
|
||||
case 0x14090086:
|
||||
/* 14090086:
|
||||
SSL routines:
|
||||
SSL3_GET_SERVER_CERTIFICATE:
|
||||
certificate verify failed */
|
||||
|
||||
certError = SSL_get_verify_result(_ssl);
|
||||
if(certError != X509_V_OK) {
|
||||
_errorDetails = std::string("SSL: certificate problem: ") +
|
||||
X509_verify_cert_error_string(certError);
|
||||
}
|
||||
else {
|
||||
_errorDetails = std::string("SSL: certificate problem, verify that the CA cert is OK.");
|
||||
}
|
||||
break;
|
||||
default:
|
||||
char errorBuffer[256];
|
||||
ERR_error_string_n(errorDetail, errorBuffer, sizeof(errorBuffer));
|
||||
_errorDetails = std::string("SSL: ") + errorBuffer;
|
||||
break;
|
||||
}
|
||||
}
|
||||
_endpoint->disconnect();
|
||||
SSL_free(_ssl);
|
||||
_ssl = 0;
|
||||
|
@ -278,6 +301,10 @@ bool SslClientConnection::prepare (const double timeout, const bool isWrite) con
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool SslClientConnection::writeClientConnection (void* buffer, size_t length, size_t* bytesWritten) {
|
||||
const char *pErr;
|
||||
#ifdef _WIN32
|
||||
char windowsErrorBuf[256];
|
||||
#endif
|
||||
*bytesWritten = 0;
|
||||
|
||||
if (_ssl == 0) {
|
||||
|
@ -301,8 +328,9 @@ bool SslClientConnection::writeClientConnection (void* buffer, size_t length, si
|
|||
case SSL_ERROR_WANT_CONNECT:
|
||||
break;
|
||||
case SSL_ERROR_SYSCALL:
|
||||
pErr = STR_ERROR();
|
||||
_errorDetails = std::string("SSL: while writing: SYSCALL returned errno = ") +
|
||||
std::to_string(errno) + std::string(" - ") + strerror(errno);
|
||||
std::to_string(errno) + std::string(" - ") + pErr;
|
||||
break;
|
||||
case SSL_ERROR_SSL:
|
||||
/* A failure in the SSL library occurred, usually a protocol error.
|
||||
|
@ -327,6 +355,11 @@ return false;
|
|||
|
||||
bool SslClientConnection::readClientConnection (StringBuffer& stringBuffer,
|
||||
bool& connectionClosed) {
|
||||
const char *pErr;
|
||||
#ifdef _WIN32
|
||||
char windowsErrorBuf[256];
|
||||
#endif
|
||||
|
||||
connectionClosed = true;
|
||||
if (_ssl == nullptr) {
|
||||
return false;
|
||||
|
@ -367,11 +400,12 @@ again:
|
|||
case SSL_ERROR_WANT_CONNECT:
|
||||
case SSL_ERROR_SYSCALL:
|
||||
default:
|
||||
pErr = STR_ERROR();
|
||||
int errorDetail = ERR_get_error();
|
||||
char errorBuffer[256];
|
||||
ERR_error_string_n(errorDetail, errorBuffer, sizeof(errorBuffer));
|
||||
_errorDetails = std::string("SSL: while reading: error '") + std::to_string(errno) +
|
||||
std::string("' - ") + errorBuffer;
|
||||
std::string("' - ") + errorBuffer + std::string("' - ") + pErr;
|
||||
|
||||
/* unexpected */
|
||||
connectionClosed = true;
|
||||
|
|
Loading…
Reference in New Issue