// File: xocoder[P]m_kcptun/vendor/m_net/src/mnet_core.c
// Function: mnet_chann_send
int
mnet_chann_send(chann_t *n, void *buf, int len) {
   if (n && buf && len>0 && n->state>=CHANN_STATE_CONNECTED) {
      int ret = len;
      rwb_head_t *prh = &n->rwb_send;

      if (_rwb_count(prh) > 0) {
         _rwb_cache(prh, (unsigned char*)buf, len);
         mm_log(n, MNET_LOG_VERBOSE, "chann %p fd:%d still cache %d(%d)!\n",
                n, n->fd, _rwb_buffered(prh->tail), _rwb_count(prh));
      } else {
         ret = _chann_send(n, buf, len);
         do {
            if (ret < 0) {
               if (errno == EWOULDBLOCK) {
                  ret = 0;
               } else {
                  mnet_t *ss = _gmnet();
                  mm_log(n, MNET_LOG_ERR, "chann %p fd:%d, send errno %d:%s\n",
                         n, n->fd, errno, strerror(errno));
                  _chann_disconnect_socket(ss, n);
                  _chann_msg(n, CHANN_EVENT_DISCONNECT, NULL, errno);
                  break;
               }
            }
            if (ret < len) {
               mm_log(n, MNET_LOG_VERBOSE, "chann %p fd:%d cache %d of %d!\n", n, n->fd, len - ret, len);
               _rwb_cache(prh, ((unsigned char*)buf) + ret, len - ret);
               ret = len;
               _evt_add(n, MNET_SET_WRITE);
            }
         } while (0);
      }
      return ret;
   }
   return -1;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x70, %rsp
movq %rdi, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
movl %edx, -0x1c(%rbp)
cmpq $0x0, -0x10(%rbp)
je 0x7f74
cmpq $0x0, -0x18(%rbp)
je 0x7f74
cmpl $0x0, -0x1c(%rbp)
jle 0x7f74
movq -0x10(%rbp), %rax
cmpl $0x3, 0x10(%rax)
jl 0x7f74
movl -0x1c(%rbp), %eax
movl %eax, -0x20(%rbp)
movq -0x10(%rbp), %rax
addq $0x38, %rax
movq %rax, -0x28(%rbp)
movq -0x28(%rbp), %rdi
callq 0x7f90
cmpl $0x0, %eax
jle 0x7e3e
movq -0x28(%rbp), %rdi
movq -0x18(%rbp), %rsi
movl -0x1c(%rbp), %edx
callq 0x7fb0
movq -0x10(%rbp), %rax
movq %rax, -0x48(%rbp)
movq -0x10(%rbp), %rax
movq %rax, -0x40(%rbp)
movq -0x10(%rbp), %rax
movl (%rax), %eax
movl %eax, -0x38(%rbp)
movq -0x28(%rbp), %rax
movq 0x8(%rax), %rdi
callq 0x8050
movl %eax, -0x34(%rbp)
movq -0x28(%rbp), %rdi
callq 0x7f90
movq -0x48(%rbp), %rdi
movq -0x40(%rbp), %rcx
movl -0x38(%rbp), %r8d
movl -0x34(%rbp), %r9d
movl $0x3, %esi
leaq 0xb4c7(%rip), %rdx      # 0x132f6
movl %eax, (%rsp)
movb $0x0, %al
callq 0x6c30
jmp 0x7f6c
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rsi
movl -0x1c(%rbp), %edx
callq 0x8080
movl %eax, -0x20(%rbp)
cmpl $0x0, -0x20(%rbp)
jge 0x7f02
callq 0x3040
cmpl $0xb, (%rax)
jne 0x7e71
movl $0x0, -0x20(%rbp)
jmp 0x7f00
callq 0x67b0
movq %rax, -0x30(%rbp)
movq -0x10(%rbp), %rax
movq %rax, -0x68(%rbp)
movq -0x10(%rbp), %rax
movq %rax, -0x60(%rbp)
movq -0x10(%rbp), %rax
movl (%rax), %eax
movl %eax, -0x58(%rbp)
callq 0x3040
movl (%rax), %eax
movl %eax, -0x54(%rbp)
callq 0x3040
movl (%rax), %edi
callq 0x3110
movq -0x68(%rbp), %rdi
movq -0x60(%rbp), %rcx
movl -0x58(%rbp), %r8d
movl -0x54(%rbp), %r9d
movl $0x1, %esi
leaq 0xb455(%rip), %rdx      # 0x1331a
movq %rax, (%rsp)
movb $0x0, %al
callq 0x6c30
movq -0x30(%rbp), %rdi
movq -0x10(%rbp), %rsi
callq 0x6940
movq -0x10(%rbp), %rax
movq %rax, -0x50(%rbp)
callq 0x3040
movq -0x50(%rbp), %rdi
movl (%rax), %ecx
movl $0x5, %esi
xorl %eax, %eax
movl %eax, %edx
callq 0x7cf0
jmp 0x7f6a
jmp 0x7f02
movl -0x20(%rbp), %eax
cmpl -0x1c(%rbp), %eax
jge 0x7f68
movq -0x10(%rbp), %rdi
movq -0x10(%rbp), %rcx
movq -0x10(%rbp), %rax
movl (%rax), %r8d
movl -0x1c(%rbp), %r9d
subl -0x20(%rbp), %r9d
movl -0x1c(%rbp), %eax
movl $0x3, %esi
leaq 0xb40c(%rip), %rdx      # 0x1333c
movl %eax, (%rsp)
movb $0x0, %al
callq 0x6c30
movq -0x28(%rbp), %rdi
movq -0x18(%rbp), %rsi
movslq -0x20(%rbp), %rax
addq %rax, %rsi
movl -0x1c(%rbp), %edx
subl -0x20(%rbp), %edx
callq 0x7fb0
movl -0x1c(%rbp), %eax
movl %eax, -0x20(%rbp)
movq -0x10(%rbp), %rdi
movl $0x1, %esi
callq 0x76d0
jmp 0x7f6a
jmp 0x7f6c
movl -0x20(%rbp), %eax
movl %eax, -0x4(%rbp)
jmp 0x7f7b
movl $0xffffffff, -0x4(%rbp) # imm = 0xFFFFFFFF
movl -0x4(%rbp), %eax
addq $0x70, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)