// File: /workspace/github_c_makefile_star2_O2/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 %r14
pushq %rbx
pushq %rax
movl %edi, %ebx
pushq $0x2
popq %rdi
callq 0x3b4a
testq %rax, %rax
jne 0x8033
movq 0x159e9(%rip), %r14     # 0x1d908
testq %r14, %r14
je 0x7f43
movq %r14, %rdi
movq 0x38(%r14), %r14
movzwl 0x52(%rdi), %eax
testb $0x8, %al
je 0x7f1f
andl $0xfff7, %eax           # imm = 0xFFF7
movw %ax, 0x52(%rdi)
callq 0x7c71
jmp 0x7f1f
xorl %edi, %edi
leaq 0x159c4(%rip), %rax     # 0x1d910
movl 0x159ca(%rip), %ecx     # 0x1d91c
xorl %edx, %edx
movq (%rax), %rax
testq %rax, %rax
je 0x7f70
movl %ecx, %esi
subl 0x58(%rax), %esi
cmpl %edx, %esi
cmovaeq %rax, %rdi
cmoval %esi, %edx
addq $0x38, %rax
jmp 0x7f54
testq %rdi, %rdi
je 0x7f7a
callq 0x71ec
pushq $0x2
popq %rdi
callq 0x3b4a
testq %rax, %rax
jne 0x8033
pushq $0x9
popq %rdi
callq 0x80c1
pushq $0x2
popq %rdi
callq 0x3b4a
testq %rax, %rax
jne 0x8033
pushq $0x8
popq %rdi
callq 0x80c1
pushq $0x2
popq %rdi
callq 0x3b4a
testq %rax, %rax
jne 0x8033
testb %bl, %bl
je 0x8022
movzbl %bl, %eax
cmpb $0x7f, %bl
pushq $0x7f
popq %rsi
cmovbl %eax, %esi
decb %sil
xorl %edi, %edi
leaq 0x15933(%rip), %rax     # 0x1d908
movl 0x15941(%rip), %ecx     # 0x1d91c
xorl %edx, %edx
movq (%rax), %rax
testq %rax, %rax
je 0x8018
movb 0x4c(%rax), %r8b
cmpb %sil, %r8b
jae 0x7ff8
movl %ecx, %edx
subl 0x58(%rax), %edx
movq %rax, %rdi
jmp 0x800f
jne 0x800c
movl %ecx, %r8d
subl 0x58(%rax), %r8d
cmpl %edx, %r8d
cmovaeq %rax, %rdi
cmoval %r8d, %edx
movl %esi, %r8d
addq $0x38, %rax
movl %r8d, %esi
jmp 0x7fdd
testq %rdi, %rdi
je 0x8022
callq 0x71ec
pushq $0x2
popq %rdi
callq 0x3b4a
testq %rax, %rax
je 0x80bc
movq %rax, %r14
movl $0x100, %edx            # imm = 0x100
movq %rax, %rdi
xorl %esi, %esi
callq 0x20f0
movb %bl, 0x4c(%r14)
movw $0x8000, %ax            # imm = 0x8000
movw %ax, 0x9c(%r14)
movl $0x80008000, 0x60(%r14) # imm = 0x80008000
movb $0x40, 0x33(%r14)
movl $0x60006, 0x76(%r14)    # imm = 0x60006
movl $0x218ffff, 0x68(%r14)  # imm = 0x218FFFF
movw $0x1, 0x80(%r14)
movl 0x1589a(%rip), %ecx     # 0x1d91c
movl %ecx, 0x58(%r14)
movb 0x15894(%rip), %cl      # 0x1d920
movb %cl, 0x56(%r14)
movw %ax, 0x82(%r14)
leaq -0x2d0(%rip), %rax      # 0x7dcf
movq %rax, 0xd8(%r14)
movl $0x6ddd00, 0xf8(%r14) # imm = 0x6DDD00
movq %r14, %rax
addq $0x8, %rsp
popq %rbx
popq %r14
retq
xorl %r14d, %r14d
jmp 0x80b1