Server: don't fall back to Unix sockets

This commit is contained in:
Marco Hinz
2017-05-16 14:56:08 +02:00
parent afa781f420
commit fd5e4e2e4c
2 changed files with 26 additions and 17 deletions

View File

@@ -18,13 +18,14 @@
#include "nvim/memory.h" #include "nvim/memory.h"
#include "nvim/macros.h" #include "nvim/macros.h"
#include "nvim/charset.h" #include "nvim/charset.h"
#include "nvim/log.h"
#ifdef INCLUDE_GENERATED_DECLARATIONS #ifdef INCLUDE_GENERATED_DECLARATIONS
# include "event/socket.c.generated.h" # include "event/socket.c.generated.h"
#endif #endif
void socket_watcher_init(Loop *loop, SocketWatcher *watcher, int socket_watcher_init(Loop *loop, SocketWatcher *watcher,
const char *endpoint) const char *endpoint)
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_NONNULL_ALL
{ {
xstrlcpy(watcher->addr, endpoint, sizeof(watcher->addr)); xstrlcpy(watcher->addr, endpoint, sizeof(watcher->addr));
@@ -32,33 +33,34 @@ void socket_watcher_init(Loop *loop, SocketWatcher *watcher,
char *host_end = strrchr(addr, ':'); char *host_end = strrchr(addr, ':');
if (host_end && addr != host_end) { if (host_end && addr != host_end) {
intmax_t port; // Split user specified address into two strings, addr(hostname) and port.
int ret = getdigits_safe(&(char_u *){ (char_u *)host_end + 1 }, &port); // The port part in watcher->addr will be updated later.
if (ret == FAIL || port < 0 || port > UINT16_MAX) { *host_end = '\0';
// Invalid port. char *port = host_end + 1;
goto do_pipe; intmax_t iport;
int ret = getdigits_safe(&(char_u *){ (char_u *)port }, &iport);
if (ret == FAIL || iport < 0 || iport > UINT16_MAX) {
ELOG("Invalid port: %s", port);
return UV_EINVAL;
} }
*host_end = '\0';
uv_getaddrinfo_t request; uv_getaddrinfo_t request;
int retval = uv_getaddrinfo(&loop->uv, &request, NULL, addr, host_end+1, int retval = uv_getaddrinfo(&loop->uv, &request, NULL, addr, port,
&(struct addrinfo){ &(struct addrinfo){
.ai_family = AF_UNSPEC, .ai_family = AF_UNSPEC,
.ai_socktype = SOCK_STREAM, .ai_socktype = SOCK_STREAM,
}); });
*host_end = ':';
if (retval != 0) { if (retval != 0) {
// Failed to look up address. ELOG("Host lookup failed: %s", endpoint);
goto do_pipe; return retval;
} }
*(host_end + 1) = '\0';
watcher->uv.tcp.addrinfo = request.addrinfo; watcher->uv.tcp.addrinfo = request.addrinfo;
uv_tcp_init(&loop->uv, &watcher->uv.tcp.handle); uv_tcp_init(&loop->uv, &watcher->uv.tcp.handle);
watcher->stream = STRUCT_CAST(uv_stream_t, &watcher->uv.tcp.handle); watcher->stream = STRUCT_CAST(uv_stream_t, &watcher->uv.tcp.handle);
} else { } else {
do_pipe:
uv_pipe_init(&loop->uv, &watcher->uv.pipe.handle, 0); uv_pipe_init(&loop->uv, &watcher->uv.pipe.handle, 0);
watcher->stream = STRUCT_CAST(uv_stream_t, &watcher->uv.pipe.handle); watcher->stream = STRUCT_CAST(uv_stream_t, &watcher->uv.pipe.handle);
} }
@@ -68,6 +70,8 @@ do_pipe:
watcher->close_cb = NULL; watcher->close_cb = NULL;
watcher->events = NULL; watcher->events = NULL;
watcher->data = NULL; watcher->data = NULL;
return 0;
} }
int socket_watcher_start(SocketWatcher *watcher, int backlog, socket_cb cb) int socket_watcher_start(SocketWatcher *watcher, int backlog, socket_cb cb)
@@ -98,7 +102,7 @@ int socket_watcher_start(SocketWatcher *watcher, int backlog, socket_cb cb)
: ((struct sockaddr_in6 *)&sas)->sin6_port; : ((struct sockaddr_in6 *)&sas)->sin6_port;
// v:servername uses the string from watcher->addr // v:servername uses the string from watcher->addr
size_t len = strlen(watcher->addr); size_t len = strlen(watcher->addr);
snprintf(watcher->addr+len, sizeof(watcher->addr)-len, "%" PRIu16, snprintf(watcher->addr+len, sizeof(watcher->addr)-len, ":%" PRIu16,
ntohs(port)); ntohs(port));
break; break;
} }

View File

@@ -118,7 +118,12 @@ int server_start(const char *endpoint)
} }
SocketWatcher *watcher = xmalloc(sizeof(SocketWatcher)); SocketWatcher *watcher = xmalloc(sizeof(SocketWatcher));
socket_watcher_init(&main_loop, watcher, endpoint);
int result = socket_watcher_init(&main_loop, watcher, endpoint);
if (result < 0) {
xfree(watcher);
return result;
}
// Check if a watcher for the endpoint already exists // Check if a watcher for the endpoint already exists
for (int i = 0; i < watchers.ga_len; i++) { for (int i = 0; i < watchers.ga_len; i++) {
@@ -132,7 +137,7 @@ int server_start(const char *endpoint)
} }
} }
int result = socket_watcher_start(watcher, MAX_CONNECTIONS, connection_cb); result = socket_watcher_start(watcher, MAX_CONNECTIONS, connection_cb);
if (result < 0) { if (result < 0) {
ELOG("Failed to start server: %s", uv_strerror(result)); ELOG("Failed to start server: %s", uv_strerror(result));
socket_watcher_close(watcher, free_server); socket_watcher_close(watcher, free_server);