Enforce seperate license keys for connected replicas

Former-commit-id: bc005cb50b1010a2bc9170e261cd93dba849c35f
This commit is contained in:
John Sully 2020-01-04 17:15:06 -05:00
parent db0e7bec78
commit 1ecc8a3eef
2 changed files with 58 additions and 10 deletions

View File

@ -985,6 +985,19 @@ LError:
return;
}
void processReplconfLicense(client *c, robj *arg)
{
if (cserver.license_key != nullptr)
{
if (strcmp(cserver.license_key, szFromObj(arg)) == 0) {
addReplyError(c, "Each replica must have a unique license key");
c->flags |= CLIENT_CLOSE_AFTER_REPLY;
return;
}
}
addReply(c, shared.ok);
}
/* REPLCONF <option> <value> <option> <value> ...
* This command is used by a replica in order to configure the replication
* process before starting it with the SYNC command.
@ -1067,6 +1080,9 @@ void replconfCommand(client *c) {
/* REPLCONF uuid is used to set and send the UUID of each host */
processReplconfUuid(c, c->argv[j+1]);
return; // the process function replies to the client for both error and success
} else if (!strcasecmp(szFromObj(c->argv[j]),"license")) {
processReplconfLicense(c, c->argv[j+1]);
return;
} else {
addReplyErrorFormat(c,"Unrecognized REPLCONF option: %s",
(char*)ptrFromObj(c->argv[j]));
@ -2072,6 +2088,36 @@ void syncWithMaster(aeEventLoop *el, int fd, void *privdata, int mask) {
}
}
sdsfree(err);
mi->repl_state = REPL_STATE_SEND_KEY;
// fallthrough
}
/* Send LICENSE Key */
if (mi->repl_state == REPL_STATE_SEND_KEY)
{
if (cserver.license_key == nullptr)
{
mi->repl_state = REPL_STATE_SEND_PORT;
}
else
{
err = sendSynchronousCommand(mi, SYNC_CMD_WRITE,fd,"REPLCONF","license",cserver.license_key,NULL);
if (err) goto write_error;
mi->repl_state = REPL_STATE_KEY_ACK;
return;
}
}
/* LICENSE Key Ack */
if (mi->repl_state == REPL_STATE_KEY_ACK)
{
err = sendSynchronousCommand(mi, SYNC_CMD_READ,fd,NULL);
if (err[0] == '-') {
serverLog(LL_WARNING, "Recieved error from client: %s", err);
sdsfree(err);
goto error;
}
sdsfree(err);
mi->repl_state = REPL_STATE_SEND_PORT;
// fallthrough
}

View File

@ -554,17 +554,19 @@ public:
#define REPL_STATE_RECEIVE_AUTH 5 /* Wait for AUTH reply */
#define REPL_STATE_SEND_UUID 6 /* send our UUID */
#define REPL_STATE_RECEIVE_UUID 7 /* they should ack with their UUID */
#define REPL_STATE_SEND_PORT 8 /* Send REPLCONF listening-port */
#define REPL_STATE_RECEIVE_PORT 9 /* Wait for REPLCONF reply */
#define REPL_STATE_SEND_IP 10 /* Send REPLCONF ip-address */
#define REPL_STATE_RECEIVE_IP 11 /* Wait for REPLCONF reply */
#define REPL_STATE_SEND_CAPA 12 /* Send REPLCONF capa */
#define REPL_STATE_RECEIVE_CAPA 13 /* Wait for REPLCONF reply */
#define REPL_STATE_SEND_PSYNC 14 /* Send PSYNC */
#define REPL_STATE_RECEIVE_PSYNC 15 /* Wait for PSYNC reply */
#define REPL_STATE_SEND_KEY 8
#define REPL_STATE_KEY_ACK 9
#define REPL_STATE_SEND_PORT 10 /* Send REPLCONF listening-port */
#define REPL_STATE_RECEIVE_PORT 11 /* Wait for REPLCONF reply */
#define REPL_STATE_SEND_IP 12 /* Send REPLCONF ip-address */
#define REPL_STATE_RECEIVE_IP 13 /* Wait for REPLCONF reply */
#define REPL_STATE_SEND_CAPA 14 /* Send REPLCONF capa */
#define REPL_STATE_RECEIVE_CAPA 15 /* Wait for REPLCONF reply */
#define REPL_STATE_SEND_PSYNC 16 /* Send PSYNC */
#define REPL_STATE_RECEIVE_PSYNC 17 /* Wait for PSYNC reply */
/* --- End of handshake states --- */
#define REPL_STATE_TRANSFER 16 /* Receiving .rdb from master */
#define REPL_STATE_CONNECTED 17 /* Connected to master */
#define REPL_STATE_TRANSFER 18 /* Receiving .rdb from master */
#define REPL_STATE_CONNECTED 19 /* Connected to master */
/* State of slaves from the POV of the master. Used in client->replstate.
* In SEND_BULK and ONLINE state the replica receives new updates