// File: /workspace/github_c_makefile_star2_O0/FH0[P]tun_direct/lwip-2.1.2/src/core/tcp_out.c
// Function: tcp_send_empty_ack
err_t
tcp_send_empty_ack(struct tcp_pcb *pcb)
{
  err_t err;
  struct pbuf *p;
  u8_t optlen, optflags = 0;
  u8_t num_sacks = 0;

  LWIP_ASSERT("tcp_send_empty_ack: invalid pcb", pcb != NULL);

#if LWIP_TCP_TIMESTAMPS
  if (pcb->flags & TF_TIMESTAMP) {
    optflags = TF_SEG_OPTS_TS;
  }
#endif
  optlen = LWIP_TCP_OPT_LENGTH_SEGMENT(optflags, pcb);

#if LWIP_TCP_SACK_OUT
  /* For now, SACKs are only sent with empty ACKs */
  if ((num_sacks = tcp_get_num_sacks(pcb, optlen)) > 0) {
    optlen += 4 + num_sacks * 8; /* 4 bytes for header (including 2*NOP), plus 8B for each SACK */
  }
#endif

  p = tcp_output_alloc_header(pcb, optlen, 0, lwip_htonl(pcb->snd_nxt));
  if (p == NULL) {
    /* let tcp_fasttmr retry sending this ACK */
    tcp_set_flags(pcb, TF_ACK_DELAY | TF_ACK_NOW);
    LWIP_DEBUGF(TCP_OUTPUT_DEBUG, ("tcp_output: (ACK) could not allocate pbuf\n"));
    return ERR_BUF;
  }
  tcp_output_fill_options(pcb, p, optflags, num_sacks);

#if LWIP_TCP_TIMESTAMPS
  pcb->ts_lastacksent = pcb->rcv_nxt;
#endif

  LWIP_DEBUGF(TCP_OUTPUT_DEBUG,
              ("tcp_output: sending ACK for %"U32_F"\n", pcb->rcv_nxt));
  err = tcp_output_control_segment(pcb, p, &pcb->local_ip, &pcb->remote_ip);
  if (err != ERR_OK) {
    /* let tcp_fasttmr retry sending this ACK */
    tcp_set_flags(pcb, TF_ACK_DELAY | TF_ACK_NOW);
  } else {
    /* remove ACK flags from the PCB, as we sent an empty ACK now */
    tcp_clear_flags(pcb, TF_ACK_DELAY | TF_ACK_NOW);
  }

  return err;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x30, %rsp
movq %rdi, -0x10(%rbp)
movb $0x0, -0x22(%rbp)
movb $0x0, -0x23(%rbp)
cmpq $0x0, -0x10(%rbp)
jne 0x153fc
jmp 0x153cd
leaq 0x11ef8(%rip), %rdi     # 0x272cc
leaq 0x13b43(%rip), %rsi     # 0x28f1e
movl $0x7ea, %edx            # imm = 0x7EA
leaq 0x135eb(%rip), %rcx     # 0x289d2
movb $0x0, %al
callq 0x20d0
xorl %eax, %eax
movl %eax, %edi
callq 0x21b0
callq 0x2040
jmp 0x153fe
movzbl -0x22(%rbp), %edx
andl $0x1, %edx
xorl %eax, %eax
movl $0x4, %ecx
cmpl $0x0, %edx
cmovnel %ecx, %eax
movzbl -0x22(%rbp), %edx
andl $0x2, %edx
xorl %ecx, %ecx
cmpl $0x0, %edx
cmovnel %ecx, %ecx
addl %ecx, %eax
movzbl -0x22(%rbp), %edx
andl $0x8, %edx
xorl %ecx, %ecx
cmpl $0x0, %edx
cmovnel %ecx, %ecx
addl %ecx, %eax
movzbl -0x22(%rbp), %edx
andl $0x10, %edx
xorl %ecx, %ecx
cmpl $0x0, %edx
cmovnel %ecx, %ecx
addl %ecx, %eax
movb %al, -0x21(%rbp)
movq -0x10(%rbp), %rax
movq %rax, -0x30(%rbp)
movzbl -0x21(%rbp), %eax
movw %ax, -0x26(%rbp)
movq -0x10(%rbp), %rax
movl 0x88(%rax), %edi
callq 0x251f0
movq -0x30(%rbp), %rdi
movl %eax, %ecx
movw -0x26(%rbp), %ax
xorl %edx, %edx
movzwl %ax, %esi
callq 0x16670
movq %rax, -0x20(%rbp)
cmpq $0x0, -0x20(%rbp)
jne 0x154a8
jmp 0x15488
movq -0x10(%rbp), %rax
movzwl 0x52(%rax), %eax
orl $0x3, %eax
movw %ax, %cx
movq -0x10(%rbp), %rax
movw %cx, 0x52(%rax)
jmp 0x154a0
jmp 0x154a2
movb $-0x2, -0x1(%rbp)
jmp 0x15522
movq -0x10(%rbp), %rdi
movq -0x20(%rbp), %rsi
movb -0x22(%rbp), %al
movzbl %al, %edx
movzbl -0x23(%rbp), %ecx
callq 0x163d0
jmp 0x154c1
movq -0x10(%rbp), %rdi
movq -0x20(%rbp), %rsi
movq -0x10(%rbp), %rdx
movq -0x10(%rbp), %rcx
addq $0x18, %rcx
callq 0x16500
movb %al, -0x11(%rbp)
movsbl -0x11(%rbp), %eax
cmpl $0x0, %eax
je 0x15500
jmp 0x154e8
movq -0x10(%rbp), %rax
movzwl 0x52(%rax), %eax
orl $0x3, %eax
movw %ax, %cx
movq -0x10(%rbp), %rax
movw %cx, 0x52(%rax)
jmp 0x1551c
jmp 0x15502
movq -0x10(%rbp), %rax
movzwl 0x52(%rax), %eax
andl $0xfffc, %eax           # imm = 0xFFFC
movw %ax, %cx
movq -0x10(%rbp), %rax
movw %cx, 0x52(%rax)
jmp 0x1551c
movb -0x11(%rbp), %al
movb %al, -0x1(%rbp)
movb -0x1(%rbp), %al
addq $0x30, %rsp
popq %rbp
retq
nopl (%rax,%rax)