// File: Distrotech[P]stund/stun.cxx
// Function: stunInitServer(StunServerInfo&, StunAddress4 const&, StunAddress4 const&, int, bool)
bool
stunInitServer(StunServerInfo& info, const StunAddress4& myAddr,
               const StunAddress4& altAddr, int startMediaPort, bool verbose )
{
   assert( myAddr.port != 0 );
   assert( altAddr.port!= 0 );
   assert( myAddr.addr  != 0 );
   //assert( altAddr.addr != 0 );
	
   info.myAddr = myAddr;
   info.altAddr = altAddr;
	
   info.myFd = INVALID_SOCKET;
   info.altPortFd = INVALID_SOCKET;
   info.altIpFd = INVALID_SOCKET;
   info.altIpPortFd = INVALID_SOCKET;

   memset(info.relays, 0, sizeof(info.relays));
   if (startMediaPort > 0)
   {
      info.relay = true;

      for (int i=0; i<MAX_MEDIA_RELAYS; ++i)
      {
         StunMediaRelay* relay = &info.relays[i];
         relay->relayPort = startMediaPort+i;
         relay->fd = 0;
         relay->expireTime = 0;
      }
   }
   else
   {
      info.relay = false;
   }
   
   if ((info.myFd = openPort(myAddr.port, myAddr.addr,verbose)) == INVALID_SOCKET)
   {
      clog << "Can't open " << myAddr << endl;
      stunStopServer(info);

      return false;
   }
   //if (verbose) clog << "Opened " << myAddr.addr << ":" << myAddr.port << " --> " << info.myFd << endl;

   if ((info.altPortFd = openPort(altAddr.port,myAddr.addr,verbose)) == INVALID_SOCKET)
   {
      clog << "Can't open " << myAddr << endl;
      stunStopServer(info);
      return false;
   }
   //if (verbose) clog << "Opened " << myAddr.addr << ":" << altAddr.port << " --> " << info.altPortFd << endl;
   
   
   info.altIpFd = INVALID_SOCKET;
   if (  altAddr.addr != 0 )
   {
      if ((info.altIpFd = openPort( myAddr.port, altAddr.addr,verbose)) == INVALID_SOCKET)
      {
         clog << "Can't open " << altAddr << endl;
         stunStopServer(info);
         return false;
      }
      //if (verbose) clog << "Opened " << altAddr.addr << ":" << myAddr.port << " --> " << info.altIpFd << endl;;
   }
   
   info.altIpPortFd = INVALID_SOCKET;
   if (  altAddr.addr != 0 )
   {  if ((info.altIpPortFd = openPort(altAddr.port, altAddr.addr,verbose)) == INVALID_SOCKET)
      {
         clog << "Can't open " << altAddr << endl;
         stunStopServer(info);
         return false;
      }
      //if (verbose) clog << "Opened " << altAddr.addr << ":" << altAddr.port << " --> " << info.altIpPortFd << endl;;
   }
   
   return true;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x40, %rsp
movb %r8b, %al
movq %rdi, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
movq %rdx, -0x20(%rbp)
movl %ecx, -0x24(%rbp)
andb $0x1, %al
movb %al, -0x25(%rbp)
movq -0x18(%rbp), %rax
movzwl (%rax), %eax
cmpl $0x0, %eax
je 0x617d
jmp 0x619c
leaq 0x4bdb(%rip), %rdi      # 0xad5f
leaq 0x45ca(%rip), %rsi      # 0xa755
movl $0x4e3, %edx            # imm = 0x4E3
leaq 0x4bd9(%rip), %rcx      # 0xad70
callq 0x2140
movq -0x20(%rbp), %rax
movzwl (%rax), %eax
cmpl $0x0, %eax
je 0x61aa
jmp 0x61c9
leaq 0x4c1c(%rip), %rdi      # 0xadcd
leaq 0x459d(%rip), %rsi      # 0xa755
movl $0x4e4, %edx            # imm = 0x4E4
leaq 0x4bac(%rip), %rcx      # 0xad70
callq 0x2140
movq -0x18(%rbp), %rax
cmpl $0x0, 0x4(%rax)
je 0x61d5
jmp 0x61f4
leaq 0x4c02(%rip), %rdi      # 0xadde
leaq 0x4572(%rip), %rsi      # 0xa755
movl $0x4e5, %edx            # imm = 0x4E5
leaq 0x4b81(%rip), %rcx      # 0xad70
callq 0x2140
movq -0x18(%rbp), %rcx
movq -0x10(%rbp), %rax
movq (%rcx), %rcx
movq %rcx, (%rax)
movq -0x20(%rbp), %rcx
movq -0x10(%rbp), %rax
movq (%rcx), %rcx
movq %rcx, 0x8(%rax)
movq -0x10(%rbp), %rax
movl $0xffffffff, 0x10(%rax) # imm = 0xFFFFFFFF
movq -0x10(%rbp), %rax
movl $0xffffffff, 0x14(%rax) # imm = 0xFFFFFFFF
movq -0x10(%rbp), %rax
movl $0xffffffff, 0x18(%rax) # imm = 0xFFFFFFFF
movq -0x10(%rbp), %rax
movl $0xffffffff, 0x1c(%rax) # imm = 0xFFFFFFFF
movq -0x10(%rbp), %rdi
addq $0x28, %rdi
xorl %esi, %esi
movl $0x2ee0, %edx           # imm = 0x2EE0
callq 0x2130
cmpl $0x0, -0x24(%rbp)
jle 0x62b6
movq -0x10(%rbp), %rax
movb $0x1, 0x20(%rax)
movl $0x0, -0x2c(%rbp)
cmpl $0x1f4, -0x2c(%rbp)     # imm = 0x1F4
jge 0x62b4
movq -0x10(%rbp), %rax
addq $0x28, %rax
movslq -0x2c(%rbp), %rcx
imulq $0x18, %rcx, %rcx
addq %rcx, %rax
movq %rax, -0x38(%rbp)
movl -0x24(%rbp), %ecx
addl -0x2c(%rbp), %ecx
movq -0x38(%rbp), %rax
movl %ecx, (%rax)
movq -0x38(%rbp), %rax
movl $0x0, 0x4(%rax)
movq -0x38(%rbp), %rax
movq $0x0, 0x10(%rax)
movl -0x2c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x2c(%rbp)
jmp 0x6266
jmp 0x62be
movq -0x10(%rbp), %rax
movb $0x0, 0x20(%rax)
movq -0x18(%rbp), %rax
movw (%rax), %cx
movq -0x18(%rbp), %rax
movl 0x4(%rax), %esi
movb -0x25(%rbp), %al
andb $0x1, %al
movzwl %cx, %edi
movzbl %al, %edx
callq 0x8e90
movq -0x10(%rbp), %rcx
movl %eax, 0x10(%rcx)
cmpl $-0x1, %eax
jne 0x6328
movq 0x7cc1(%rip), %rdi      # 0xdfb0
leaq 0x4af9(%rip), %rsi      # 0xadef
callq 0x21f0
movq %rax, %rdi
movq -0x18(%rbp), %rsi
callq 0x4040
movq %rax, %rdi
movq 0x7caf(%rip), %rsi      # 0xdfc0
callq 0x2200
movq -0x10(%rbp), %rdi
callq 0x64a0
movb $0x0, -0x1(%rbp)
jmp 0x6495
movq -0x20(%rbp), %rax
movw (%rax), %cx
movq -0x18(%rbp), %rax
movl 0x4(%rax), %esi
movb -0x25(%rbp), %al
andb $0x1, %al
movzwl %cx, %edi
movzbl %al, %edx
callq 0x8e90
movq -0x10(%rbp), %rcx
movl %eax, 0x14(%rcx)
cmpl $-0x1, %eax
jne 0x6392
movq 0x7c57(%rip), %rdi      # 0xdfb0
leaq 0x4a8f(%rip), %rsi      # 0xadef
callq 0x21f0
movq %rax, %rdi
movq -0x18(%rbp), %rsi
callq 0x4040
movq %rax, %rdi
movq 0x7c45(%rip), %rsi      # 0xdfc0
callq 0x2200
movq -0x10(%rbp), %rdi
callq 0x64a0
movb $0x0, -0x1(%rbp)
jmp 0x6495
movq -0x10(%rbp), %rax
movl $0xffffffff, 0x18(%rax) # imm = 0xFFFFFFFF
movq -0x20(%rbp), %rax
cmpl $0x0, 0x4(%rax)
je 0x6413
movq -0x18(%rbp), %rax
movw (%rax), %cx
movq -0x20(%rbp), %rax
movl 0x4(%rax), %esi
movb -0x25(%rbp), %al
andb $0x1, %al
movzwl %cx, %edi
movzbl %al, %edx
callq 0x8e90
movq -0x10(%rbp), %rcx
movl %eax, 0x18(%rcx)
cmpl $-0x1, %eax
jne 0x6411
movq 0x7bd8(%rip), %rdi      # 0xdfb0
leaq 0x4a10(%rip), %rsi      # 0xadef
callq 0x21f0
movq %rax, %rdi
movq -0x20(%rbp), %rsi
callq 0x4040
movq %rax, %rdi
movq 0x7bc6(%rip), %rsi      # 0xdfc0
callq 0x2200
movq -0x10(%rbp), %rdi
callq 0x64a0
movb $0x0, -0x1(%rbp)
jmp 0x6495
jmp 0x6413
movq -0x10(%rbp), %rax
movl $0xffffffff, 0x1c(%rax) # imm = 0xFFFFFFFF
movq -0x20(%rbp), %rax
cmpl $0x0, 0x4(%rax)
je 0x6491
movq -0x20(%rbp), %rax
movw (%rax), %cx
movq -0x20(%rbp), %rax
movl 0x4(%rax), %esi
movb -0x25(%rbp), %al
andb $0x1, %al
movzwl %cx, %edi
movzbl %al, %edx
callq 0x8e90
movq -0x10(%rbp), %rcx
movl %eax, 0x1c(%rcx)
cmpl $-0x1, %eax
jne 0x648f
movq 0x7b57(%rip), %rdi      # 0xdfb0
leaq 0x498f(%rip), %rsi      # 0xadef
callq 0x21f0
movq %rax, %rdi
movq -0x20(%rbp), %rsi
callq 0x4040
movq %rax, %rdi
movq 0x7b45(%rip), %rsi      # 0xdfc0
callq 0x2200
movq -0x10(%rbp), %rdi
callq 0x64a0
movb $0x0, -0x1(%rbp)
jmp 0x6495
jmp 0x6491
movb $0x1, -0x1(%rbp)
movb -0x1(%rbp), %al
andb $0x1, %al
addq $0x40, %rsp
popq %rbp
retq