// File: /workspace/github_c_makefile_star2_O1/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
testl %esi, %esi
je 0x6fdb
movl 0x48(%rbx), %eax
cmpl $0x7, %eax
je 0x6fc1
cmpl $0x4, %eax
jne 0x6fdb
cmpq $0x0, 0xc0(%rbx)
jne 0x705e
xorl %eax, %eax
cmpw 0x60(%rbx), %ax
jno 0x705e
movl 0x48(%rbx), %eax
testl %eax, %eax
je 0x70d5
cmpl $0x2, %eax
je 0x70ba
cmpl $0x1, %eax
jne 0x7102
movl $0x1, %eax
leaq 0x15d5c(%rip), %rcx     # 0x1cd60
movq (%rcx,%rax,8), %rdx
movq (%rdx), %rdx
testq %rdx, %rdx
je 0x702a
cmpq %rbx, 0xc8(%rdx)
jne 0x7024
movq $0x0, 0xc8(%rdx)
movq 0x38(%rdx), %rdx
jmp 0x700b
incq %rax
cmpq $0x4, %rax
jne 0x7004
leaq 0x168be(%rip), %rdi     # 0x1d8f8
movq %rbx, %rsi
callq 0x743d
cmpl $0x1, 0x48(%rbx)
je 0x7181
movl $0x3, %edi
movq %rbx, %rsi
callq 0x3d28
jmp 0x715d
testb $0x10, 0x52(%rbx)
je 0x7165
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 0xc9d6
movq %rbx, %rdi
callq 0x7fc6
movq 0x1686d(%rip), %rcx     # 0x1d908
cmpq %rbx, %rcx
je 0x710f
testq %rcx, %rcx
je 0x711d
movq %rcx, %rax
movq 0x38(%rcx), %rcx
cmpq %rbx, %rcx
jne 0x70a0
addq $0x38, %rax
movq %rbx, %rcx
jmp 0x7116
leaq 0x16847(%rip), %rdi     # 0x1d908
movq %rbx, %rsi
callq 0x743d
movb $0x1, 0x16849(%rip)     # 0x1d919
jmp 0x7155
cmpw $0x0, 0x4e(%rbx)
je 0x7155
movq 0x1681d(%rip), %rcx     # 0x1d900
cmpq %rbx, %rcx
je 0x713f
testq %rcx, %rcx
je 0x714d
movq %rcx, %rax
movq 0x38(%rcx), %rcx
cmpq %rbx, %rcx
jne 0x70e8
addq $0x38, %rax
movq %rbx, %rcx
jmp 0x7146
movq %rbx, %rdi
addq $0x10, %rsp
popq %rbx
jmp 0x80b8
leaq 0x167f2(%rip), %rax     # 0x1d908
movq 0x38(%rcx), %rcx
movq %rcx, (%rax)
movq $0x0, 0x38(%rbx)
movb $0x1, 0x167ed(%rip)     # 0x1d919
leaq 0x1684d(%rip), %rax     # 0x1d980
cmpq %rbx, (%rax)
jne 0x7155
callq 0x9cd8
jmp 0x715d
leaq 0x167ba(%rip), %rax     # 0x1d900
movq 0x38(%rcx), %rcx
movq %rcx, (%rax)
movq $0x0, 0x38(%rbx)
movq %rbx, %rdi
callq 0x685c
xorl %eax, %eax
addq $0x10, %rsp
popq %rbx
retq
leaq 0xe160(%rip), %rdi      # 0x152cc
leaq 0xf1a7(%rip), %rsi      # 0x1631a
leaq 0xeb25(%rip), %rcx      # 0x15c9f
movl $0x164, %edx            # imm = 0x164
jmp 0x719b
leaq 0xe144(%rip), %rdi      # 0x152cc
leaq 0xf1a4(%rip), %rsi      # 0x16333
leaq 0xeb09(%rip), %rcx      # 0x15c9f
movl $0xdf, %edx
xorl %eax, %eax
callq 0x20d0
xorl %edi, %edi
callq 0x21b0
callq 0x2050