Browse Source

Merge branch 'master' of bitbucket.org:ckolivas/ckpool

master
Con Kolivas 10 years ago
parent
commit
4be7c15484
  1. 2
      pool/base.php
  2. 2
      src/ckdb.c
  3. 24
      src/ckdb.h
  4. 88
      src/ckdb_cmd.c
  5. 20
      src/ckdb_data.c
  6. 24
      src/ckdb_dbio.c

2
pool/base.php

@ -259,7 +259,7 @@ function safetext($txt, $len = 1024)
# #
function dbd($data, $user) function dbd($data, $user)
{ {
return "<span class=alert><br>Web site is currently down</span>"; return "<span class=alert><br>Database is reloading, mining is all OK</span>";
} }
# #
function dbdown() function dbdown()

2
src/ckdb.c

@ -151,6 +151,8 @@ static char *restorefrom;
// Only accessed in here // Only accessed in here
static bool markersummary_auto; static bool markersummary_auto;
int switch_state = SWITCH_STATE_ALL;
// disallow: '/' '.' '_' and FLDSEP // disallow: '/' '.' '_' and FLDSEP
const char *userpatt = "^[^/\\._"FLDSEPSTR"]*$"; const char *userpatt = "^[^/\\._"FLDSEPSTR"]*$";
const char *mailpatt = "^[A-Za-z0-9_-][A-Za-z0-9_\\.-]*@[A-Za-z0-9][A-Za-z0-9\\.-]*[A-Za-z0-9]$"; const char *mailpatt = "^[A-Za-z0-9_-][A-Za-z0-9_\\.-]*@[A-Za-z0-9][A-Za-z0-9\\.-]*[A-Za-z0-9]$";

24
src/ckdb.h

