Changeset: a11f73dd283d for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/a11f73dd283d
Added Files:
clients/mapilib/connect_openssl.c
Modified Files:
clients/mapilib/CMakeLists.txt
clients/mapilib/connect.c
clients/mapilib/mapi_intern.h
Branch: monetdburl
Log Message:
Add conditionally compiled openssl stub
diffs (truncated from 372 to 300 lines):
diff --git a/clients/mapilib/CMakeLists.txt b/clients/mapilib/CMakeLists.txt
--- a/clients/mapilib/CMakeLists.txt
+++ b/clients/mapilib/CMakeLists.txt
@@ -11,6 +11,7 @@
add_library(mapi
SHARED)
+
# We need to add the public library twice to the target sources, once for
# the build interface and once for the install interface. This is because
# of the fact that cmake < 3.13 does not handle relative paths well. If we
@@ -22,6 +23,7 @@ target_sources(mapi
connect.c
msettings.c
parseurl.c
+ $<$<BOOL:${HAVE_OPENSSL}>:connect_openssl.c>
mapi_intern.h
PUBLIC
$<BUILD_INTERFACE:$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>/mapi.h>
diff --git a/clients/mapilib/connect.c b/clients/mapilib/connect.c
--- a/clients/mapilib/connect.c
+++ b/clients/mapilib/connect.c
@@ -27,8 +27,8 @@
static MapiMsg establish_connection(Mapi mid);
static MapiMsg scan_unix_sockets(Mapi mid);
static MapiMsg connect_socket(Mapi mid);
-static SOCKET connect_socket_unix(Mapi mid, const char *sockname);
-static SOCKET connect_socket_tcp(Mapi mid, const char *host, int port);
+static MapiMsg connect_socket_unix(Mapi mid);
+static MapiMsg connect_socket_tcp(Mapi mid);
static SOCKET connect_socket_tcp_addr(Mapi mid, struct addrinfo *addr);
static MapiMsg mapi_handshake(Mapi mid);
@@ -43,10 +43,6 @@ mapi_reconnect(Mapi mid)
return MERROR;
}
- bool tls = msetting_bool(mid->settings, MP_TLS);
- if (tls)
- return mapi_setError(mid, "TLS (monetdbs://...) is not
supported yet", __func__, MERROR);
-
// If neither host nor port are given, scan the Unix domain sockets in
// /tmp and see if any of them serve this database.
// Otherwise, just try to connect to what was given.
@@ -191,76 +187,122 @@ establish_connection(Mapi mid)
static MapiMsg
connect_socket(Mapi mid)
{
- SOCKET s = INVALID_SOCKET;
-
assert(!mid->connected);
const char *sockname = msettings_connect_unix(mid->settings);
const char *tcp_host = msettings_connect_tcp(mid->settings);
- int tcp_port = msettings_connect_port(mid->settings);
assert(*sockname || *tcp_host);
- if (*sockname) {
- s = connect_socket_unix(mid, sockname);
- }
- if (s == INVALID_SOCKET && *tcp_host) {
- s = connect_socket_tcp(mid, tcp_host, tcp_port);
- }
- if (s == INVALID_SOCKET) {
+ if (*sockname && connect_socket_unix(mid) == MOK) {
+ mid->connected = true;
+ return MOK;
+ } else if (*tcp_host && connect_socket_tcp(mid) == MOK) {
+ mid->connected = true;
+ return MOK;
+ } else {
assert(mid->error == MERROR);
- mid->error = MERROR;
+ mid->error = MERROR; // in case assert above was not enabled
return mid->error;
}
- mid->to = socket_wstream(s, "Mapi client write");
- mapi_log_record(mid, "Mapi client write");
- mid->from = socket_rstream(s, "Mapi client read");
- mapi_log_record(mid, "Mapi client read");
- check_stream(mid, mid->to, "Cannot open socket for writing",
mid->error);
- check_stream(mid, mid->from, "Cannot open socket for reading",
mid->error);
+ assert(0 && "unreachable");
+ return MERROR;
+}
+
+static MapiMsg
+wrap_socket(Mapi mid, SOCKET sock)
+{
+ // do not use check_stream here yet because the socket is not yet in
'mid'
+ const char *error_message;
+ stream *error_stream;
+
+ stream *rstream = NULL;
+ stream *wstream = NULL;
+ stream *brstream = NULL;
+ stream *bwstream = NULL;
- // Send an even number of NUL '\0' bytes to the server.
- // This forces an error message when accidentally connecting to a TLS
server.
- // Also, surprisingly it seems to make connection setup slightly faster!
- static const char zeroes[8] = { 0 };
- for (ssize_t nleft = sizeof(zeroes); nleft > 0; ) {
- ssize_t nwritten = mnstr_write(mid->to, zeroes, 1, nleft);
- if (nwritten < 0)
- return mapi_setError(mid, "could not send leader
block", __func__, MERROR);
- nleft -= nwritten;
+ wstream = socket_wstream(sock, "Mapi client write");
+ if (wstream == NULL || mnstr_errnr(wstream) != MNSTR_NO__ERROR) {
+ error_stream = wstream;
+ error_message = "socket_wstream";
+ goto bailout;
+ }
+ mapi_log_record(mid, "Mapi client write");
+
+ rstream = socket_rstream(sock, "Mapi client write");
+ if (rstream == NULL || mnstr_errnr(rstream) != MNSTR_NO__ERROR) {
+ error_stream = rstream;
+ error_message = "socket_rstream";
+ goto bailout;
+ }
+ mapi_log_record(mid, "Mapi client read");
+
+ // old logic checked for this but that doesn't make sense, does it?
+ assert(!isa_block_stream(wstream));
+
+ bwstream = block_stream(wstream);
+ if (bwstream == NULL || mnstr_errnr(bwstream) != MNSTR_NO__ERROR) {
+ error_stream = bwstream;
+ error_message = "block_stream wstream";
+ goto bailout;
+ }
+ brstream = block_stream(rstream);
+ if (brstream == NULL || mnstr_errnr(brstream) != MNSTR_NO__ERROR) {
+ error_stream = brstream;
+ error_message = "block_stream rstream";
+ goto bailout;
}
- mid->connected = true;
-
- if (!isa_block_stream(mid->to)) {
- mid->to = block_stream(mid->to);
- check_stream(mid, mid->to, "not a block stream", mid->error);
-
- mid->from = block_stream(mid->from);
- check_stream(mid, mid->from, "not a block stream", mid->error);
- }
-
+ mid->to = bwstream;
+ mid->from = brstream;
return MOK;
+bailout:
+ // adapted from the check_stream macro
+ mapi_log_record(mid, error_message);
+ mapi_log_record(mid, mnstr_peek_error(error_stream));
+ mapi_log_record(mid, __func__);
+ if (brstream)
+ mnstr_destroy(brstream);
+ if (bwstream)
+ mnstr_destroy(bwstream);
+ if (brstream)
+ mnstr_destroy(brstream);
+ if (bwstream)
+ mnstr_destroy(bwstream);
+ closesocket(sock);
+ // malloc failure is the only way these calls could have failed
+ return mapi_printError(mid, __func__, MERROR, "%s: %s", error_message,
mnstr_peek_error(error_stream));
}
+#ifndef HAVE_OPENSSL
+// The real implementation is in connect_openssl.c.
+MapiMsg
+wrap_tls(Mapi mid, SOCKET sock)
+{
+ closesocket(sock);
+ return mapi_setError(mid, "Cannot connect to monetdbs://, not built
with OpenSSL support", __func__, MERROR);
+}
+#endif // HAVE_OPENSSL
+
#ifndef HAVE_SYS_UN_H
-static SOCKET
-connect_socket_unix(Mapi mid, const char *sockname)
+static MapiMsg
+connect_socket_unix(Mapi mid)
{
(void)sockname;
- mapi_setError(mid, "Unix domain sockets not supported", __func__,
MERROR);
- return INVALID_SOCKET;
+ return mapi_setError(mid, "Unix domain sockets not supported",
__func__, MERROR);
}
#endif
#ifdef HAVE_SYS_UN_H
-static SOCKET
-connect_socket_unix(Mapi mid, const char *sockname)
+static MapiMsg
+connect_socket_unix(Mapi mid)
{
+ const char *sockname = msettings_connect_unix(mid->settings);
+ assert (*sockname != '\0');
+
struct sockaddr_un userver;
if (strlen(sockname) >= sizeof(userver.sun_path)) {
- mapi_printError(mid, __func__, MERROR, "path name '%s' too
long", sockname);
- return INVALID_SOCKET;
+ return mapi_printError(mid, __func__, MERROR, "path name '%s'
too long", sockname);
}
// Create the socket, taking care of CLOEXEC
@@ -271,10 +313,9 @@ connect_socket_unix(Mapi mid, const char
int s = socket(PF_UNIX, SOCK_STREAM, 0);
#endif
if (s == INVALID_SOCKET) {
- mapi_printError(
+ return mapi_printError(
mid, __func__, MERROR,
- "could not create Unix domain socket '%s': %s",
sockname, strerror(errno));
- return INVALID_SOCKET;
+ "could not create Unix domain socket '%s': %s",
sockname, SOCKET_STRERROR());
}
#if !defined(SOCK_CLOEXEC) && defined(HAVE_FCNTL)
(void) fcntl(s, F_SETFD, FD_CLOEXEC);
@@ -289,10 +330,9 @@ connect_socket_unix(Mapi mid, const char
if (connect(s, (struct sockaddr *) &userver, sizeof(struct
sockaddr_un)) == SOCKET_ERROR) {
closesocket(s);
- mapi_printError(
+ return mapi_printError(
mid, __func__, MERROR,
- "connect to Unix domain socket '%s' failed: %s",
sockname, strerror(errno));
- return INVALID_SOCKET;
+ "connect to Unix domain socket '%s' failed: %s",
sockname, SOCKET_STRERROR());
}
// Send an initial zero (not NUL) to let the server know we're not
passing a file
@@ -302,21 +342,25 @@ connect_socket_unix(Mapi mid, const char
if (n < 1) {
// used to be if n < 0 but this makes more sense
closesocket(s);
- mapi_printError(
+ return mapi_printError(
mid, __func__, MERROR,
- "could not send initial '0' on Unix domain socket: %s",
strerror(errno));
- return INVALID_SOCKET;
+ "could not send initial '0' on Unix domain socket: %s",
SOCKET_STRERROR());
}
- return s;
+ return wrap_socket(mid, s);
}
#endif // end of ifdef HAVE_SYS_UN_H
-static SOCKET
-connect_socket_tcp(Mapi mid, const char *host, int port)
+static MapiMsg
+connect_socket_tcp(Mapi mid)
{
int ret;
+
+ bool use_tls = msetting_bool(mid->settings, MP_TLS);
+ const char *host = msettings_connect_tcp(mid->settings);
+ int port = msettings_connect_port(mid->settings);
+
assert(host);
char portbuf[10];
snprintf(portbuf, sizeof(portbuf), "%d", port);
@@ -329,16 +373,14 @@ connect_socket_tcp(Mapi mid, const char
struct addrinfo *addresses;
ret = getaddrinfo(host, portbuf, &hints, &addresses);
if (ret != 0) {
- mapi_printError(
+ return mapi_printError(
mid, __func__, MERROR,
"getaddrinfo %s:%s failed: %s", host, portbuf,
gai_strerror(ret));
- return INVALID_SOCKET;
}
if (addresses == NULL) {
- mapi_printError(
+ return mapi_printError(
mid, __func__, MERROR,
"getaddrinfo return 0 addresses");
- return INVALID_SOCKET;
}
assert(addresses);
@@ -350,7 +392,8 @@ connect_socket_tcp(Mapi mid, const char
}
freeaddrinfo(addresses);
if (s == INVALID_SOCKET) {
- return INVALID_SOCKET;
+ // connect_socket_tcp_addr has already set an error message
+ return MERROR;
}
/* compare our own address with that of our peer and
@@ -376,12 +419,32 @@ connect_socket_tcp(Mapi mid, const char
praddr.i6.sin6_addr.s6_addr,
_______________________________________________
checkin-list mailing list -- [email protected]
To unsubscribe send an email to [email protected]