⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 transports.cxx

📁 sloedgy open sip stack source code
💻 CXX
📖 第 1 页 / 共 5 页
字号:
 * Updated to OpenH323 v1.9.1
 *
 * Revision 2.16  2002/06/16 23:07:19  robertj
 * Fixed several memory leaks, thanks Ted Szoczei
 * Fixed error opening UDP listener for broadcast packets under Win32.
 *   Is not needed as it is under windows, thanks Ted Szoczei
 *
 * Revision 2.15  2002/04/16 07:52:51  robertj
 * Change to allow SetRemoteAddress before UDP is connected.
 *
 * Revision 2.14  2002/04/10 03:12:35  robertj
 * Fixed SetLocalAddress to return FALSE if did not set the address to a
 *   different address to the current one. Altered UDP version to cope.
 *
 * Revision 2.13  2002/04/09 04:44:36  robertj
 * Fixed bug where crahses if close channel while in UDP connect mode.
 *
 * Revision 2.12  2002/04/09 00:22:16  robertj
 * Added ability to set the local address on a transport, under some circumstances.
 *
 * Revision 2.11  2002/03/27 05:37:39  robertj
 * Fixed removal of writeChannel after wrinting to UDP transport in connect mode.
 *
 * Revision 2.10  2002/03/15 00:20:54  robertj
 * Fixed bug when closing UDP transport when in "connect" mode.
 *
 * Revision 2.9  2002/02/06 06:07:10  robertj
 * Fixed shutting down UDP listener thread
 *
 * Revision 2.8  2002/01/14 00:19:33  craigs
 * Fixed problems with remote address used instead of local address
 *
 * Revision 2.7  2001/12/07 08:55:32  robertj
 * Used UDP port base when creating UDP transport.
 *
 * Revision 2.6  2001/11/14 06:28:20  robertj
 * Added missing break when ending UDP connect phase.
 *
 * Revision 2.5  2001/11/13 04:29:48  robertj
 * Changed OpalTransportAddress CreateTransport and CreateListsner functions
 *   to have extra parameter to control local binding of sockets.
 *
 * Revision 2.4  2001/11/12 05:31:36  robertj
 * Changed CreateTransport() on an OpalTransportAddress to bind to local address.
 * Added OpalTransportAddress::GetIpAddress when don't need port number.
 *
 * Revision 2.3  2001/11/09 05:49:47  robertj
 * Abstracted UDP connection algorithm
 *
 * Revision 2.2  2001/11/06 05:40:13  robertj
 * Added OpalListenerUDP class to do listener semantics on a UDP socket.
 *
 * Revision 2.1  2001/10/03 05:53:25  robertj
 * Update to new PTLib channel error system.
 *
 * Revision 2.0  2001/07/27 15:48:25  robertj
 * Conversion of OpenH323 to Open Phone Abstraction Library (OPAL)
 *
 */

#include <ptlib.h>

#ifdef __GNUC__
#pragma implementation "transports.h"
#endif

#include <opal/transports.h>

#include <opal/manager.h>
#include <opal/endpoint.h>
#include <opal/call.h>

#include <ptclib/pstun.h>


static const char IpPrefix[] = "ip$"; // For backward compatibility with OpenH323
static const char TcpPrefix[] = "tcp$";
static const char UdpPrefix[] = "udp$";

#include <ptclib/pstun.h>


////////////////////////////////////////////////////////////////

class OpalInternalTransport : public PObject
{
    PCLASSINFO(OpalInternalTransport, PObject);
  public:
    virtual PString GetHostName(
      const OpalTransportAddress & address
    ) const;

    virtual BOOL GetIpAndPort(
      const OpalTransportAddress & address,
      PIPSocket::Address & ip,
      WORD & port
    ) const;

    virtual OpalListener * CreateListener(
      const OpalTransportAddress & address,
      OpalEndPoint & endpoint,
      OpalTransportAddress::BindOptions options
    ) const  = 0;

    virtual OpalTransport * CreateTransport(
      const OpalTransportAddress & address,
      OpalEndPoint & endpoint,
      OpalTransportAddress::BindOptions options
    ) const = 0;
};


