// File: /workspace/github_c_makefile_star2_O1/sfeakes[P]unifi-motion/mongoose.c
// Function: mg_tun_client_handler
static void mg_tun_client_handler(struct mg_connection *nc, int ev,
                                  void *ev_data MG_UD_ARG(void *user_data)) {
#if !MG_ENABLE_CALLBACK_USERDATA
  void *user_data = nc->user_data;
#else
  (void) nc;
#endif
  struct mg_tun_client *client = (struct mg_tun_client *) user_data;

  switch (ev) {
    case MG_EV_CONNECT: {
      int err = *(int *) ev_data;

      if (err) {
        LOG(LL_ERROR, ("Cannot connect to the tunnel dispatcher: %d", err));
      } else {
        LOG(LL_INFO, ("Connected to the tunnel dispatcher"));
      }
      break;
    }
    case MG_EV_HTTP_REPLY: {
      struct http_message *hm = (struct http_message *) ev_data;

      if (hm->resp_code != 200) {
        LOG(LL_ERROR,
            ("Tunnel dispatcher reply non-OK status code %d", hm->resp_code));
      }
      break;
    }
    case MG_EV_WEBSOCKET_HANDSHAKE_DONE: {
      LOG(LL_INFO, ("Tunnel dispatcher handshake done"));
      break;
    }
    case MG_EV_WEBSOCKET_FRAME: {
      struct websocket_message *wm = (struct websocket_message *) ev_data;
      struct mg_connection *tc;
      struct mg_tun_frame frame;

      if (mg_tun_parse_frame(wm->data, wm->size, &frame) == -1) {
        LOG(LL_ERROR, ("Got invalid tun frame dropping"));
        break;
      }

      mg_tun_log_frame(&frame);

      tc = mg_tun_if_find_conn(client, frame.stream_id);
      if (tc == NULL) {
        if (frame.body.len > 0) {
          LOG(LL_DEBUG, ("Got frame after receiving end has been closed"));
        }
        break;
      }
      if (frame.body.len > 0) {
        mg_if_recv_tcp_cb(tc, (void *) frame.body.p, frame.body.len,
                          0 /* own */);
      }
      if (frame.flags & MG_TUN_F_END_STREAM) {
        LOG(LL_DEBUG, ("Closing tunneled connection because got end of stream "
                       "from other end"));
        tc->flags |= MG_F_CLOSE_IMMEDIATELY;
        mg_close_conn(tc);
      }
      break;
    }
    case MG_EV_CLOSE: {
      LOG(LL_DEBUG, ("Closing all tunneled connections"));
      /*
       * The client might have been already freed when the listening socket is
       * closed.
       */
      if (client != NULL) {
        mg_tun_close_all(client);
        client->disp = NULL;
        LOG(LL_INFO, ("Dispatcher connection is no more, reconnecting"));
        /* TODO(mkm): implement exp back off */
        mg_tun_reconnect(client, MG_TUN_RECONNECT_INTERVAL);
      }
      break;
    }
    default:
      break;
  }
}

