// File: /workspace/github_c_makefile_star2_O2/TeaInside[P]teavpn/src/teavpn/server/tcp.c
// Function: teavpn_tcp_accept_worker_thread
static void *teavpn_tcp_accept_worker_thread(server_config *config)
{
	FILE *h;
	int client_fd;
	uint64_t seq = 0;
	char *remote_addr;
	int16_t conn_index;
	uint16_t remote_port;
	teavpn_packet packet;
	ssize_t nread, nwrite;
	struct timeval timeout;
	struct sockaddr_in client_addr;
	socklen_t rlen = sizeof(struct sockaddr_in);

	/**
	 * NDF
	 */
	char buffer[64 + OFFSETOF(teavpn_packet, data)], *pbuf;
	size_t len, sp = 0;
	const uint8_t sig = 0xff;


	/**
	 * Set timeout to 10 seconds.
	 */
	timeout.tv_sec = 10;
	timeout.tv_usec = 0;


	while (true) {

		pthread_mutex_lock(&accept_worker_mutex);
		pthread_cond_wait(&accept_worker_cond, &accept_worker_mutex);

		/**
		 * Set client_addr to zero.
		 */
		seq = 0;
		memset(&client_addr, 0, sizeof(client_addr));

		client_fd = accept(net_fd, (struct sockaddr *)&client_addr, &rlen);

		if (client_fd < 0) {
			debug_log(0, "Error on accept");
			perror("Error on accept");
			goto next_cycle;
		}

		remote_addr = inet_ntoa(client_addr.sin_addr);
		remote_port = ntohs(client_addr.sin_port);

		debug_log(3, "%s:%d is attempting to make a connection...", remote_addr, remote_port);

		conn_index = get_free_conn_index();

		if (conn_index == -1) {
			debug_log(0, "Connection entry is full, cannot accept more client");
			debug_log(0, "Dropping connection from %s:%d...", remote_addr, remote_port);
			close(client_fd);
			goto next_cycle;
		}

		/**
		 * Set recv timeout.
		 */
		if (setsockopt(client_fd, SOL_SOCKET, SO_RCVTIMEO, (char *)&timeout, sizeof(timeout)) < 0) {
			debug_log(0, "Error set recv timeout");
			perror("Error set recv timeout");
			goto next_cycle;
		}

		/**
		 * Set send timeout.
		 */
		if (setsockopt(client_fd, SOL_SOCKET, SO_SNDTIMEO, (char *)&timeout, sizeof(timeout)) < 0) {
			debug_log(0, "Error set recv timeout");
			perror("Error set recv timeout");
			goto next_cycle;
		}

		/**
		 * Read auth packet (username and password).
		 */
		seq++; // seq 1
		nread = read(client_fd, &packet, sizeof(packet));

		debug_log(3, "[%ld] Read auth packet from %s:%d %ld bytes (server_seq: %ld) (client_seq: %ld) (seq %s)",
				seq, remote_addr, remote_port, nread, seq, packet.info.seq,
				(seq == packet.info.seq) ? "match" : "invalid");

		if (nread == 0) {
			debug_log(3, "Client %s:%d closed connection");
			close(client_fd);
			goto next_cycle;
		}

		if (nread < 0) {
			debug_log(3, "An error occured when reading auth packet from %s:%d", remote_addr, remote_port);
			perror("Error read from client (acceptor)");
			close(client_fd);
			goto next_cycle;
		}

		if (seq != packet.info.seq) {
			debug_log(0, "Invalid packet sequence from %s:%d (client_seq: %ld) (server_seq: %ld)",
				remote_addr, remote_port, seq, packet.info.seq);
			close(client_fd);
			goto next_cycle;
		}

		/**
		 * Validate credential from auth packet.
		 */
		if (packet.info.type == TEAVPN_PACKET_AUTH) {
			h = teavpn_auth_check(config, &(packet.data.auth));
		} else {
			debug_log(3, "Invalid auth packet from %s:%d", remote_addr, remote_port);
			debug_log(3, "Dropping connection from %s:%d...", remote_addr, remote_port);
			close(client_fd);
			goto next_cycle;
		}

		if (h == NULL) {
			/**
			 * Invalid username or password.
			 */
			packet.info.type = TEAVPN_PACKET_SIG;
			packet.info.len = TEAVPN_PACK(sizeof(packet.data.sig));
			packet.info.seq = ++seq; // seq 2
			packet.data.sig.sig = TEAVPN_SIG_AUTH_REJECT;
			nwrite = write(client_fd, &packet, TEAVPN_PACK(sizeof(packet.data.sig)));
			debug_log(3, "Invalid username or password from %s:%d", remote_addr, remote_port);
			debug_log(3, "Dropping connection from %s:%d...", remote_addr, remote_port);
			close(client_fd);
			goto next_cycle;
		}


		/**
		 * Preparing client network interface configuration.
		 */
		memset(buffer, 0, sizeof(buffer));
		pbuf = fgets(buffer, 63, h);
		fclose(h);
		if (pbuf == NULL) {
			debug_log(0, "Invalid IP configuration for username %s", packet.data.auth.username);
		}

		len = strlen(buffer);

		while (buffer[sp] != ' ') {
			if (sp >= len) {
				close(client_fd);
				debug_log(0, "Invalid IP configuration for username %s", packet.data.auth.username);
				goto next_cycle;
			}
			sp++;
		}

		if ((sp > sizeof("xxx.xxx.xxx.xxx/xx")) || ((len - (sp - 1)) > sizeof("xxx.xxx.xxx.xxx"))) {
			close(client_fd);
			debug_log(0, "Invalid IP configuration for username %s", packet.data.auth.username);
			goto next_cycle;	
		}

		debug_log(1, "%s connected from (%s:%d) [%s]", packet.data.auth.username, remote_addr, remote_port, buffer);


		/**
		 * Assign client fd to connection entry.
		 */
		connections[conn_index].fd = client_fd;
		connections[conn_index].priv_ip = ip_read_conv(buffer);
		connections[conn_index].error = 0;
		connections[conn_index].addr = client_addr;


		/**
		 * Send auth ok signal.
		 */
		packet.info.type = TEAVPN_PACKET_SIG;
		packet.info.len = TEAVPN_PACK(sizeof(packet.data.sig));
		packet.data.sig.sig = TEAVPN_SIG_AUTH_OK;
		packet.info.seq = ++seq; // seq 2

		nwrite = write(client_fd, &packet, TEAVPN_PACK(sizeof(packet.data.sig)));

		debug_log(3, "[%ld] Write sig auth to %s:%d %ld bytes (server_seq: %ld) (client_seq: %ld) (seq %s)",
				seq, remote_addr, remote_port, nwrite, seq, packet.info.seq,
				(seq == packet.info.seq) ? "match" : "invalid");

		if (nwrite == 0) {
			debug_log(3, "Client %s:%d closed connection (authenticated)", remote_addr, remote_port);
			close(client_fd);
			connection_zero(conn_index);
			goto next_cycle;
		}

		if (nwrite < 0) {
			debug_log(3, "Error send auth ok signal to %s:%d", remote_addr, remote_port);
			perror("Error write to client_fd (acceptor)");
			close(client_fd);
			connection_zero(conn_index);
			goto next_cycle;
		}


		/**
		 * Wait for ack signal.
		 */
		seq++; // seq 3
		nread = read(client_fd, &packet, sizeof(packet));

		debug_log(3, "[%ld] Read sig ack from %s:%d %ld bytes (server_seq: %ld) (client_seq: %ld) (seq %s)",
				seq, remote_addr, remote_port, nread, seq, packet.info.seq,
				(seq == packet.info.seq) ? "match" : "invalid");

		if (nread == 0) {
			debug_log(3, "Client %s:%d closed connection (authenticated)", remote_addr, remote_port);
			close(client_fd);
			connection_zero(conn_index);
			goto next_cycle;
		}

		if (nread < 0) {
			debug_log(3, "Error read ack packet from %s:%d", remote_addr, remote_port);
			perror("Error read from client_fd (acceptor)");
			close(client_fd);
			connection_zero(conn_index);
			goto next_cycle;
		}

		if (seq != packet.info.seq) {
			debug_log(0, "Invalid packet sequence from %s:%d (client_seq: %ld) (server_seq: %ld) (authenticated)",
				remote_addr, remote_port, seq, packet.info.seq);
			close(client_fd);
			connection_zero(conn_index);
			goto next_cycle;
		}

		/**
		 * Verify ack signal..
		 */
		if ((packet.info.type == TEAVPN_PACKET_SIG) && (packet.data.sig.sig == TEAVPN_SIG_ACK)) {
			debug_log(3, "[%ld] Got ack from %s:%d (connection established)", seq, remote_addr, remote_port);
		} else {
			debug_log(3, "[%ld] Invalid ack signal from %s:%d (authenticated)", seq, remote_addr, remote_port);
			debug_log(0, "Dropping connection from %s:%d...", remote_addr, remote_port);
			close(client_fd);
			connection_zero(conn_index);
			goto next_cycle;
		}


		/**
		 * Send network interface configuration.
		 */
		packet.info.type = TEAVPN_PACKET_CONF;
		packet.info.seq = ++seq; // seq 4
		packet.info.len = TEAVPN_PACK(sizeof(packet.data.conf));
		memcpy(packet.data.conf.inet4, buffer, sp);
		packet.data.conf.inet4[sp] = '\0';
		strcpy(packet.data.conf.inet4_broadcast, &(buffer[sp+1]));
		nwrite = write(client_fd, &packet, TEAVPN_PACK(sizeof(packet.data.conf)));

		debug_log(3, "[%ld] Write packet conf to %s:%d %ld bytes (server_seq: %ld) (client_seq: %ld) (seq %s)",
				seq, remote_addr, remote_port, nwrite, seq, packet.info.seq,
				(seq == packet.info.seq) ? "match" : "invalid");

		if (nwrite == 0) {
			debug_log(3, "Client %s:%d closed connection (authenticated)", remote_addr, remote_port);
			close(client_fd);
			connection_zero(conn_index);
			goto next_cycle;
		}

		if (nwrite < 0) {
			debug_log(3, "Error send network config to %s:%d", remote_addr, remote_port);
			perror("Error write to client_fd (acceptor)");
			close(client_fd);
			connection_zero(conn_index);
			goto next_cycle;
		}


		/**
		 * Set entry to connected state.
		 */
		connections[conn_index].connected = true;
		connections[conn_index].seq = seq;
		conn_count++;


		/**
		 * Interrupt main process in order to read rd_set.
		 */
		nwrite = write(m_pipe_fd[1], &sig, sizeof(sig));
		if (nwrite < 0) {
			debug_log(0, "Error write to m_pipe_fd[1]");
			perror("Error write to m_pipe_fd[1]");
			goto next_cycle;
		}

		next_cycle:
		(void)1;
		pthread_mutex_unlock(&accept_worker_mutex);
	}

	return NULL;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x10b8, %rsp           # imm = 0x10B8
movq %rdi, -0x70(%rbp)
leaq -0x3c(%rbp), %r14
movl $0x10, (%r14)
leaq -0x3d(%rbp), %rax
leaq -0x80(%rbp), %rcx
movq $0xa, (%rcx)
andq $0x0, 0x8(%rcx)
movb $-0x1, (%rax)
leaq 0x642a(%rip), %rbx      # 0xb3f8
leaq 0x63cb(%rip), %r15      # 0xb3a0
leaq -0x50(%rbp), %r12
movq $0x0, -0x60(%rbp)
movq %rbx, %rdi
callq 0x23f0
movq %r15, %rdi
movq %rbx, %rsi
callq 0x20e0
xorps %xmm0, %xmm0
movaps %xmm0, -0x50(%rbp)
movl 0x638f(%rip), %edi      # 0xb390
movq %r12, %rsi
movq %r14, %rdx
callq 0x2370
testl %eax, %eax
jns 0x502e
leaq 0x2cd4(%rip), %r13      # 0x7ceb
movq %r13, %rdi
xorl %eax, %eax
callq 0x5aec
movq %r13, %rdi
callq 0x2350
jmp 0x512d
movl %eax, -0x54(%rbp)
movl -0x4c(%rbp), %edi
callq 0x20d0
movzwl -0x4e(%rbp), %ecx
rolw $0x8, %cx
movq %rax, %r14
leaq 0x63d9(%rip), %rax      # 0xb424
cmpb $0x3, (%rax)
movzwl %cx, %ebx
jb 0x5066
leaq 0x2ca1(%rip), %rdi      # 0x7cfb
movq %r14, %rsi
movl %ebx, %edx
xorl %eax, %eax
callq 0x5aec
movq %r14, -0x38(%rbp)
movl %ebx, -0x2c(%rbp)
movq 0x6304(%rip), %rax      # 0xb378
xorl %r12d, %r12d
xorl %ebx, %ebx
leaq -0x80(%rbp), %r15
pushq $0x1
popq %r14
pushq $0x10
popq %r8
cmpq $0x18, %rbx
je 0x509c
cmpb $0x1, 0x4(%rax,%r12)
jne 0x50c9
incq %rbx
addq $0x50, %r12
jmp 0x5085
leaq 0x2c84(%rip), %rdi      # 0x7d27
xorl %eax, %eax
callq 0x5aec
leaq 0x2caa(%rip), %rdi      # 0x7d5b
movq -0x38(%rbp), %rsi
movl -0x2c(%rbp), %edx
xorl %eax, %eax
callq 0x5aec
movl -0x54(%rbp), %edi
callq 0x21a0
jmp 0x5117
movl -0x54(%rbp), %r13d
movl %r13d, %edi
movl %r14d, %esi
pushq $0x14
popq %rdx
movq %r15, %rcx
movl %r8d, %r15d
callq 0x20b0
testl %eax, %eax
js 0x50fe
movl %r13d, %edi
movl %r14d, %esi
pushq $0x15
popq %rdx
leaq -0x80(%rbp), %rcx
movl %r15d, %r8d
callq 0x20b0
testl %eax, %eax
jns 0x513a
leaq 0x2c78(%rip), %rbx      # 0x7d7d
movq %rbx, %rdi
xorl %eax, %eax
callq 0x5aec
movq %rbx, %rdi
callq 0x2350
leaq 0x62da(%rip), %rbx      # 0xb3f8
leaq 0x627b(%rip), %r15      # 0xb3a0
leaq -0x50(%rbp), %r12
leaq -0x3c(%rbp), %r14
movq %rbx, %rdi
callq 0x22b0
jmp 0x4fe1
movl $0x1010, %edx           # imm = 0x1010
movl %r13d, %edi
leaq -0x10e0(%rbp), %rsi
callq 0x21d0
movq %rax, %r15
leaq 0x62cc(%rip), %rax      # 0xb424
cmpb $0x3, (%rax)
jb 0x519e
movq -0x10d8(%rbp), %r10
cmpq $0x1, %r10
leaq 0x23bf(%rip), %r11      # 0x752e
leaq 0x23b2(%rip), %rax      # 0x7528
cmoveq %rax, %r11
leaq 0x2c13(%rip), %rdi      # 0x7d94
pushq $0x1
popq %rsi
movq -0x38(%rbp), %rdx
movl -0x2c(%rbp), %ecx
movq %r15, %r8
movq %rsi, %r9
xorl %eax, %eax
pushq %r11
pushq %r10
callq 0x5aec
popq %rcx
popq %rdx
testq %r15, %r15
jne 0x51ca
leaq 0x627a(%rip), %rax      # 0xb424
cmpb $0x3, (%rax)
leaq -0x3c(%rbp), %r14
jb 0x52f7
leaq 0x2c2f(%rip), %rdi      # 0x7ded
xorl %eax, %eax
callq 0x5aec
jmp 0x52f7
leaq -0x3c(%rbp), %r14
jns 0x521c
leaq 0x624d(%rip), %rax      # 0xb424
cmpb $0x3, (%rax)
leaq 0x6217(%rip), %rbx      # 0xb3f8
leaq 0x61b8(%rip), %r15      # 0xb3a0
leaq -0x50(%rbp), %r12
jb 0x5203
leaq 0x2c17(%rip), %rdi      # 0x7e0c
movq -0x38(%rbp), %rsi
movl -0x2c(%rbp), %edx
xorl %eax, %eax
callq 0x5aec
leaq 0x2c37(%rip), %rdi      # 0x7e41
callq 0x2350
movl %r13d, %edi
callq 0x21a0
jmp 0x512d
movq -0x10d8(%rbp), %r8
cmpq $0x1, %r8
jne 0x52df
cmpl $0x1, -0x10e0(%rbp)
jne 0x5316
movq -0x70(%rbp), %rdi
leaq -0x10d0(%rbp), %rsi
callq 0x59cc
testq %rax, %rax
jne 0x5377
movl $0x4, -0x10e0(%rbp)
movw $0x14, -0x10dc(%rbp)
movq $0x2, -0x10d8(%rbp)
movl $0x1, -0x10d0(%rbp)
movl %r13d, %edi
leaq -0x10e0(%rbp), %rsi
pushq $0x14
popq %rdx
callq 0x20c0
leaq 0x6190(%rip), %rax      # 0xb424
cmpb $0x3, (%rax)
movl -0x2c(%rbp), %ebx
movq -0x38(%rbp), %r14
jb 0x52d2
leaq 0x2c22(%rip), %rdi      # 0x7ec9
movq %r14, %rsi
movl %ebx, %edx
xorl %eax, %eax
callq 0x5aec
leaq 0x616a(%rip), %rax      # 0xb424
cmpb $0x3, (%rax)
jb 0x52d2
leaq 0x2a95(%rip), %rdi      # 0x7d5b
movq %r14, %rsi
movl %ebx, %edx
xorl %eax, %eax
callq 0x5aec
movl %r13d, %edi
callq 0x21a0
jmp 0x545b
leaq 0x2b7d(%rip), %rdi      # 0x7e63
movq -0x38(%rbp), %rsi
movl -0x2c(%rbp), %edx
pushq $0x1
popq %rcx
xorl %eax, %eax
callq 0x5aec
movl %r13d, %edi
callq 0x21a0
leaq 0x60f2(%rip), %rbx      # 0xb3f8
leaq 0x6093(%rip), %r15      # 0xb3a0
leaq -0x50(%rbp), %r12
jmp 0x512d
leaq 0x6107(%rip), %rax      # 0xb424
cmpb $0x3, (%rax)
leaq 0x60d1(%rip), %rbx      # 0xb3f8
leaq 0x6072(%rip), %r15      # 0xb3a0
leaq -0x50(%rbp), %r12
jb 0x520f
leaq 0x2b6b(%rip), %rdi      # 0x7eaa
movq -0x38(%rbp), %rsi
movl -0x2c(%rbp), %edx
xorl %eax, %eax
callq 0x5aec
leaq 0x60d0(%rip), %rax      # 0xb424
cmpb $0x3, (%rax)
jb 0x520f
leaq 0x29f7(%rip), %rdi      # 0x7d5b
movq -0x38(%rbp), %rsi
movl -0x2c(%rbp), %edx
xorl %eax, %eax
callq 0x5aec
jmp 0x520f
movq %rax, %r15
xorps %xmm0, %xmm0
movaps %xmm0, -0x90(%rbp)
movaps %xmm0, -0xa0(%rbp)
movaps %xmm0, -0xb0(%rbp)
movaps %xmm0, -0xc0(%rbp)
movaps %xmm0, -0xd0(%rbp)
leaq -0xd0(%rbp), %rdi
pushq $0x3f
popq %rsi
movq %rax, %rdx
callq 0x21e0
movq %rax, %r14
movq %r15, %rdi
callq 0x20f0
testq %r14, %r14
jne 0x53d7
leaq 0x2b28(%rip), %rdi      # 0x7ef1
leaq -0x10ce(%rbp), %rsi
xorl %eax, %eax
callq 0x5aec
leaq -0xd0(%rbp), %rdi
callq 0x2100
movq -0x60(%rbp), %rcx
cmpq %rcx, %rax
movq %rcx, %r15
cmovaq %rax, %r15
cmpb $0x20, -0xd0(%rbp,%rcx)
je 0x5405
cmpq %rax, %rcx
jae 0x543a
incq %rcx
jmp 0x53f1
cmpq $0x13, %rcx
movq %rcx, -0x60(%rbp)
ja 0x541b
subq %rcx, %rax
incq %rax
cmpq $0x11, %rax
jb 0x5464
movl %r13d, %edi
callq 0x21a0
leaq 0x2ac7(%rip), %rdi      # 0x7ef1
leaq -0x10ce(%rbp), %rsi
xorl %eax, %eax
callq 0x5aec
jmp 0x545b
movl %r13d, %edi
callq 0x21a0
leaq 0x2aa8(%rip), %rdi      # 0x7ef1
leaq -0x10ce(%rbp), %rsi
xorl %eax, %eax
callq 0x5aec
movq %r15, -0x60(%rbp)
leaq -0x3c(%rbp), %r14
jmp 0x52ff
leaq 0x5fb9(%rip), %rax      # 0xb424
cmpb $0x0, (%rax)
leaq -0x3c(%rbp), %r14
movl -0x2c(%rbp), %r15d
je 0x549b
leaq 0x2a9b(%rip), %rdi      # 0x7f1a
leaq -0x10ce(%rbp), %rsi
movq -0x38(%rbp), %rdx
movl %r15d, %ecx
leaq -0xd0(%rbp), %r8
xorl %eax, %eax
callq 0x5aec
movq 0x5ed6(%rip), %rax      # 0xb378
movl %r13d, (%rax,%r12)
leaq -0xd0(%rbp), %rdi
callq 0x25fc
movq 0x5ebf(%rip), %rcx      # 0xb378
movl %eax, 0x10(%rcx,%r12)
movb $0x0, 0x5(%rcx,%r12)
movaps -0x50(%rbp), %xmm0
movups %xmm0, 0x40(%rcx,%r12)
movl $0x4, -0x10e0(%rbp)
movw $0x14, -0x10dc(%rbp)
movl $0x2, -0x10d0(%rbp)
movq $0x2, -0x10d8(%rbp)
movl %r13d, %edi
leaq -0x10e0(%rbp), %rsi
pushq $0x14
popq %rdx
callq 0x20c0
movq %rax, %r8
leaq 0x5f12(%rip), %rax      # 0xb424
cmpb $0x3, (%rax)
jb 0x5561
movq -0x10d8(%rbp), %r10
cmpq $0x2, %r10
leaq 0x2005(%rip), %r11      # 0x752e
leaq 0x1ff8(%rip), %rax      # 0x7528
cmoveq %rax, %r11
leaq 0x29fe(%rip), %rdi      # 0x7f39
pushq $0x2
popq %rsi
movq -0x38(%rbp), %rdx
movl %r15d, %ecx
movq %r8, %r15
movq %rsi, %r9
xorl %eax, %eax
pushq %r11
pushq %r10
callq 0x5aec
movq %r15, %r8
movl -0x2c(%rbp), %r15d
addq $0x10, %rsp
testq %r8, %r8
jne 0x5589
leaq 0x5eb7(%rip), %rax      # 0xb424
cmpb $0x3, (%rax)
jb 0x55b8
leaq 0x2a15(%rip), %rdi      # 0x7f8e
movq -0x38(%rbp), %rsi
movl %r15d, %edx
xorl %eax, %eax
callq 0x5aec
jmp 0x55b8
jns 0x55cd
leaq 0x5e92(%rip), %rax      # 0xb424
cmpb $0x3, (%rax)
jb 0x55ac
leaq 0x2a1f(%rip), %rdi      # 0x7fbd
movq -0x38(%rbp), %rsi
movl %r15d, %edx
xorl %eax, %eax
callq 0x5aec
leaq 0x2a2d(%rip), %rdi      # 0x7fe0
callq 0x2350
movl %r13d, %edi
callq 0x21a0
movzwl %bx, %edi
callq 0x58c5
jmp 0x52ff
movl $0x1010, %edx           # imm = 0x1010
movl %r13d, %edi
leaq -0x10e0(%rbp), %rsi
callq 0x21d0
movq %rax, %r8
leaq 0x5e39(%rip), %rax      # 0xb424
cmpb $0x3, (%rax)
jb 0x563c
movq -0x10d8(%rbp), %r10
cmpq $0x3, %r10
leaq 0x1f2c(%rip), %r11      # 0x752e
leaq 0x1f1f(%rip), %rax      # 0x7528
cmoveq %rax, %r11
leaq 0x29f0(%rip), %rdi      # 0x8004
pushq $0x3
popq %rsi
movq -0x38(%rbp), %rdx
movl %r15d, %ecx
movq %r8, -0x68(%rbp)
movq -0x68(%rbp), %r8
movq %rsi, %r9
xorl %eax, %eax
pushq %r11
pushq %r10
callq 0x5aec
movq -0x68(%rbp), %r8
addq $0x10, %rsp
testq %r8, %r8
je 0x5566
jns 0x569b
leaq 0x5dd6(%rip), %rax      # 0xb424
cmpb $0x3, (%rax)
leaq 0x5d48(%rip), %r15      # 0xb3a0
leaq -0x50(%rbp), %r12
jb 0x5673
leaq 0x29f4(%rip), %rdi      # 0x8059
movq -0x38(%rbp), %rsi
movl -0x2c(%rbp), %edx
xorl %eax, %eax
callq 0x5aec
leaq 0x2a00(%rip), %rdi      # 0x807a
callq 0x2350
movl %r13d, %edi
callq 0x21a0
movzwl %bx, %edi
callq 0x58c5
leaq 0x5d62(%rip), %rbx      # 0xb3f8
jmp 0x512d
movq -0x10d8(%rbp), %r8
cmpq $0x3, %r8
jne 0x57d7
cmpl $0x4, -0x10e0(%rbp)
leaq 0x5d6a(%rip), %rax      # 0xb424
movb (%rax), %al
jne 0x57f4
cmpl $0x10, -0x10d0(%rbp)
jne 0x57f4
movq %r14, %r15
cmpb $0x3, %al
jb 0x56ee
leaq 0x2a19(%rip), %rdi      # 0x80f6
pushq $0x3
popq %rsi
movq -0x38(%rbp), %rdx
movl -0x2c(%rbp), %ecx
xorl %eax, %eax
callq 0x5aec
movl $0x8, -0x10e0(%rbp)
movq $0x4, -0x10d8(%rbp)
movw $0x43, -0x10dc(%rbp)
leaq -0x10d0(%rbp), %rdi
leaq -0xd0(%rbp), %rsi
movq -0x60(%rbp), %r14
movq %r14, %rdx
callq 0x2260
movb $0x0, -0x10d0(%rbp,%r14)
leaq (%r14,%rbp), %rsi
addq $-0xcf, %rsi
leaq -0x10bd(%rbp), %rdi
callq 0x2070
movl %r13d, %edi
leaq -0x10e0(%rbp), %rsi
pushq $0x43
popq %rdx
callq 0x20c0
movq %rax, %r14
leaq 0x5cc2(%rip), %rax      # 0xb424
cmpb $0x3, (%rax)
jb 0x57a8
movq -0x10d8(%rbp), %r10
cmpq $0x4, %r10
leaq 0x1db5(%rip), %r11      # 0x752e
leaq 0x1da8(%rip), %rax      # 0x7528
cmoveq %rax, %r11
leaq 0x29d1(%rip), %rdi      # 0x815c
pushq $0x4
popq %rsi
movq -0x38(%rbp), %rdx
movl -0x2c(%rbp), %ecx
movq %r14, %r8
movq %rsi, %r9
xorl %eax, %eax
pushq %r11
pushq %r10
callq 0x5aec
popq %rcx
popq %rdx
testq %r14, %r14
movq %r15, %r14
jne 0x5835
leaq 0x5c69(%rip), %rax      # 0xb424
cmpb $0x3, (%rax)
movl -0x2c(%rbp), %edx
jb 0x55b8
leaq 0x27c0(%rip), %rdi      # 0x7f8e
movq -0x38(%rbp), %rsi
jmp 0x5580
leaq 0x28c1(%rip), %rdi      # 0x809f
movq -0x38(%rbp), %rsi
movl %r15d, %edx
pushq $0x3
popq %rcx
xorl %eax, %eax
callq 0x5aec
jmp 0x55b8
cmpb $0x3, %al
leaq 0x5ba3(%rip), %r15      # 0xb3a0
leaq -0x50(%rbp), %r12
jb 0x581b
leaq 0x291e(%rip), %rdi      # 0x8128
pushq $0x3
popq %rsi
movq -0x38(%rbp), %rdx
movl -0x2c(%rbp), %ecx
xorl %eax, %eax
callq 0x5aec
leaq 0x2539(%rip), %rdi      # 0x7d5b
movq -0x38(%rbp), %rsi
movl -0x2c(%rbp), %edx
xorl %eax, %eax
callq 0x5aec
jmp 0x567f
jns 0x586f
leaq 0x5be6(%rip), %rax      # 0xb424
cmpb $0x3, (%rax)
leaq 0x5b58(%rip), %r15      # 0xb3a0
leaq -0x50(%rbp), %r12
jb 0x5863
leaq 0x295f(%rip), %rdi      # 0x81b4
movq -0x38(%rbp), %rsi
movl -0x2c(%rbp), %edx
xorl %eax, %eax
callq 0x5aec
leaq 0x2776(%rip), %rdi      # 0x7fe0
jmp 0x567a
movq 0x5b02(%rip), %rax      # 0xb378
movb $0x1, 0x4(%rax,%r12)
movq $0x4, 0x8(%rax,%r12)
incw 0x5b94(%rip)            # 0xb420
movl 0x5b0a(%rip), %edi      # 0xb39c
leaq -0x3d(%rbp), %rsi
pushq $0x1
popq %rdx
callq 0x20c0
testq %rax, %rax
jns 0x52ff
leaq 0x2929(%rip), %rbx      # 0x81d7
movq %rbx, %rdi
xorl %eax, %eax
callq 0x5aec
movq %rbx, %rdi
callq 0x2350
jmp 0x52ff