// File: renzibei[P]TSProxy/proxyserver.cpp
// Function: serverHandShake(int, std::unordered_map<int, ClientNode*, std::hash<int>, std::equal_to<int>, std::allocator<std::pair<int const, ClientNode*>>>&)
ssize_t serverHandShake(int sockFd, ClientMap &cMap) {
    uint64_t sSeq = getRand63();
    static InnerMsg innerMsg;
    memset(&innerMsg, 0, sizeof(innerMsg));

    ssize_t recvCode = recvTSPacket(sockFd, &innerMsg, constants::serverNonBlocking);
    if (recvCode < 0) {
        LogHelper::log(Error, "server hand shake failed, fail to recv first packet");
        return recvCode;
    }
    if (innerMsg.msgType != 1) {
        LogHelper::log(Error, "server hand shake failed, first packet type get: %d", innerMsg.msgType);
        return -4;
    }

    uint64_t cSeq = innerMsg.cSeq;

    innerMsg.sSeq = sSeq;
    innerMsg.msgType = 2;
    innerMsg.dataLength = 0;
    ssize_t sendCode = sendTSPacket(sockFd, &innerMsg, constants::serverNonBlocking);
    if (sendCode < 0) {
        LogHelper::log(Error, "server hand shake shake failed, fail to send second packet");
        return sendCode;
    }

    memset(&innerMsg, 0, sizeof(innerMsg));
    recvCode = recvTSPacket(sockFd, &innerMsg, constants::serverNonBlocking);
    if (recvCode < 0) {
        LogHelper::log(Error, "server hand shake failed, fail to recv third packet");
    }
    if (innerMsg.sSeq != sSeq || innerMsg.cSeq != cSeq + 1) {
        LogHelper::log(Error, "server hand shake failed, third packet receive seq not inc, receive cSeq: %llu, expected: %llu, receive sSeq: %llu, expected: %llu", innerMsg.cSeq, cSeq + 1, innerMsg.sSeq, sSeq);
        return -3;
    }
    if (innerMsg.msgType != 3) {
        LogHelper::log(Error, "server hand shake failed, third packet type get: %d", innerMsg.msgType);
        return -5;
    }
    
    cMap[sockFd] = new ClientNode(innerMsg.cSeq, innerMsg.sSeq, time(NULL));
    LogHelper::log(Debug, "Server handshake completed");
    
    return 0;
}

// Assembly:
subq $0x68, %rsp
movl %edi, 0x5c(%rsp)
movq %rsi, 0x50(%rsp)
callq 0xd850
movq %rax, 0x48(%rsp)
leaq 0x147e2(%rip), %rdi     # 0x17240
xorl %esi, %esi
movl $0x10000, %edx          # imm = 0x10000
callq 0x2140
movl 0x5c(%rsp), %edi
leaq 0x147cb(%rip), %rsi     # 0x17240
movl $0x1, %edx
callq 0xd5b0
movq %rax, 0x40(%rsp)
cmpq $0x0, 0x40(%rsp)
jge 0x2aab
xorl %edi, %edi
leaq 0xd595(%rip), %rsi      # 0x1002a
movb $0x0, %al
callq 0x28f0
movq 0x40(%rsp), %rax
movq %rax, 0x60(%rsp)
jmp 0x2cb4
movzwl 0x1479e(%rip), %eax     # 0x17250
cmpl $0x1, %eax
je 0x2adc
movzwl 0x14792(%rip), %edx     # 0x17250
xorl %edi, %edi
leaq 0xd597(%rip), %rsi      # 0x1005e
movb $0x0, %al
callq 0x28f0
movq $-0x4, 0x60(%rsp)
jmp 0x2cb4
movq 0x1475d(%rip), %rax     # 0x17240
movq %rax, 0x38(%rsp)
movq 0x48(%rsp), %rax
movq %rax, 0x14754(%rip)     # 0x17248
movw $0x2, 0x14753(%rip)     # 0x17250
movw $0x0, 0x1474c(%rip)     # 0x17252
movl 0x5c(%rsp), %edi
leaq 0x1472f(%rip), %rsi     # 0x17240
movl $0x1, %edx
callq 0xd3b0
movq %rax, 0x30(%rsp)
cmpq $0x0, 0x30(%rsp)
jge 0x2b47
xorl %edi, %edi
leaq 0xd561(%rip), %rsi      # 0x10092
movb $0x0, %al
callq 0x28f0
movq 0x30(%rsp), %rax
movq %rax, 0x60(%rsp)
jmp 0x2cb4
leaq 0x146f2(%rip), %rdi     # 0x17240
xorl %esi, %esi
movl $0x10000, %edx          # imm = 0x10000
callq 0x2140
movl 0x5c(%rsp), %edi
leaq 0x146db(%rip), %rsi     # 0x17240
movl $0x1, %edx
callq 0xd5b0
movq %rax, 0x40(%rsp)
cmpq $0x0, 0x40(%rsp)
jge 0x2b8c
xorl %edi, %edi
leaq 0xd548(%rip), %rsi      # 0x100cd
movb $0x0, %al
callq 0x28f0
movq 0x146b5(%rip), %rax     # 0x17248
cmpq 0x48(%rsp), %rax
jne 0x2baf
movq 0x1469f(%rip), %rax     # 0x17240
movq 0x38(%rsp), %rcx
addq $0x1, %rcx
cmpq %rcx, %rax
je 0x2be9
movq 0x1468a(%rip), %rdx     # 0x17240
movq 0x38(%rsp), %rcx
addq $0x1, %rcx
movq 0x14682(%rip), %r8      # 0x17248
movq 0x48(%rsp), %r9
xorl %edi, %edi
leaq 0xd52d(%rip), %rsi      # 0x10101
movb $0x0, %al
callq 0x28f0
movq $-0x3, 0x60(%rsp)
jmp 0x2cb4
movzwl 0x14660(%rip), %eax     # 0x17250
cmpl $0x3, %eax
je 0x2c1a
movzwl 0x14654(%rip), %edx     # 0x17250
xorl %edi, %edi
leaq 0xd57f(%rip), %rsi      # 0x10184
movb $0x0, %al
callq 0x28f0
movq $-0x5, 0x60(%rsp)
jmp 0x2cb4
movl $0x50, %edi
callq 0x2200
movq %rax, 0x8(%rsp)
movq %rax, (%rsp)
movq 0x1460c(%rip), %rax     # 0x17240
movq %rax, 0x10(%rsp)
movq 0x14608(%rip), %rax     # 0x17248
movq %rax, 0x18(%rsp)
xorl %eax, %eax
movl %eax, %edi
callq 0x21c0
movq 0x8(%rsp), %rdi
movq 0x10(%rsp), %rsi
movq 0x18(%rsp), %rdx
movq %rax, %rcx
callq 0x5600
jmp 0x2c67
movq 0x50(%rsp), %rdi
leaq 0x5c(%rsp), %rsi
callq 0x5650
movq (%rsp), %rcx
movq %rcx, (%rax)
movl $0x3, %edi
leaq 0xd52f(%rip), %rsi      # 0x101b8
movb $0x0, %al
callq 0x28f0
movq $0x0, 0x60(%rsp)
jmp 0x2cb4
movq (%rsp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x28(%rsp)
movl %eax, 0x24(%rsp)
callq 0x21d0
jmp 0x2cbe
movq 0x60(%rsp), %rax
addq $0x68, %rsp
retq
movq 0x28(%rsp), %rdi
callq 0x2360
nopl (%rax,%rax)