// File: /workspace/github_c_makefile_star2_O0/TeaInside[P]teavpn/src/teavpn/server/tcp.c
// Function: teavpn_tcp_worker_thread
static void *teavpn_tcp_worker_thread(struct worker_thread *worker)
{

	#define packet ((teavpn_packet *)(bufchan[queues[i].bufchan_index].buffer))

	register int16_t i;
	register ssize_t nwrite;

	while (true) {
		pthread_mutex_lock(&(worker->mutex));
		pthread_cond_wait(&(worker->cond), &(worker->mutex));

		worker->busy = true;

		i = worker_job_pull();

		/**
		 * There is no queue.
		 */
		if (i == -1) {
			goto job_done;
		}

		packet->info.seq = ++(connections[queues[i].conn_index].seq);

		nwrite = write(connections[queues[i].conn_index].fd, packet, packet->info.len);

		debug_log(3, "[%ld] Write to client %s:%d %ld bytes (server_seq: %ld) (client_seq: %ld) (seq %s)",
			connections[queues[i].conn_index].seq,
			inet_ntoa(connections[queues[i].conn_index].addr.sin_addr),
			ntohs(connections[queues[i].conn_index].addr.sin_port),
			nwrite,
			connections[queues[i].conn_index].seq,
			packet->info.seq,
			(connections[queues[i].conn_index].seq == packet->info.seq) ? "match" : "invalid"
		);

		/**
		 * Connection closed by client.
		 */
		if (nwrite == 0) {
			close(connections[queues[i].conn_index].fd);
			debug_log(1, "(%s:%d) connection closed",
				inet_ntoa(connections[queues[i].conn_index].addr.sin_addr),
				ntohs(connections[queues[i].conn_index].addr.sin_port)
			);
			connection_zero(i);
			goto job_release;
		}


		if (nwrite < 0) {
			char *remote_addr = inet_ntoa(connections[queues[i].conn_index].addr.sin_addr);
			uint16_t remote_port = ntohs(connections[queues[i].conn_index].addr.sin_port);

			debug_log(0, "Error write to %s:%d", remote_addr, remote_port);
			perror("Error write to connection fd");

			/**
			 * Increment the error counter.
			 */
			connections[queues[i].conn_index].error++;

			/**
			 * Force disconnect client if it has
			 * reached the max number of errors.
			 */
			if (connections[queues[i].conn_index].error > MAX_CLIENT_ERR) {
				debug_log(0,
					"Client %s:%d has been disconnected because it has reached the max number of errors",
					remote_port,
					remote_port
				);
				close(connections[queues[i].conn_index].fd);
				connection_zero(i);
			}
		}


		job_release:
		bufchan[queues[i].bufchan_index].ref_count--;
		// printf("i = %d;  r = %d\n", queues[i].bufchan_index, bufchan[queues[i].bufchan_index].ref_count);

		pthread_mutex_lock(&worker_job_pull_mutex);
		queues[i].used = false;
		queues[i].taken = false;
		pthread_mutex_unlock(&worker_job_pull_mutex);

		job_done:
		worker->busy = false;
		pthread_mutex_unlock(&(worker->mutex));
	}
	return NULL;

	#undef packet
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %rbx
subq $0x58, %rsp
movq %rdi, -0x10(%rbp)
movq -0x10(%rbp), %rdi
addq $0x10, %rdi
callq 0x2400
movq -0x10(%rbp), %rdi
addq $0x38, %rdi
movq -0x10(%rbp), %rsi
addq $0x10, %rsi
callq 0x20d0
movq -0x10(%rbp), %rax
movb $0x1, (%rax)
callq 0x7e50
movw %ax, -0x12(%rbp)
movswl -0x12(%rbp), %eax
cmpl $-0x1, %eax
jne 0x699d
jmp 0x6ebf
movq 0x79d4(%rip), %rax      # 0xe378
movq 0x79bd(%rip), %rcx      # 0xe368
movswq -0x12(%rbp), %rdx
imulq $0x18, %rdx, %rdx
addq %rdx, %rcx
movswq 0x10(%rcx), %rcx
imulq $0x50, %rcx, %rcx
addq %rcx, %rax
movq 0x8(%rax), %rcx
addq $0x1, %rcx
movq %rcx, 0x8(%rax)
movq 0x799a(%rip), %rax      # 0xe370
movq 0x798b(%rip), %rdx      # 0xe368
movswq -0x12(%rbp), %rsi
imulq $0x18, %rsi, %rsi
addq %rsi, %rdx
movswq 0x12(%rdx), %rdx
imulq $0x1030, %rdx, %rdx     # imm = 0x1030
addq %rdx, %rax
movq %rcx, 0x18(%rax)
movq 0x7975(%rip), %rax      # 0xe378
movq 0x795e(%rip), %rcx      # 0xe368
movswq -0x12(%rbp), %rdx
imulq $0x18, %rdx, %rdx
addq %rdx, %rcx
movswq 0x10(%rcx), %rcx
imulq $0x50, %rcx, %rcx
addq %rcx, %rax
movl (%rax), %edi
movq 0x7945(%rip), %rsi      # 0xe370
movq 0x7936(%rip), %rax      # 0xe368
movswq -0x12(%rbp), %rcx
imulq $0x18, %rcx, %rcx
addq %rcx, %rax
movswq 0x12(%rax), %rax
imulq $0x1030, %rax, %rax     # imm = 0x1030
addq %rax, %rsi
addq $0x10, %rsi
movq 0x7918(%rip), %rax      # 0xe370
movq 0x7909(%rip), %rcx      # 0xe368
movswq -0x12(%rbp), %rdx
imulq $0x18, %rdx, %rdx
addq %rdx, %rcx
movswq 0x12(%rcx), %rcx
imulq $0x1030, %rcx, %rcx     # imm = 0x1030
addq %rcx, %rax
movzwl 0x14(%rax), %eax
movl %eax, %edx
callq 0x20b0
movq %rax, -0x20(%rbp)
leaq 0x7994(%rip), %rax      # 0xe424
movzbl (%rax), %ecx
movl $0x3, %eax
cmpl %ecx, %eax
jg 0x6c18
movq 0x78d1(%rip), %rax      # 0xe378
movq 0x78ba(%rip), %rcx      # 0xe368
movswq -0x12(%rbp), %rdx
imulq $0x18, %rdx, %rdx
addq %rdx, %rcx
movswq 0x10(%rcx), %rcx
imulq $0x50, %rcx, %rcx
addq %rcx, %rax
movq 0x8(%rax), %rax
movq %rax, -0x40(%rbp)
movq 0x78a3(%rip), %rax      # 0xe378
movq 0x788c(%rip), %rcx      # 0xe368
movswq -0x12(%rbp), %rdx
imulq $0x18, %rdx, %rdx
addq %rdx, %rcx
movswq 0x10(%rcx), %rcx
imulq $0x50, %rcx, %rcx
addq %rcx, %rax
movl 0x44(%rax), %edi
callq 0x20c0
movq %rax, -0x38(%rbp)
movq 0x7871(%rip), %rax      # 0xe378
movq 0x785a(%rip), %rcx      # 0xe368
movswq -0x12(%rbp), %rdx
imulq $0x18, %rdx, %rdx
addq %rdx, %rcx
movswq 0x10(%rcx), %rcx
imulq $0x50, %rcx, %rcx
addq %rcx, %rax
movzwl 0x42(%rax), %edi
callq 0x2300
movq -0x40(%rbp), %rsi
movq -0x38(%rbp), %rdx
movzwl %ax, %ecx
movq -0x20(%rbp), %r8
movq 0x7833(%rip), %rax      # 0xe378
movq 0x781c(%rip), %rdi      # 0xe368
movswq -0x12(%rbp), %r9
imulq $0x18, %r9, %r9
addq %r9, %rdi
movswq 0x10(%rdi), %rdi
imulq $0x50, %rdi, %rdi
addq %rdi, %rax
movq 0x8(%rax), %r9
movq 0x7801(%rip), %rax      # 0xe370
movq 0x77f2(%rip), %rdi      # 0xe368
movswq -0x12(%rbp), %r10
imulq $0x18, %r10, %r10
addq %r10, %rdi
movswq 0x12(%rdi), %rdi
imulq $0x1030, %rdi, %rdi     # imm = 0x1030
addq %rdi, %rax
movq 0x18(%rax), %r10
movq 0x77dc(%rip), %rax      # 0xe378
movq 0x77c5(%rip), %rdi      # 0xe368
movswq -0x12(%rbp), %r11
imulq $0x18, %r11, %r11
addq %r11, %rdi
movswq 0x10(%rdi), %rdi
imulq $0x50, %rdi, %rdi
addq %rdi, %rax
movq 0x8(%rax), %r11
movq 0x77aa(%rip), %rax      # 0xe370
movq 0x779b(%rip), %rdi      # 0xe368
movswq -0x12(%rbp), %rbx
imulq $0x18, %rbx, %rbx
addq %rbx, %rdi
movswq 0x12(%rdi), %rdi
imulq $0x1030, %rdi, %rdi     # imm = 0x1030
addq %rdi, %rax
movq 0x18(%rax), %rbx
leaq 0x391a(%rip), %rax      # 0xa50d
leaq 0x390d(%rip), %rdi      # 0xa507
cmpq %rbx, %r11
cmoveq %rdi, %rax
leaq 0x4009(%rip), %rdi      # 0xac11
movq %r10, (%rsp)
movq %rax, 0x8(%rsp)
movb $0x0, %al
callq 0x84c0
cmpq $0x0, -0x20(%rbp)
jne 0x6ce7
movq 0x774e(%rip), %rax      # 0xe378
movq 0x7737(%rip), %rcx      # 0xe368
movswq -0x12(%rbp), %rdx
imulq $0x18, %rdx, %rdx
addq %rdx, %rcx
movswq 0x10(%rcx), %rcx
imulq $0x50, %rcx, %rcx
addq %rcx, %rax
movl (%rax), %edi
callq 0x21b0
leaq 0x77cd(%rip), %rax      # 0xe424
movzbl (%rax), %ecx
movl $0x1, %eax
cmpl %ecx, %eax
jg 0x6cd9
movq 0x770e(%rip), %rax      # 0xe378
movq 0x76f7(%rip), %rcx      # 0xe368
movswq -0x12(%rbp), %rdx
imulq $0x18, %rdx, %rdx
addq %rdx, %rcx
movswq 0x10(%rcx), %rcx
imulq $0x50, %rcx, %rcx
addq %rcx, %rax
movl 0x44(%rax), %edi
callq 0x20c0
movq %rax, -0x48(%rbp)
movq 0x76dc(%rip), %rax      # 0xe378
movq 0x76c5(%rip), %rcx      # 0xe368
movswq -0x12(%rbp), %rdx
imulq $0x18, %rdx, %rdx
addq %rdx, %rcx
movswq 0x10(%rcx), %rcx
imulq $0x50, %rcx, %rcx
addq %rcx, %rax
movzwl 0x42(%rax), %edi
callq 0x2300
movq -0x48(%rbp), %rsi
movzwl %ax, %edx
leaq 0x3e0a(%rip), %rdi      # 0xaadc
movb $0x0, %al
callq 0x84c0
movzwl -0x12(%rbp), %edi
callq 0x7cf0
jmp 0x6e47
cmpq $0x0, -0x20(%rbp)
jge 0x6e45
movq 0x767f(%rip), %rax      # 0xe378
movq 0x7668(%rip), %rcx      # 0xe368
movswq -0x12(%rbp), %rdx
imulq $0x18, %rdx, %rdx
addq %rdx, %rcx
movswq 0x10(%rcx), %rcx
imulq $0x50, %rcx, %rcx
addq %rcx, %rax
movl 0x44(%rax), %edi
callq 0x20c0
movq %rax, -0x28(%rbp)
movq 0x764d(%rip), %rax      # 0xe378
movq 0x7636(%rip), %rcx      # 0xe368
movswq -0x12(%rbp), %rdx
imulq $0x18, %rdx, %rdx
addq %rdx, %rcx
movswq 0x10(%rcx), %rcx
imulq $0x50, %rcx, %rcx
addq %rcx, %rax
movzwl 0x42(%rax), %edi
callq 0x2300
movw %ax, -0x2a(%rbp)
leaq 0x76c6(%rip), %rax      # 0xe424
movzbl (%rax), %ecx
xorl %eax, %eax
cmpl %ecx, %eax
jg 0x6d7d
movq -0x28(%rbp), %rsi
movzwl -0x2a(%rbp), %edx
leaq 0x3eee(%rip), %rdi      # 0xac64
movb $0x0, %al
callq 0x84c0
leaq 0x3ef5(%rip), %rdi      # 0xac79
callq 0x2360
movq 0x75e8(%rip), %rax      # 0xe378
movq 0x75d1(%rip), %rcx      # 0xe368
movswq -0x12(%rbp), %rdx
imulq $0x18, %rdx, %rdx
addq %rdx, %rcx
movswq 0x10(%rcx), %rcx
imulq $0x50, %rcx, %rcx
addq %rcx, %rax
movb 0x5(%rax), %cl
addb $0x1, %cl
movb %cl, 0x5(%rax)
movq 0x75b9(%rip), %rax      # 0xe378
movq 0x75a2(%rip), %rcx      # 0xe368
movswq -0x12(%rbp), %rdx
imulq $0x18, %rdx, %rdx
addq %rdx, %rcx
movswq 0x10(%rcx), %rcx
imulq $0x50, %rcx, %rcx
addq %rcx, %rax
movzbl 0x5(%rax), %eax
cmpl $0xf, %eax
jle 0x6e43
leaq 0x7636(%rip), %rax      # 0xe424
movzbl (%rax), %ecx
xorl %eax, %eax
cmpl %ecx, %eax
jg 0x6e0d
movzwl -0x2a(%rbp), %esi
movzwl -0x2a(%rbp), %edx
leaq 0x3d26(%rip), %rdi      # 0xab2c
movb $0x0, %al
callq 0x84c0
movq 0x7564(%rip), %rax      # 0xe378
movq 0x754d(%rip), %rcx      # 0xe368
movswq -0x12(%rbp), %rdx
imulq $0x18, %rdx, %rdx
addq %rdx, %rcx
movswq 0x10(%rcx), %rcx
imulq $0x50, %rcx, %rcx
addq %rcx, %rax
movl (%rax), %edi
callq 0x21b0
movzwl -0x12(%rbp), %edi
callq 0x7cf0
jmp 0x6e45
jmp 0x6e47
movq 0x7522(%rip), %rax      # 0xe370
movq 0x7513(%rip), %rcx      # 0xe368
movswq -0x12(%rbp), %rdx
imulq $0x18, %rdx, %rdx
addq %rdx, %rcx
movswq 0x12(%rcx), %rcx
imulq $0x1030, %rcx, %rcx     # imm = 0x1030
addq %rcx, %rax
movw (%rax), %cx
addw $-0x1, %cx
movw %cx, (%rax)
leaq 0x754f(%rip), %rdi      # 0xe3d0
callq 0x2400
movq 0x74db(%rip), %rax      # 0xe368
movswq -0x12(%rbp), %rcx
imulq $0x18, %rcx, %rcx
addq %rcx, %rax
movb $0x0, (%rax)
movq 0x74c5(%rip), %rax      # 0xe368
movswq -0x12(%rbp), %rcx
imulq $0x18, %rcx, %rcx
addq %rcx, %rax
movb $0x0, 0x1(%rax)
leaq 0x7516(%rip), %rdi      # 0xe3d0
callq 0x22b0
movq -0x10(%rbp), %rax
movb $0x0, (%rax)
movq -0x10(%rbp), %rdi
addq $0x10, %rdi
callq 0x22b0
jmp 0x695d
nopl (%rax,%rax)