You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

322 lines
7.5 KiB

/*
* Copyright 2014-2015 Con Kolivas
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
* Software Foundation; either version 3 of the License, or (at your option)
* any later version. See COPYING for more details.
*/
#ifndef CKPOOL_H
#define CKPOOL_H
#include "config.h"
#include <sys/file.h>
#include <sys/socket.h>
#include <sys/types.h>
#include "libckpool.h"
#include "uthash.h"
#define RPC_TIMEOUT 60
struct ckpool_instance;
typedef struct ckpool_instance ckpool_t;
struct ckmsg {
struct ckmsg *next;
struct ckmsg *prev;
void *data;
};
typedef struct ckmsg ckmsg_t;
typedef struct unix_msg unix_msg_t;
struct unix_msg {
unix_msg_t *next;
unix_msg_t *prev;
int sockd;
char *buf;
};
struct ckmsgq {
ckpool_t *ckp;
char name[16];
pthread_t pth;
mutex_t *lock;
pthread_cond_t *cond;
ckmsg_t *msgs;
void (*func)(ckpool_t *, void *);
int64_t messages;
};
typedef struct ckmsgq ckmsgq_t;
typedef struct proc_instance proc_instance_t;
struct proc_instance {
ckpool_t *ckp;
unixsock_t us;
char *processname;
char *sockname;
int pid;
int oldpid;
int (*process)(proc_instance_t *);
/* Linked list of received messages, locking and conditional */
unix_msg_t *unix_msgs;
mutex_t rmsg_lock;
pthread_cond_t rmsg_cond;
};
struct connsock {
int fd;
char *url;
char *port;
char *auth;
char *buf;
int bufofs;
int buflen;
ckpool_t *ckp;
/* Semaphore used to serialise request/responses */
sem_t sem;
};
typedef struct connsock connsock_t;
typedef struct char_entry char_entry_t;
struct char_entry {
char_entry_t *next;
char_entry_t *prev;
char *buf;
};
typedef struct log_entry log_entry_t;
struct log_entry {
log_entry_t *next;
log_entry_t *prev;
char *fname;
char *buf;
};
struct server_instance {
/* Hash table data */
UT_hash_handle hh;
int id;
char *url;
char *auth;
char *pass;
bool notify;
bool alive;
connsock_t cs;
void *data; // Private data
};
typedef struct server_instance server_instance_t;
struct ckpool_instance {
/* Start time */
time_t starttime;
/* Start pid */
pid_t startpid;
/* The initial command line arguments */
char **initial_args;
/* Number of arguments */
int args;
/* Filename of config file */
char *config;
/* Kill old instance with same name */
bool killold;
/* Whether to log shares or not */
bool logshares;
/* Logging level */
int loglevel;
/* Main process name */
char *name;
/* Directory where sockets are created */
char *socket_dir;
/* Directory where ckdb sockets are */
char *ckdb_sockdir;
/* Name of the ckdb process */
char *ckdb_name;
char *ckdb_sockname;
/* Group ID for unix sockets */
char *grpnam;
gid_t gr_gid;
/* Directory where logs are written */
char *logdir;
/* Logfile */
FILE *logfp;
int logfd;
/* Connector fds if we inherit them from a running process */
int *oldconnfd;
/* Should we inherit a running instance's socket and shut it down */
bool handover;
/* How many clients maximum to accept before rejecting further */
int maxclients;
/* API message queue */
ckmsgq_t *ckpapi;
/* Logger message queue NOTE: Unique per process */
ckmsgq_t *logger;
/* Process instance data of parent/child processes */
proc_instance_t main;
int proc_instances;
proc_instance_t **children;
proc_instance_t *generator;
proc_instance_t *stratifier;
proc_instance_t *connector;
/* Threads of main process */
pthread_t pth_listener;
pthread_t pth_watchdog;
/* Are we running in node proxy mode */
bool node;
/* Are we running in passthrough mode */
bool passthrough;
/* Are we a redirecting passthrough */
bool redirector;
/* Are we running as a proxy */
bool proxy;
/* Are we running without ckdb */
bool standalone;
/* Are we running in userproxy mode */
bool userproxy;
/* Should we daemonise the ckpool process */
bool daemon;
/* Bitcoind data */
int btcds;
char **btcdurl;
char **btcdauth;
char **btcdpass;
bool *btcdnotify;
int blockpoll; // How frequently in ms to poll bitcoind for block updates
int nonce1length; // Extranonce1 length
int nonce2length; // Extranonce2 length
/* Difficulty settings */
int64_t mindiff; // Default 1
int64_t startdiff; // Default 42
int64_t maxdiff; // No default
/* Coinbase data */
char *btcaddress; // Address to mine to
char *btcsig; // Optional signature to add to coinbase
char *donaddress; // Donation address
bool donvalid; // Donation address works on this network
/* Stratum options */
server_instance_t **servers;
char **serverurl; // Array of URLs to bind our server/proxy to
int serverurls; // Number of server bindings
int update_interval; // Seconds between stratum updates
/* Proxy options */
int proxies;
char **proxyurl;
char **proxyauth;
char **proxypass;
/* Passthrough redirect options */
int redirecturls;
char **redirecturl;
char **redirectport;
/* Private data for each process */
void *data;
};
enum stratum_msgtype {
SM_RECONNECT = 0,
SM_DIFF,
SM_MSG,
SM_UPDATE,
SM_ERROR,
SM_SUBSCRIBE,
SM_SUBSCRIBERESULT,
SM_SHARE,
SM_SHARERESULT,
SM_AUTH,
SM_AUTHRESULT,
SM_TXNS,
SM_TXNSRESULT
};
static const char __maybe_unused *stratum_msgs[] = {
"reconnect",
"diff",
"message",
"update",
"error",
"subscribe",
"subscribe.result",
"share",
"share.result",
"auth",
"auth.result",
"txns",
"txns.result"
};
#ifdef USE_CKDB
#define CKP_STANDALONE(CKP) ((CKP)->standalone == true)
#else
#define CKP_STANDALONE(CKP) ((CKP) == (CKP)) /* Always true, silences unused warn */
#endif
#define SAFE_HASH_OVERHEAD(HASHLIST) (HASHLIST ? HASH_OVERHEAD(hh, HASHLIST) : 0)
ckmsgq_t *create_ckmsgq(ckpool_t *ckp, const char *name, const void *func);
ckmsgq_t *create_ckmsgqs(ckpool_t *ckp, const char *name, const void *func, const int count);
void ckmsgq_add(ckmsgq_t *ckmsgq, void *data);
bool ckmsgq_empty(ckmsgq_t *ckmsgq);
unix_msg_t *get_unix_msg(proc_instance_t *pi);
void create_unix_receiver(proc_instance_t *pi);
ckpool_t *global_ckp;
bool ping_main(ckpool_t *ckp);
void empty_buffer(connsock_t *cs);
int read_socket_line(connsock_t *cs, float *timeout);
void _send_proc(proc_instance_t *pi, const char *msg, const char *file, const char *func, const int line);
#define send_proc(pi, msg) _send_proc(pi, msg, __FILE__, __func__, __LINE__)
char *_send_recv_proc(proc_instance_t *pi, const char *msg, int writetimeout, int readtimedout,
const char *file, const char *func, const int line);
#define send_recv_proc(pi, msg) _send_recv_proc(pi, msg, UNIX_WRITE_TIMEOUT, UNIX_READ_TIMEOUT, __FILE__, __func__, __LINE__)
char *_send_recv_ckdb(const ckpool_t *ckp, const char *msg, const char *file, const char *func, const int line);
#define send_recv_ckdb(ckp, msg) _send_recv_ckdb(ckp, msg, __FILE__, __func__, __LINE__)
char *_ckdb_msg_call(const ckpool_t *ckp, const char *msg, const char *file, const char *func,
const int line);
#define ckdb_msg_call(ckp, msg) _ckdb_msg_call(ckp, msg, __FILE__, __func__, __LINE__)
json_t *json_rpc_call(connsock_t *cs, const char *rpc_req);
void childsighandler(const int sig);
int process_exit(ckpool_t *ckp, const proc_instance_t *pi, int ret);
bool json_get_string(char **store, const json_t *val, const char *res);
bool json_get_int64(int64_t *store, const json_t *val, const char *res);
bool json_get_int(int *store, const json_t *val, const char *res);
bool json_get_double(double *store, const json_t *val, const char *res);
bool json_get_bool(bool *store, const json_t *val, const char *res);
bool json_getdel_int(int *store, json_t *val, const char *res);
bool json_getdel_int64(int64_t *store, json_t *val, const char *res);
#endif /* CKPOOL_H */