PTLib  Version 2.18.8
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
pnat.h
Go to the documentation of this file.
1 /*
2  * pnat.h
3  *
4  * NAT Strategy support for Portable Windows Library.
5  *
6  * Virteos is a Trade Mark of ISVO (Asia) Pte Ltd.
7  *
8  * Copyright (c) 2004 ISVO (Asia) Pte Ltd. All Rights Reserved.
9  *
10  * The contents of this file are subject to the Mozilla Public License
11  * Version 1.0 (the "License"); you may not use this file except in
12  * compliance with the License. You may obtain a copy of the License at
13  * http://www.mozilla.org/MPL/
14  *
15  * Software distributed under the License is distributed on an "AS IS"
16  * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
17  * the License for the specific language governing rights and limitations
18  * under the License.
19  *
20  *
21  * The Original Code is derived from and used in conjunction with the
22  * OpenH323 Project (www.openh323.org/)
23  *
24  * The Initial Developer of the Original Code is ISVO (Asia) Pte Ltd.
25  *
26  *
27  * Contributor(s): ______________________________________.
28  */
29 
30 #ifndef PTLIB_PNAT_H
31 #define PTLIB_PNAT_H
32 
33 #include <ptlib.h>
34 
35 #if P_NAT
36 
37 #include <ptlib/sockets.h>
38 
39 #include <ptlib/plugin.h>
40 #include <ptlib/pluginmgr.h>
41 
42 class PNATUDPSocket;
43 
44 
52 class PNatMethod : public PObject
53 {
54  PCLASSINFO(PNatMethod,PObject);
55 
56  public:
57  enum Component {
58  eComponent_RTP = 1,
59  eComponent_RTCP = 2,
60  eComponent_Unknown = 255,
61  };
62 
68  UnknownNat,
69  OpenNat,
70  ConeNat,
79  RestrictedNat,
91  PortRestrictedNat,
105  SymmetricNat,
117  BlockedNat,
121  PartiallyBlocked
127  );
128 
133  protected:
134  PNatMethod(unsigned priority);
135 
136  public:
139  ~PNatMethod();
141 
142 
145  virtual void PrintOn(
146  ostream & strm
147  ) const;
148  virtual Comparison Compare(
149  const PObject & obj
150  ) const;
152 
153 
158  static PNatMethod * Create(
159  const PString & name,
160  PPluginManager * pluginMgr = NULL
161  );
162 
165  static PString GetNatTypeString(
166  NatTypes type
167  );
168 
171  virtual PCaselessString GetMethodName() const = 0;
172 
175  virtual PString GetFriendlyName() const;
176 
180  virtual void Activate(bool active);
181 
185  virtual bool IsAvailable(
187  PObject * context = NULL
188  );
189 
192  virtual PString GetServer() const = 0;
193 
196  bool GetServerAddress(
197  PIPSocket::Address & address,
198  WORD & port
199  ) const;
200  bool GetServerAddress(
201  PIPSocketAddressAndPort & externalAddressAndPort
202  ) const;
203 
204  NatTypes GetNatType(
205  const PTimeInterval & maxAge
206  );
207 
208  __inline NatTypes GetNatType(
209  bool force = false
210  ) { return GetNatType(force ? PTimeInterval(0) : PMaxTimeInterval); }
211 
212  __inline NatTypes GetNatType() const { return m_natType; }
213 
217  PString GetNatTypeName(
218  bool force = false
219  ) { return GetNatTypeString(GetNatType(force)); }
220 
221  PString GetNatTypeName() const { return GetNatTypeString(GetNatType()); }
222 
226  virtual bool SetServer(const PString & server);
227 
230  virtual void SetCredentials(
231  const PString & username,
232  const PString & password,
233  const PString & realm
234  );
235 
236  static const PTimeInterval & GetDefaultMaxAge();
237 
240  bool GetExternalAddress(
241  PIPSocket::Address & externalAddress,
242  const PTimeInterval & maxAge = GetDefaultMaxAge()
243  );
244  bool GetExternalAddress(
245  PIPSocket::Address & externalAddress
246  ) const;
247 
250  virtual bool GetInterfaceAddress(
251  PIPSocket::Address & internalAddress
252  ) const;
253 
256  PString GetInterface() const;
257 
260  virtual bool Open(
261  const PIPSocket::Address & ifaceAddr
262  );
263 
266  virtual void Close() { }
267 
281  virtual PBoolean CreateSocket(
282  PUDPSocket * & socket,
284  WORD localPort = 0,
285  PObject * context = NULL,
286  Component component = eComponent_Unknown
287  );
288 
302  virtual bool CreateSocketPair(
303  PUDPSocket * & socket1,
304  PUDPSocket * & socket2,
306  PObject * context = NULL
307  );
308 
309  P_DECLARE_ENUM(RTPSupportTypes,
310  RTPSupported,
311  RTPIfSendMedia,
312  RTPUnsupported,
313  RTPUnknown
314  );
315 
319  virtual RTPSupportTypes GetRTPSupport(
320  bool force = false
321  );
322 
333  virtual void SetPortRanges(
334  WORD portBase,
335  WORD portMax = 0,
336  WORD portPairBase = 0,
337  WORD portPairMax = 0
338  );
340 
341  bool IsActive() const { return m_active; }
342  unsigned GetPriority() const { return m_priority; }
343 
344  protected:
345  virtual PNATUDPSocket * InternalCreateSocket(Component component, PObject * context) = 0;
346  virtual void InternalUpdate(bool externalAddressOnly) = 0;
347  virtual bool InternalGetServerAddress(PIPSocketAddressAndPort & externalAddressAndPort) const = 0;
348 
349  bool m_active;
350 
351  PIPSocket::PortRange m_singlePortRange;
352  PIPSocket::PortRange m_pairedPortRange;
353 
354  PNatMethod::NatTypes m_natType;
355  PIPSocket::Address m_externalAddress;
356  PTime m_updateTime;
357  PDECLARE_MUTEX( m_mutex);
358 
359  private:
360  unsigned m_priority;
361 
362  P_REMOVE_VIRTUAL(NatTypes,InternalGetNatType(bool,const PTimeInterval &),UnknownNat);
363 
364  friend class PNatMethods;
365 };
366 
367 
369 
370 class PNatCandidate : public PObject
371 {
372  PCLASSINFO(PNatCandidate, PObject);
373  public:
374  P_DECLARE_ENUM(Types,
375  HostType,
376  ServerReflexiveType,
377  PeerReflexiveType,
378  RelayType,
379  FinalType
380  );
381 
382  PNatCandidate(
383  Types type = EndTypes,
384  PNatMethod::Component component = PNatMethod::eComponent_Unknown,
385  const char * foundation = NULL,
386  unsigned priority = 1,
387  const char * protocol = "udp"
388  );
389 
390  virtual Comparison Compare(const PObject & other) const;
391  virtual void PrintOn(ostream & strm) const;
392 
393  Types m_type;
394  PNatMethod::Component m_component;
395  unsigned m_priority;
396  PString m_foundation; // ICE support
397  PCaselessString m_protocol; // Almost invariably "udp"
398  unsigned m_networkCost; // https://tools.ietf.org/html/draft-thatcher-ice-network-cost-01
399  unsigned m_networkId;
400  PIPSocketAddressAndPort m_baseTransportAddress; // Address of physical host
401  PIPSocketAddressAndPort m_localTransportAddress; // Address presented to remote system
402 };
403 
404 
405 typedef PList<PNatCandidate> PNatCandidateList;
406 
407 
409 
412 class PNATUDPSocket : public PUDPSocket
413 {
414  PCLASSINFO(PNATUDPSocket, PUDPSocket);
415 
416  public:
417  PNATUDPSocket(
418  PNatMethod::Component component
419  );
420 
421  virtual PString GetName() const;
422  virtual const char * GetNatName() const { return "NAT"; }
423 
424  virtual void GetCandidateInfo(PNatCandidate & candidate);
425 
426  // Get phsyical, non-translated, IP/port for socket.
427  PString GetBaseAddress() const;
428  bool GetBaseAddress(PIPSocketAddressAndPort & addrAndPort) const;
429 
430  PNatMethod::Component GetComponent() const
431  { return m_component; }
432 
433  protected:
434  virtual bool InternalGetBaseAddress(PIPSocketAddressAndPort & addrAndPort);
435 
436  PNatMethod::Component m_component;
437 };
438 
439 
441 
461 class PNatMethod_Fixed : public PNatMethod
462 {
463  PCLASSINFO(PNatMethod_Fixed, PNatMethod);
464  public:
465  enum { DefaultPriority = 50 };
466  PNatMethod_Fixed(unsigned priority = DefaultPriority);
467 
468  static const char * MethodName();
469  virtual PCaselessString GetMethodName() const;
470 
471  virtual PString GetServer() const;
472  virtual bool SetServer(const PString & str);
473  virtual bool GetInterfaceAddress(PIPSocket::Address & ifaceAddr) const;
474  virtual bool Open(const PIPSocket::Address & ifaceAddr);
475  virtual void Close();
476  virtual bool IsAvailable(const PIPSocket::Address & binding, PObject * context);
477 
478  class Socket : public PNATUDPSocket
479  {
480  PCLASSINFO(Socket, PNATUDPSocket);
481  public:
482  Socket(
483  PNatMethod::Component component,
484  const PIPSocket::Address & externalAddress
485  );
486  private:
487  bool InternalGetLocalAddress(PIPSocketAddressAndPort & addr);
488  PIPSocket::Address m_externalAddress;
489  };
490  protected:
491  virtual bool InternalGetServerAddress(PIPSocketAddressAndPort & externalAddressAndPort) const;
492  virtual PNATUDPSocket * InternalCreateSocket(Component component, PObject * context);
493  virtual void InternalUpdate(bool);
494 
495  PString m_serverString;
496  PIPSocket::Address m_interfaceAddress;
497 };
498 
499 
501 
506 class PNatMethod_AWS : public PNatMethod_Fixed
507 {
508  PCLASSINFO(PNatMethod_AWS, PNatMethod_Fixed);
509  public:
510  PNatMethod_AWS(unsigned priority = DefaultPriority);
511 
512  static const char * MethodName();
513  virtual PCaselessString GetMethodName() const;
514 
515  virtual PString GetServer() const;
516  virtual bool SetServer(const PString & str);
517 
518  protected:
519  virtual bool InternalGetServerAddress(PIPSocketAddressAndPort & externalAddressAndPort) const;
520  void InternalUpdate(bool);
521 };
522 
524 
528 class PNatMethods : public PSortedList<PNatMethod>
529 {
530  typedef PSortedList<PNatMethod> BaseClass;
531  PCLASSINFO(PNatMethods, BaseClass);
532  public :
537  PNatMethods(
538  bool loadFromFactory = false,
539  PPluginManager * pluginMgr = NULL
540  );
542 
547  void LoadAll(PPluginManager * pluginMgr = NULL);
548 
552  virtual PNatMethod * GetMethod(
554  PObject * context = NULL
555  );
556 
560  virtual PNatMethod * GetMethodByName(
561  const PString & name
562  );
563 
566  virtual bool RemoveMethod(
567  const PString & name
568  );
569 
572  virtual bool SetMethodPriority(
573  const PString & name,
574  unsigned priority
575  );
576 
579  virtual bool IsLocalAddress(
580  const PIPSocket::Address & ip
581  ) const;
582 
593  void SetPortRanges(
594  WORD portBase,
595  WORD portMax = 0,
596  WORD portPairBase = 0,
597  WORD portPairMax = 0
598  );
600 
601 
602  PNatMethods & GetNATList() { return *this; } // For backward compatibility
603 };
604 
605 
606 typedef PNatMethods PNatList; // For backward compatibility
607 typedef PNatMethods PNatStrategy; // For backward compatibility
608 
609 
610 
612 //
613 // declare macros and structures needed for NAT plugins
614 //
615 
616 PCREATE_PLUGIN_SERVICE(PNatMethod);
617 
618 #define PCREATE_NAT_PLUGIN(name, friendlyName) \
619  PCREATE_PLUGIN(name, PNatMethod, PNatMethod_##name, PPlugin_PNatMethod, \
620  virtual const char * GetFriendlyName() const { return friendlyName; } \
621  )
622 
623 
624 #define P_NAT_PARAM(...) ,__VA_ARGS__
625 
626 
627 #if P_STUN
628  PPLUGIN_STATIC_LOAD(STUN, PNatMethod);
629 #endif
630 
631 #if P_TURN
632  PPLUGIN_STATIC_LOAD(TURN, PNatMethod);
633 #endif
634 
635 #else // P_NAT
636 
637 #define P_NAT_PARAM(...)
638 
639 #endif // P_NAT
640 
641 #endif // PTLIB_PNAT_H
642 
643 
644 // End Of File ///////////////////////////////////////////////////////////////
#define PMaxTimeInterval
Definition: timeint.h:31
This class defines an arbitrary time interval to millisecond accuracy.
Definition: timeint.h:51
#define PCLASSINFO(cls, par)
Declare all the standard PTLib class information.
Definition: object.h:2164
This class defines an absolute time and date.
Definition: ptime.h:49
A socket channel that uses the UDP transport on the Internet Protocol.
Definition: udpsock.h:42
#define PPLUGIN_STATIC_LOAD(serviceName, serviceType)
Definition: plugin.h:123
This class is a variation of a string that ignores case.
Definition: pstring.h:2012
virtual PString GetName() const
Get the platform and I/O channel type name of the channel.
A class describing an IP address and port number combination.
Definition: ipsock.h:278
PCREATE_PLUGIN_SERVICE(PLDAPSchema)
This template class maps the PAbstractList to a specific object type.
Definition: lists.h:322
#define PDECLARE_MUTEX(...)
Definition: mutex.h:200
#define P_REMOVE_VIRTUAL(type, fn, ret)
Definition: object.h:146
#define P_DECLARE_ENUM(name, first,...)
This declares a standard enumeration (enum) of symbols with ++ and – operators.
Definition: object.h:248
bool PBoolean
Definition: object.h:174
#define P_DECLARE_STREAMABLE_ENUM(name, first,...)
This declares a standard enumeration using P_DECLARE_ENUM() and adds the text names so can be streame...
Definition: object.h:326
The character string class.
Definition: pstring.h:108
virtual Comparison Compare(const PObject &obj) const
Compare the two objects and return their relative rank.
A class describing an IP address.
Definition: ipsock.h:59
Class for handling a range of ports for local binding.
Definition: ipsock.h:412
This template class maps the PAbstractSortedList to a specific object type.
Definition: lists.h:964
static const PIPSocket::Address & GetDefaultIpAny()
Ultimate parent class for all objects in the class library.
Definition: object.h:2204
virtual void PrintOn(ostream &strm) const
Output the contents of the object to the stream.