@ -55,7 +55,7 @@
#define DB_VLOCK "1" #define DB_VLOCK "1"
#define DB_VERSION "1.0.0" #define DB_VERSION "1.0.0"
#define CKDB_VERSION DB_VERSION"-1.023" #define CKDB_VERSION DB_VERSION"-1.031"
#define WHERE_FFL " - from %s %s() line %d" #define WHERE_FFL " - from %s %s() line %d"
#define WHERE_FFL_HERE __FILE__, __func__, __LINE__ #define WHERE_FFL_HERE __FILE__, __func__, __LINE__
@ -81,6 +81,27 @@
#define TRUE_CHR 'Y' #define TRUE_CHR 'Y'
#define FALSE_CHR 'N' #define FALSE_CHR 'N'
/* Set by cmd_setopts() and used by whatever code needs it
* It's loaded during startup but set to SWITCH_STATE_ALL if it's missing,
* meaning all switches are active
* The idea is that if you need to manually switch code over from one version
* up to the next version at an indeterminate time then you can do that by
* coding a switch_state test and then externally switch the code over via
* the cmd_setopts() socket interface
* It's not for coding runtime options into the code since that can be done
* using optioncontrol directly
* It's stored in optioncontrol so that it's value is permanent and
* activationdate and activationheight have their values overridden to
* disable using them
* N.B. optioncontrol_item_add() intercepts the change by name and updates
* switch_state but ONLY if the DB update succeeds */
extern int switch_state;
#define SWITCH_STATE_NAME "SwitchState"
/* Each switch state must be higher than all previous
* so that future states don't undo old changes */
#define SWITCH_STATE_AUTHWORKERS 1
#define SWITCH_STATE_ALL 666666
extern char *EMPTY; extern char *EMPTY;
extern const char *userpatt; extern const char *userpatt;
@ -1726,6 +1747,7 @@ extern cmp_t cmp_useratts(K_ITEM *a, K_ITEM *b);
extern K_ITEM *find_useratts(int64_t userid, char *attname); extern K_ITEM *find_useratts(int64_t userid, char *attname);
extern cmp_t cmp_workers(K_ITEM *a, K_ITEM *b); extern cmp_t cmp_workers(K_ITEM *a, K_ITEM *b);
extern K_ITEM *find_workers(int64_t userid, char *workername); extern K_ITEM *find_workers(int64_t userid, char *workername);
extern K_ITEM *first_workers(int64_t userid, K_TREE_CTX *ctx);
extern K_ITEM *new_worker(PGconn *conn, bool update, int64_t userid, char *workername, extern K_ITEM *new_worker(PGconn *conn, bool update, int64_t userid, char *workername,
char *diffdef, char *idlenotificationenabled, char *diffdef, char *idlenotificationenabled,
char *idlenotificationtime, char *by, char *idlenotificationtime, char *by,

88
src/ckdb_cmd.c

@ -2308,15 +2308,18 @@ static char *cmd_auth_do(PGconn *conn, char *cmd, char *id, char *by,
char *code, char *inet, tv_t *cd, char *code, char *inet, tv_t *cd,
K_TREE *trf_root) K_TREE *trf_root)
{ {
K_TREE_CTX ctx[1];
char reply[1024] = ""; char reply[1024] = "";
size_t siz = sizeof(reply); size_t siz = sizeof(reply);
K_ITEM *i_poolinstance, *i_username, *i_workername, *i_clientid; K_ITEM *i_poolinstance, *i_username, *i_workername, *i_clientid;
K_ITEM *i_enonce1, *i_useragent, *i_preauth, *u_item, *oc_item; K_ITEM *i_enonce1, *i_useragent, *i_preauth, *u_item, *oc_item, *w_item;
USERS *users = NULL; USERS *users = NULL;
char *username; char *username;
WORKERS *workers = NULL; WORKERS *workers = NULL;
OPTIONCONTROL *optioncontrol; OPTIONCONTROL *optioncontrol;
bool ok; size_t len, off;
char *buf;
bool ok, first;
LOGDEBUG("%s(): cmd '%s'", __func__, cmd); LOGDEBUG("%s(): cmd '%s'", __func__, cmd);
@ -2378,18 +2381,51 @@ static char *cmd_auth_do(PGconn *conn, char *cmd, char *id, char *by,
if (!ok) { if (!ok) {
LOGDEBUG("%s() %s.failed.DBE", __func__, id); LOGDEBUG("%s() %s.failed.DBE", __func__, id);
return strdup("failed.DBE"); return strdup("failed.DBE");
} else { }
// Only flag a successful auth // Only flag a successful auth
ck_wlock(&last_lock); ck_wlock(&last_lock);
setnow(&last_auth); setnow(&last_auth);
ck_wunlock(&last_lock); ck_wunlock(&last_lock);
}
if (switch_state < SWITCH_STATE_AUTHWORKERS) {
snprintf(reply, siz, snprintf(reply, siz,
"ok.authorise={\"secondaryuserid\":\"%s\"," "ok.authorise={\"secondaryuserid\":\"%s\","
"\"difficultydefault\":%d}", "\"difficultydefault\":%d}",
users->secondaryuserid, workers->difficultydefault); users->secondaryuserid, workers->difficultydefault);
LOGDEBUG("%s.%s", id, reply); LOGDEBUG("%s.%s", id, reply);
return strdup(reply); return strdup(reply);
}
APPEND_REALLOC_INIT(buf, off, len);
snprintf(reply, siz,
"ok.authorise={\"secondaryuserid\":\"%s\","
"\"workers\":[",
users->secondaryuserid);
APPEND_REALLOC(buf, off, len, reply);
first = true;
K_RLOCK(workers_free);
w_item = first_workers(users->userid, ctx);
DATA_WORKERS_NULL(workers, w_item);
while (w_item && workers->userid == users->userid) {
if (CURRENT(&(workers->expirydate))) {
snprintf(reply, siz,
"%s{\"workername\":\"%s\","
"\"difficultydefault\":%"PRId32"}",
first ? EMPTY : ",",
workers->workername,
workers->difficultydefault);
APPEND_REALLOC(buf, off, len, reply);
first = false;
}
w_item = next_in_ktree(ctx);
DATA_WORKERS_NULL(workers, w_item);
}
K_RUNLOCK(workers_free);
APPEND_REALLOC(buf, off, len, "]}");
LOGDEBUG("%s.%s", id, buf);
return buf;
} }
static char *cmd_auth(PGconn *conn, char *cmd, char *id, static char *cmd_auth(PGconn *conn, char *cmd, char *id,
@ -2404,13 +2440,16 @@ static char *cmd_addrauth_do(PGconn *conn, char *cmd, char *id, char *by,
char *code, char *inet, tv_t *cd, char *code, char *inet, tv_t *cd,
K_TREE *trf_root) K_TREE *trf_root)
{ {
K_TREE_CTX ctx[1];
char reply[1024] = ""; char reply[1024] = "";
size_t siz = sizeof(reply); size_t siz = sizeof(reply);
K_ITEM *i_poolinstance, *i_username, *i_workername, *i_clientid; K_ITEM *i_poolinstance, *i_username, *i_workername, *i_clientid;
K_ITEM *i_enonce1, *i_useragent, *i_preauth; K_ITEM *i_enonce1, *i_useragent, *i_preauth, *w_item;
USERS *users = NULL; USERS *users = NULL;
WORKERS *workers = NULL; WORKERS *workers = NULL;
bool ok; size_t len, off;
char *buf;
bool ok, first;
LOGDEBUG("%s(): cmd '%s'", __func__, cmd); LOGDEBUG("%s(): cmd '%s'", __func__, cmd);
@ -2456,18 +2495,51 @@ static char *cmd_addrauth_do(PGconn *conn, char *cmd, char *id, char *by,
if (!ok) { if (!ok) {
LOGDEBUG("%s() %s.failed.DBE", __func__, id); LOGDEBUG("%s() %s.failed.DBE", __func__, id);
return strdup("failed.DBE"); return strdup("failed.DBE");
} else { }
// Only flag a successful auth // Only flag a successful auth
ck_wlock(&last_lock); ck_wlock(&last_lock);
setnow(&last_auth); setnow(&last_auth);
ck_wunlock(&last_lock); ck_wunlock(&last_lock);
}
if (switch_state < SWITCH_STATE_AUTHWORKERS) {
snprintf(reply, siz, snprintf(reply, siz,
"ok.addrauth={\"secondaryuserid\":\"%s\"," "ok.addrauth={\"secondaryuserid\":\"%s\","
"\"difficultydefault\":%d}", "\"difficultydefault\":%d}",
users->secondaryuserid, workers->difficultydefault); users->secondaryuserid, workers->difficultydefault);
LOGDEBUG("%s.%s", id, reply); LOGDEBUG("%s.%s", id, reply);
return strdup(reply); return strdup(reply);
}
APPEND_REALLOC_INIT(buf, off, len);
snprintf(reply, siz,
"ok.addrauth={\"secondaryuserid\":\"%s\","
"\"workers\":[",
users->secondaryuserid);
APPEND_REALLOC(buf, off, len, reply);
first = true;
K_RLOCK(workers_free);
w_item = first_workers(users->userid, ctx);
DATA_WORKERS_NULL(workers, w_item);
while (w_item && workers->userid == users->userid) {
if (CURRENT(&(workers->expirydate))) {
snprintf(reply, siz,
"%s{\"workername\":\"%s\","
"\"difficultydefault\":%"PRId32"}",
first ? EMPTY : ",",
workers->workername,
workers->difficultydefault);
APPEND_REALLOC(buf, off, len, reply);
first = false;
}
w_item = next_in_ktree(ctx);
DATA_WORKERS_NULL(workers, w_item);
}
K_RUNLOCK(workers_free);
APPEND_REALLOC(buf, off, len, "]}");
LOGDEBUG("%s.%s", id, buf);
return buf;
} }
static char *cmd_addrauth(PGconn *conn, char *cmd, char *id, static char *cmd_addrauth(PGconn *conn, char *cmd, char *id,

20
src/ckdb_data.c

@ -1113,6 +1113,26 @@ K_ITEM *find_workers(int64_t userid, char *workername)
return find_in_ktree(workers_root, &look, cmp_workers, ctx); return find_in_ktree(workers_root, &look, cmp_workers, ctx);
} }
K_ITEM *first_workers(int64_t userid, K_TREE_CTX *ctx)
{
WORKERS workers;
K_TREE_CTX ctx0[1];
K_ITEM look;
if (ctx == NULL)
ctx = ctx0;
workers.userid = userid;
workers.workername[0] = '\0';
workers.expirydate.tv_sec = 0L;
workers.expirydate.tv_usec = 0L;
INIT_WORKERS(&look);
look.data = (void *)(&workers);
// Caller needs to check userid/expirydate if the result != NULL
return find_after_in_ktree(workers_root, &look, cmp_workers, ctx);
}
K_ITEM *new_worker(PGconn *conn, bool update, int64_t userid, char *workername, K_ITEM *new_worker(PGconn *conn, bool update, int64_t userid, char *workername,
char *diffdef, char *idlenotificationenabled, char *diffdef, char *idlenotificationenabled,
char *idlenotificationtime, char *by, char *idlenotificationtime, char *by,

24
src/ckdb_dbio.c

@ -2183,6 +2183,13 @@ K_ITEM *optioncontrol_item_add(PGconn *conn, K_ITEM *oc_item, tv_t *cd, bool beg
DATA_OPTIONCONTROL(row, oc_item); DATA_OPTIONCONTROL(row, oc_item);
// Enforce the rule that switch_state isn't date/height controlled
if (strcmp(row->optionname, SWITCH_STATE_NAME) == 0) {
row->activationdate.tv_sec = date_begin.tv_sec;
row->activationdate.tv_usec = date_begin.tv_usec;
row->activationheight = OPTIONCONTROL_HEIGHT;
}
INIT_OPTIONCONTROL(&look); INIT_OPTIONCONTROL(&look);
look.data = (void *)row; look.data = (void *)row;
K_RLOCK(optioncontrol_free); K_RLOCK(optioncontrol_free);
@ -2282,6 +2289,11 @@ nostart:
} }
optioncontrol_root = add_to_ktree(optioncontrol_root, oc_item, cmp_optioncontrol); optioncontrol_root = add_to_ktree(optioncontrol_root, oc_item, cmp_optioncontrol);
k_add_head(optioncontrol_store, oc_item); k_add_head(optioncontrol_store, oc_item);
if (strcmp(row->optionname, SWITCH_STATE_NAME) == 0) {
switch_state = atoi(row->optionvalue);
LOGWARNING("%s() set switch_state to %d",
__func__, switch_state);
}
} }
K_WUNLOCK(optioncontrol_free); K_WUNLOCK(optioncontrol_free);
@ -2320,7 +2332,7 @@ K_ITEM *optioncontrol_add(PGconn *conn, char *optionname, char *optionvalue,
TXT_TO_INT("activationheight", activationheight, TXT_TO_INT("activationheight", activationheight,
row->activationheight); row->activationheight);
} else } else
row->activationheight = 1; row->activationheight = OPTIONCONTROL_HEIGHT;
HISTORYDATEINIT(row, cd, by, code, inet); HISTORYDATEINIT(row, cd, by, code, inet);
HISTORYDATETRANSFER(trf_root, row); HISTORYDATETRANSFER(trf_root, row);
@ -2406,6 +2418,14 @@ bool optioncontrol_fill(PGconn *conn)
optioncontrol_root = add_to_ktree(optioncontrol_root, item, cmp_optioncontrol); optioncontrol_root = add_to_ktree(optioncontrol_root, item, cmp_optioncontrol);
k_add_head(optioncontrol_store, item); k_add_head(optioncontrol_store, item);
// There should only be one CURRENT version of switch_state
if (CURRENT(&(row->expirydate)) &&
strcmp(row->optionname, SWITCH_STATE_NAME) == 0) {
switch_state = atoi(row->optionvalue);
LOGWARNING("%s() set switch_state to %d",
__func__, switch_state);
}
} }
if (!ok) { if (!ok) {
FREENULL(row->optionvalue); FREENULL(row->optionvalue);
@ -2418,6 +2438,8 @@ bool optioncontrol_fill(PGconn *conn)
if (ok) { if (ok) {
LOGDEBUG("%s(): built", __func__); LOGDEBUG("%s(): built", __func__);
LOGWARNING("%s(): loaded %d optioncontrol records", __func__, n); LOGWARNING("%s(): loaded %d optioncontrol records", __func__, n);
LOGWARNING("%s() switch_state initially %d",
__func__, switch_state);
} }
return ok; return ok;

Loading…
Cancel
Save