// File: /workspace/github_c_makefile_star2_O0/FH0[P]tun_direct/lwip-2.1.2/src/core/tcp.c
// Function: tcp_connect
err_t
tcp_connect(struct tcp_pcb *pcb, const ip_addr_t *ipaddr, u16_t port,
            tcp_connected_fn connected)
{
  struct netif *netif = NULL;
  err_t ret;
  u32_t iss;
  u16_t old_local_port;

  LWIP_ASSERT_CORE_LOCKED();

  LWIP_ERROR("tcp_connect: invalid pcb", pcb != NULL, return ERR_ARG);
  LWIP_ERROR("tcp_connect: invalid ipaddr", ipaddr != NULL, return ERR_ARG);

  LWIP_ERROR("tcp_connect: can only connect from state CLOSED", pcb->state == CLOSED, return ERR_ISCONN);

  LWIP_DEBUGF(TCP_DEBUG, ("tcp_connect to port %"U16_F"\n", port));
  ip_addr_set(&pcb->remote_ip, ipaddr);
  pcb->remote_port = port;

  if (pcb->netif_idx != NETIF_NO_INDEX) {
    netif = netif_get_by_index(pcb->netif_idx);
  } else {
    /* check if we have a route to the remote host */
    netif = ip_route(&pcb->local_ip, &pcb->remote_ip);
  }
  if (netif == NULL) {
    /* Don't even try to send a SYN packet if we have no route since that will fail. */
    return ERR_RTE;
  }

  /* check if local IP has been assigned to pcb, if not, get one */
  if (ip_addr_isany(&pcb->local_ip)) {
    const ip_addr_t *local_ip = ip_netif_get_local_ip(netif, ipaddr);
    if (local_ip == NULL) {
      return ERR_RTE;
    }
    ip_addr_copy(pcb->local_ip, *local_ip);
  }

#if LWIP_IPV6 && LWIP_IPV6_SCOPES
  /* If the given IP address should have a zone but doesn't, assign one now.
   * Given that we already have the target netif, this is easy and cheap. */
  if (IP_IS_V6(&pcb->remote_ip) &&
      ip6_addr_lacks_zone(ip_2_ip6(&pcb->remote_ip), IP6_UNICAST)) {
    ip6_addr_assign_zone(ip_2_ip6(&pcb->remote_ip), IP6_UNICAST, netif);
  }
#endif /* LWIP_IPV6 && LWIP_IPV6_SCOPES */

  old_local_port = pcb->local_port;
  if (pcb->local_port == 0) {
    pcb->local_port = tcp_new_port();
    if (pcb->local_port == 0) {
      return ERR_BUF;
    }
  } else {
#if SO_REUSE
    if (ip_get_option(pcb, SOF_REUSEADDR)) {
      /* Since SOF_REUSEADDR allows reusing a local address, we have to make sure
         now that the 5-tuple is unique. */
      struct tcp_pcb *cpcb;
      int i;
      /* Don't check listen- and bound-PCBs, check active- and TIME-WAIT PCBs. */
      for (i = 2; i < NUM_TCP_PCB_LISTS; i++) {
        for (cpcb = *tcp_pcb_lists[i]; cpcb != NULL; cpcb = cpcb->next) {
          if ((cpcb->local_port == pcb->local_port) &&
              (cpcb->remote_port == port) &&
              ip_addr_cmp(&cpcb->local_ip, &pcb->local_ip) &&
              ip_addr_cmp(&cpcb->remote_ip, ipaddr)) {
            /* linux returns EISCONN here, but ERR_USE should be OK for us */
            return ERR_USE;
          }
        }
      }
    }
#endif /* SO_REUSE */
  }

  iss = tcp_next_iss(pcb);
  pcb->rcv_nxt = 0;
  pcb->snd_nxt = iss;
  pcb->lastack = iss - 1;
  pcb->snd_wl2 = iss - 1;
  pcb->snd_lbb = iss - 1;
  /* 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->rcv_ann_right_edge = pcb->rcv_nxt;
  pcb->snd_wnd = TCP_WND;
  /* 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;
#if TCP_CALCULATE_EFF_SEND_MSS
  pcb->mss = tcp_eff_send_mss_netif(pcb->mss, netif, &pcb->remote_ip);
#endif /* TCP_CALCULATE_EFF_SEND_MSS */
  pcb->cwnd = 1;
#if LWIP_CALLBACK_API
  pcb->connected = connected;
#else /* LWIP_CALLBACK_API */
  LWIP_UNUSED_ARG(connected);
#endif /* LWIP_CALLBACK_API */

  /* Send a SYN together with the MSS option. */
  ret = tcp_enqueue_flags(pcb, TCP_SYN);
  if (ret == ERR_OK) {
    /* SYN segment was enqueued, changed the pcbs state now */
    pcb->state = SYN_SENT;
    if (old_local_port != 0) {
      TCP_RMV(&tcp_bound_pcbs, pcb);
    }
    TCP_REG_ACTIVE(pcb);
    MIB2_STATS_INC(mib2.tcpactiveopens);

    tcp_output(pcb);
  }
  return ret;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x90, %rsp
movw %dx, %ax
movq %rdi, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
movw %ax, -0x1a(%rbp)
movq %rcx, -0x28(%rbp)
movq $0x0, -0x30(%rbp)
cmpq $0x0, -0x10(%rbp)
jne 0xca3e
jmp 0xca0f
leaq 0x1a8b6(%rip), %rdi     # 0x272cc
leaq 0x1b501(%rip), %rsi     # 0x27f1e
movl $0x435, %edx            # imm = 0x435
leaq 0x1b342(%rip), %rcx     # 0x27d6b
movb $0x0, %al
callq 0x20d0
xorl %eax, %eax
movl %eax, %edi
callq 0x21b0
callq 0x2040
jmp 0xca40
jmp 0xca42
cmpq $0x0, -0x18(%rbp)
jne 0xca7a
jmp 0xca4b
leaq 0x1a87a(%rip), %rdi     # 0x272cc
leaq 0x1b4de(%rip), %rsi     # 0x27f37
movl $0x436, %edx            # imm = 0x436
leaq 0x1b306(%rip), %rcx     # 0x27d6b
movb $0x0, %al
callq 0x20d0
xorl %eax, %eax
movl %eax, %edi
callq 0x21b0
callq 0x2040
jmp 0xca7c
jmp 0xca7e
movq -0x10(%rbp), %rax
cmpl $0x0, 0x48(%rax)
je 0xcab9
jmp 0xca8a
leaq 0x1a83b(%rip), %rdi     # 0x272cc
leaq 0x1b4bb(%rip), %rsi     # 0x27f53
movl $0x438, %edx            # imm = 0x438
leaq 0x1b2c7(%rip), %rcx     # 0x27d6b
movb $0x0, %al
callq 0x20d0
xorl %eax, %eax
movl %eax, %edi
callq 0x21b0
callq 0x2040
jmp 0xcabb
jmp 0xcabd
jmp 0xcabf
jmp 0xcac1
jmp 0xcac3
movq -0x10(%rbp), %rax
addq $0x18, %rax
cmpq $0x0, %rax
je 0xcae3
jmp 0xcad3
movq -0x18(%rbp), %rax
movb 0x14(%rax), %cl
movq -0x10(%rbp), %rax
movb %cl, 0x2c(%rax)
jmp 0xcae3
jmp 0xcae5
cmpq $0x0, -0x18(%rbp)
je 0xcbc0
movq -0x18(%rbp), %rax
movzbl 0x14(%rax), %eax
cmpl $0x6, %eax
jne 0xcbc0
jmp 0xcb03
movq -0x18(%rbp), %rax
cmpq $0x0, %rax
jne 0xcb14
xorl %eax, %eax
movl %eax, -0x54(%rbp)
jmp 0xcb1d
movq -0x18(%rbp), %rax
movl (%rax), %eax
movl %eax, -0x54(%rbp)
movl -0x54(%rbp), %ecx
movq -0x10(%rbp), %rax
movl %ecx, 0x18(%rax)
movq -0x18(%rbp), %rax
cmpq $0x0, %rax
jne 0xcb38
xorl %eax, %eax
movl %eax, -0x58(%rbp)
jmp 0xcb42
movq -0x18(%rbp), %rax
movl 0x4(%rax), %eax
movl %eax, -0x58(%rbp)
movl -0x58(%rbp), %ecx
movq -0x10(%rbp), %rax
movl %ecx, 0x1c(%rax)
movq -0x18(%rbp), %rax
cmpq $0x0, %rax
jne 0xcb5d
xorl %eax, %eax
movl %eax, -0x5c(%rbp)
jmp 0xcb67
movq -0x18(%rbp), %rax
movl 0x8(%rax), %eax
movl %eax, -0x5c(%rbp)
movl -0x5c(%rbp), %ecx
movq -0x10(%rbp), %rax
movl %ecx, 0x20(%rax)
movq -0x18(%rbp), %rax
cmpq $0x0, %rax
jne 0xcb82
xorl %eax, %eax
movl %eax, -0x60(%rbp)
jmp 0xcb8c
movq -0x18(%rbp), %rax
movl 0xc(%rax), %eax
movl %eax, -0x60(%rbp)
movl -0x60(%rbp), %ecx
movq -0x10(%rbp), %rax
movl %ecx, 0x24(%rax)
movq -0x18(%rbp), %rax
cmpq $0x0, %rax
jne 0xcba7
xorl %eax, %eax
movl %eax, -0x64(%rbp)
jmp 0xcbb2
movq -0x18(%rbp), %rax
movzbl 0x10(%rax), %eax
movl %eax, -0x64(%rbp)
movl -0x64(%rbp), %eax
movb %al, %cl
movq -0x10(%rbp), %rax
movb %cl, 0x28(%rax)
jmp 0xcc0f
movq -0x18(%rbp), %rax
cmpq $0x0, %rax
jne 0xcbd1
xorl %eax, %eax
movl %eax, -0x68(%rbp)
jmp 0xcbda
movq -0x18(%rbp), %rax
movl (%rax), %eax
movl %eax, -0x68(%rbp)
movl -0x68(%rbp), %ecx
movq -0x10(%rbp), %rax
movl %ecx, 0x18(%rax)
movq -0x10(%rbp), %rax
movl $0x0, 0x24(%rax)
movq -0x10(%rbp), %rax
movl $0x0, 0x20(%rax)
movq -0x10(%rbp), %rax
movl $0x0, 0x1c(%rax)
movq -0x10(%rbp), %rax
movb $0x0, 0x28(%rax)
jmp 0xcc0f
jmp 0xcc11
movw -0x1a(%rbp), %cx
movq -0x10(%rbp), %rax
movw %cx, 0x50(%rax)
movq -0x10(%rbp), %rax
movzbl 0x30(%rax), %eax
cmpl $0x0, %eax
je 0xcc3d
movq -0x10(%rbp), %rax
movzbl 0x30(%rax), %edi
callq 0x6cf0
movq %rax, -0x30(%rbp)
jmp 0xcc88
movq -0x10(%rbp), %rax
addq $0x18, %rax
cmpq $0x0, %rax
je 0xcc6f
movq -0x10(%rbp), %rax
movzbl 0x2c(%rax), %eax
cmpl $0x6, %eax
jne 0xcc6f
movq -0x10(%rbp), %rdi
movq -0x10(%rbp), %rsi
addq $0x18, %rsi
callq 0x1c270
movq %rax, -0x70(%rbp)
jmp 0xcc80
movq -0x10(%rbp), %rdi
addq $0x18, %rdi
callq 0x196c0
movq %rax, -0x70(%rbp)
movq -0x70(%rbp), %rax
movq %rax, -0x30(%rbp)
cmpq $0x0, -0x30(%rbp)
jne 0xcc98
movb $-0x4, -0x1(%rbp)
jmp 0xd0b9
movq -0x10(%rbp), %rax
cmpq $0x0, %rax
jne 0xccad
movb $0x1, %al
testb $0x1, %al
jne 0xcd1d
jmp 0xce45
movq -0x10(%rbp), %rax
cmpq $0x0, %rax
je 0xcd06
movq -0x10(%rbp), %rax
movzbl 0x14(%rax), %eax
cmpl $0x6, %eax
jne 0xcd06
movq -0x10(%rbp), %rax
cmpq $0x0, %rax
je 0xcd1d
movq -0x10(%rbp), %rax
cmpl $0x0, (%rax)
jne 0xce45
movq -0x10(%rbp), %rax
cmpl $0x0, 0x4(%rax)
jne 0xce45
movq -0x10(%rbp), %rax
cmpl $0x0, 0x8(%rax)
jne 0xce45
movq -0x10(%rbp), %rax
cmpl $0x0, 0xc(%rax)
je 0xcd1d
jmp 0xce45
movq -0x10(%rbp), %rax
cmpq $0x0, %rax
je 0xcd1d
movq -0x10(%rbp), %rax
cmpl $0x0, (%rax)
jne 0xce45
cmpq $0x0, -0x18(%rbp)
je 0xcd5d
movq -0x18(%rbp), %rax
movzbl 0x14(%rax), %eax
cmpl $0x6, %eax
jne 0xcd5d
cmpq $0x0, -0x30(%rbp)
je 0xcd4b
movq -0x30(%rbp), %rdi
movq -0x18(%rbp), %rsi
callq 0x1c290
movq %rax, -0x78(%rbp)
jmp 0xcd53
xorl %eax, %eax
movq %rax, -0x78(%rbp)
jmp 0xcd53
movq -0x78(%rbp), %rax
movq %rax, -0x80(%rbp)
jmp 0xcd8b
cmpq $0x0, -0x30(%rbp)
je 0xcd75
movq -0x30(%rbp), %rax
addq $0x8, %rax
movq %rax, -0x88(%rbp)
jmp 0xcd80
xorl %eax, %eax
movq %rax, -0x88(%rbp)
jmp 0xcd80
movq -0x88(%rbp), %rax
movq %rax, -0x80(%rbp)
movq -0x80(%rbp), %rax
movq %rax, -0x48(%rbp)
cmpq $0x0, -0x48(%rbp)
jne 0xcda3
movb $-0x4, -0x1(%rbp)
jmp 0xd0b9
jmp 0xcda5
jmp 0xcda7
movq -0x48(%rbp), %rax
movb 0x14(%rax), %cl
movq -0x10(%rbp), %rax
movb %cl, 0x14(%rax)
movq -0x48(%rbp), %rax
movzbl 0x14(%rax), %eax
cmpl $0x6, %eax
jne 0xce0a
jmp 0xcdc4
movq -0x48(%rbp), %rax
movl (%rax), %ecx
movq -0x10(%rbp), %rax
movl %ecx, (%rax)
movq -0x48(%rbp), %rax
movl 0x4(%rax), %ecx
movq -0x10(%rbp), %rax
movl %ecx, 0x4(%rax)
movq -0x48(%rbp), %rax
movl 0x8(%rax), %ecx
movq -0x10(%rbp), %rax
movl %ecx, 0x8(%rax)
movq -0x48(%rbp), %rax
movl 0xc(%rax), %ecx
movq -0x10(%rbp), %rax
movl %ecx, 0xc(%rax)
movq -0x48(%rbp), %rax
movb 0x10(%rax), %cl
movq -0x10(%rbp), %rax
movb %cl, 0x10(%rax)
jmp 0xce41
movq -0x48(%rbp), %rax
movl (%rax), %ecx
movq -0x10(%rbp), %rax
movl %ecx, (%rax)
movq -0x10(%rbp), %rax
movl $0x0, 0xc(%rax)
movq -0x10(%rbp), %rax
movl $0x0, 0x8(%rax)
movq -0x10(%rbp), %rax
movl $0x0, 0x4(%rax)
movq -0x10(%rbp), %rax
movb $0x0, 0x10(%rax)
jmp 0xce41
jmp 0xce43
jmp 0xce45
movq -0x10(%rbp), %rax
addq $0x18, %rax
cmpq $0x0, %rax
je 0xcec9
movq -0x10(%rbp), %rax
movzbl 0x2c(%rax), %eax
cmpl $0x6, %eax
jne 0xcec9
movq -0x10(%rbp), %rax
movzbl 0x28(%rax), %eax
cmpl $0x0, %eax
jne 0xcec9
movq -0x10(%rbp), %rax
movl 0x18(%rax), %eax
andq $0xc0ff, %rax           # imm = 0xC0FF
cmpq $0x80fe, %rax           # imm = 0x80FE
jne 0xcec9
movq -0x10(%rbp), %rax
movl 0x18(%rax), %eax
andq $0xc0ff, %rax           # imm = 0xC0FF
cmpq $0x80fe, %rax           # imm = 0x80FE
jne 0xceb0
movq -0x30(%rbp), %rax
movzbl 0xee(%rax), %eax
addl $0x1, %eax
movzbl %al, %eax
movl %eax, -0x8c(%rbp)
jmp 0xceba
xorl %eax, %eax
movl %eax, -0x8c(%rbp)
jmp 0xceba
movl -0x8c(%rbp), %eax
movb %al, %cl
movq -0x10(%rbp), %rax
movb %cl, 0x28(%rax)
movq -0x10(%rbp), %rax
movw 0x4e(%rax), %ax
movw %ax, -0x3a(%rbp)
movq -0x10(%rbp), %rax
movzwl 0x4e(%rax), %eax
cmpl $0x0, %eax
jne 0xcf0a
callq 0xc310
movw %ax, %cx
movq -0x10(%rbp), %rax
movw %cx, 0x4e(%rax)
movq -0x10(%rbp), %rax
movzwl 0x4e(%rax), %eax
cmpl $0x0, %eax
jne 0xcf08
movb $-0x2, -0x1(%rbp)
jmp 0xd0b9
jmp 0xcf0c
jmp 0xcf0c
movq -0x10(%rbp), %rdi
callq 0xd0d0
movl %eax, -0x38(%rbp)
movq -0x10(%rbp), %rax
movl $0x0, 0x5c(%rax)
movl -0x38(%rbp), %ecx
movq -0x10(%rbp), %rax
movl %ecx, 0x88(%rax)
movl -0x38(%rbp), %ecx
subl $0x1, %ecx
movq -0x10(%rbp), %rax
movl %ecx, 0x7c(%rax)
movl -0x38(%rbp), %ecx
subl $0x1, %ecx
movq -0x10(%rbp), %rax
movl %ecx, 0x90(%rax)
movl -0x38(%rbp), %ecx
subl $0x1, %ecx
movq -0x10(%rbp), %rax
movl %ecx, 0x94(%rax)
movq -0x10(%rbp), %rax
movw $0x8000, 0x62(%rax)     # imm = 0x8000
movq -0x10(%rbp), %rax
movw $0x8000, 0x60(%rax)     # imm = 0x8000
movq -0x10(%rbp), %rax
movl 0x5c(%rax), %ecx
movq -0x10(%rbp), %rax
movl %ecx, 0x64(%rax)
movq -0x10(%rbp), %rax
movw $0x8000, 0x98(%rax)     # imm = 0x8000
movq -0x10(%rbp), %rax
movw $0x218, 0x6a(%rax)      # imm = 0x218
movq -0x10(%rbp), %rax
movw 0x6a(%rax), %ax
movq -0x30(%rbp), %rsi
movq -0x10(%rbp), %rdx
addq $0x18, %rdx
movzwl %ax, %edi
callq 0xd140
movw %ax, %cx
movq -0x10(%rbp), %rax
movw %cx, 0x6a(%rax)
movq -0x10(%rbp), %rax
movw $0x1, 0x80(%rax)
movq -0x28(%rbp), %rcx
movq -0x10(%rbp), %rax
movq %rcx, 0xe0(%rax)
movq -0x10(%rbp), %rdi
movl $0x2, %esi
callq 0x147d0
movb %al, -0x31(%rbp)
movsbl -0x31(%rbp), %eax
cmpl $0x0, %eax
jne 0xd0b3
movq -0x10(%rbp), %rax
movl $0x2, 0x48(%rax)
movzwl -0x3a(%rbp), %eax
cmpl $0x0, %eax
je 0xd080
jmp 0xd00d
movq 0x228ec(%rip), %rax     # 0x2f900
cmpq -0x10(%rbp), %rax
jne 0xd02e
movq 0x228df(%rip), %rax     # 0x2f900
movq 0x38(%rax), %rax
movq %rax, 0x228d4(%rip)     # 0x2f900
jmp 0xd072
movq 0x228cb(%rip), %rax     # 0x2f900
movq %rax, -0x50(%rbp)
cmpq $0x0, -0x50(%rbp)
je 0xd070
movq -0x50(%rbp), %rax
movq 0x38(%rax), %rax
cmpq -0x10(%rbp), %rax
jne 0xd060
movq -0x10(%rbp), %rax
movq 0x38(%rax), %rcx
movq -0x50(%rbp), %rax
movq %rcx, 0x38(%rax)
jmp 0xd070
jmp 0xd062
movq -0x50(%rbp), %rax
movq 0x38(%rax), %rax
movq %rax, -0x50(%rbp)
jmp 0xd039
jmp 0xd072
movq -0x10(%rbp), %rax
movq $0x0, 0x38(%rax)
jmp 0xd080
jmp 0xd082
jmp 0xd084
movq 0x2287d(%rip), %rcx     # 0x2f908
movq -0x10(%rbp), %rax
movq %rcx, 0x38(%rax)
movq -0x10(%rbp), %rax
movq %rax, 0x2286a(%rip)     # 0x2f908
callq 0x16a90
movb $0x1, 0x2286f(%rip)     # 0x2f919
movq -0x10(%rbp), %rdi
callq 0x14b70
movb -0x31(%rbp), %al
movb %al, -0x1(%rbp)
movb -0x1(%rbp), %al
addq $0x90, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)