// File: /workspace/github_c_makefile_star2_O2/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 0x6c89
cmpl $0x7, %eax
je 0x6c77
cmpl $0x4, %eax
jne 0x6c89
cmpq $0x0, 0xc0(%rbx)
jne 0x6cdf
xorl %ecx, %ecx
cmpw 0x60(%rbx), %cx
jno 0x6cdf
testl %eax, %eax
je 0x6d61
cmpl $0x2, %eax
je 0x6d46
cmpl $0x1, %eax
jne 0x6d92
pushq $0x1
popq %rax
leaq 0x160b3(%rip), %rcx     # 0x1cd60
cmpq $0x4, %rax
je 0x6d9f
movq (%rcx,%rax,8), %rdx
movq (%rdx), %rdx
testq %rdx, %rdx
je 0x6cda
cmpq %rbx, 0xc8(%rdx)
jne 0x6cd4
andq $0x0, 0xc8(%rdx)
addq $0x38, %rdx
jmp 0x6cbb
incq %rax
jmp 0x6cad
testb $0x10, 0x52(%rbx)
je 0x6e11
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 0xc200
movq %rbx, %rdi
callq 0x7bc0
movq 0x16bec(%rip), %rcx     # 0x1d908
cmpq %rbx, %rcx
je 0x6dc1
testq %rcx, %rcx
je 0x6dcf
movq %rcx, %rax
movq 0x38(%rcx), %rcx
cmpq %rbx, %rcx
jne 0x6d25
addq $0x38, %rax
movq %rbx, %rcx
jmp 0x6dc8
leaq 0x16bbb(%rip), %rdi     # 0x1d908
movq %rbx, %rsi
callq 0x7097
movb $0x1, 0x16bbd(%rip)     # 0x1d919
jmp 0x6e01
cmpw $0x0, 0x4e(%rbx)
je 0x6e01
movq 0x16b8d(%rip), %rcx     # 0x1d900
cmpq %rbx, %rcx
je 0x6dee
testq %rcx, %rcx
je 0x6dfc
movq %rcx, %rax
movq 0x38(%rcx), %rcx
cmpq %rbx, %rcx
jne 0x6d78
addq $0x38, %rax
movq %rbx, %rcx
jmp 0x6df5
movq %rbx, %rdi
addq $0x10, %rsp
popq %rbx
jmp 0x7c71
leaq 0x16b52(%rip), %rdi     # 0x1d8f8
movq %rbx, %rsi
callq 0x7097
cmpl $0x1, 0x48(%rbx)
je 0x6e2d
pushq $0x3
popq %rdi
movq %rbx, %rsi
callq 0x3bcd
jmp 0x6e09
leaq 0x16b40(%rip), %rax     # 0x1d908
movq 0x38(%rcx), %rcx
movq %rcx, (%rax)
andq $0x0, 0x38(%rbx)
movb $0x1, 0x16b3e(%rip)     # 0x1d919
leaq 0x16b9e(%rip), %rax     # 0x1d980
cmpq %rbx, (%rax)
jne 0x6e01
callq 0x971b
jmp 0x6e09
leaq 0x16b0b(%rip), %rax     # 0x1d900
movq 0x38(%rcx), %rcx
movq %rcx, (%rax)
andq $0x0, 0x38(%rbx)
movq %rbx, %rdi
callq 0x6530
xorl %eax, %eax
addq $0x10, %rsp
popq %rbx
retq
leaq 0xd4b4(%rip), %rdi      # 0x142cc
leaq 0xe4fb(%rip), %rsi      # 0x1531a
leaq 0xde79(%rip), %rcx      # 0x14c9f
movl $0x164, %edx            # imm = 0x164
jmp 0x6e47
leaq 0xd498(%rip), %rdi      # 0x142cc
leaq 0xe4f8(%rip), %rsi      # 0x15333
leaq 0xde5d(%rip), %rcx      # 0x14c9f
movl $0xdf, %edx
xorl %eax, %eax
callq 0x20d0
xorl %edi, %edi
callq 0x21b0
callq 0x2050