// File: /workspace/github_c_makefile_star2_O3/FH0[P]tun_direct/lwip-2.1.2/src/core/tcp.c
// Function: tcp_close_shutdown
static err_t
tcp_close_shutdown(struct tcp_pcb *pcb, u8_t rst_on_unacked_data)
{
  LWIP_ASSERT("tcp_close_shutdown: invalid pcb", pcb != NULL);

  if (rst_on_unacked_data && ((pcb->state == ESTABLISHED) || (pcb->state == CLOSE_WAIT))) {
    if ((pcb->refused_data != NULL) || (pcb->rcv_wnd != TCP_WND_MAX(pcb))) {
      /* Not all data received by application, send RST to tell the remote
         side about this. */
      LWIP_ASSERT("pcb->flags & TF_RXCLOSED", pcb->flags & TF_RXCLOSED);

      /* don't call tcp_abort here: we must not deallocate the pcb since
         that might not be expected when calling tcp_close */
      tcp_rst(pcb, pcb->snd_nxt, pcb->rcv_nxt, &pcb->local_ip, &pcb->remote_ip,
              pcb->local_port, pcb->remote_port);

      tcp_pcb_purge(pcb);
      TCP_RMV_ACTIVE(pcb);
      /* Deallocate the pcb since we already sent a RST for it */
      if (tcp_input_pcb == pcb) {
        /* prevent using a deallocated pcb: free it from tcp_input later */
        tcp_trigger_input_pcb_close();
      } else {
        tcp_free(pcb);
      }
      return ERR_OK;
    }
  }

  /* - states which free the pcb are handled here,
     - states which send FIN and change state are handled in tcp_close_shutdown_fin() */
  switch (pcb->state) {
    case CLOSED:
      /* Closing a pcb in the CLOSED state might seem erroneous,
       * however, it is in this state once allocated and as yet unused
       * and the user needs some way to free it should the need arise.
       * Calling tcp_close() with a pcb that has already been closed, (i.e. twice)
       * or for a pcb that has been used and then entered the CLOSED state
       * is erroneous, but this should never happen as the pcb has in those cases
       * been freed, and so any remaining handles are bogus. */
      if (pcb->local_port != 0) {
        TCP_RMV(&tcp_bound_pcbs, pcb);
      }
      tcp_free(pcb);
      break;
    case LISTEN:
      tcp_listen_closed(pcb);
      tcp_pcb_remove(&tcp_listen_pcbs.pcbs, pcb);
      tcp_free_listen(pcb);
      break;
    case SYN_SENT:
      TCP_PCB_REMOVE_ACTIVE(pcb);
      tcp_free(pcb);
      MIB2_STATS_INC(mib2.tcpattemptfails);
      break;
    default:
      return tcp_close_shutdown_fin(pcb);
  }
  return ERR_OK;
}

// Assembly:
pushq %rbx
subq $0x10, %rsp
movq %rdi, %rbx
movl 0x48(%rdi), %eax
testl %esi, %esi
je 0x6eef
cmpl $0x7, %eax
je 0x6ed5
cmpl $0x4, %eax
jne 0x6eef
cmpq $0x0, 0xc0(%rbx)
jne 0x6f6f
xorl %ecx, %ecx
cmpw 0x60(%rbx), %cx
jno 0x6f6f
testl %eax, %eax
je 0x6fe6
cmpl $0x2, %eax
je 0x6fcb
cmpl $0x1, %eax
jne 0x7013
movl $0x1, %eax
leaq 0x14e4b(%rip), %rcx     # 0x1bd60
movq (%rcx,%rax,8), %rdx
movq (%rdx), %rdx
testq %rdx, %rdx
je 0x6f3b
cmpq %rbx, 0xc8(%rdx)
jne 0x6f35
movq $0x0, 0xc8(%rdx)
movq 0x38(%rdx), %rdx
jmp 0x6f1c
incq %rax
cmpq $0x4, %rax
jne 0x6f15
leaq 0x159ad(%rip), %rdi     # 0x1c8f8
movq %rbx, %rsi
callq 0x732d
cmpl $0x1, 0x48(%rbx)
je 0x7092
movl $0x3, %edi
movq %rbx, %rsi
callq 0x3cf8
jmp 0x706e
testb $0x10, 0x52(%rbx)
je 0x7076
movl 0x5c(%rbx), %edx
movl 0x88(%rbx), %esi
leaq 0x18(%rbx), %r8
movzwl 0x4e(%rbx), %r9d
movzwl 0x50(%rbx), %eax
movl %eax, (%rsp)
movq %rbx, %rdi
movq %rbx, %rcx
callq 0xc757
movq %rbx, %rdi
callq 0x7eb3
movq 0x1595c(%rip), %rcx     # 0x1c908
cmpq %rbx, %rcx
je 0x7020
testq %rcx, %rcx
je 0x702e
movq %rcx, %rax
movq 0x38(%rcx), %rcx
cmpq %rbx, %rcx
jne 0x6fb1
addq $0x38, %rax
movq %rbx, %rcx
jmp 0x7027
leaq 0x15936(%rip), %rdi     # 0x1c908
movq %rbx, %rsi
callq 0x732d
movb $0x1, 0x15938(%rip)     # 0x1c919
jmp 0x7066
cmpw $0x0, 0x4e(%rbx)
je 0x7066
movq 0x1590c(%rip), %rcx     # 0x1c900
cmpq %rbx, %rcx
je 0x7050
testq %rcx, %rcx
je 0x705e
movq %rcx, %rax
movq 0x38(%rcx), %rcx
cmpq %rbx, %rcx
jne 0x6ff9
addq $0x38, %rax
movq %rbx, %rcx
jmp 0x7057
movq %rbx, %rdi
addq $0x10, %rsp
popq %rbx
jmp 0x7fa5
leaq 0x158e1(%rip), %rax     # 0x1c908
movq 0x38(%rcx), %rcx
movq %rcx, (%rax)
movq $0x0, 0x38(%rbx)
movb $0x1, 0x158dc(%rip)     # 0x1c919
leaq 0x1593c(%rip), %rax     # 0x1c980
cmpq %rbx, (%rax)
jne 0x7066
callq 0x9b5b
jmp 0x706e
leaq 0x158a9(%rip), %rax     # 0x1c900
movq 0x38(%rcx), %rcx
movq %rcx, (%rax)
movq $0x0, 0x38(%rbx)
movq %rbx, %rdi
callq 0x6780
xorl %eax, %eax
addq $0x10, %rsp
popq %rbx
retq
leaq 0xd24f(%rip), %rdi      # 0x142cc
leaq 0xe27f(%rip), %rsi      # 0x15303
leaq 0xdbfd(%rip), %rcx      # 0x14c88
movl $0x164, %edx            # imm = 0x164
jmp 0x70ac
leaq 0xd233(%rip), %rdi      # 0x142cc
leaq 0xe27c(%rip), %rsi      # 0x1531c
leaq 0xdbe1(%rip), %rcx      # 0x14c88
movl $0xdf, %edx
xorl %eax, %eax
callq 0x20d0
xorl %edi, %edi
callq 0x21b0
callq 0x2050