forked from Ocean/datum_gateway
Merge remote-tracking branch 'github-pull/77/head'
This commit is contained in:
commit
9166d3c835
@ -1163,7 +1163,7 @@ enum MHD_Result datum_api_answer(void *cls, struct MHD_Connection *connection, c
|
||||
return ret;
|
||||
}
|
||||
|
||||
static struct MHD_Daemon *datum_api_try_start(unsigned int flags) {
|
||||
static struct MHD_Daemon *datum_api_try_start(unsigned int flags, const int sock) {
|
||||
flags |= MHD_USE_AUTO; // event loop API
|
||||
flags |= MHD_USE_INTERNAL_POLLING_THREAD;
|
||||
return MHD_start_daemon(
|
||||
@ -1171,6 +1171,7 @@ static struct MHD_Daemon *datum_api_try_start(unsigned int flags) {
|
||||
datum_config.api_listen_port,
|
||||
NULL, NULL, // accept policy filter
|
||||
&datum_api_answer, NULL, // default URI handler
|
||||
MHD_OPTION_LISTEN_SOCKET, sock,
|
||||
MHD_OPTION_CONNECTION_LIMIT, 128,
|
||||
MHD_OPTION_NOTIFY_COMPLETED, datum_api_request_completed, NULL,
|
||||
MHD_OPTION_LISTENING_ADDRESS_REUSE, (unsigned int)1,
|
||||
@ -1185,8 +1186,13 @@ void *datum_api_thread(void *ptr) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
daemon = datum_api_try_start(MHD_USE_DUAL_STACK);
|
||||
if (!daemon) daemon = datum_api_try_start(0);
|
||||
int listen_socks[1];
|
||||
size_t listen_socks_len = 1;
|
||||
if (!datum_sockets_setup_listening_sockets("API", datum_config.api_listen_addr, datum_config.api_listen_port, listen_socks, &listen_socks_len)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
daemon = datum_api_try_start(0, listen_socks[0]);
|
||||
|
||||
if (!daemon) {
|
||||
DLOG_FATAL("Unable to start daemon for API");
|
||||
@ -1194,7 +1200,7 @@ void *datum_api_thread(void *ptr) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
DLOG_INFO("API listening on port %d", datum_config.api_listen_port);
|
||||
DLOG_INFO("API listening on address %s port %d", datum_config.api_listen_addr[0] ? datum_config.api_listen_addr : "(any)", datum_config.api_listen_port);
|
||||
|
||||
while(1) {
|
||||
sleep(3);
|
||||
|
@ -67,6 +67,8 @@ const T_DATUM_CONFIG_ITEM datum_config_options[] = {
|
||||
.required = false, .ptr = &datum_config.bitcoind_notify_fallback, .default_bool = true },
|
||||
|
||||
// stratum v1 server configs
|
||||
{ .var_type = DATUM_CONF_STRING, .category = "stratum", .name = "listen_addr", .description = "IP address to listen for Stratum Gateway connections",
|
||||
.required = false, .ptr = datum_config.stratum_v1_listen_addr, .default_string[0] = "", .max_string_len = sizeof(datum_config.stratum_v1_listen_addr) },
|
||||
{ .var_type = DATUM_CONF_INT, .category = "stratum", .name = "listen_port", .description = "Listening port for Stratum Gateway",
|
||||
.required = false, .ptr = &datum_config.stratum_v1_listen_port, .default_int = 23334 },
|
||||
{ .var_type = DATUM_CONF_INT, .category = "stratum", .name = "max_clients_per_thread", .description = "Maximum clients per Stratum server thread",
|
||||
@ -109,6 +111,8 @@ const T_DATUM_CONFIG_ITEM datum_config_options[] = {
|
||||
// API/dashboard
|
||||
{ .var_type = DATUM_CONF_STRING, .category = "api", .name = "admin_password", .description = "API password for actions/changes (username 'admin'; disabled if blank)",
|
||||
.required = false, .ptr = datum_config.api_admin_password, .default_string[0] = "", .max_string_len = sizeof(datum_config.api_admin_password) },
|
||||
{ .var_type = DATUM_CONF_STRING, .category = "api", .name = "listen_addr", .description = "IP address to listen for API/dashboard requests",
|
||||
.required = false, .ptr = datum_config.api_listen_addr, .default_string[0] = "", .max_string_len = sizeof(datum_config.api_listen_addr) },
|
||||
{ .var_type = DATUM_CONF_INT, .category = "api", .name = "listen_port", .description = "Port to listen for API/dashboard requests (0=disabled)",
|
||||
.required = false, .ptr = &datum_config.api_listen_port, .default_int = 0 },
|
||||
|
||||
|
@ -78,6 +78,7 @@ typedef struct {
|
||||
int bitcoind_work_update_seconds;
|
||||
bool bitcoind_notify_fallback;
|
||||
|
||||
char stratum_v1_listen_addr[128];
|
||||
int stratum_v1_listen_port;
|
||||
int stratum_v1_max_clients;
|
||||
int stratum_v1_max_threads;
|
||||
@ -102,6 +103,7 @@ typedef struct {
|
||||
char api_admin_password[64];
|
||||
size_t api_admin_password_len;
|
||||
char api_csrf_token[65];
|
||||
char api_listen_addr[128];
|
||||
int api_listen_port;
|
||||
|
||||
int extra_block_submissions_count;
|
||||
|
@ -33,11 +33,14 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netdb.h>
|
||||
#include <netinet/in.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/epoll.h>
|
||||
@ -560,6 +563,84 @@ const char *datum_sockets_setup_listen_sock(const int listen_sock, const struct
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bool datum_sockets_setup_listening_sockets(const char * const purpose, const char * const addr, const uint16_t port, int * const out_socks, size_t * const inout_socks_n) {
|
||||
assert(*inout_socks_n > 0);
|
||||
if (addr && addr[0]) {
|
||||
char port_str[6];
|
||||
snprintf(port_str, sizeof(port_str), "%u", (unsigned int)port);
|
||||
const struct addrinfo hints = {
|
||||
.ai_family = AF_UNSPEC,
|
||||
.ai_socktype = SOCK_STREAM,
|
||||
.ai_protocol = 0,
|
||||
.ai_flags = AI_PASSIVE | AI_NUMERICHOST | AI_NUMERICSERV,
|
||||
};
|
||||
struct addrinfo *res;
|
||||
int err = getaddrinfo(addr, port_str, &hints, &res);
|
||||
if (err) {
|
||||
DLOG_FATAL("Failed to resolve listen address '%s' (%s): %s", purpose, addr, gai_strerror(err));
|
||||
panic_from_thread(__LINE__);
|
||||
return false;
|
||||
}
|
||||
*out_socks = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
|
||||
const char *errstr = datum_sockets_setup_listen_sock(*out_socks, res->ai_addr, res->ai_addrlen);
|
||||
const int errno_saved = errno;
|
||||
freeaddrinfo(res);
|
||||
if (errstr) {
|
||||
DLOG_FATAL("%s (%s): %s", errstr, purpose, strerror(errno_saved));
|
||||
panic_from_thread(__LINE__);
|
||||
return false;
|
||||
}
|
||||
*inout_socks_n = 1;
|
||||
} else {
|
||||
const struct sockaddr_in6 anyaddr6 = {
|
||||
.sin6_family = AF_INET6,
|
||||
.sin6_port = htons(port),
|
||||
.sin6_addr = IN6ADDR_ANY_INIT,
|
||||
};
|
||||
out_socks[0] = socket(AF_INET6, SOCK_STREAM, 0);
|
||||
#if defined(IPPROTO_IPV6) && defined(IPV6_V6ONLY)
|
||||
if (out_socks[0] != -1) {
|
||||
static const int zero = 0;
|
||||
setsockopt(out_socks[0], IPPROTO_IPV6, IPV6_V6ONLY, &zero, sizeof(zero));
|
||||
}
|
||||
#endif
|
||||
const char * const errstr6 = datum_sockets_setup_listen_sock(out_socks[0], (const struct sockaddr *)&anyaddr6, sizeof(anyaddr6));
|
||||
const int errno6 = errno;
|
||||
unsigned int socks_n = 1;
|
||||
if (errstr6 && out_socks[0] != -1) {
|
||||
close(out_socks[0]);
|
||||
out_socks[0] = -1;
|
||||
--socks_n;
|
||||
}
|
||||
|
||||
if (*inout_socks_n > socks_n) {
|
||||
const struct sockaddr_in anyaddr4 = {
|
||||
.sin_family = AF_INET,
|
||||
.sin_port = htons(port),
|
||||
.sin_addr.s_addr = INADDR_ANY,
|
||||
};
|
||||
out_socks[socks_n] = socket(AF_INET, SOCK_STREAM, 0);
|
||||
const char *errstr = datum_sockets_setup_listen_sock(out_socks[socks_n], (const struct sockaddr *)&anyaddr4, sizeof(anyaddr4));
|
||||
if (errstr && errstr6) {
|
||||
const int errno4 = errno;
|
||||
DLOG_FATAL("%s (IPv6): %s", errstr6, strerror(errno6));
|
||||
DLOG_FATAL("%s (IPv4): %s", errstr, strerror(errno4));
|
||||
panic_from_thread(__LINE__);
|
||||
return false;
|
||||
}
|
||||
if (errstr && out_socks[socks_n] != -1) {
|
||||
close(out_socks[socks_n]);
|
||||
out_socks[socks_n] = -1;
|
||||
} else {
|
||||
++socks_n;
|
||||
}
|
||||
}
|
||||
|
||||
*inout_socks_n = socks_n;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void *datum_gateway_listener_thread(void *arg) {
|
||||
int i, ret;
|
||||
bool rejecting_now = false;
|
||||
@ -577,7 +658,7 @@ void *datum_gateway_listener_thread(void *arg) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
DLOG_DEBUG("Setting up app '%s' on port %d. (T:%d/TC:%d/C:%d)", app->name, app->listen_port, app->max_threads, app->max_clients_thread, app->max_clients);
|
||||
DLOG_DEBUG("Setting up app '%s' on address %s port %d. (T:%d/TC:%d/C:%d)", app->name, datum_config.stratum_v1_listen_addr[0] ? datum_config.stratum_v1_listen_addr : "(any)", app->listen_port, app->max_threads, app->max_clients_thread, app->max_clients);
|
||||
|
||||
// we assume the caller sets up the thread data in some way
|
||||
// don't clobber those pointers
|
||||
@ -598,37 +679,10 @@ void *datum_gateway_listener_thread(void *arg) {
|
||||
|
||||
app->datum_active_threads = 0;
|
||||
|
||||
const struct sockaddr_in6 anyaddr6 = {
|
||||
.sin6_family = AF_INET6,
|
||||
.sin6_port = htons(app->listen_port),
|
||||
.sin6_addr = IN6ADDR_ANY_INIT,
|
||||
};
|
||||
listen_socks[0] = socket(AF_INET6, SOCK_STREAM, 0);
|
||||
const char * const errstr6 = datum_sockets_setup_listen_sock(listen_socks[0], (const struct sockaddr *)&anyaddr6, sizeof(anyaddr6));
|
||||
const int errno6 = errno;
|
||||
if (errstr6 && listen_socks[0] != -1) {
|
||||
close(listen_socks[0]);
|
||||
listen_socks[0] = -1;
|
||||
}
|
||||
|
||||
const struct sockaddr_in anyaddr4 = {
|
||||
.sin_family = AF_INET,
|
||||
.sin_port = htons(app->listen_port),
|
||||
.sin_addr.s_addr = INADDR_ANY,
|
||||
};
|
||||
listen_socks[1] = socket(AF_INET, SOCK_STREAM, 0);
|
||||
const char *errstr = datum_sockets_setup_listen_sock(listen_socks[1], (const struct sockaddr *)&anyaddr4, sizeof(anyaddr4));
|
||||
if (errstr && errstr6) {
|
||||
const int errno4 = errno;
|
||||
DLOG_FATAL("%s (IPv6): %s", errstr6, strerror(errno6));
|
||||
DLOG_FATAL("%s (IPv4): %s", errstr, strerror(errno4));
|
||||
panic_from_thread(__LINE__);
|
||||
size_t listen_socks_len = 2;
|
||||
if (!datum_sockets_setup_listening_sockets("stratum", datum_config.stratum_v1_listen_addr, app->listen_port, listen_socks, &listen_socks_len)) {
|
||||
return NULL;
|
||||
}
|
||||
if (errstr && listen_socks[1] != -1) {
|
||||
close(listen_socks[1]);
|
||||
listen_socks[1] = -1;
|
||||
}
|
||||
|
||||
epollfd = epoll_create1(0);
|
||||
if (epollfd < 0) {
|
||||
|
@ -161,6 +161,7 @@ typedef struct T_DATUM_THREAD_DATA {
|
||||
void *app_thread_data;
|
||||
} T_DATUM_THREAD_DATA;
|
||||
|
||||
bool datum_sockets_setup_listening_sockets(const char *purpose, const char *addr, uint16_t port, int *out_socks, size_t *inout_socks_n);
|
||||
void *datum_gateway_listener_thread(void *arg);
|
||||
void datum_socket_setoptions(int sock);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user