// File: /workspace/github_c_makefile_star2_O3/unixlab[P]cloudflare-udp-ping/udpclient.c
// Function: thread_loop
void thread_loop(void *userdata)
{
	struct state *state = userdata;

	pthread_spin_init(&state->lock, PTHREAD_PROCESS_PRIVATE);

	char send_buf[PKT_SIZE], recv_buf[PKT_SIZE];
	struct msghdr *msg = calloc(2, sizeof(struct msghdr));
	struct iovec *iovec = calloc(2, sizeof(struct iovec));
	int i;
	for (i = 0; i < 2; i++) {
		msg[i].msg_iov = &iovec[i];
		msg[i].msg_iovlen = 1;
		iovec[i].iov_len = sizeof(send_buf);
	}

	iovec[0].iov_base = send_buf;
	iovec[1].iov_base = recv_buf;

	char pktinfo[4096];
	msg[1].msg_control = pktinfo;
	msg[1].msg_controllen = sizeof(pktinfo);

	uint64_t packet_no = 0;
	while (1) {
		int fd = net_connect_udp(state->target_addr, state->src_port,
					 state->busy_poll);

		struct timeval tv = {1, 0}; // 1 second
		int r = setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, &tv,
				   sizeof(tv));
		if (r < 0) {
			PFATAL("setsockopt(SO_RCVTIMEO)");
		}

		for (;; packet_no++) {
			memset(send_buf, 0, sizeof(send_buf));
			snprintf(send_buf, sizeof(send_buf), "%i-%li-%lu",
				 getpid(), gettid(), packet_no);

			uint64_t t0 = realtime_now(), t1 = 0, tp = 0;
			int r = sendmsg(fd, &msg[0], 0);
			if (r <= 0) {
				if (errno == EAGAIN || errno == EWOULDBLOCK ||
				    errno == ECONNREFUSED) {
					break;
				}
				if (errno == EINTR) {
					continue;
				}
				PFATAL("sendmmsg()");
			}

			msg[1].msg_controllen = sizeof(pktinfo);
			while (1) {
				int flags = state->polling ? MSG_DONTWAIT : 0;
				r = recvmsg(fd, &msg[1], flags);
				t1 = realtime_now();
				if (t1 - t0 >= 1000000000) {
					/* No msg for 1s */
					errno = ECONNREFUSED;
					break;
				}

				if (r <= 0 &&
				    (errno == EINTR || errno == EAGAIN ||
				     errno == EWOULDBLOCK)) {
					continue;
				}

				if (r == 0 && state->polling) {
					continue;
				}
				break;
			}

			if (r <= 0 && errno == ECONNREFUSED) {
				sleep(1);
				break;
			}

			if (r <= 0) {
				PFATAL("recvmmsg()");
			}

			if (memcmp(send_buf, recv_buf, sizeof(recv_buf)) != 0) {
				fprintf(stderr, "[!] bad message\n");
				sleep(1);
				break;
			}

			struct cmsghdr *cmsg;
			for (cmsg = CMSG_FIRSTHDR(&msg[1]); cmsg;
			     cmsg = CMSG_NXTHDR(&msg[1], cmsg)) {
				switch (cmsg->cmsg_level) {
				case SOL_SOCKET:
					switch (cmsg->cmsg_type) {
					case SO_TIMESTAMPNS: {
						struct timespec *ts =
							(struct timespec *)
							CMSG_DATA(cmsg);
						tp = TIMESPEC_NSEC(ts);
						break;
					}
					}
					break;
				}
			}

			pthread_spin_lock(&state->lock);
			stddev_add(&state->stddev, t1 - t0);
			if (tp != 0) {
				stddev_add(&state->stddev_packet, t1 - tp);
			}
			pthread_spin_unlock(&state->lock);
		}
		close(fd);
	}
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x1088, %rsp           # imm = 0x1088
movq %rdi, -0x30(%rbp)
addq $0x14, %rdi
movq %rdi, -0x50(%rbp)
xorl %esi, %esi
callq 0x4210f0
movl $0x2, %edi
movl $0x38, %esi
callq 0x426f80
movq %rax, %r14
movl $0x2, %edi
movl $0x10, %esi
callq 0x426f80
movq %rax, 0x10(%r14)
movl $0x1, %ecx
movq %rcx, 0x18(%r14)
movl $0x20, %edx
movq %rdx, 0x8(%rax)
leaq 0x10(%rax), %rsi
leaq 0x38(%r14), %rdi
movq %rdi, -0x40(%rbp)
movq %rsi, 0x48(%r14)
movq %rcx, 0x50(%r14)
movq %rdx, 0x18(%rax)
leaq -0x80(%rbp), %rcx
movq %rcx, (%rax)
leaq -0xb0(%rbp), %rcx
movq %rcx, 0x10(%rax)
leaq -0x10b0(%rbp), %rax
movq %rax, 0x58(%r14)
movq $0x1000, 0x60(%r14)     # imm = 0x1000
xorl %r15d, %r15d
movq %r14, -0x48(%rbp)
movq -0x30(%rbp), %rax
movq (%rax), %rdi
movl 0x8(%rax), %esi
movl 0x10(%rax), %edx
callq 0x402f4f
movl %eax, %r12d
movdqu 0xb1db9(%rip), %xmm0    # 0x4b4040
movdqa %xmm0, -0x90(%rbp)
movl %eax, %edi
movl $0x1, %esi
movl $0x14, %edx
leaq -0x90(%rbp), %rcx
movl $0x10, %r8d
callq 0x45fc00
testl %eax, %eax
movl %r12d, -0x34(%rbp)
js 0x40259b
pxor %xmm0, %xmm0
movdqa %xmm0, -0x70(%rbp)
movdqa %xmm0, -0x80(%rbp)
callq 0x45af40
movl %eax, %ebx
callq 0x45f5b0
movl $0x20, %esi
leaq -0x80(%rbp), %rdi
leaq 0xb1de4(%rip), %rdx     # 0x4b40c7
movl %ebx, %ecx
movl %eax, %r8d
movq %r15, %r9
xorl %eax, %eax
callq 0x40d8b0
xorl %eax, %eax
callq 0x403218
movq %rax, %r13
movl %r12d, %edi
movq %r14, %rsi
xorl %edx, %edx
callq 0x45fb60
testl %eax, %eax
jle 0x402369
movq %r15, -0x58(%rbp)
movq $0x1000, 0x60(%r14)     # imm = 0x1000
xorl %edx, %edx
movq -0x30(%rbp), %rax
cmpl $0x0, 0xc(%rax)
setne %dl
shll $0x6, %edx
movl %r12d, %edi
movq -0x40(%rbp), %rsi
callq 0x45fab0
movq %rax, %r14
xorl %eax, %eax
callq 0x403218
movq %rax, %r12
movq %rax, %r15
subq %r13, %r15
cmpq $0x3b9ac9ff, %r15       # imm = 0x3B9AC9FF
jbe 0x40237e
callq 0x405e20
movq %rax, %rbx
movl $0x6f, (%rbx)
testl %r14d, %r14d
jg 0x402387
jmp 0x4024ee
callq 0x405e20
movl (%rax), %eax
cmpl $0x4, %eax
je 0x402466
jmp 0x4024d7
testl %r14d, %r14d
jle 0x40246e
movdqa -0x80(%rbp), %xmm0
movdqa -0x70(%rbp), %xmm1
pcmpeqb -0xa0(%rbp), %xmm1
pcmpeqb -0xb0(%rbp), %xmm0
pand %xmm1, %xmm0
pmovmskb %xmm0, %eax
cmpl $0xffff, %eax           # imm = 0xFFFF
jne 0x402511
movq -0x48(%rbp), %r14
cmpq $0x10, 0x60(%r14)
jb 0x4023f8
movq 0x58(%r14), %rax
testq %rax, %rax
movq -0x40(%rbp), %r13
je 0x4023f8
xorl %ebx, %ebx
cmpl $0x1, 0x8(%rax)
jne 0x4023e6
cmpl $0x23, 0xc(%rax)
jne 0x4023e6
imulq $0x3b9aca00, 0x10(%rax), %rbx # imm = 0x3B9ACA00
addq 0x18(%rax), %rbx
movq %r13, %rdi
movq %rax, %rsi
callq 0x45fc70
testq %rax, %rax
jne 0x4023ce
jmp 0x4023fa
xorl %ebx, %ebx
movq -0x50(%rbp), %rdi
callq 0x4210d0
movq -0x30(%rbp), %rdx
incq 0x30(%rdx)
movslq %r15d, %rax
addq %rax, 0x20(%rdx)
movl %eax, %ecx
imull %ecx, %ecx
addq %rcx, 0x28(%rdx)
cmpl %eax, 0x18(%rdx)
jle 0x402428
movq -0x30(%rbp), %rax
movl %r15d, 0x18(%rax)
testq %rbx, %rbx
je 0x402455
subq %rbx, %r12
movq -0x30(%rbp), %rdx
incq 0x50(%rdx)
movslq %r12d, %rax
addq %rax, 0x40(%rdx)
movl %eax, %ecx
imull %ecx, %ecx
addq %rcx, 0x48(%rdx)
cmpl %eax, 0x38(%rdx)
jle 0x402455
movq -0x30(%rbp), %rax
movl %r12d, 0x38(%rax)
movq -0x50(%rbp), %rdi
callq 0x4210f0
movq -0x58(%rbp), %r15
movl -0x34(%rbp), %r12d
incq %r15
jmp 0x4022b9
callq 0x405e20
movq %rax, %rbx
movl (%rbx), %eax
cmpl $0x4, %eax
movl -0x34(%rbp), %edi
je 0x402494
cmpl $0xb, %eax
je 0x402494
testl %r14d, %r14d
jne 0x4024e5
movq -0x30(%rbp), %rax
cmpl $0x0, 0xc(%rax)
je 0x4024e3
xorl %edx, %edx
movq -0x30(%rbp), %rax
cmpl $0x0, 0xc(%rax)
setne %dl
shll $0x6, %edx
movq -0x40(%rbp), %rsi
callq 0x45fab0
movq %rax, %r14
xorl %eax, %eax
callq 0x403218
movq %rax, %r12
movq %rax, %r15
subq %r13, %r15
cmpq $0x3b9aca00, %r15       # imm = 0x3B9ACA00
jae 0x402359
testl %r14d, %r14d
jle 0x402476
jmp 0x402387
cmpl $0xb, %eax
je 0x402504
cmpl $0x6f, %eax
je 0x402504
jmp 0x402533
movl (%rbx), %eax
cmpl $0x6f, %eax
jne 0x4025db
movl $0x1, %edi
callq 0x45ae40
movq -0x48(%rbp), %r14
movq -0x58(%rbp), %r15
movl -0x34(%rbp), %r12d
movl %r12d, %edi
callq 0x45cd30
jmp 0x40226a
movq $0x4e87a8, %rax         # imm = 0x4E87A8
movq (%rax), %rcx
movl $0x10, %esi
movl $0x1, %edx
leaq 0xb1be2(%rip), %rdi     # 0x4b410e
callq 0x414780
jmp 0x4024ee
movq $0x4e87a8, %rbx         # imm = 0x4E87A8
movq (%rbx), %rcx
leaq 0xb1b8e(%rip), %rdi     # 0x4b40d2
movl $0x1d, %esi
movl $0x1, %edx
callq 0x414780
movq (%rbx), %rdi
leaq 0xb1b26(%rip), %rsi     # 0x4b4083
leaq 0xb1b39(%rip), %rdx     # 0x4b409d
leaq 0xb1b3e(%rip), %rcx     # 0x4b40a9
movl $0x53, %r8d
xorl %eax, %eax
callq 0x40d720
leaq 0xb1b36(%rip), %rdi     # 0x4b40b5
callq 0x40dad0
movq (%rbx), %rsi
movl $0xa, %edi
callq 0x416af0
movl $0x1, %edi
callq 0x40c680
movq $0x4e87a8, %rbx         # imm = 0x4E87A8
movq (%rbx), %rcx
leaq 0xb1aac(%rip), %rdi     # 0x4b4058
movl $0x2a, %esi
movl $0x1, %edx
callq 0x414780
movq (%rbx), %rdi
leaq 0xb1abe(%rip), %rsi     # 0x4b4083
leaq 0xb1ad1(%rip), %rdx     # 0x4b409d
leaq 0xb1ad6(%rip), %rcx     # 0x4b40a9
movl $0x41, %r8d
jmp 0x402571
movq $0x4e87a8, %rbx         # imm = 0x4E87A8
movq (%rbx), %rcx
leaq 0xb1b04(%rip), %rdi     # 0x4b40f0
movl $0x1d, %esi
movl $0x1, %edx
callq 0x414780
movq (%rbx), %rdi
leaq 0xb1a7e(%rip), %rsi     # 0x4b4083
leaq 0xb1a91(%rip), %rdx     # 0x4b409d
leaq 0xb1a96(%rip), %rcx     # 0x4b40a9
movl $0x73, %r8d
jmp 0x402571