// File: Distrotech[P]stund/stun.cxx
// Function: stunOpenSocket(StunAddress4&, StunAddress4*, int, StunAddress4*, bool)
int
stunOpenSocket( StunAddress4& dest, StunAddress4* mapAddr, 
                int port, StunAddress4* srcAddr, 
                bool verbose )
{
   assert( dest.addr != 0 );
   assert( dest.port != 0 );
   assert( mapAddr );
   
   if ( port == 0 )
   {
      port = stunRandomPort();
   }
   unsigned int interfaceIp = 0;
   if ( srcAddr )
   {
      interfaceIp = srcAddr->addr;
   }
   
   Socket myFd = openPort(port,interfaceIp,verbose);
   if (myFd == INVALID_SOCKET)
   {
      return myFd;
   }
   
   char msg[STUN_MAX_MESSAGE_SIZE];
   int msgLen = sizeof(msg);
	
   StunAtrString username;
   StunAtrString password;
	
   username.sizeValue = 0;
   password.sizeValue = 0;
	
#ifdef USE_TLS
   stunGetUserNameAndPassword( dest, username, password );
#endif
	
   stunSendTest(myFd, dest, username, password, 1, 0/*false*/ );
	
   StunAddress4 from;
	
   getMessage( myFd, msg, &msgLen, &from.addr, &from.port,verbose );
	
   StunMessage resp;
   memset(&resp, 0, sizeof(StunMessage));
	
   bool ok = stunParseMessage( msg, msgLen, resp,verbose );
   if (!ok)
   {
      return -1;
   }
	
   StunAddress4 mappedAddr = resp.mappedAddress.ipv4;
   StunAddress4 changedAddr = resp.changedAddress.ipv4;
	
   //clog << "--- stunOpenSocket --- " << endl;
   //clog << "\treq  id=" << req.id << endl;
   //clog << "\tresp id=" << id << endl;
   //clog << "\tmappedAddr=" << mappedAddr << endl;
	
   *mapAddr = mappedAddr;
	
   return myFd;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0xf30, %rsp            # imm = 0xF30
movb %r8b, %al
movq %rdi, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
movl %edx, -0x1c(%rbp)
movq %rcx, -0x28(%rbp)
andb $0x1, %al
movb %al, -0x29(%rbp)
movq -0x10(%rbp), %rax
cmpl $0x0, 0x4(%rax)
je 0x87ce
jmp 0x87ed
leaq 0x2706(%rip), %rdi      # 0xaedb
leaq 0x1f79(%rip), %rsi      # 0xa755
movl $0x8ca, %edx            # imm = 0x8CA
leaq 0x2962(%rip), %rcx      # 0xb14a
callq 0x2140
movq -0x10(%rbp), %rax
movzwl (%rax), %eax
cmpl $0x0, %eax
je 0x87fb
jmp 0x881a
leaq 0x2717(%rip), %rdi      # 0xaf19
leaq 0x1f4c(%rip), %rsi      # 0xa755
movl $0x8cb, %edx            # imm = 0x8CB
leaq 0x2935(%rip), %rcx      # 0xb14a
callq 0x2140
cmpq $0x0, -0x18(%rbp)
je 0x8823
jmp 0x8842
leaq 0x296e(%rip), %rdi      # 0xb198
leaq 0x1f24(%rip), %rsi      # 0xa755
movl $0x8cc, %edx            # imm = 0x8CC
leaq 0x290d(%rip), %rcx      # 0xb14a
callq 0x2140
cmpl $0x0, -0x1c(%rbp)
jne 0x8850
callq 0x5050
movl %eax, -0x1c(%rbp)
movl $0x0, -0x30(%rbp)
cmpq $0x0, -0x28(%rbp)
je 0x8868
movq -0x28(%rbp), %rax
movl 0x4(%rax), %eax
movl %eax, -0x30(%rbp)
movl -0x1c(%rbp), %eax
movw %ax, %cx
movl -0x30(%rbp), %esi
movb -0x29(%rbp), %al
andb $0x1, %al
movzwl %cx, %edi
movzbl %al, %edx
callq 0x8e90
movl %eax, -0x34(%rbp)
cmpl $-0x1, -0x34(%rbp)
jne 0x8895
movl -0x34(%rbp), %eax
movl %eax, -0x4(%rbp)
jmp 0x8983
movl $0x800, -0x844(%rbp)    # imm = 0x800
movw $0x0, -0x846(%rbp)
movw $0x0, -0x948(%rbp)
movl -0x34(%rbp), %edi
movq -0x10(%rbp), %rsi
leaq -0x946(%rbp), %rdx
leaq -0xa48(%rbp), %rcx
movl $0x1, %r8d
xorl %r9d, %r9d
callq 0x7b70
movl -0x34(%rbp), %edi
leaq -0x840(%rbp), %rsi
leaq -0xa50(%rbp), %rcx
addq $0x4, %rcx
leaq -0xa50(%rbp), %r8
movb -0x29(%rbp), %al
leaq -0x844(%rbp), %rdx
andb $0x1, %al
movzbl %al, %r9d
callq 0x91a0
leaq -0xf18(%rbp), %rdi
xorl %esi, %esi
movl $0x4c8, %edx            # imm = 0x4C8
callq 0x2130
leaq -0x840(%rbp), %rdi
movl -0x844(%rbp), %esi
movb -0x29(%rbp), %al
leaq -0xf18(%rbp), %rdx
andb $0x1, %al
movzbl %al, %ecx
callq 0x3380
andb $0x1, %al
movb %al, -0xf19(%rbp)
testb $0x1, -0xf19(%rbp)
jne 0x8953
movl $0xffffffff, -0x4(%rbp) # imm = 0xFFFFFFFF
jmp 0x8983
movq -0xefc(%rbp), %rax
movq %rax, -0xf24(%rbp)
movq -0xec4(%rbp), %rax
movq %rax, -0xf2c(%rbp)
movq -0x18(%rbp), %rax
movq -0xf24(%rbp), %rcx
movq %rcx, (%rax)
movl -0x34(%rbp), %eax
movl %eax, -0x4(%rbp)
movl -0x4(%rbp), %eax
addq $0xf30, %rsp            # imm = 0xF30
popq %rbp
retq
nop