////////////////////////////////////////////////////////////////

class OpalInternalIPTransport : public OpalInternalTransport
{
    PCLASSINFO(OpalInternalIPTransport, OpalInternalTransport);
  public:
    virtual PString GetHostName(
      const OpalTransportAddress & address
    ) const;
    virtual BOOL GetIpAndPort(
      const OpalTransportAddress & address,
      PIPSocket::Address & ip,
      WORD & port
    ) const;
};


////////////////////////////////////////////////////////////////

static class OpalInternalTCPTransport : public OpalInternalIPTransport
{
    PCLASSINFO(OpalInternalTCPTransport, OpalInternalIPTransport);
  public:
    virtual OpalListener * CreateListener(
      const OpalTransportAddress & address,
      OpalEndPoint & endpoint,
      OpalTransportAddress::BindOptions options
    ) const;
    virtual OpalTransport * CreateTransport(
      const OpalTransportAddress & address,
      OpalEndPoint & endpoint,
      OpalTransportAddress::BindOptions options
    ) const;
} internalTCPTransport;


////////////////////////////////////////////////////////////////

static class OpalInternalUDPTransport : public OpalInternalIPTransport
{
    PCLASSINFO(OpalInternalUDPTransport, OpalInternalIPTransport);
  public:
    virtual OpalListener * CreateListener(
      const OpalTransportAddress & address,
      OpalEndPoint & endpoint,
      OpalTransportAddress::BindOptions options
    ) const;
    virtual OpalTransport * CreateTransport(
      const OpalTransportAddress & address,
      OpalEndPoint & endpoint,
      OpalTransportAddress::BindOptions options
    ) const;
} internalUDPTransport;


/////////////////////////////////////////////////////////////////

#define new PNEW


/////////////////////////////////////////////////////////////////

OpalTransportAddress::OpalTransportAddress()
{
  transport = NULL;
}


OpalTransportAddress::OpalTransportAddress(const char * cstr,
                                           WORD port,
                                           const char * proto)
  : PString(cstr)
{
  SetInternalTransport(port, proto);
}


OpalTransportAddress::OpalTransportAddress(const PString & str,
                                           WORD port,
                                           const char * proto)
  : PString(str)
{
  SetInternalTransport(port, proto);
}


OpalTransportAddress::OpalTransportAddress(const PIPSocket::Address & addr, WORD port, const char * proto)
  : PString(addr.AsString())
{
  SetInternalTransport(port, proto);
}


PString OpalTransportAddress::GetHostName() const
{
  if (transport == NULL)
    return PString();

  return transport->GetHostName(*this);
}
  

BOOL OpalTransportAddress::IsEquivalent(const OpalTransportAddress & address)
{
  if (*this == address)
    return TRUE;

  if (IsEmpty() || address.IsEmpty())
    return FALSE;

  PIPSocket::Address ip1, ip2;
  WORD port1 = 65535, port2 = 65535;
  return GetIpAndPort(ip1, port1) &&
         address.GetIpAndPort(ip2, port2) &&
         (ip1.IsAny() || ip2.IsAny() || (ip1 *= ip2)) &&
         (port1 == 65535 || port2 == 65535 || port1 == port2);
}


BOOL OpalTransportAddress::GetIpAddress(PIPSocket::Address & ip) const
{
  if (transport == NULL)
    return FALSE;

  WORD dummy = 65535;
  return transport->GetIpAndPort(*this, ip, dummy);
}


BOOL OpalTransportAddress::GetIpAndPort(PIPSocket::Address & ip, WORD & port) const
{
  if (transport == NULL)
    return FALSE;

  return transport->GetIpAndPort(*this, ip, port);
}


OpalListener * OpalTransportAddress::CreateListener(OpalEndPoint & endpoint,
                                                    BindOptions option) const
{
  if (transport == NULL)
    return NULL;

  return transport->CreateListener(*this, endpoint, option);
}


OpalTransport * OpalTransportAddress::CreateTransport(OpalEndPoint & endpoint,
                                                      BindOptions option) const
{
  if (transport == NULL)
    return NULL;

  return transport->CreateTransport(*this, endpoint, option);
}


