Changeset: 166d521e5469 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/166d521e5469
Added Files:
clients/mapilib/connect_unix.c
Modified Files:
clients/mapilib/CMakeLists.txt
clients/mapilib/connect.c
clients/mapilib/mapi_intern.h
Branch: monetdburl
Log Message:
Split off Unix domain functionality to separate file
diffs (truncated from 476 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
@@ -23,6 +23,7 @@ target_sources(mapi
connect.c
msettings.c
parseurl.c
+ $<$<BOOL:${HAVE_SYS_UN_H}>:connect_unix.c>
$<$<BOOL:${OPENSSL_FOUND}>:connect_openssl.c>
mapi_intern.h
PUBLIC
diff --git a/clients/mapilib/connect.c b/clients/mapilib/connect.c
--- a/clients/mapilib/connect.c
+++ b/clients/mapilib/connect.c
@@ -34,14 +34,41 @@
#endif
-static MapiMsg establish_connection(Mapi mid);
-static MapiMsg scan_unix_sockets(Mapi mid);
+static MapiMsg scan_sockets(Mapi mid);
static MapiMsg connect_socket(Mapi mid);
-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);
+#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
+
+MapiMsg
+connect_socket_unix(Mapi mid)
+{
+ return mapi_setError(mid, "Unix domain sockets not supported",
__func__, MERROR);
+}
+
+static MapiMsg
+scan_unix_sockets(Mapi mid)
+{
+ return mapi_setError(mid, "Unix domain sockets not supported",
__func__, MERROR);
+}
+
+#endif
+
+
+
+
/* (Re-)establish a connection with the server. */
MapiMsg
mapi_reconnect(Mapi mid)
@@ -57,112 +84,18 @@ mapi_reconnect(Mapi mid)
// /tmp and see if any of them serve this database.
// Otherwise, just try to connect to what was given.
if (msettings_connect_scan(mid->settings))
- return scan_unix_sockets(mid);
+ return scan_sockets(mid);
else
return establish_connection(mid);
}
-#define MAX_SCAN (24)
-
static MapiMsg
-scan_unix_sockets(Mapi mid)
+scan_sockets(Mapi mid)
{
- struct {
- int port;
- int priority;
- } candidates[MAX_SCAN];
- int ncandidates = 0;
- DIR *dir = NULL;
- struct dirent *entry;
-
- const char *sockdir = msettings_connect_sockdir(mid->settings);
- size_t len = strlen(sockdir);
- char *namebuf = malloc(len + 50);
- if (namebuf == NULL)
- return mapi_setError(mid, "malloc failed", __func__, MERROR);
- strcpy(namebuf, sockdir);
- strcpy(namebuf + len, "/.s.monetdb.PORTXXXXX");
- char *put_port_here = strrchr(namebuf, 'P');
-
- msettings *original = mid->settings;
- mid->settings = NULL; // invalid state, will fix it before use and on
return
-
- mapi_log_record(mid, "CONN", "Scanning %s for Unix domain sockets",
sockdir);
-
- // Make a list of Unix domain sockets in /tmp
- uid_t me = getuid();
- if (DO_UNIX_DOMAIN && (dir = opendir(sockdir))) {
- while (ncandidates < MAX_SCAN && (entry = readdir(dir)) !=
NULL) {
- const char *basename = entry->d_name;
- if (strncmp(basename, ".s.monetdb.", 11) != 0 ||
basename[11] == '\0' || strlen(basename) > 20)
- continue;
-
- char *end;
- long port = strtol(basename + 11, &end, 10);
- if (port < 1 || port > 65535 || *end)
- continue;
-
- sprintf(put_port_here, "%ld", port);
- struct stat st;
- if (stat(namebuf, &st) < 0 || !S_ISSOCK(st.st_mode))
- continue;
-
- candidates[ncandidates].port = port;
- candidates[ncandidates++].priority = st.st_uid == me ?
0 : 1;
- }
- }
+ if (scan_unix_sockets(mid) == MOK)
+ return MOK;
- mapi_log_record(mid, "CONN", "Found %d Unix domain sockets",
ncandidates);
-
- // Try those owned by us first, then all others
- for (int round = 0; round < 2; round++) {
- for (int i = 0; i < ncandidates; i++) {
- if (candidates[i].priority != round)
- continue;
-
- assert(!mid->connected);
- assert(mid->settings == NULL);
- mid->settings = msettings_clone(original);
- if (!mid->settings) {
- mid->settings = original;
- free(namebuf);
- return mapi_setError(mid, "malloc failed",
__func__, MERROR);
- }
- msettings_error errmsg =
msetting_set_long(mid->settings, MP_PORT, candidates[i].port);
- char *allocated_errmsg = NULL;
- if (!errmsg && !msettings_validate(mid->settings,
&allocated_errmsg)) {
- errmsg = allocated_errmsg;
- }
- if (errmsg) {
- mapi_setError(mid, errmsg, __func__, MERROR);
- free(allocated_errmsg);
- free(namebuf);
- msettings_destroy(mid->settings);
- mid->settings = original;
- return MERROR;
- }
- MapiMsg msg = establish_connection(mid);
- if (msg == MOK) {
- // do not restore original
- msettings_destroy(original);
- free(namebuf);
- return MOK;
- } else {
- msettings_destroy(mid->settings);
- mid->settings = NULL;
- // now we're ready to try another one
- }
- }
- }
-
- free(namebuf);
-
- // Last-ditch attempt.
- mapi_log_record(mid, "CONN", "All %d Unix domain sockets failed.
Falling back to TCP", ncandidates);
-
- // We can now freely modify original
- assert(mid->settings == NULL);
- mid->settings = original;
+ // When the Unix sockets have been scanned we can freely modify
'original'.
msettings_error errmsg = msetting_set_string(mid->settings, MP_HOST,
"localhost");
char *allocated_errmsg = NULL;
if (!errmsg && !msettings_validate(mid->settings, &allocated_errmsg)) {
@@ -175,7 +108,7 @@ scan_unix_sockets(Mapi mid)
}
/* (Re-)establish a connection with the server. */
-static MapiMsg
+MapiMsg
establish_connection(Mapi mid)
{
if (mid->connected) {
@@ -224,7 +157,7 @@ connect_socket(Mapi mid)
return MOK;
}
-static MapiMsg
+MapiMsg
wrap_socket(Mapi mid, SOCKET sock)
{
// do not use check_stream here yet because the socket is not yet in
'mid'
@@ -266,86 +199,6 @@ bailout:
}
}
-#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 MapiMsg
-connect_socket_unix(Mapi mid)
-{
- return mapi_setError(mid, "Unix domain sockets not supported",
__func__, MERROR);
-}
-#endif
-
-#ifdef HAVE_SYS_UN_H
-
-static MapiMsg
-connect_socket_unix(Mapi mid)
-{
- const char *sockname = msettings_connect_unix(mid->settings);
- assert (*sockname != '\0');
-
- mapi_log_record(mid, "CONN", "Connecting to Unix domain socket %s",
sockname);
-
- struct sockaddr_un userver;
- if (strlen(sockname) >= sizeof(userver.sun_path)) {
- return mapi_printError(mid, __func__, MERROR, "path name '%s'
too long", sockname);
- }
-
- // Create the socket, taking care of CLOEXEC
-
-#ifdef SOCK_CLOEXEC
- int s = socket(PF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0);
-#else
- int s = socket(PF_UNIX, SOCK_STREAM, 0);
-#endif
- if (s == INVALID_SOCKET) {
- return mapi_printError(
- mid, __func__, MERROR,
- "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);
-#endif
-
- // Attempt to connect
-
- userver = (struct sockaddr_un) {
- .sun_family = AF_UNIX,
- };
- strcpy_len(userver.sun_path, sockname, sizeof(userver.sun_path));
-
- if (connect(s, (struct sockaddr *) &userver, sizeof(struct
sockaddr_un)) == SOCKET_ERROR) {
- closesocket(s);
- return mapi_printError(
- mid, __func__, MERROR,
- "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
- // descriptor.
-
- ssize_t n = send(s, "0", 1, 0);
- if (n < 1) {
- // used to be if n < 0 but this makes more sense
- closesocket(s);
- return mapi_printError(
- mid, __func__, MERROR,
- "could not send initial '0' on Unix domain socket: %s",
SOCKET_STRERROR());
- }
-
- return wrap_socket(mid, s);
-}
-
-#endif // end of ifdef HAVE_SYS_UN_H
-
static MapiMsg
connect_socket_tcp(Mapi mid)
{
diff --git a/clients/mapilib/connect_unix.c b/clients/mapilib/connect_unix.c
new file mode 100644
--- /dev/null
+++ b/clients/mapilib/connect_unix.c
@@ -0,0 +1,175 @@
+
+
+#include "monetdb_config.h"
+#include "stream.h" /* include before mapi.h */
+#include "stream_socket.h"
+#include "mapi.h"
+#include "mapi_prompt.h"
+#include "mcrypt.h"
+#include "matomic.h"
+#include "mstring.h"
+#include "mutils.h"
+
+#include "mapi_intern.h"
_______________________________________________
checkin-list mailing list -- [email protected]
To unsubscribe send an email to [email protected]