| 1555 | } |
| 1556 | |
| 1557 | void processReplconfUuid(client *c, robj *arg) |
| 1558 | { |
| 1559 | const char *remoteUUID = nullptr; |
| 1560 | |
| 1561 | if (arg->type != OBJ_STRING) |
| 1562 | goto LError; |
| 1563 | |
| 1564 | remoteUUID = (const char*)ptrFromObj(arg); |
| 1565 | if (strlen(remoteUUID) != 36) |
| 1566 | goto LError; |
| 1567 | |
| 1568 | if (uuid_parse(remoteUUID, c->uuid) != 0) |
| 1569 | goto LError; |
| 1570 | |
| 1571 | listIter liMi; |
| 1572 | listNode *lnMi; |
| 1573 | listRewind(g_pserver->masters, &liMi); |
| 1574 | |
| 1575 | // Enforce a fair ordering for connection, if they attempt to connect before us close them out |
| 1576 | // This must be consistent so that both make the same decision of who should proceed first |
| 1577 | while ((lnMi = listNext(&liMi))) { |
| 1578 | redisMaster *mi = (redisMaster*)listNodeValue(lnMi); |
| 1579 | if (mi->repl_state == REPL_STATE_CONNECTED) |
| 1580 | continue; |
| 1581 | if (FSameUuidNoNil(mi->master_uuid, c->uuid)) { |
| 1582 | // Decide based on UUID so both clients make the same decision of which host loses |
| 1583 | // otherwise we may entere a loop where neither client can proceed |
| 1584 | if (memcmp(mi->master_uuid, c->uuid, UUID_BINARY_LEN) < 0) { |
| 1585 | freeClientAsync(c); |
| 1586 | } |
| 1587 | } |
| 1588 | } |
| 1589 | |
| 1590 | char szServerUUID[36 + 2]; // 1 for the '+', another for '\0' |
| 1591 | szServerUUID[0] = '+'; |
| 1592 | uuid_unparse(cserver.uuid, szServerUUID+1); |
| 1593 | addReplyProto(c, szServerUUID, 37); |
| 1594 | addReplyProto(c, "\r\n", 2); |
| 1595 | return; |
| 1596 | |
| 1597 | LError: |
| 1598 | addReplyError(c, "Invalid UUID"); |
| 1599 | return; |
| 1600 | } |
| 1601 | |
| 1602 | void processReplconfLicense(client *c, robj *) |
| 1603 | { |
no test coverage detected