REPLCONF ... * This command is used by a replica in order to configure the replication * process before starting it with the SYNC command. * This command is also used by a master in order to get the replication * offset from a replica. * * Currently we support these options: * * - listening-port * - ip-address * What is the listening ip and p
| 1635 | * - rdb-only |
| 1636 | * Only wants RDB snapshot without replication buffer. */ |
| 1637 | void replconfCommand(client *c) { |
| 1638 | int j; |
| 1639 | bool fCapaCommand = false; |
| 1640 | |
| 1641 | if ((c->argc % 2) == 0) { |
| 1642 | /* Number of arguments must be odd to make sure that every |
| 1643 | * option has a corresponding value. */ |
| 1644 | addReplyErrorObject(c,shared.syntaxerr); |
| 1645 | return; |
| 1646 | } |
| 1647 | |
| 1648 | /* Process every option-value pair. */ |
| 1649 | for (j = 1; j < c->argc; j+=2) { |
| 1650 | fCapaCommand = false; |
| 1651 | if (!strcasecmp((const char*)ptrFromObj(c->argv[j]),"listening-port")) { |
| 1652 | long port; |
| 1653 | |
| 1654 | if ((getLongFromObjectOrReply(c,c->argv[j+1], |
| 1655 | &port,NULL) != C_OK)) |
| 1656 | return; |
| 1657 | c->slave_listening_port = port; |
| 1658 | } else if (!strcasecmp((const char*)ptrFromObj(c->argv[j]),"ip-address")) { |
| 1659 | sds addr = (sds)ptrFromObj(c->argv[j+1]); |
| 1660 | if (sdslen(addr) < NET_HOST_STR_LEN) { |
| 1661 | if (c->slave_addr) sdsfree(c->slave_addr); |
| 1662 | c->slave_addr = sdsdup(addr); |
| 1663 | } else { |
| 1664 | addReplyErrorFormat(c,"REPLCONF ip-address provided by " |
| 1665 | "replica instance is too long: %zd bytes", sdslen(addr)); |
| 1666 | return; |
| 1667 | } |
| 1668 | } else if (!strcasecmp((const char*)ptrFromObj(c->argv[j]),"capa")) { |
| 1669 | /* Ignore capabilities not understood by this master. */ |
| 1670 | if (!strcasecmp((const char*)ptrFromObj(c->argv[j+1]),"eof")) |
| 1671 | c->slave_capa |= SLAVE_CAPA_EOF; |
| 1672 | else if (!strcasecmp((const char*)ptrFromObj(c->argv[j+1]),"psync2")) |
| 1673 | c->slave_capa |= SLAVE_CAPA_PSYNC2; |
| 1674 | else if (!strcasecmp((const char*)ptrFromObj(c->argv[j+1]), "activeExpire")) |
| 1675 | c->slave_capa |= SLAVE_CAPA_ACTIVE_EXPIRE; |
| 1676 | else if (!strcasecmp((const char*)ptrFromObj(c->argv[j+1]), "keydb-fastsync")) |
| 1677 | c->slave_capa |= SLAVE_CAPA_KEYDB_FASTSYNC; |
| 1678 | |
| 1679 | fCapaCommand = true; |
| 1680 | } else if (!strcasecmp((const char*)ptrFromObj(c->argv[j]),"ack")) { |
| 1681 | /* REPLCONF ACK is used by replica to inform the master the amount |
| 1682 | * of replication stream that it processed so far. It is an |
| 1683 | * internal only command that normal clients should never use. */ |
| 1684 | long long offset; |
| 1685 | |
| 1686 | if (!(c->flags & CLIENT_SLAVE)) return; |
| 1687 | if ((getLongLongFromObject(c->argv[j+1], &offset) != C_OK)) |
| 1688 | return; |
| 1689 | if (offset > c->repl_ack_off) |
| 1690 | c->repl_ack_off = offset; |
| 1691 | c->repl_ack_time = g_pserver->unixtime; |
| 1692 | /* If this was a diskless replication, we need to really put |
| 1693 | * the replica online when the first ACK is received (which |
| 1694 | * confirms slave is online and ready to get more data). This |
nothing calls this directly
no test coverage detected