// File: renzibei[P]TSProxy/proxyclient.cpp
// Function: clientHandleShake(ClientContext*)
ssize_t clientHandleShake(ClientContext *ctx) {
    srand(time(NULL));
    uint64_t cSeq = getRand63();
    static InnerMsg innerMsg;
    memset(&innerMsg, 0, sizeof(innerMsg));
    innerMsg.cSeq = cSeq;
    innerMsg.sSeq = 0;
    innerMsg.msgType = 1;
    innerMsg.dataLength = 0;
    ssize_t sendCode = sendTSPacket(SocketPlugin::getInstance()->getSockFd(), &innerMsg, constants::clientNonBlocking);
    if (sendCode < 0) {
        LogHelper::log(Error, "client handle shake failed, fail to send first packet");
        return sendCode;
    }
    memset(&innerMsg, 0, sizeof(innerMsg));
    ssize_t recvCode = recvTSPacket(SocketPlugin::getInstance()->getSockFd(), &innerMsg, constants::clientNonBlocking);
    if (recvCode < 0) {
        LogHelper::log(Error, "client handle failed, fail to recv second packet");
    }
    if (innerMsg.cSeq != cSeq) {
        LogHelper::log(Error, "receive cSeq not inc, receive cSeq: %llu, expected: %llu", innerMsg.cSeq, cSeq);
        return -3;
    }
    if (innerMsg.msgType != 2) {
        LogHelper::log(Error, "client hand shake failed, msgType not equals to 2, recv Type: %d", innerMsg.msgType);
        return -4;
    }
    innerMsg.cSeq++;
    // innerMsg.sSeq;
    innerMsg.msgType = 3;
    innerMsg.dataLength = 0;
    sendCode = sendTSPacket(SocketPlugin::getInstance()->getSockFd(), &innerMsg, constants::clientNonBlocking);
    if (sendCode < 0) {
        LogHelper::log(Error, "client handle shake failed, fail to send third packet");
        return sendCode;
    }

    *ctx = ClientContext(innerMsg.cSeq, innerMsg.sSeq);
    return 0;
}

// Assembly:
subq $0x38, %rsp
movq %rdi, 0x28(%rsp)
xorl %eax, %eax
movl %eax, %edi
callq 0x2200
movl %eax, %edi
callq 0x2230
callq 0x8cc0
movq %rax, 0x20(%rsp)
leaq 0xe6a6(%rip), %rdi      # 0x11270
xorl %esi, %esi
movl $0x10000, %edx          # imm = 0x10000
callq 0x2150
movq 0x20(%rsp), %rax
movq %rax, 0xe68e(%rip)      # 0x11270
movq $0x0, 0xe68b(%rip) # 0x11278
movw $0x1, 0xe68a(%rip)      # 0x11280
movw $0x0, 0xe683(%rip)      # 0x11282
callq 0x4d10
movq %rax, %rdi
callq 0x78e0
movl %eax, %edi
leaq 0xe65b(%rip), %rsi      # 0x11270
movl $0x1, %edx
callq 0x8820
movq %rax, 0x18(%rsp)
cmpq $0x0, 0x18(%rsp)
jge 0x2c4b
xorl %edi, %edi
leaq 0x83f5(%rip), %rsi      # 0xb02a
movb $0x0, %al
callq 0x2a50
movq 0x18(%rsp), %rax
movq %rax, 0x30(%rsp)
jmp 0x2da5
leaq 0xe61e(%rip), %rdi      # 0x11270
xorl %esi, %esi
movl $0x10000, %edx          # imm = 0x10000
callq 0x2150
callq 0x4d10
movq %rax, %rdi
callq 0x78e0
movl %eax, %edi
leaq 0xe5fc(%rip), %rsi      # 0x11270
movl $0x1, %edx
callq 0x8a20
movq %rax, 0x10(%rsp)
cmpq $0x0, 0x10(%rsp)
jge 0x2c9b
xorl %edi, %edi
leaq 0x83cc(%rip), %rsi      # 0xb060
movb $0x0, %al
callq 0x2a50
movq 0xe5ce(%rip), %rax      # 0x11270
cmpq 0x20(%rsp), %rax
je 0x2cd3
movq 0xe5c0(%rip), %rdx      # 0x11270
movq 0x20(%rsp), %rcx
xorl %edi, %edi
leaq 0x83d3(%rip), %rsi      # 0xb091
movb $0x0, %al
callq 0x2a50
movq $-0x3, 0x30(%rsp)
jmp 0x2da5
movzwl 0xe5a6(%rip), %eax      # 0x11280
cmpl $0x2, %eax
je 0x2d04
movzwl 0xe59a(%rip), %edx      # 0x11280
xorl %edi, %edi
leaq 0x83db(%rip), %rsi      # 0xb0ca
movb $0x0, %al
callq 0x2a50
movq $-0x4, 0x30(%rsp)
jmp 0x2da5
movq 0xe565(%rip), %rax      # 0x11270
addq $0x1, %rax
movq %rax, 0xe55a(%rip)      # 0x11270
movw $0x3, 0xe561(%rip)      # 0x11280
movw $0x0, 0xe55a(%rip)      # 0x11282
callq 0x4d10
movq %rax, %rdi
callq 0x78e0
movl %eax, %edi
leaq 0xe532(%rip), %rsi      # 0x11270
movl $0x1, %edx
callq 0x8820
movq %rax, 0x18(%rsp)
cmpq $0x0, 0x18(%rsp)
jge 0x2d71
xorl %edi, %edi
leaq 0x83ad(%rip), %rsi      # 0xb10b
movb $0x0, %al
callq 0x2a50
movq 0x18(%rsp), %rax
movq %rax, 0x30(%rsp)
jmp 0x2da5
movq 0xe4f8(%rip), %rsi      # 0x11270
movq 0xe4f9(%rip), %rdx      # 0x11278
movq %rsp, %rdi
callq 0x4dc0
movq 0x28(%rsp), %rax
movq (%rsp), %rcx
movq %rcx, (%rax)
movq 0x8(%rsp), %rcx
movq %rcx, 0x8(%rax)
movq $0x0, 0x30(%rsp)
movq 0x30(%rsp), %rax
addq $0x38, %rsp
retq
nop