// File: /workspace/github_c_makefile_star2_O0/FH0[P]tun_direct/lwip-2.1.2/src/core/tcp.c
// Function: tcp_alloc
struct tcp_pcb *
tcp_alloc(u8_t prio)
{
  struct tcp_pcb *pcb;

  LWIP_ASSERT_CORE_LOCKED();

  pcb = (struct tcp_pcb *)memp_malloc(MEMP_TCP_PCB);
  if (pcb == NULL) {
    /* Try to send FIN for all pcbs stuck in TF_CLOSEPEND first */
    tcp_handle_closepend();

    /* Try killing oldest connection in TIME-WAIT. */
    LWIP_DEBUGF(TCP_DEBUG, ("tcp_alloc: killing off oldest TIME-WAIT connection\n"));
    tcp_kill_timewait();
    /* Try to allocate a tcp_pcb again. */
    pcb = (struct tcp_pcb *)memp_malloc(MEMP_TCP_PCB);
    if (pcb == NULL) {
      /* Try killing oldest connection in LAST-ACK (these wouldn't go to TIME-WAIT). */
      LWIP_DEBUGF(TCP_DEBUG, ("tcp_alloc: killing off oldest LAST-ACK connection\n"));
      tcp_kill_state(LAST_ACK);
      /* Try to allocate a tcp_pcb again. */
      pcb = (struct tcp_pcb *)memp_malloc(MEMP_TCP_PCB);
      if (pcb == NULL) {
        /* Try killing oldest connection in CLOSING. */
        LWIP_DEBUGF(TCP_DEBUG, ("tcp_alloc: killing off oldest CLOSING connection\n"));
        tcp_kill_state(CLOSING);
        /* Try to allocate a tcp_pcb again. */
        pcb = (struct tcp_pcb *)memp_malloc(MEMP_TCP_PCB);
        if (pcb == NULL) {
          /* Try killing oldest active connection with lower priority than the new one. */
          LWIP_DEBUGF(TCP_DEBUG, ("tcp_alloc: killing oldest connection with prio lower than %d\n", prio));
          tcp_kill_prio(prio);
          /* Try to allocate a tcp_pcb again. */
          pcb = (struct tcp_pcb *)memp_malloc(MEMP_TCP_PCB);
          if (pcb != NULL) {
            /* adjust err stats: memp_malloc failed multiple times before */
            MEMP_STATS_DEC(err, MEMP_TCP_PCB);
          }
        }
        if (pcb != NULL) {
          /* adjust err stats: memp_malloc failed multiple times before */
          MEMP_STATS_DEC(err, MEMP_TCP_PCB);
        }
      }
      if (pcb != NULL) {
        /* adjust err stats: memp_malloc failed multiple times before */
        MEMP_STATS_DEC(err, MEMP_TCP_PCB);
      }
    }
    if (pcb != NULL) {
      /* adjust err stats: memp_malloc failed above */
      MEMP_STATS_DEC(err, MEMP_TCP_PCB);
    }
  }
  if (pcb != NULL) {
    /* zero out the whole pcb, so there is no need to initialize members to zero */
    memset(pcb, 0, sizeof(struct tcp_pcb));
    pcb->prio = prio;
    pcb->snd_buf = TCP_SND_BUF;
    /* Start with a window that does not need scaling. When window scaling is
       enabled and used, the window is enlarged when both sides agree on scaling. */
    pcb->rcv_wnd = pcb->rcv_ann_wnd = TCPWND_MIN16(TCP_WND);
    pcb->ttl = TCP_TTL;
    /* As initial send MSS, we use TCP_MSS but limit it to 536.
       The send MSS is updated when an MSS option is received. */
    pcb->mss = INITIAL_MSS;
    pcb->rto = 3000 / TCP_SLOW_INTERVAL;
    pcb->sv = 3000 / TCP_SLOW_INTERVAL;
    pcb->rtime = -1;
    pcb->cwnd = 1;
    pcb->tmr = tcp_ticks;
    pcb->last_timer = tcp_timer_ctr;

    /* RFC 5681 recommends setting ssthresh abritrarily high and gives an example
    of using the largest advertised receive window.  We've seen complications with
    receiving TCPs that use window scaling and/or window auto-tuning where the
    initial advertised window is very small and then grows rapidly once the
    connection is established. To avoid these complications, we set ssthresh to the
    largest effective cwnd (amount of in-flight data) that the sender can have. */
    pcb->ssthresh = TCP_SND_BUF;

#if LWIP_CALLBACK_API
    pcb->recv = tcp_recv_null;
#endif /* LWIP_CALLBACK_API */

    /* Init KEEPALIVE timer */
    pcb->keep_idle  = TCP_KEEPIDLE_DEFAULT;

#if LWIP_TCP_KEEPALIVE
    pcb->keep_intvl = TCP_KEEPINTVL_DEFAULT;
    pcb->keep_cnt   = TCP_KEEPCNT_DEFAULT;
#endif /* LWIP_TCP_KEEPALIVE */
  }
  return pcb;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x10, %rsp
movb %dil, %al
movb %al, -0x1(%rbp)
movl $0x2, %edi
callq 0x4930
movq %rax, -0x10(%rbp)
cmpq $0x0, -0x10(%rbp)
jne 0xd9d9
callq 0xdab0
jmp 0xd92e
callq 0xdb20
movl $0x2, %edi
callq 0x4930
movq %rax, -0x10(%rbp)
cmpq $0x0, -0x10(%rbp)
jne 0xd9ce
jmp 0xd94e
jmp 0xd950
movl $0x9, %edi
callq 0xdba0
movl $0x2, %edi
callq 0x4930
movq %rax, -0x10(%rbp)
cmpq $0x0, -0x10(%rbp)
jne 0xd9c3
jmp 0xd971
jmp 0xd973
movl $0x8, %edi
callq 0xdba0
movl $0x2, %edi
callq 0x4930
movq %rax, -0x10(%rbp)
cmpq $0x0, -0x10(%rbp)
jne 0xd9b8
jmp 0xd994
jmp 0xd996
movzbl -0x1(%rbp), %edi
callq 0xdc70
movl $0x2, %edi
callq 0x4930
movq %rax, -0x10(%rbp)
cmpq $0x0, -0x10(%rbp)
je 0xd9b6
jmp 0xd9b6
jmp 0xd9b8
cmpq $0x0, -0x10(%rbp)
je 0xd9c1
jmp 0xd9c1
jmp 0xd9c3
cmpq $0x0, -0x10(%rbp)
je 0xd9cc
jmp 0xd9cc
jmp 0xd9ce
cmpq $0x0, -0x10(%rbp)
je 0xd9d7
jmp 0xd9d7
jmp 0xd9d9
cmpq $0x0, -0x10(%rbp)
je 0xdaa3
movq -0x10(%rbp), %rdi
xorl %esi, %esi
movl $0x100, %edx            # imm = 0x100
callq 0x20f0
movb -0x1(%rbp), %cl
movq -0x10(%rbp), %rax
movb %cl, 0x4c(%rax)
movq -0x10(%rbp), %rax
movw $0x8000, 0x9c(%rax)     # imm = 0x8000
movq -0x10(%rbp), %rax
movw $0x8000, 0x62(%rax)     # imm = 0x8000
movq -0x10(%rbp), %rax
movw $0x8000, 0x60(%rax)     # imm = 0x8000
movq -0x10(%rbp), %rax
movb $0x40, 0x33(%rax)
movq -0x10(%rbp), %rax
movw $0x218, 0x6a(%rax)      # imm = 0x218
movq -0x10(%rbp), %rax
movw $0x6, 0x78(%rax)
movq -0x10(%rbp), %rax
movw $0x6, 0x76(%rax)
movq -0x10(%rbp), %rax
movw $0xffff, 0x68(%rax)     # imm = 0xFFFF
movq -0x10(%rbp), %rax
movw $0x1, 0x80(%rax)
movl 0x21eba(%rip), %ecx     # 0x2f91c
movq -0x10(%rbp), %rax
movl %ecx, 0x58(%rax)
movb 0x21eb1(%rip), %cl      # 0x2f920
movq -0x10(%rbp), %rax
movb %cl, 0x56(%rax)
movq -0x10(%rbp), %rax
movw $0x8000, 0x82(%rax)     # imm = 0x8000
movq -0x10(%rbp), %rax
leaq -0x38e(%rip), %rcx      # 0xd700
movq %rcx, 0xd8(%rax)
movq -0x10(%rbp), %rax
movl $0x6ddd00, 0xf8(%rax)   # imm = 0x6DDD00
movq -0x10(%rbp), %rax
addq $0x10, %rsp
popq %rbp
retq
nopl (%rax)