// File: /workspace/github_c_makefile_star2_O0/agl[P]obstcp/obstcp-serv.c
// Function: server
static int
server() {
  const int urfd = open("/dev/urandom", O_RDONLY);
  if (urfd < 0) {
    perror("opening urandom");
    return 1;
  }

  const int fd = socket(AF_INET, SOCK_STREAM, 0);
  if (fd < 0) {
    perror("socket");
    return 1;
  }

  struct sockaddr_in sin;
  memset(&sin, 0, sizeof(sin));
  sin.sin_family = PF_INET;

  if (bind(fd, (struct sockaddr *) &sin, sizeof(sin))) {
    perror("bind");
    return 1;
  }

  socklen_t sinlen = sizeof(sin);
  if (getsockname(fd, (struct sockaddr *) &sin, &sinlen)) {
    perror("getsockname");
    return 1;
  }

  uint8_t secret[32];
  read(urfd, secret, sizeof(secret));

  struct obstcp_keys keys;

  obstcp_keys_init(&keys);
  if (!obstcp_keys_key_add(&keys, secret)) {
    perror("key_add");
    return 1;
  }

  char advert[1024];
  const int advertlen =
    obstcp_advert_base32_create(advert, sizeof(advert), &keys,
                                OBSTCP_ADVERT_OBSPORT, ntohs(sin.sin_port),
                                OBSTCP_ADVERT_END);
  if (advertlen < 0 || advertlen >= sizeof(advert)) {
    perror("advert_create");
    return 1;
  }
  advert[advertlen] = 0;

  fprintf(stderr, "port: %d\nadvert: %s\n", ntohs(sin.sin_port), advert);

  if (listen(fd, 1)) {
    perror("listen");
    return 1;
  }

  const int nfd = accept(fd, NULL, NULL);
  if (nfd < 0) {
    perror("accept");
    return 1;
  }
  close(fd);

  fprintf(stderr, "accepted connection\n");

  struct obstcp_server_ctx ctx;
  obstcp_server_ctx_init(&ctx, &keys);

  struct obstcp_rbuf rbuf;
  obstcp_rbuf_server_init(&rbuf, &ctx);

  do {
    uint8_t b;
    const ssize_t n = obstcp_rbuf_read_fd(&rbuf, nfd, &b, 1);
    if (n < 0) {
      if (errno == EAGAIN)
        continue;
      perror("obstcp_rbuf_read_fd");
      return 1;
    } else if (n == 0) {
      fprintf(stderr, "  * Peer closed connection in handshake\n");
    } else {
      write(1, &b, 1);
    }
  } while (!obstcp_server_ready(&ctx));

  const int efd = epoll_create(2);
  if (efd < 0) {
    perror("epoll_create");
    return 1;
  }

  struct epoll_event eev;
  memset(&eev, 0, sizeof(eev));
  eev.events = EPOLLIN;

  eev.data.fd = 0;
  if (epoll_ctl(efd, EPOLL_CTL_ADD, 0, &eev)) {
    perror("epoll_ctl");
    return 1;
  }

  eev.data.fd = nfd;
  if (epoll_ctl(efd, EPOLL_CTL_ADD, nfd, &eev)) {
    perror("epoll_ctl");
    return 1;
  }

  for (;;) {
    if (epoll_wait(efd, &eev, 1, -1) == -1) {
      perror("epoll_wait");
      return 1;
    }

    if (eev.data.fd == 0) {
      uint8_t buffer[8192];
      ssize_t n;

      do {
        n = read(0, buffer, sizeof(buffer));
      } while (n == -1 && errno == EINTR);

      if (n == 0) {
        fprintf(stderr, " ** Stdin closed\n");
        return 0;
      } else if (n < 0) {
        perror("reading from stdin");
        return 1;
      } else {
        struct iovec iov[2];

        obstcp_server_encrypt(&ctx, buffer, buffer, n);
        const int a = obstcp_server_prefix(&ctx, &iov[0]);
        if (a == -1) {
          perror("obstcp_server_ends");
          return 1;
        } else if (a == 0) {
          write(nfd, buffer, n);
        } else {
          iov[1].iov_base = buffer;
          iov[1].iov_len = n;
          writev(nfd, iov, 2);
        }
      }
    } else {
      uint8_t buffer[8192];

      const ssize_t n = obstcp_rbuf_read_fd(&rbuf, nfd, buffer, sizeof(buffer));
      if (n == 0) {
        fprintf(stderr, "  ** Remote closed\n");
        return 0;
      } else if (n < 0) {
        if (errno == EAGAIN)
          continue;
        perror("obstcp_rbuf_read_fd");
        return 1;
      } else {
        write(1, buffer, n);
      }
    }
  }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x46a0, %rsp           # imm = 0x46A0
leaq 0xac9d(%rip), %rdi      # 0xc00f
xorl %esi, %esi
movb $0x0, %al
callq 0x1170
movl %eax, -0x8(%rbp)
cmpl $0x0, -0x8(%rbp)
jge 0x139c
leaq 0xac91(%rip), %rdi      # 0xc01c
callq 0x1180
movl $0x1, -0x4(%rbp)
jmp 0x19a3
movl $0x2, %edi
movl $0x1, %esi
xorl %edx, %edx
callq 0x11d0
movl %eax, -0xc(%rbp)
cmpl $0x0, -0xc(%rbp)
jge 0x13ce
leaq 0xac6f(%rip), %rdi      # 0xc02c
callq 0x1180
movl $0x1, -0x4(%rbp)
jmp 0x19a3
leaq -0x1c(%rbp), %rdi
xorl %esi, %esi
movl $0x10, %edx
callq 0x10c0
movw $0x2, -0x1c(%rbp)
movl -0xc(%rbp), %edi
leaq -0x1c(%rbp), %rsi
movl $0x10, %edx
callq 0x1160
cmpl $0x0, %eax
je 0x1412
leaq 0xac32(%rip), %rdi      # 0xc033
callq 0x1180
movl $0x1, -0x4(%rbp)
jmp 0x19a3
movl $0x10, -0x20(%rbp)
movl -0xc(%rbp), %edi
leaq -0x1c(%rbp), %rsi
leaq -0x20(%rbp), %rdx
callq 0x11a0
cmpl $0x0, %eax
je 0x1446
leaq 0xac03(%rip), %rdi      # 0xc038
callq 0x1180
movl $0x1, -0x4(%rbp)
jmp 0x19a3
movl -0x8(%rbp), %edi
leaq -0x40(%rbp), %rsi
movl $0x20, %edx
callq 0x10f0
leaq -0x48(%rbp), %rdi
callq 0x2780
leaq -0x40(%rbp), %rsi
leaq -0x48(%rbp), %rdi
callq 0x27b0
cmpl $0x0, %eax
jne 0x148a
leaq 0xabcb(%rip), %rdi      # 0xc044
callq 0x1180
movl $0x1, -0x4(%rbp)
jmp 0x19a3
leaq -0x450(%rbp), %rax
movq %rax, -0x4690(%rbp)
movzwl -0x1a(%rbp), %edi
callq 0x1140
movq -0x4690(%rbp), %rdi
movzwl %ax, %r8d
movl $0x400, %esi            # imm = 0x400
leaq -0x48(%rbp), %rdx
movl $0x1, %ecx
xorl %r9d, %r9d
movb $0x0, %al
callq 0x1d70
movl %eax, -0x454(%rbp)
cmpl $0x0, -0x454(%rbp)
jl 0x14e2
movslq -0x454(%rbp), %rax
cmpq $0x400, %rax            # imm = 0x400
jb 0x14fa
leaq 0xab63(%rip), %rdi      # 0xc04c
callq 0x1180
movl $0x1, -0x4(%rbp)
jmp 0x19a3
movslq -0x454(%rbp), %rax
movb $0x0, -0x450(%rbp,%rax)
movq 0xdae8(%rip), %rax      # 0xeff8
movq (%rax), %rax
movq %rax, -0x4698(%rbp)
movzwl -0x1a(%rbp), %edi
callq 0x1140
movq -0x4698(%rbp), %rdi
movzwl %ax, %edx
leaq -0x450(%rbp), %rcx
leaq 0xab1f(%rip), %rsi      # 0xc05a
movb $0x0, %al
callq 0x1100
movl -0xc(%rbp), %edi
movl $0x1, %esi
callq 0x1130
cmpl $0x0, %eax
je 0x156c
leaq 0xab14(%rip), %rdi      # 0xc06f
callq 0x1180
movl $0x1, -0x4(%rbp)
jmp 0x19a3
movl -0xc(%rbp), %edi
xorl %eax, %eax
movl %eax, %edx
movq %rdx, %rsi
callq 0x1190
movl %eax, -0x458(%rbp)
cmpl $0x0, -0x458(%rbp)
jge 0x15a2
leaq 0xaae5(%rip), %rdi      # 0xc076
callq 0x1180
movl $0x1, -0x4(%rbp)
jmp 0x19a3
movl -0xc(%rbp), %edi
callq 0x10d0
movq 0xda47(%rip), %rax      # 0xeff8
movq (%rax), %rdi
leaq 0xaac2(%rip), %rsi      # 0xc07d
movb $0x0, %al
callq 0x1100
leaq -0x5f0(%rbp), %rdi
leaq -0x48(%rbp), %rsi
callq 0x2980
leaq -0x620(%rbp), %rdi
leaq -0x5f0(%rbp), %rsi
callq 0x4980
movl -0x458(%rbp), %esi
leaq -0x620(%rbp), %rdi
leaq -0x621(%rbp), %rdx
movl $0x1, %ecx
callq 0x51b0
movq %rax, -0x630(%rbp)
cmpq $0x0, -0x630(%rbp)
jge 0x1638
callq 0x1050
cmpl $0xb, (%rax)
jne 0x1620
jmp 0x1676
leaq 0xaa6b(%rip), %rdi      # 0xc092
callq 0x1180
movl $0x1, -0x4(%rbp)
jmp 0x19a3
cmpq $0x0, -0x630(%rbp)
jne 0x165c
movq 0xd9af(%rip), %rax      # 0xeff8
movq (%rax), %rdi
leaq 0xaa53(%rip), %rsi      # 0xc0a6
movb $0x0, %al
callq 0x1100
jmp 0x1672
movl $0x1, %edi
leaq -0x621(%rbp), %rsi
movl $0x1, %edx
callq 0x1080
jmp 0x1674
jmp 0x1676
leaq -0x5f0(%rbp), %rdi
callq 0x3450
cmpl $0x0, %eax
setne %al
xorb $-0x1, %al
testb $0x1, %al
jne 0x15e5
movl $0x2, %edi
callq 0x11b0
movl %eax, -0x634(%rbp)
cmpl $0x0, -0x634(%rbp)
jge 0x16c3
leaq 0xaa1d(%rip), %rdi      # 0xc0cf
callq 0x1180
movl $0x1, -0x4(%rbp)
jmp 0x19a3
leaq -0x640(%rbp), %rdi
xorl %esi, %esi
movl $0xc, %edx
callq 0x10c0
movl $0x1, -0x640(%rbp)
movl $0x0, -0x63c(%rbp)
movl -0x634(%rbp), %edi
movl $0x1, %esi
xorl %edx, %edx
leaq -0x640(%rbp), %rcx
callq 0x10e0
cmpl $0x0, %eax
je 0x1720
leaq 0xa9cd(%rip), %rdi      # 0xc0dc
callq 0x1180
movl $0x1, -0x4(%rbp)
jmp 0x19a3
movl -0x458(%rbp), %eax
movl %eax, -0x63c(%rbp)
movl -0x634(%rbp), %edi
movl -0x458(%rbp), %edx
movl $0x1, %esi
leaq -0x640(%rbp), %rcx
callq 0x10e0
cmpl $0x0, %eax
je 0x1766
leaq 0xa987(%rip), %rdi      # 0xc0dc
callq 0x1180
movl $0x1, -0x4(%rbp)
jmp 0x19a3
jmp 0x1768
movl -0x634(%rbp), %edi
leaq -0x640(%rbp), %rsi
movl $0x1, %edx
movl $0xffffffff, %ecx       # imm = 0xFFFFFFFF
callq 0x1150
cmpl $-0x1, %eax
jne 0x17a1
leaq 0xa956(%rip), %rdi      # 0xc0e6
callq 0x1180
movl $0x1, -0x4(%rbp)
jmp 0x19a3
cmpl $0x0, -0x63c(%rbp)
jne 0x1904
jmp 0x17b0
leaq -0x2640(%rbp), %rsi
xorl %edi, %edi
movl $0x2000, %edx           # imm = 0x2000
callq 0x10f0
movq %rax, -0x2648(%rbp)
xorl %eax, %eax
cmpq $-0x1, -0x2648(%rbp)
movb %al, -0x4699(%rbp)
jne 0x17ed
callq 0x1050
cmpl $0x4, (%rax)
sete %al
movb %al, -0x4699(%rbp)
movb -0x4699(%rbp), %al
testb $0x1, %al
jne 0x17b0
cmpq $0x0, -0x2648(%rbp)
jne 0x1825
movq 0xd7f0(%rip), %rax      # 0xeff8
movq (%rax), %rdi
leaq 0xa8df(%rip), %rsi      # 0xc0f1
movb $0x0, %al
callq 0x1100
movl $0x0, -0x4(%rbp)
jmp 0x19a3
cmpq $0x0, -0x2648(%rbp)
jge 0x1847
leaq 0xa8cd(%rip), %rdi      # 0xc103
callq 0x1180
movl $0x1, -0x4(%rbp)
jmp 0x19a3
leaq -0x2640(%rbp), %rsi
leaq -0x2640(%rbp), %rdx
movq -0x2648(%rbp), %rcx
leaq -0x5f0(%rbp), %rdi
callq 0x3470
leaq -0x2670(%rbp), %rsi
leaq -0x5f0(%rbp), %rdi
callq 0x34f0
movl %eax, -0x2674(%rbp)
cmpl $-0x1, -0x2674(%rbp)
jne 0x18a2
leaq 0xa885(%rip), %rdi      # 0xc116
callq 0x1180
movl $0x1, -0x4(%rbp)
jmp 0x19a3
cmpl $0x0, -0x2674(%rbp)
jne 0x18c6
movl -0x458(%rbp), %edi
leaq -0x2640(%rbp), %rsi
movq -0x2648(%rbp), %rdx
callq 0x1080
jmp 0x18f9
leaq -0x2640(%rbp), %rax
movq %rax, -0x2660(%rbp)
movq -0x2648(%rbp), %rax
movq %rax, -0x2658(%rbp)
movl -0x458(%rbp), %edi
leaq -0x2670(%rbp), %rsi
movl $0x2, %edx
callq 0x1070
jmp 0x18fb
jmp 0x18fd
jmp 0x18ff
jmp 0x199e
movl -0x458(%rbp), %esi
leaq -0x4680(%rbp), %rdx
leaq -0x620(%rbp), %rdi
movl $0x2000, %ecx           # imm = 0x2000
callq 0x51b0
movq %rax, -0x4688(%rbp)
cmpq $0x0, -0x4688(%rbp)
jne 0x1954
movq 0xd6be(%rip), %rax      # 0xeff8
movq (%rax), %rdi
leaq 0xa7e5(%rip), %rsi      # 0xc129
movb $0x0, %al
callq 0x1100
movl $0x0, -0x4(%rbp)
jmp 0x19a3
cmpq $0x0, -0x4688(%rbp)
jge 0x1982
callq 0x1050
cmpl $0xb, (%rax)
jne 0x196d
jmp 0x1768
leaq 0xa71e(%rip), %rdi      # 0xc092
callq 0x1180
movl $0x1, -0x4(%rbp)
jmp 0x19a3
leaq -0x4680(%rbp), %rsi
movq -0x4688(%rbp), %rdx
movl $0x1, %edi
callq 0x1080
jmp 0x199c
jmp 0x199e
jmp 0x1768
movl -0x4(%rbp), %eax
addq $0x46a0, %rsp           # imm = 0x46A0
popq %rbp
retq
nop