// File: /workspace/github_c_makefile_star2_O0/FH0[P]tun_direct/lwip-2.1.2/src/core/tcp.c
// Function: tcp_close_shutdown_fin
static err_t
tcp_close_shutdown_fin(struct tcp_pcb *pcb)
{
  err_t err;
  LWIP_ASSERT("pcb != NULL", pcb != NULL);

  switch (pcb->state) {
    case SYN_RCVD:
      err = tcp_send_fin(pcb);
      if (err == ERR_OK) {
        tcp_backlog_accepted(pcb);
        MIB2_STATS_INC(mib2.tcpattemptfails);
        pcb->state = FIN_WAIT_1;
      }
      break;
    case ESTABLISHED:
      err = tcp_send_fin(pcb);
      if (err == ERR_OK) {
        MIB2_STATS_INC(mib2.tcpestabresets);
        pcb->state = FIN_WAIT_1;
      }
      break;
    case CLOSE_WAIT:
      err = tcp_send_fin(pcb);
      if (err == ERR_OK) {
        MIB2_STATS_INC(mib2.tcpestabresets);
        pcb->state = LAST_ACK;
      }
      break;
    default:
      /* Has already been closed, do nothing. */
      return ERR_OK;
  }

  if (err == ERR_OK) {
    /* To ensure all data has been sent when tcp_close returns, we have
       to make sure tcp_output doesn't fail.
       Since we don't really have to ensure all data has been sent when tcp_close
       returns (unsent data is sent from tcp timer functions, also), we don't care
       for the return value of tcp_output for now. */
    tcp_output(pcb);
  } else if (err == ERR_MEM) {
    /* Mark this pcb for closing. Closing is retried from tcp_tmr. */
    tcp_set_flags(pcb, TF_CLOSEPEND);
    /* We have to return ERR_OK from here to indicate to the callers that this
       pcb should not be used any more as it will be freed soon via tcp_tmr.
       This is OK here since sending FIN does not guarantee a time frime for
       actually freeing the pcb, either (it is left in closure states for
       remote ACK or timeout) */
    return ERR_OK;
  }
  return err;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x20, %rsp
movq %rdi, -0x10(%rbp)
cmpq $0x0, -0x10(%rbp)
jne 0xd444
jmp 0xd415
leaq 0x19eb0(%rip), %rdi     # 0x272cc
leaq 0x1b01c(%rip), %rsi     # 0x2843f
movl $0x19c, %edx            # imm = 0x19C
leaq 0x1a93c(%rip), %rcx     # 0x27d6b
movb $0x0, %al
callq 0x20d0
xorl %eax, %eax
movl %eax, %edi
callq 0x21b0
callq 0x2040
jmp 0xd446
movq -0x10(%rbp), %rax
movl 0x48(%rax), %eax
movl %eax, -0x18(%rbp)
subl $0x3, %eax
je 0xd46b
jmp 0xd457
movl -0x18(%rbp), %eax
subl $0x4, %eax
je 0xd48d
jmp 0xd461
movl -0x18(%rbp), %eax
subl $0x7, %eax
je 0xd4af
jmp 0xd4d1
movq -0x10(%rbp), %rdi
callq 0x146c0
movb %al, -0x11(%rbp)
movsbl -0x11(%rbp), %eax
cmpl $0x0, %eax
jne 0xd48b
movq -0x10(%rbp), %rax
movl $0x5, 0x48(%rax)
jmp 0xd4d7
movq -0x10(%rbp), %rdi
callq 0x146c0
movb %al, -0x11(%rbp)
movsbl -0x11(%rbp), %eax
cmpl $0x0, %eax
jne 0xd4ad
movq -0x10(%rbp), %rax
movl $0x5, 0x48(%rax)
jmp 0xd4d7
movq -0x10(%rbp), %rdi
callq 0x146c0
movb %al, -0x11(%rbp)
movsbl -0x11(%rbp), %eax
cmpl $0x0, %eax
jne 0xd4cf
movq -0x10(%rbp), %rax
movl $0x9, 0x48(%rax)
jmp 0xd4d7
movb $0x0, -0x1(%rbp)
jmp 0xd51a
movsbl -0x11(%rbp), %eax
cmpl $0x0, %eax
jne 0xd4eb
movq -0x10(%rbp), %rdi
callq 0x14b70
jmp 0xd514
movsbl -0x11(%rbp), %eax
cmpl $-0x1, %eax
jne 0xd512
jmp 0xd4f6
movq -0x10(%rbp), %rax
movzwl 0x52(%rax), %eax
orl $0x8, %eax
movw %ax, %cx
movq -0x10(%rbp), %rax
movw %cx, 0x52(%rax)
movb $0x0, -0x1(%rbp)
jmp 0xd51a
jmp 0xd514
movb -0x11(%rbp), %al
movb %al, -0x1(%rbp)
movb -0x1(%rbp), %al
addq $0x20, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)