void OpalTransportAddress::SetInternalTransport(WORD port, const char * proto)
{
  transport = NULL;
  
  if (IsEmpty())
    return;

  PINDEX dollar = Find('$');
  if (dollar == P_MAX_INDEX) {
    PString prefix(proto == NULL ? TcpPrefix : proto);
    if (prefix.Find('$') == P_MAX_INDEX)
      prefix += '$';

    Splice(prefix, 0);
    dollar = prefix.GetLength()-1;
  }

  PCaselessString type = Left(dollar+1);

  // look for known transport types, note that "ip$" == "tcp$"
  if ((type == IpPrefix) || (type == TcpPrefix))
    transport = &internalTCPTransport;
  else if (type == UdpPrefix)
    transport = &internalUDPTransport;
  else
    return;

  if (port != 0 && Find(':', dollar) == P_MAX_INDEX)
    sprintf(":%u", port);
}


/////////////////////////////////////////////////////////////////

void OpalTransportAddressArray::AppendString(const char * str)
{
  AppendAddress(OpalTransportAddress(str));
}


void OpalTransportAddressArray::AppendString(const PString & str)
{
  AppendAddress(OpalTransportAddress(str));
}


void OpalTransportAddressArray::AppendAddress(const OpalTransportAddress & addr)
{
  if (!addr)
    Append(new OpalTransportAddress(addr));
}


void OpalTransportAddressArray::AppendStringCollection(const PCollection & coll)
{
  for (PINDEX i = 0; i < coll.GetSize(); i++) {
    PObject * obj = coll.GetAt(i);
    if (obj != NULL && PIsDescendant(obj, PString))
      AppendAddress(OpalTransportAddress(*(PString *)obj));
  }
}


/////////////////////////////////////////////////////////////////

PString OpalInternalTransport::GetHostName(const OpalTransportAddress & address) const
{
  // skip transport identifier
  PINDEX pos = address.Find('$');
  if (pos == P_MAX_INDEX)
    return PString();

  return address.Mid(pos+1);
}


BOOL OpalInternalTransport::GetIpAndPort(const OpalTransportAddress &,
                                         PIPSocket::Address &,
                                         WORD &) const
{
  return FALSE;
}


//////////////////////////////////////////////////////////////////////////

static BOOL SplitAddress(const PString & addr, PString & host, PString & service)
{
  // skip transport identifier
  PINDEX dollar = addr.Find('$');
  if (dollar == P_MAX_INDEX)
    return FALSE;
  
  PINDEX lastChar = addr.GetLength()-1;
  if (addr[lastChar] == '+')
    lastChar--;

  PINDEX bracket = addr.FindLast(']');
  if (bracket == P_MAX_INDEX)
    bracket = 0;

  PINDEX colon = addr.Find(':', bracket);
  if (colon == P_MAX_INDEX)
    host = addr(dollar+1, lastChar);
  else {
    host = addr(dollar+1, colon-1);
    service = addr(colon+1, lastChar);
  }

  return TRUE;
}


PString OpalInternalIPTransport::GetHostName(const OpalTransportAddress & address) const
{
  PString host, service;
  if (!SplitAddress(address, host, service))
    return address;

  PIPSocket::Address ip;
  if (PIPSocket::GetHostAddress(host, ip))
    return ip.AsString();

  return host;
}


BOOL OpalInternalIPTransport::GetIpAndPort(const OpalTransportAddress & address,
                                           PIPSocket::Address & ip,
                                           WORD & port) const
{
  PString host, service;
  if (!SplitAddress(address, host, service))
    return FALSE;

  if (host.IsEmpty()) {
    PTRACE(2, "Opal\tIllegal IP transport address: \"" << address << '"');
    return FALSE;
  }

  if (service == "*")
    port = 0;
  else {
    if (!service) {
      PString proto = address.Left(address.Find('$'));
      if (proto *= "ip")
        proto = "tcp";
      port = PIPSocket::GetPortByService(proto, service);
    }
    if (port == 0) {
      PTRACE(2, "Opal\tIllegal IP transport port/service: \"" << address << '"');
      return FALSE;
    }
  }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -