// File: /workspace/github_c_makefile_star2_O0/gplessis[P]dotdeb-redis/src/cluster.c
// Function: clusterSendFailoverAuthIfNeeded
void clusterSendFailoverAuthIfNeeded(clusterNode *node, clusterMsg *request) {
    clusterNode *master = node->slaveof;
    uint64_t requestCurrentEpoch = ntohu64(request->currentEpoch);
    uint64_t requestConfigEpoch = ntohu64(request->configEpoch);
    unsigned char *claimed_slots = request->myslots;
    int force_ack = request->mflags[0] & CLUSTERMSG_FLAG0_FORCEACK;
    int j;

    /* IF we are not a master serving at least 1 slot, we don't have the
     * right to vote, as the cluster size in Redis Cluster is the number
     * of masters serving at least one slot, and quorum is the cluster
     * size + 1 */
    if (nodeIsSlave(myself) || myself->numslots == 0) return;

    /* Request epoch must be >= our currentEpoch.
     * Note that it is impossible for it to actually be greater since
     * our currentEpoch was updated as a side effect of receiving this
     * request, if the request epoch was greater. */
    if (requestCurrentEpoch < server.cluster->currentEpoch) {
        serverLog(LL_WARNING,
            "Failover auth denied to %.40s: reqEpoch (%llu) < curEpoch(%llu)",
            node->name,
            (unsigned long long) requestCurrentEpoch,
            (unsigned long long) server.cluster->currentEpoch);
        return;
    }

    /* I already voted for this epoch? Return ASAP. */
    if (server.cluster->lastVoteEpoch == server.cluster->currentEpoch) {
        serverLog(LL_WARNING,
                "Failover auth denied to %.40s: already voted for epoch %llu",
                node->name,
                (unsigned long long) server.cluster->currentEpoch);
        return;
    }

    /* Node must be a slave and its master down.
     * The master can be non failing if the request is flagged
     * with CLUSTERMSG_FLAG0_FORCEACK (manual failover). */
    if (nodeIsMaster(node) || master == NULL ||
        (!nodeFailed(master) && !force_ack))
    {
        if (nodeIsMaster(node)) {
            serverLog(LL_WARNING,
                    "Failover auth denied to %.40s: it is a master node",
                    node->name);
        } else if (master == NULL) {
            serverLog(LL_WARNING,
                    "Failover auth denied to %.40s: I don't know its master",
                    node->name);
        } else if (!nodeFailed(master)) {
            serverLog(LL_WARNING,
                    "Failover auth denied to %.40s: its master is up",
                    node->name);
        }
        return;
    }

    /* We did not voted for a slave about this master for two
     * times the node timeout. This is not strictly needed for correctness
     * of the algorithm but makes the base case more linear. */
    if (mstime() - node->slaveof->voted_time < server.cluster_node_timeout * 2)
    {
        serverLog(LL_WARNING,
                "Failover auth denied to %.40s: "
                "can't vote about this master before %lld milliseconds",
                node->name,
                (long long) ((server.cluster_node_timeout*2)-
                             (mstime() - node->slaveof->voted_time)));
        return;
    }

    /* The slave requesting the vote must have a configEpoch for the claimed
     * slots that is >= the one of the masters currently serving the same
     * slots in the current configuration. */
    for (j = 0; j < CLUSTER_SLOTS; j++) {
        if (bitmapTestBit(claimed_slots, j) == 0) continue;
        if (server.cluster->slots[j] == NULL ||
            server.cluster->slots[j]->configEpoch <= requestConfigEpoch)
        {
            continue;
        }
        /* If we reached this point we found a slot that in our current slots
         * is served by a master with a greater configEpoch than the one claimed
         * by the slave requesting our vote. Refuse to vote for this slave. */
        serverLog(LL_WARNING,
                "Failover auth denied to %.40s: "
                "slot %d epoch (%llu) > reqEpoch (%llu)",
                node->name, j,
                (unsigned long long) server.cluster->slots[j]->configEpoch,
                (unsigned long long) requestConfigEpoch);
        return;
    }

    /* We can vote for this slave. */
    clusterSendFailoverAuth(node);
    server.cluster->lastVoteEpoch = server.cluster->currentEpoch;
    node->slaveof->voted_time = mstime();
    serverLog(LL_WARNING, "Failover auth granted to %.40s for epoch %llu",
        node->name, (unsigned long long) server.cluster->currentEpoch);
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x50, %rsp
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq -0x8(%rbp), %rax
movq 0x850(%rax), %rax
movq %rax, -0x18(%rbp)
movq -0x10(%rbp), %rax
movq 0x10(%rax), %rdi
callq 0x87850
movq %rax, -0x20(%rbp)
movq -0x10(%rbp), %rax
movq 0x18(%rax), %rdi
callq 0x87850
movq %rax, -0x28(%rbp)
movq -0x10(%rbp), %rax
addq $0x50, %rax
movq %rax, -0x30(%rbp)
movq -0x10(%rbp), %rax
movzbl 0x89d(%rax), %eax
andl $0x2, %eax
movl %eax, -0x34(%rbp)
movq 0x10bf0b(%rip), %rax    # 0x18cb60
movl 0x30(%rax), %eax
andl $0x2, %eax
cmpl $0x0, %eax
jne 0x80c70
movq 0x10bef9(%rip), %rax    # 0x18cb60
cmpl $0x0, 0x840(%rax)
jne 0x80c75
jmp 0x80f93
movq -0x20(%rbp), %rax
leaq 0xf7558(%rip), %rcx     # 0x1781d8
movq 0x9b0(%rcx), %rcx
cmpq 0x8(%rcx), %rax
jae 0x80cc3
movq -0x8(%rbp), %rdx
addq $0x8, %rdx
movq -0x20(%rbp), %rcx
leaq 0xf7538(%rip), %rax     # 0x1781d8
movq 0x9b0(%rax), %rax
movq 0x8(%rax), %r8
movl $0x3, %edi
leaq 0xc143c(%rip), %rsi     # 0x1420f3
movb $0x0, %al
callq 0x2fc60
jmp 0x80f93
leaq 0xf750e(%rip), %rax     # 0x1781d8
movq 0x9b0(%rax), %rax
movq 0x60078(%rax), %rax
leaq 0xf74f9(%rip), %rcx     # 0x1781d8
movq 0x9b0(%rcx), %rcx
cmpq 0x8(%rcx), %rax
jne 0x80d1e
movq -0x8(%rbp), %rdx
addq $0x8, %rdx
leaq 0xf74dd(%rip), %rax     # 0x1781d8
movq 0x9b0(%rax), %rax
movq 0x8(%rax), %rcx
movl $0x3, %edi
leaq 0xc1421(%rip), %rsi     # 0x142133
movb $0x0, %al
callq 0x2fc60
jmp 0x80f93
movq -0x8(%rbp), %rax
movl 0x30(%rax), %eax
andl $0x1, %eax
cmpl $0x0, %eax
jne 0x80d51
cmpq $0x0, -0x18(%rbp)
je 0x80d51
movq -0x18(%rbp), %rax
movl 0x30(%rax), %eax
andl $0x8, %eax
cmpl $0x0, %eax
jne 0x80dd4
cmpl $0x0, -0x34(%rbp)
jne 0x80dd4
movq -0x8(%rbp), %rax
movl 0x30(%rax), %eax
andl $0x1, %eax
cmpl $0x0, %eax
je 0x80d7d
movq -0x8(%rbp), %rdx
addq $0x8, %rdx
movl $0x3, %edi
leaq 0xc13fb(%rip), %rsi     # 0x14216f
movb $0x0, %al
callq 0x2fc60
jmp 0x80dcf
cmpq $0x0, -0x18(%rbp)
jne 0x80da1
movq -0x8(%rbp), %rdx
addq $0x8, %rdx
movl $0x3, %edi
leaq 0xc140a(%rip), %rsi     # 0x1421a2
movb $0x0, %al
callq 0x2fc60
jmp 0x80dcd
movq -0x18(%rbp), %rax
movl 0x30(%rax), %eax
andl $0x8, %eax
cmpl $0x0, %eax
jne 0x80dcb
movq -0x8(%rbp), %rdx
addq $0x8, %rdx
movl $0x3, %edi
leaq 0xc1415(%rip), %rsi     # 0x1421d9
movb $0x0, %al
callq 0x2fc60
jmp 0x80dcd
jmp 0x80dcf
jmp 0x80f93
callq 0x2ff70
movq -0x8(%rbp), %rcx
movq 0x850(%rcx), %rcx
subq 0x870(%rcx), %rax
leaq 0xf73e6(%rip), %rcx     # 0x1781d8
movq 0x9a0(%rcx), %rcx
shlq %rcx
cmpq %rcx, %rax
jge 0x80e5c
movq -0x8(%rbp), %rax
addq $0x8, %rax
movq %rax, -0x40(%rbp)
leaq 0xf73c4(%rip), %rax     # 0x1781d8
movq 0x9a0(%rax), %rax
shlq %rax
movq %rax, -0x48(%rbp)
callq 0x2ff70
movq -0x48(%rbp), %rcx
movq -0x40(%rbp), %rdx
movq -0x8(%rbp), %rsi
movq 0x850(%rsi), %rsi
subq 0x870(%rsi), %rax
subq %rax, %rcx
movl $0x3, %edi
leaq 0xc13b9(%rip), %rsi     # 0x142209
movb $0x0, %al
callq 0x2fc60
jmp 0x80f93
movl $0x0, -0x38(%rbp)
cmpl $0x4000, -0x38(%rbp)    # imm = 0x4000
jge 0x80f1c
movq -0x30(%rbp), %rdi
movl -0x38(%rbp), %esi
callq 0x7f570
cmpl $0x0, %eax
jne 0x80e86
jmp 0x80f0e
leaq 0xf734b(%rip), %rax     # 0x1781d8
movq 0x9b0(%rax), %rax
movslq -0x38(%rbp), %rcx
cmpq $0x0, 0x40028(%rax,%rcx,8)
je 0x80ec7
leaq 0xf732e(%rip), %rax     # 0x1781d8
movq 0x9b0(%rax), %rax
movslq -0x38(%rbp), %rcx
movq 0x40028(%rax,%rcx,8), %rax
movq 0x38(%rax), %rax
cmpq -0x28(%rbp), %rax
ja 0x80ec9
jmp 0x80f0e
movq -0x8(%rbp), %rdx
addq $0x8, %rdx
movl -0x38(%rbp), %ecx
leaq 0xf72fd(%rip), %rax     # 0x1781d8
movq 0x9b0(%rax), %rax
movslq -0x38(%rbp), %rsi
movq 0x40028(%rax,%rsi,8), %rax
movq 0x38(%rax), %r8
movq -0x28(%rbp), %r9
movl $0x3, %edi
leaq 0xc135c(%rip), %rsi     # 0x14225e
movb $0x0, %al
callq 0x2fc60
jmp 0x80f93
movl -0x38(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x38(%rbp)
jmp 0x80e63
movq -0x8(%rbp), %rdi
callq 0x818f0
leaq 0xf72ac(%rip), %rax     # 0x1781d8
movq 0x9b0(%rax), %rax
movq 0x8(%rax), %rcx
leaq 0xf729a(%rip), %rax     # 0x1781d8
movq 0x9b0(%rax), %rax
movq %rcx, 0x60078(%rax)
callq 0x2ff70
movq %rax, %rcx
movq -0x8(%rbp), %rax
movq 0x850(%rax), %rax
movq %rcx, 0x870(%rax)
movq -0x8(%rbp), %rdx
addq $0x8, %rdx
leaq 0xf7263(%rip), %rax     # 0x1781d8
movq 0x9b0(%rax), %rax
movq 0x8(%rax), %rcx
movl $0x3, %edi
leaq 0xc1318(%rip), %rsi     # 0x1422a4
movb $0x0, %al
callq 0x2fc60
addq $0x50, %rsp
popq %rbp
retq
nopl (%rax)