// File: /workspace/github_c_makefile_star2_O1/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 $0x10a8, %rsp           # imm = 0x10A8
movq %rdi, -0x60(%rbp)
leaq -0x54(%rbp), %rax
movl $0x10, (%rax)
leaq -0x29(%rbp), %rax
movb $-0x1, (%rax)
leaq -0xc0(%rbp), %rax
movq $0xa, (%rax)
movq $0x0, 0x8(%rax)
leaq 0x5e3b(%rip), %rbx      # 0xb3f8
leaq 0x5ddc(%rip), %r14      # 0xb3a0
leaq -0x40(%rbp), %r15
movq $0x0, -0x48(%rbp)
movq %rbx, %rdi
callq 0x23f0
movq %r14, %rdi
movq %rbx, %rsi
callq 0x20e0
xorps %xmm0, %xmm0
movaps %xmm0, -0x40(%rbp)
movl 0x5da0(%rip), %edi      # 0xb390
movq %r15, %rsi
leaq -0x54(%rbp), %rdx
callq 0x2370
testl %eax, %eax
jns 0x561e
leaq 0x26e4(%rip), %r12      # 0x7ceb
movq %r12, %rdi
xorl %eax, %eax
callq 0x605c
movq %r12, %rdi
callq 0x2350
jmp 0x5720
movl %eax, %r13d
movl -0x3c(%rbp), %edi
callq 0x20d0
movq %rax, %rbx
movzwl -0x3e(%rbp), %r15d
rolw $0x8, %r15w
leaq 0x5de7(%rip), %rax      # 0xb424
cmpb $0x3, (%rax)
jb 0x5657
movzwl %r15w, %edx
leaq 0x26ae(%rip), %rdi      # 0x7cfb
movq %rbx, %rsi
xorl %eax, %eax
callq 0x605c
movq 0x5d1a(%rip), %rax      # 0xb378
addq $0x4, %rax
xorl %r14d, %r14d
leaq -0xc0(%rbp), %r12
cmpb $0x1, (%rax)
jne 0x5683
incq %r14
addq $0x50, %rax
cmpq $0x18, %r14
jne 0x566c
movw $0xffff, %r14w          # imm = 0xFFFF
cmpw $-0x1, %r14w
jne 0x56b7
leaq 0x2696(%rip), %rdi      # 0x7d27
xorl %eax, %eax
callq 0x605c
movzwl %r15w, %edx
leaq 0x26b8(%rip), %rdi      # 0x7d5b
movq %rbx, %rsi
xorl %eax, %eax
callq 0x605c
movl %r13d, %edi
callq 0x21a0
jmp 0x570e
movl %r13d, %edi
movl $0x1, %esi
movl $0x14, %edx
movq %r12, %rcx
movl $0x10, %r8d
callq 0x20b0
testl %eax, %eax
js 0x56f5
movl %r13d, %edi
movl $0x1, %esi
movl $0x15, %edx
movq %r12, %rcx
movl $0x10, %r8d
callq 0x20b0
testl %eax, %eax
jns 0x572d
leaq 0x2681(%rip), %rbx      # 0x7d7d
movq %rbx, %rdi
xorl %eax, %eax
callq 0x605c
movq %rbx, %rdi
callq 0x2350
leaq 0x5ce3(%rip), %rbx      # 0xb3f8
leaq 0x5c84(%rip), %r14      # 0xb3a0
leaq -0x40(%rbp), %r15
movq %rbx, %rdi
callq 0x22b0
jmp 0x55d0
movl $0x1010, %edx           # imm = 0x1010
movl %r13d, %edi
leaq -0x10d0(%rbp), %rsi
callq 0x21d0
movq %rax, %r12
leaq 0x5cd9(%rip), %rax      # 0xb424
cmpb $0x3, (%rax)
jb 0x5798
movzwl %r15w, %ecx
movq -0x10c8(%rbp), %r10
cmpq $0x1, %r10
leaq 0x1deb(%rip), %r11      # 0x7551
leaq 0x1dde(%rip), %rax      # 0x754b
cmoveq %rax, %r11
movl $0x1, %esi
movl $0x1, %r9d
leaq 0x2611(%rip), %rdi      # 0x7d94
movq %rbx, %rdx
movq %r12, %r8
xorl %eax, %eax
pushq %r11
pushq %r10
callq 0x605c
addq $0x10, %rsp
testq %r12, %r12
jne 0x57c0
leaq 0x5c80(%rip), %rax      # 0xb424
cmpb $0x3, (%rax)
jb 0x56ad
leaq 0x2639(%rip), %rdi      # 0x7ded
xorl %eax, %eax
callq 0x605c
jmp 0x56ad
jns 0x580a
leaq 0x5c5b(%rip), %rax      # 0xb424
cmpb $0x3, (%rax)
leaq 0x5bcd(%rip), %r14      # 0xb3a0
jb 0x57ea
movzwl %r15w, %edx
leaq 0x262c(%rip), %rdi      # 0x7e0c
movq %rbx, %rsi
xorl %eax, %eax
callq 0x605c
leaq 0x2650(%rip), %rdi      # 0x7e41
callq 0x2350
movl %r13d, %edi
callq 0x21a0
leaq 0x5bf3(%rip), %rbx      # 0xb3f8
jmp 0x571c
movq -0x10c8(%rbp), %r8
cmpq $0x1, %r8
jne 0x5892
cmpl $0x1, -0x10d0(%rbp)
jne 0x58b1
movq -0x60(%rbp), %rdi
leaq -0x10c0(%rbp), %rsi
callq 0x5f3c
testq %rax, %rax
jne 0x5903
movl $0x4, -0x10d0(%rbp)
movw $0x14, -0x10cc(%rbp)
movq $0x2, -0x10c8(%rbp)
movl $0x1, -0x10c0(%rbp)
movl $0x14, %edx
movl %r13d, %edi
leaq -0x10d0(%rbp), %rsi
callq 0x20c0
leaq 0x5ba4(%rip), %rax      # 0xb424
cmpb $0x3, (%rax)
jb 0x58d2
movzwl %r15w, %edx
leaq 0x2639(%rip), %rdi      # 0x7ec9
jmp 0x58c8
movzwl %r15w, %edx
movl $0x1, %ecx
leaq 0x25c1(%rip), %rdi      # 0x7e63
movq %rbx, %rsi
xorl %eax, %eax
callq 0x605c
jmp 0x56ad
leaq 0x5b6c(%rip), %rax      # 0xb424
cmpb $0x3, (%rax)
jb 0x58d2
movzwl %r15w, %edx
leaq 0x25e2(%rip), %rdi      # 0x7eaa
movq %rbx, %rsi
xorl %eax, %eax
callq 0x605c
leaq 0x5b4b(%rip), %rax      # 0xb424
cmpb $0x3, (%rax)
leaq 0x5abd(%rip), %r14      # 0xb3a0
jb 0x57f6
movzwl %r15w, %edx
leaq 0x2467(%rip), %rdi      # 0x7d5b
movq %rbx, %rsi
xorl %eax, %eax
callq 0x605c
jmp 0x57f6
movq %rax, %r12
xorps %xmm0, %xmm0
movaps %xmm0, -0x70(%rbp)
movaps %xmm0, -0x80(%rbp)
movaps %xmm0, -0x90(%rbp)
movaps %xmm0, -0xa0(%rbp)
movaps %xmm0, -0xb0(%rbp)
leaq -0xb0(%rbp), %rdi
movl $0x3f, %esi
movq %rax, %rdx
callq 0x21e0
movq %rax, -0x50(%rbp)
movq %r12, %rdi
callq 0x20f0
cmpq $0x0, -0x50(%rbp)
jne 0x5962
leaq 0x259d(%rip), %rdi      # 0x7ef1
leaq -0x10be(%rbp), %rsi
xorl %eax, %eax
callq 0x605c
leaq -0xb0(%rbp), %rdi
callq 0x2100
movq -0x48(%rbp), %rdx
cmpb $0x20, -0xb0(%rbp,%rdx)
je 0x599f
cmpq %rdx, %rax
movq %rdx, %r12
cmovaq %rax, %r12
movq %rdx, %rcx
cmpq %rax, %rcx
jae 0x59d7
leaq 0x1(%rcx), %rdx
cmpb $0x20, -0xaf(%rbp,%rcx)
movq %rdx, %rcx
jne 0x5989
cmpq $0x13, %rdx
movq %rdx, -0x48(%rbp)
ja 0x59b5
subq %rdx, %rax
incq %rax
cmpq $0x11, %rax
jb 0x59fd
movl %r13d, %edi
callq 0x21a0
leaq 0x252d(%rip), %rdi      # 0x7ef1
leaq -0x10be(%rbp), %rsi
xorl %eax, %eax
callq 0x605c
jmp 0x570e
movl %r13d, %edi
callq 0x21a0
leaq 0x250b(%rip), %rdi      # 0x7ef1
leaq -0x10be(%rbp), %rsi
xorl %eax, %eax
callq 0x605c
movq %r12, -0x48(%rbp)
jmp 0x570e
leaq 0x5a20(%rip), %rax      # 0xb424
cmpb $0x0, (%rax)
je 0x5a2c
movzwl %r15w, %ecx
leaq 0x2506(%rip), %rdi      # 0x7f1a
leaq -0x10be(%rbp), %rsi
movq %rbx, %rdx
leaq -0xb0(%rbp), %r8
xorl %eax, %eax
callq 0x605c
movq 0x5945(%rip), %rax      # 0xb378
movswq %r14w, %rcx
movq %rcx, -0x50(%rbp)
shlq $0x4, %rcx
leaq (%rcx,%rcx,4), %r12
movl %r13d, (%rax,%r12)
leaq -0xb0(%rbp), %rdi
callq 0x2ae1
movq 0x591e(%rip), %rcx      # 0xb378
movl %eax, 0x10(%rcx,%r12)
movb $0x0, 0x5(%rcx,%r12)
movaps -0x40(%rbp), %xmm0
movups %xmm0, 0x40(%rcx,%r12)
movl $0x4, -0x10d0(%rbp)
movw $0x14, -0x10cc(%rbp)
movl $0x2, -0x10c0(%rbp)
movq $0x2, -0x10c8(%rbp)
movl $0x14, %edx
movl %r13d, %edi
leaq -0x10d0(%rbp), %rsi
callq 0x20c0
movq %rax, %r12
leaq 0x596f(%rip), %rax      # 0xb424
cmpb $0x3, (%rax)
jb 0x5b02
movzwl %r15w, %ecx
movq -0x10c8(%rbp), %r10
cmpq $0x2, %r10
leaq 0x1a81(%rip), %r11      # 0x7551
leaq 0x1a74(%rip), %rax      # 0x754b
cmoveq %rax, %r11
movl $0x2, %esi
movl $0x2, %r9d
leaq 0x244c(%rip), %rdi      # 0x7f39
movq %rbx, %rdx
movq %r12, %r8
xorl %eax, %eax
pushq %r11
pushq %r10
callq 0x605c
addq $0x10, %rsp
testq %r12, %r12
jne 0x5b2a
leaq 0x5916(%rip), %rax      # 0xb424
cmpb $0x3, (%rax)
jb 0x5b59
movzwl %r15w, %edx
leaq 0x2470(%rip), %rdi      # 0x7f8e
movq %rbx, %rsi
xorl %eax, %eax
callq 0x605c
jmp 0x5b59
jns 0x5b6f
leaq 0x58f1(%rip), %rax      # 0xb424
cmpb $0x3, (%rax)
jb 0x5b4d
movzwl %r15w, %edx
leaq 0x247a(%rip), %rdi      # 0x7fbd
movq %rbx, %rsi
xorl %eax, %eax
callq 0x605c
leaq 0x248c(%rip), %rdi      # 0x7fe0
callq 0x2350
movl %r13d, %edi
callq 0x21a0
movzwl %r14w, %edi
callq 0x5e10
jmp 0x570e
movl $0x1010, %edx           # imm = 0x1010
movl %r13d, %edi
leaq -0x10d0(%rbp), %rsi
callq 0x21d0
movq %rax, %r12
leaq 0x5897(%rip), %rax      # 0xb424
cmpb $0x3, (%rax)
jb 0x5bda
movzwl %r15w, %ecx
movq -0x10c8(%rbp), %r10
cmpq $0x3, %r10
leaq 0x19a9(%rip), %r11      # 0x7551
leaq 0x199c(%rip), %rax      # 0x754b
cmoveq %rax, %r11
movl $0x3, %esi
movl $0x3, %r9d
leaq 0x243f(%rip), %rdi      # 0x8004
movq %rbx, %rdx
movq %r12, %r8
xorl %eax, %eax
pushq %r11
pushq %r10
callq 0x605c
addq $0x10, %rsp
testq %r12, %r12
je 0x5b07
jns 0x5c12
leaq 0x5838(%rip), %rax      # 0xb424
cmpb $0x3, (%rax)
jb 0x5c06
movzwl %r15w, %edx
leaq 0x245d(%rip), %rdi      # 0x8059
movq %rbx, %rsi
xorl %eax, %eax
callq 0x605c
leaq 0x246d(%rip), %rdi      # 0x807a
jmp 0x5b54
movq -0x10c8(%rbp), %r8
cmpq $0x3, %r8
jne 0x5d52
cmpl $0x4, -0x10d0(%rbp)
leaq 0x57f3(%rip), %rax      # 0xb424
movb (%rax), %al
jne 0x5d71
cmpl $0x10, -0x10c0(%rbp)
jne 0x5d71
cmpb $0x3, %al
jb 0x5c64
movzwl %r15w, %ecx
movl $0x3, %esi
leaq 0x249c(%rip), %rdi      # 0x80f6
movq %rbx, %rdx
xorl %eax, %eax
callq 0x605c
movl $0x8, -0x10d0(%rbp)
movq $0x4, -0x10c8(%rbp)
movw $0x43, -0x10cc(%rbp)
leaq -0x10c0(%rbp), %rdi
leaq -0xb0(%rbp), %rsi
movq -0x48(%rbp), %r12
movq %r12, %rdx
callq 0x2260
movb $0x0, -0x10c0(%rbp,%r12)
leaq -0xaf(%rbp), %rax
leaq (%rax,%r12), %rsi
leaq -0x10ad(%rbp), %rdi
callq 0x2070
movl $0x43, %edx
movl %r13d, %edi
leaq -0x10d0(%rbp), %rsi
callq 0x20c0
movq %rax, %r12
leaq 0x574a(%rip), %rax      # 0xb424
cmpb $0x3, (%rax)
jb 0x5d27
movzwl %r15w, %ecx
movq -0x10c8(%rbp), %r10
cmpq $0x4, %r10
leaq 0x185c(%rip), %r11      # 0x7551
leaq 0x184f(%rip), %rax      # 0x754b
cmoveq %rax, %r11
movl $0x4, %esi
movl $0x4, %r9d
leaq 0x244a(%rip), %rdi      # 0x815c
movq %rbx, %rdx
movq %r12, %r8
xorl %eax, %eax
pushq %r11
pushq %r10
callq 0x605c
addq $0x10, %rsp
testq %r12, %r12
je 0x5b07
jns 0x5d9f
leaq 0x56eb(%rip), %rax      # 0xb424
cmpb $0x3, (%rax)
jb 0x5b4d
movzwl %r15w, %edx
leaq 0x2467(%rip), %rdi      # 0x81b4
jmp 0x5b43
movzwl %r15w, %edx
movl $0x3, %ecx
leaq 0x233d(%rip), %rdi      # 0x809f
movq %rbx, %rsi
xorl %eax, %eax
callq 0x605c
jmp 0x5b59
cmpb $0x3, %al
jb 0x5d8f
movzwl %r15w, %ecx
movl $0x3, %esi
leaq 0x23a3(%rip), %rdi      # 0x8128
movq %rbx, %rdx
xorl %eax, %eax
callq 0x605c
movzwl %r15w, %edx
leaq 0x1fc1(%rip), %rdi      # 0x7d5b
jmp 0x5b1e
movq 0x55d2(%rip), %rax      # 0xb378
movq -0x50(%rbp), %rcx
leaq (%rcx,%rcx,4), %rcx
shlq $0x4, %rcx
movb $0x1, 0x4(%rax,%rcx)
movq $0x4, 0x8(%rax,%rcx)
incw 0x5659(%rip)            # 0xb420
movl 0x55cf(%rip), %edi      # 0xb39c
movl $0x1, %edx
leaq -0x29(%rbp), %rsi
callq 0x20c0
testq %rax, %rax
leaq 0x5613(%rip), %rbx      # 0xb3f8
leaq -0x40(%rbp), %r15
jns 0x5e04
leaq 0x23e5(%rip), %r14      # 0x81d7
movq %r14, %rdi
xorl %eax, %eax
callq 0x605c
movq %r14, %rdi
callq 0x2350
leaq 0x5595(%rip), %r14      # 0xb3a0
jmp 0x5720