// File: /workspace/github_cpp_makefile_star2_O2/Distrotech[P]stund/stun.cxx
// Function: stunServerProcess(StunServerInfo&, bool)
bool
stunServerProcess(StunServerInfo& info, bool verbose)
{
   char msg[STUN_MAX_MESSAGE_SIZE];
   int msgLen = sizeof(msg);
   	
   bool ok = false;
   bool recvAltIp =false;
   bool recvAltPort = false;
	
   fd_set fdSet; 
   Socket maxFd=0;

   FD_ZERO(&fdSet); 
   FD_SET(info.myFd,&fdSet); 
   if ( info.myFd >= maxFd ) maxFd=info.myFd+1;
   FD_SET(info.altPortFd,&fdSet); 
   if ( info.altPortFd >= maxFd ) maxFd=info.altPortFd+1;

   if ( info.altIpFd != INVALID_SOCKET )
   {
      FD_SET(info.altIpFd,&fdSet);
      if (info.altIpFd>=maxFd) maxFd=info.altIpFd+1;
   }
   if ( info.altIpPortFd != INVALID_SOCKET )
   {
      FD_SET(info.altIpPortFd,&fdSet);
      if (info.altIpPortFd>=maxFd) maxFd=info.altIpPortFd+1;
   }

   if (info.relay)
   {
      for (int i=0; i<MAX_MEDIA_RELAYS; ++i)
      {
         StunMediaRelay* relay = &info.relays[i];
         if (relay->fd)
         {
            FD_SET(relay->fd, &fdSet);
            if (relay->fd >= maxFd) 
			{
				maxFd=relay->fd+1;
			}
         }
      }
   }
   
   if ( info.altIpFd != INVALID_SOCKET )
   {
      FD_SET(info.altIpFd,&fdSet);
      if (info.altIpFd>=maxFd) maxFd=info.altIpFd+1;
   }
   if ( info.altIpPortFd != INVALID_SOCKET )
   {
      FD_SET(info.altIpPortFd,&fdSet);
      if (info.altIpPortFd>=maxFd) maxFd=info.altIpPortFd+1;
   }
   
   struct timeval tv;
   tv.tv_sec = 0;
   tv.tv_usec = 1000;
	
   int e = select( maxFd, &fdSet, NULL,NULL, &tv );
   if (e < 0)
   {
      int err = getErrno();
      clog << "Error on select: " << strerror(err) << endl;
   }
   else if (e >= 0)
   {
      StunAddress4 from;

      // do the media relaying
      if (info.relay)
      {
         time_t now = time(0);
         for (int i=0; i<MAX_MEDIA_RELAYS; ++i)
         {
            StunMediaRelay* relay = &info.relays[i];
            if (relay->fd)
            {
               if (FD_ISSET(relay->fd, &fdSet))
               {
                  char msg[MAX_RTP_MSG_SIZE];
                  int msgLen = sizeof(msg);
                  
                  StunAddress4 rtpFrom;
                  ok = getMessage( relay->fd, msg, &msgLen, &rtpFrom.addr, &rtpFrom.port ,verbose);
                  if (ok)
                  {
                     sendMessage(info.myFd, msg, msgLen, relay->destination.addr, relay->destination.port, verbose);
                     relay->expireTime = now + MEDIA_RELAY_TIMEOUT;
                     if ( verbose ) clog << "Relay packet on " 
                                         << relay->fd 
                                         << " from " << rtpFrom 
                                         << " -> " << relay->destination 
                                         << endl;
                  }
               }
               else if (now > relay->expireTime)
               {
                  closesocket(relay->fd);
                  relay->fd = 0;
               }
            }
         }
      }
      
     
      if (FD_ISSET(info.myFd,&fdSet))
      {
         if (verbose) clog << "received on A1:P1" << endl;
         recvAltIp = false;
         recvAltPort = false;
         ok = getMessage( info.myFd, msg, &msgLen, &from.addr, &from.port,verbose );
      }
      else if (FD_ISSET(info.altPortFd, &fdSet))
      {
         if (verbose) clog << "received on A1:P2" << endl;
         recvAltIp = false;
         recvAltPort = true;
         ok = getMessage( info.altPortFd, msg, &msgLen, &from.addr, &from.port,verbose );
      }
      else if ( (info.altIpFd!=INVALID_SOCKET) && FD_ISSET(info.altIpFd,&fdSet))
      {
         if (verbose) clog << "received on A2:P1" << endl;
         recvAltIp = true;
         recvAltPort = false;
         ok = getMessage( info.altIpFd, msg, &msgLen, &from.addr, &from.port ,verbose);
      }
      else if ( (info.altIpPortFd!=INVALID_SOCKET) && FD_ISSET(info.altIpPortFd, &fdSet))
      {
         if (verbose) clog << "received on A2:P2" << endl;
         recvAltIp = true;
         recvAltPort = true;
         ok = getMessage( info.altIpPortFd, msg, &msgLen, &from.addr, &from.port,verbose );
      }
      else
      {
         return true;
      }

      int relayPort = 0;
      if (info.relay)
      {
         for (int i=0; i<MAX_MEDIA_RELAYS; ++i)
         {
            StunMediaRelay* relay = &info.relays[i];
            if (relay->destination.addr == from.addr && 
                relay->destination.port == from.port)
            {
               relayPort = relay->relayPort;
               relay->expireTime = time(0) + MEDIA_RELAY_TIMEOUT;
               break;
            }
         }

         if (relayPort == 0)
         {
            for (int i=0; i<MAX_MEDIA_RELAYS; ++i)
            {
               StunMediaRelay* relay = &info.relays[i];
               if (relay->fd == 0)
               {
                  if ( verbose ) clog << "Open relay port " << relay->relayPort << endl;
                  
                  relay->fd = openPort(relay->relayPort, info.myAddr.addr, verbose);
                  relay->destination.addr = from.addr;
                  relay->destination.port = from.port;
                  relay->expireTime = time(0) + MEDIA_RELAY_TIMEOUT;
                  relayPort = relay->relayPort;
                  break;
               }
            }
         }
      }
         
      if ( !ok ) 
      {
         if ( verbose ) clog << "Get message did not return a valid message" <<endl;
         return true;
      }
		
      if ( verbose ) clog << "Got a request (len=" << msgLen << ") from " << from << endl;
		
      if ( msgLen <= 0 )
      {
         return true;
      }
		
      bool changePort = false;
      bool changeIp = false;
		
      StunMessage resp;
      StunAddress4 dest;
      StunAtrString hmacPassword;  
      hmacPassword.sizeValue = 0;

      StunAddress4 secondary;
      secondary.port = 0;
      secondary.addr = 0;
               
      if (info.relay && relayPort)
      {
         secondary = from;
         
         from.addr = info.myAddr.addr;
         from.port = relayPort;
      }
      
      ok = stunServerProcessMsg( msg, msgLen, from, secondary,
                                 recvAltIp ? info.altAddr : info.myAddr,
                                 recvAltIp ? info.myAddr : info.altAddr, 
                                 &resp,
                                 &dest,
                                 &hmacPassword,
                                 &changePort,
                                 &changeIp,
                                 verbose );
		
      if ( !ok )
      {
         if ( verbose ) clog << "Failed to parse message" << endl;
         return true;
      }
		
      char buf[STUN_MAX_MESSAGE_SIZE];
      int len = sizeof(buf);
      		
      len = stunEncodeMessage( resp, buf, len, hmacPassword,verbose );
		
      if ( dest.addr == 0 )  ok=false;
      if ( dest.port == 0 ) ok=false;
		
      if ( ok )
      {
         assert( dest.addr != 0 );
         assert( dest.port != 0 );
			
         Socket sendFd;
			
         bool sendAltIp   = recvAltIp;   // send on the received IP address 
         bool sendAltPort = recvAltPort; // send on the received port
			
         if ( changeIp )   sendAltIp   = !sendAltIp;   // if need to change IP, then flip logic 
         if ( changePort ) sendAltPort = !sendAltPort; // if need to change port, then flip logic 
			
         if ( !sendAltPort )
         {
            if ( !sendAltIp )
            {
               sendFd = info.myFd;
            }
            else
            {
               sendFd = info.altIpFd;
            }
         }
         else
         {
            if ( !sendAltIp )
            {
               sendFd = info.altPortFd;
            }
            else
            {
               sendFd = info.altIpPortFd;
            }
         }
	
         if ( sendFd != INVALID_SOCKET )
         {
            sendMessage( sendFd, buf, len, dest.addr, dest.port, verbose );
         }
      }
   }
	
   return true;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x16b8, %rsp           # imm = 0x16B8
movl %esi, 0x8(%rsp)
movq %rdi, %r14
movl $0x800, 0x1c(%rsp)      # imm = 0x800
xorl %eax, %eax
cmpq $0x10, %rax
je 0x4dbd
andq $0x0, 0x50(%rsp,%rax,8)
incq %rax
jmp 0x4dac
movl 0x10(%r14), %esi
pushq $0x40
popq %r13
movl %esi, %eax
cltd
idivl %r13d
movslq %eax, %rdx
shll $0x6, %eax
movl %esi, %ecx
subl %eax, %ecx
pushq $0x1
popq %r10
movq %r10, %rax
shlq %cl, %rax
orq %rax, 0x50(%rsp,%rdx,8)
leal 0x1(%rsi), %eax
xorl %r8d, %r8d
testl %esi, %esi
cmovnsl %eax, %r8d
movl 0x14(%r14), %esi
movl %esi, %eax
cltd
idivl %r13d
movslq %eax, %rdx
shll $0x6, %eax
movl %esi, %ecx
subl %eax, %ecx
movq %r10, %rax
shlq %cl, %rax
orq %rax, 0x50(%rsp,%rdx,8)
leal 0x1(%rsi), %edi
cmpl %r8d, %esi
cmovll %r8d, %edi
movl 0x18(%r14), %esi
cmpl $-0x1, %esi
je 0x4e45
movl %esi, %eax
cltd
idivl %r13d
movslq %eax, %rdx
shll $0x6, %eax
movl %esi, %ecx
subl %eax, %ecx
movq %r10, %rax
shlq %cl, %rax
orq %rax, 0x50(%rsp,%rdx,8)
leal 0x1(%rsi), %eax
cmpl %edi, %esi
cmovgel %eax, %edi
movl 0x1c(%r14), %r8d
cmpl $-0x1, %r8d
je 0x4e76
movl %r8d, %eax
cltd
idivl %r13d
movslq %eax, %rdx
shll $0x6, %eax
movl %r8d, %ecx
subl %eax, %ecx
movq %r10, %rax
shlq %cl, %rax
orq %rax, 0x50(%rsp,%rdx,8)
leal 0x1(%r8), %eax
cmpl %edi, %r8d
cmovgel %eax, %edi
cmpb $0x1, 0x20(%r14)
jne 0x4ec0
pushq $0x2c
popq %r11
cmpq $0x2f0c, %r11           # imm = 0x2F0C
je 0x4ec0
movl (%r14,%r11), %r9d
testl %r9d, %r9d
je 0x4eba
movl %r9d, %eax
cltd
idivl %r13d
movslq %eax, %rdx
shll $0x6, %eax
movl %r9d, %ecx
subl %eax, %ecx
movq %r10, %rax
shlq %cl, %rax
orq %rax, 0x50(%rsp,%rdx,8)
leal 0x1(%r9), %eax
cmpl %edi, %r9d
cmovgel %eax, %edi
addq $0x18, %r11
jmp 0x4e81
cmpl $-0x1, %esi
je 0x4ee8
movl %esi, %eax
cltd
idivl %r13d
movslq %eax, %rdx
shll $0x6, %eax
movl %esi, %ecx
subl %eax, %ecx
movq %r10, %rax
shlq %cl, %rax
orq %rax, 0x50(%rsp,%rdx,8)
leal 0x1(%rsi), %eax
cmpl %edi, %esi
cmovgel %eax, %edi
cmpl $-0x1, %r8d
je 0x4f12
movl %r8d, %eax
cltd
idivl %r13d
movslq %eax, %rdx
shll $0x6, %eax
movl %r8d, %ecx
subl %eax, %ecx
shlq %cl, %r10
orq %r10, 0x50(%rsp,%rdx,8)
leal 0x1(%r8), %eax
cmpl %edi, %r8d
cmovgel %eax, %edi
leaq 0xd0(%rsp), %r8
andq $0x0, (%r8)
movq $0x3e8, 0x8(%r8)        # imm = 0x3E8
leaq 0x50(%rsp), %rsi
xorl %edx, %edx
xorl %ecx, %ecx
callq 0x21b0
testl %eax, %eax
js 0x518d
leaq 0x10(%r14), %rax
movq %rax, 0x38(%rsp)
cmpb $0x1, 0x20(%r14)
movzbl 0x8(%rsp), %ebx
movq %rbx, 0x20(%rsp)
jne 0x50c4
xorl %r12d, %r12d
xorl %edi, %edi
callq 0x2190
movq %rax, %r15
leaq 0x6b4(%rsp), %rbp
addq $0xb4, %rax
movq %rax, 0x30(%rsp)
leaq 0x30(%r14), %rax
movq %rax, 0x28(%rsp)
cmpq $0x2ee0, %r12           # imm = 0x2EE0
je 0x50c4
movl 0x2c(%r14,%r12), %edi
testl %edi, %edi
je 0x50bb
movl %edi, %eax
cltd
idivl %r13d
cltq
movq 0x50(%rsp,%rax,8), %rax
btq %rdx, %rax
jae 0x50a9
movl $0x5dc, 0x1e8(%rsp) # imm = 0x5DC
leaq 0xeb0(%rsp), %rsi
leaq 0x1e8(%rsp), %rdx
movq %rbp, %rcx
leaq 0x6b0(%rsp), %r8
movl %ebx, %r9d
callq 0x6a0e
testb %al, %al
je 0x50bb
movl 0x10(%r14), %edi
movl 0x1e8(%rsp), %edx
movl 0x34(%r14,%r12), %ecx
movzwl 0x30(%r14,%r12), %r8d
leaq 0xeb0(%rsp), %rsi
movl %ebx, %r9d
callq 0x6b66
movq 0x30(%rsp), %rax
movq %rax, 0x38(%r14,%r12)
testb %bl, %bl
je 0x50bb
movq 0x28(%rsp), %rax
leaq (%rax,%r12), %rbx
movq 0x5f86(%rip), %rdi      # 0xafb8
leaq 0x2dbf(%rip), %rsi      # 0x7df8
callq 0x21d0
movl 0x2c(%r14,%r12), %esi
movq %rax, %rdi
callq 0x22a0
movq %rax, %rdi
leaq 0x2e52(%rip), %rsi      # 0x7ea7
callq 0x21d0
movq %rbp, %r13
movq %r15, %rbp
movq %rax, %r15
movq %rax, %rdi
leaq 0x6b0(%rsp), %rsi
callq 0x3732
movq %r15, %rdi
leaq 0x2d8c(%rip), %rsi      # 0x7e09
callq 0x21d0
movq %rax, %r15
movq %rax, %rdi
movq %rbx, %rsi
movq 0x20(%rsp), %rbx
callq 0x3732
movq %r15, %rdi
movq %rbp, %r15
movq %r13, %rbp
pushq $0x40
popq %r13
callq 0x20c0
jmp 0x50bb
cmpq 0x38(%r14,%r12), %r15
jle 0x50bb
callq 0x22c0
andl $0x0, 0x2c(%r14,%r12)
addq $0x18, %r12
jmp 0x4f83
movq 0x38(%rsp), %rax
movl (%rax), %edi
movl %edi, %eax
cltd
idivl %r13d
leaq 0x14(%r14), %r15
leaq 0x18(%r14), %rsi
leaq 0x1c(%r14), %rcx
cltq
movq 0x50(%rsp,%rax,8), %rax
btq %rdx, %rax
movq %rcx, 0x28(%rsp)
movq %rsi, 0x30(%rsp)
jae 0x51bc
cmpb $0x0, 0x8(%rsp)
je 0x5121
movq 0x5eb2(%rip), %rdi      # 0xafb8
leaq 0x2d01(%rip), %rsi      # 0x7e0e
callq 0x21d0
movq %rax, %rdi
callq 0x20c0
movq 0x38(%rsp), %rax
movl (%rax), %edi
movl $0x0, 0xc(%rsp)
xorl %r12d, %r12d
leaq 0x14(%rsp), %rcx
leaq 0xeb0(%rsp), %rsi
leaq 0x1c(%rsp), %rdx
leaq 0x10(%rsp), %r8
movl %ebx, %r9d
callq 0x6a0e
movl %eax, %ebx
xorl %ebp, %ebp
cmpb $0x1, 0x20(%r14)
jne 0x52b7
movl 0x14(%rsp), %eax
pushq $0x38
popq %r13
movzwl 0x10(%rsp), %ecx
cmpq $0x2f18, %r13           # imm = 0x2F18
je 0x5228
cmpl %eax, -0x4(%r14,%r13)
jne 0x5187
cmpw %cx, -0x8(%r14,%r13)
je 0x520a
addq $0x18, %r13
jmp 0x5167
callq 0x67e9
movl %eax, %ebx
movq 0x5e1d(%rip), %rdi      # 0xafb8
leaq 0x2c44(%rip), %rsi      # 0x7de6
callq 0x21d0
movq %rax, %r14
movl %ebx, %edi
callq 0x2090
movq %r14, %rdi
movq %rax, %rsi
jmp 0x5478
movl (%r15), %edi
movl %edi, %eax
cltd
idivl %r13d
cltq
movq 0x50(%rsp,%rax,8), %rax
btq %rdx, %rax
jae 0x5499
movb $0x1, %al
movl %eax, 0xc(%rsp)
cmpb $0x0, 0x8(%rsp)
je 0x5129
movq 0x5dca(%rip), %rdi      # 0xafb8
leaq 0x2c2b(%rip), %rsi      # 0x7e20
callq 0x21d0
movq %rax, %rdi
callq 0x20c0
movl (%r15), %edi
jmp 0x5129
movl -0x10(%r14,%r13), %ebp
xorl %edi, %edi
callq 0x2190
addq $0xb4, %rax
movq %rax, (%r14,%r13)
testl %ebp, %ebp
jne 0x52b7
xorl %ebp, %ebp
xorl %eax, %eax
leaq 0x18(%rax), %r13
cmpq $0x2ef8, %r13           # imm = 0x2EF8
je 0x52b7
cmpl $0x0, 0x2c(%r14,%rax)
movq %r13, %rax
jne 0x522c
cmpb $0x0, 0x8(%rsp)
je 0x5273
movq 0x5d66(%rip), %rdi      # 0xafb8
leaq 0x2bfd(%rip), %rsi      # 0x7e56
callq 0x21d0
movl 0x10(%r14,%r13), %esi
movq %rax, %rdi
callq 0x22a0
movq %rax, %rdi
callq 0x20c0
movzwl 0x10(%r14,%r13), %edi
movl 0x4(%r14), %esi
movq 0x20(%rsp), %rdx
callq 0x67f4
movl %eax, 0x14(%r14,%r13)
movl 0x14(%rsp), %eax
movl %eax, 0x1c(%r14,%r13)
movzwl 0x10(%rsp), %eax
movw %ax, 0x18(%r14,%r13)
xorl %edi, %edi
callq 0x2190
addq $0xb4, %rax
movq %rax, 0x20(%r14,%r13)
movl 0x10(%r14,%r13), %ebp
testb %bl, %bl
je 0x544c
cmpb $0x0, 0x8(%rsp)
je 0x530c
movq 0x5ceb(%rip), %rdi      # 0xafb8
leaq 0x2bbe(%rip), %rsi      # 0x7e92
callq 0x21d0
movl 0x1c(%rsp), %esi
movq %rax, %rdi
callq 0x22a0
leaq 0x2bba(%rip), %rsi      # 0x7ea6
movq %rax, %rdi
callq 0x21d0
movq %rax, %rbx
leaq 0x10(%rsp), %rsi
movq %rax, %rdi
callq 0x3732
movq %rbx, %rdi
callq 0x20c0
movl 0x1c(%rsp), %esi
testl %esi, %esi
jle 0x5485
andw $0x0, 0x1e6(%rsp)
andw $0x0, 0x40(%rsp)
xorl %eax, %eax
andl $0x0, 0x44(%rsp)
movb %al, 0x7(%rsp)
movb %al, 0x6(%rsp)
cmpb $0x1, 0x20(%r14)
jne 0x5358
testl %ebp, %ebp
je 0x5358
movq 0x10(%rsp), %rax
movq %rax, 0x40(%rsp)
movl 0x4(%r14), %eax
movl %eax, 0x14(%rsp)
movw %bp, 0x10(%rsp)
leaq 0x8(%r14), %r9
testb %r12b, %r12b
movq %r14, %r8
cmovneq %r9, %r8
cmovneq %r14, %r9
leaq 0x6(%rsp), %rax
leaq 0x7(%rsp), %r10
leaq 0xe6(%rsp), %r11
leaq 0x48(%rsp), %rbx
leaq 0x1e8(%rsp), %r14
leaq 0xeb0(%rsp), %rdi
leaq 0x10(%rsp), %rdx
leaq 0x40(%rsp), %rcx
movq 0x20(%rsp), %r13
pushq %r13
pushq %rax
pushq %r10
pushq %r11
pushq %rbx
pushq %r14
callq 0x4424
addq $0x30, %rsp
testb %al, %al
je 0x5463
leaq 0x1e8(%rsp), %rdi
leaq 0x6b0(%rsp), %rsi
leaq 0xe6(%rsp), %rcx
movl $0x800, %edx            # imm = 0x800
movl %r13d, %r8d
callq 0x3849
movl 0x4c(%rsp), %ecx
testl %ecx, %ecx
setne %sil
movzwl 0x48(%rsp), %edx
testw %dx, %dx
setne %dil
andb %sil, %dil
cmpb $0x1, %dil
jne 0x5485
xorb 0x6(%rsp), %r12b
movl 0xc(%rsp), %edi
xorb 0x7(%rsp), %dil
testb %r12b, %r12b
movq 0x38(%rsp), %rsi
cmovneq 0x30(%rsp), %rsi
cmovneq 0x28(%rsp), %r15
testb %dil, %dil
cmoveq %rsi, %r15
movl (%r15), %edi
cmpl $-0x1, %edi
je 0x5485
movzwl %dx, %r8d
leaq 0x6b0(%rsp), %rsi
movl %eax, %edx
movl %r13d, %r9d
callq 0x6b66
jmp 0x5485
cmpb $0x0, 0x8(%rsp)
je 0x5485
movq 0x5b5e(%rip), %rdi      # 0xafb8
leaq 0x2a06(%rip), %rsi      # 0x7e67
jmp 0x5478
cmpb $0x0, 0x8(%rsp)
je 0x5485
movq 0x5b47(%rip), %rdi      # 0xafb8
leaq 0x2a36(%rip), %rsi      # 0x7eae
callq 0x21d0
movq %rax, %rdi
callq 0x20c0
movb $0x1, %al
addq $0x16b8, %rsp           # imm = 0x16B8
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movl (%rsi), %edi
cmpl $-0x1, %edi
je 0x54ec
movl %edi, %eax
cltd
idivl %r13d
cltq
movq 0x50(%rsp,%rax,8), %rax
btq %rdx, %rax
jae 0x54ec
movb $0x1, %r12b
cmpb $0x0, 0x8(%rsp)
je 0x54df
movq 0x5af4(%rip), %rdi      # 0xafb8
leaq 0x2967(%rip), %rsi      # 0x7e32
callq 0x21d0
movq %rax, %rdi
callq 0x20c0
movq 0x30(%rsp), %rax
movl (%rax), %edi
movl $0x0, 0xc(%rsp)
jmp 0x512c
movl (%rcx), %edi
cmpl $-0x1, %edi
je 0x5485
movl %edi, %eax
cltd
idivl %r13d
cltq
movq 0x50(%rsp,%rax,8), %rax
btq %rdx, %rax
jae 0x5485
movb $0x1, %al
movl %eax, 0xc(%rsp)
cmpb $0x0, 0x8(%rsp)
je 0x5539
movq 0x5a9a(%rip), %rdi      # 0xafb8
leaq 0x291f(%rip), %rsi      # 0x7e44
callq 0x21d0
movq %rax, %rdi
callq 0x20c0
movq 0x28(%rsp), %rax
movl (%rax), %edi
movb $0x1, %r12b
movq 0x20(%rsp), %rbx
jmp 0x512c