< Previous by Date Date Index Next by Date >
< Previous in Thread Thread Index Next in Thread >

Re: [reSIProcate] STUN Error


By the way, if make the call without STUN, then all are ok.


 
2008/1/13, Karlsson <boost.regex@xxxxxxxxx>:
Hi all, I try to implement the STUN, but now I got a matter.
As I read the WIKI, I wrote some code for my UA, now the UA can be used the STUN to register to server,
but when I make a call, I got a assert error:
 
TransportSelector::transmit, line 587
 
               assert((source.getPort()==temp.getPort() ||
                       temp.getPort()==0) &&
                        source.ipVersion()==temp.ipVersion() &&
                        source.getType()==temp.getType());
 
 
 
The attachment is SIP message log and there are my source code, please help me to solve this problem.
 
Thanks
 
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

bool UserAgent::addUDPPort(int port, bool enableSTUN)
{
 bool state = true;

 try
 {
  mUDPTransport = (resip::UdpTransport*)mStack.addTransport(UDP, port, V4, StunEnabled);
 }
 catch(const Transport::Exception& e)
 {
  state = false;
 }

 return state; 
}

void UserAgent::sendStunTest()
{
 if (!mUDPTransport)
 {
  return;
 }

 hostent* h = gethostbyname(mStunServer.c_str());
 if (!h)
 {
  return;
 }

 in_addr sin_addr = *(struct in_addr*)h->h_addr;
 resip::Tuple tStunDest(sin_addr, 3478, UDP, Data::Empty);

 mUDPTransport->stunSendTest(tStunDest);

 mLastStunTestTime = GetTickCount();
}


resip::Tuple UserAgent::getStunAddress()
{
 resip::Tuple mappedAddress;

 mappedAddress.setPort(0);

 if (!mUDPTransport)
 {
  return mappedAddress;
 }

 if (!mUDPTransport->stunResult(mappedAddress))
 {
  // no valid result available, send another request


  sendStunTest();
 }

 else if ((GetTickCount() - mLastStunTestTime) > 1000 * 60 * 3)
 {
  // don't use a STUN response that is older than 3 minutes
  sendStunTest();
 }

 DWORD tmpLastStunTestTime = mLastStunTestTime;

 while ((GetTickCount() - tmpLastStunTestTime) < 5 * 1000) // wait 5s for result
 {
  if (mUDPTransport->stunResult(mappedAddress))
  {
   break;
  }

  Sleep(200);
 }

 mLastStunTestTime = 0;

 return mappedAddress;
}

 

void UserAgent::stunTest(const Data & stunServer, int stunPort)
{
 mStunServer = stunServer;
 mStunPort = stunPort;

 if (stunServer.empty() == true)
 {
  return;
 }

 string ip;
 int port;
 Utility utility;

 string emptyIP = "0.0.0.0";


 for (int i=0; i<3; ++i)
 {
  Tuple mapAddress = getStunAddress();
  ip = Tuple::inet_ntop(mapAddress).c_str();
  port = mapAddress.getPort();

  if (utility.compareStringNoCase(ip, emptyIP) != 0)
  {
   break;
  }
 }

 if (utility.compareStringNoCase(ip, emptyIP) == 0)
 {
  return;
 }

 

 Data newUri = "sip:";
 newUri += ip.c_str();
 newUri += ":";
 Data temPort(port);
 newUri += temPort;

 Uri stunUri(newUri);


 mMasterProfile->setOverrideHostAndPort(stunUri);

 StunMessageDecorator * stunMessageDec = new StunMessageDecorator;
 stunMessageDec->setStunResult(ip, port);

 SharedPtr<MessageDecorator> messageDec((MessageDecorator *)stunMessageDec);

 mMasterProfile->setOutboundDecorator(messageDec);
 
}

 

void StunMessageDecorator::decorateMessage(SipMessage &msg, const Tuple &source, const Tuple &destination)
{
 if (mStunPort!=0 && mStunIP.empty()==false)
 {
 Utility utility;

  ParserContainer<Via>::iterator viaIter = msg.header(h_Vias).begin();
  for (; viaIter!=msg.header(h_Vias).end(); ++viaIter)
  {
   string srcIP = Tuple::inet_ntop(source).c_str();
   string viaIP = msg.header(h_Vias).front().sentHost().c_str();

   if (utility.compareStringNoCase(srcIP, viaIP) == 0)
   {
    msg.header(h_Vias).front().sentPort() = mStunPort;
    msg.header(h_Vias).front().sentHost() = mStunIP.c_str();
   }
  }
 }

}