// Assembly:
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x20, %rsp
movq %rdx, %r14
movq 0xa0(%rdi), %rbx
cmpl $0x64, %esi
jle 0x1400d
cmpl $0x65, %esi
je 0x14106
cmpl $0x70, %esi
je 0x1413e
cmpl $0x71, %esi
jne 0x142b0
movq 0x8(%r14), %rax
cmpq $0x6, %rax
jae 0x141af
leaq 0x37b5(%rip), %rsi      # 0x17799
leaq 0x15bf(%rip), %rdx      # 0x155aa
xorl %edi, %edi
callq 0x44b4
testl %eax, %eax
je 0x142b0
leaq 0x384c(%rip), %rdi      # 0x1784d
xorl %eax, %eax
callq 0x45a0
jmp 0x142b0
cmpl $0x2, %esi
je 0x1416a
cmpl $0x5, %esi
jne 0x142b0
leaq 0x3773(%rip), %rsi      # 0x17799
leaq 0x157d(%rip), %rdx      # 0x155aa
movl $0x3, %edi
callq 0x44b4
testl %eax, %eax
je 0x14049
leaq 0x389d(%rip), %rdi      # 0x178df
xorl %eax, %eax
callq 0x45a0
testq %rbx, %rbx
je 0x142b0
movq (%rbx), %rax
movq (%rax), %r14
testq %r14, %r14
je 0x140ba
leaq 0x38cb(%rip), %r15      # 0x1792f
leaq 0x153f(%rip), %r12      # 0x155aa
leaq 0x38ce(%rip), %r13      # 0x17940
movq 0xc0(%r14), %rax
cmpq 0x8(%rbx), %rax
jne 0x140b2
testb $0x1, 0xc8(%r14)
jne 0x140b2
movl $0x3, %edi
movq %r15, %rsi
movq %r12, %rdx
callq 0x44b4
testl %eax, %eax
je 0x140aa
movq %r13, %rdi
movq %r14, %rsi
xorl %eax, %eax
callq 0x45a0
orb $0x8, 0xc9(%r14)
movq (%r14), %r14
testq %r14, %r14
jne 0x14072
movq $0x0, 0x20(%rbx)
leaq 0x36d0(%rip), %rsi      # 0x17799
leaq 0x14da(%rip), %rdx      # 0x155aa
movl $0x2, %edi
callq 0x44b4
testl %eax, %eax
je 0x140ec
leaq 0x381b(%rip), %rdi      # 0x17900
xorl %eax, %eax
callq 0x45a0
movq %rbx, %rdi
movl $0x1, %esi
addq $0x20, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
jmp 0x12a75
cmpl $0xc8, 0x50(%r14)
je 0x142b0
leaq 0x367e(%rip), %rsi      # 0x17799
leaq 0x1488(%rip), %rdx      # 0x155aa
xorl %edi, %edi
callq 0x44b4
testl %eax, %eax
je 0x142b0
movl 0x50(%r14), %esi
leaq 0x36c2(%rip), %rdi      # 0x177fe
jmp 0x1419b
leaq 0x3654(%rip), %rsi      # 0x17799
leaq 0x145e(%rip), %rdx      # 0x155aa
movl $0x2, %edi
callq 0x44b4
testl %eax, %eax
je 0x142b0
leaq 0x36c7(%rip), %rdi      # 0x1782c
jmp 0x1426f
movl (%r14), %ebx
leaq 0x3625(%rip), %rsi      # 0x17799
leaq 0x142f(%rip), %rdx      # 0x155aa
testl %ebx, %ebx
je 0x1425a
xorl %edi, %edi
callq 0x44b4
testl %eax, %eax
je 0x142b0
leaq 0x3616(%rip), %rdi      # 0x177af
movl %ebx, %esi
xorl %eax, %eax
addq $0x20, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
jmp 0x45a0
movq (%r14), %rcx
movb (%rcx), %dl
leaq 0x8(%rsp), %r14
movb %dl, (%r14)
movb 0x1(%rcx), %dl
movb %dl, 0x1(%r14)
movl 0x2(%rcx), %edx
bswapl %edx
movl %edx, 0x4(%r14)
addq $0x6, %rcx
movq %rcx, 0x8(%r14)
addq $-0x6, %rax
movq %rax, 0x10(%r14)
movq %r14, %rdi
callq 0x1291a
movl 0x4(%r14), %esi
movq %rbx, %rdi
callq 0xad35
movq 0x10(%r14), %rdx
testq %rax, %rax
je 0x14283
movq %rax, %rbx
testq %rdx, %rdx
je 0x14214
movq 0x10(%rsp), %rsi
movq %rbx, %rdi
xorl %ecx, %ecx
callq 0x85c4
testb $0x1, 0x9(%rsp)
je 0x142b0
leaq 0x3573(%rip), %rsi      # 0x17799
leaq 0x137d(%rip), %rdx      # 0x155aa
movl $0x3, %edi
callq 0x44b4
testl %eax, %eax
je 0x14249
leaq 0x3658(%rip), %rdi      # 0x1789a
xorl %eax, %eax
callq 0x45a0
orb $0x8, 0xc9(%rbx)
movq %rbx, %rdi
callq 0x7f83
jmp 0x142b0
movl $0x2, %edi
callq 0x44b4
testl %eax, %eax
je 0x142b0
leaq 0x356c(%rip), %rdi      # 0x177db
xorl %eax, %eax
addq $0x20, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
jmp 0x45a0
testq %rdx, %rdx
je 0x142b0
leaq 0x350a(%rip), %rsi      # 0x17799
leaq 0x1314(%rip), %rdx      # 0x155aa
movl $0x3, %edi
callq 0x44b4
testl %eax, %eax
je 0x142b0
leaq 0x35c1(%rip), %rdi      # 0x1786c
jmp 0x14001
addq $0x20, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
retq
nop