PTLib  Version 2.14.3
 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  * $Revision: 31475 $
30  * $Author: rjongbloed $
31  * $Date: 2014-02-15 14:40:04 +1100 (Sat, 15 Feb 2014) $
32  */
33 
34 #ifndef PTLIB_PNAT_H
35 #define PTLIB_PNAT_H
36 
37 #include <ptlib.h>
38 
39 #if P_NAT
40 
41 #include <ptlib/sockets.h>
42 
43 #include <ptlib/plugin.h>
44 #include <ptlib/pluginmgr.h>
45 
46 class PNATUDPSocket;
47 
48 
56 class PNatMethod : public PObject
57 {
58  PCLASSINFO(PNatMethod,PObject);
59 
60  public:
61  enum Component {
62  eComponent_RTP = 1,
63  eComponent_RTCP = 2,
64  eComponent_Unknown = 255,
65  };
66 
72  UnknownNat,
73  OpenNat,
74  ConeNat,
83  RestrictedNat,
95  PortRestrictedNat,
109  SymmetricNat,
121  BlockedNat,
125  PartiallyBlocked
131  );
132 
137  protected:
138  PNatMethod(unsigned priority);
139 
140  public:
143  ~PNatMethod();
145 
146 
149  virtual void PrintOn(
150  ostream & strm
151  ) const;
152  virtual Comparison Compare(
153  const PObject & obj
154  ) const;
156 
157 
162  static PNatMethod * Create(
163  const PString & name,
164  PPluginManager * pluginMgr = NULL
165  );
166 
169  static PString GetNatTypeString(
170  NatTypes type
171  );
172 
175  virtual PCaselessString GetMethodName() const = 0;
176 
179  virtual PString GetFriendlyName() const;
180 
184  virtual void Activate(bool active);
185 
189  virtual bool IsAvailable(
191  PObject * context = NULL
192  );
193 
196  virtual PString GetServer() const = 0;
197 
200  virtual bool GetServerAddress(
201  PIPSocket::Address & address,
202  WORD & port
203  ) const;
204  virtual bool GetServerAddress(
205  PIPSocketAddressAndPort & externalAddressAndPort
206  ) const;
207 
208  NatTypes GetNatType(
209  const PTimeInterval & maxAge
210  );
211 
212  __inline NatTypes GetNatType(
213  bool force = false
214  ) { return GetNatType(force ? PTimeInterval(0) : PMaxTimeInterval); }
215 
216  __inline NatTypes GetNatType() const { return m_natType; }
217 
221  PString GetNatTypeName(
222  bool force = false
223  ) { return GetNatTypeString(GetNatType(force)); }
224 
225  PString GetNatTypeName() const { return GetNatTypeString(GetNatType()); }
226 
230  virtual bool SetServer(const PString & server);
231 
234  virtual void SetCredentials(
235  const PString & username,
236  const PString & password,
237  const PString & realm
238  );
239 
240  static const PTimeInterval & GetDefaultMaxAge();
241 
244  bool GetExternalAddress(
245  PIPSocket::Address & externalAddress,
246  const PTimeInterval & maxAge = GetDefaultMaxAge()
247  );
248  bool GetExternalAddress(
249  PIPSocket::Address & externalAddress
250  ) const;
251 
254  bool GetInterfaceAddress(
255  PIPSocket::Address & internalAddress
256  ) 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() = 0;
347 
348  bool m_active;
349 
350  PIPSocket::PortRange m_singlePortRange;
351  PIPSocket::PortRange m_pairedPortRange;
352 
353  PNatMethod::NatTypes m_natType;
354  PIPSocketAddressAndPort m_externalAddress;
355  PTime m_updateTime;
356  PMutex m_mutex;
357 
358  private:
359  unsigned m_priority;
360 
361  P_REMOVE_VIRTUAL(NatTypes,InternalGetNatType(bool,const PTimeInterval &),UnknownNat);
362 
363  friend class PNatMethods;
364 };
365 
366 
368 
369 class PNatCandidate : public PObject
370 {
371  PCLASSINFO(PNatCandidate, PObject);
372  public:
373  P_DECLARE_ENUM(Types,
374  HostType,
375  ServerReflexiveType,
376  PeerReflexiveType,
377  RelayType
378  );
379 
380  PNatCandidate(
381  Types type = EndTypes,
382  PNatMethod::Component component = PNatMethod::eComponent_Unknown,
383  const char * foundation = NULL
384  );
385 
386  virtual void PrintOn(ostream & strm) const;
387 
388  void CalculatePriority();
389 
390  Types m_type;
391  PNatMethod::Component m_component;
392  unsigned m_priority;
393  PString m_foundation; // ICE support
394  PString m_protocol; // Almost invariably "udp"
395  PIPSocketAddressAndPort m_baseTransportAddress; // Address of physical host
396  PIPSocketAddressAndPort m_localTransportAddress; // Address presented to remote system
397 };
398 
399 
400 typedef PList<PNatCandidate> PNatCandidateList;
401 
402 
404 
407 class PNATUDPSocket : public PUDPSocket
408 {
409  PCLASSINFO(PNATUDPSocket, PUDPSocket);
410 
411  public:
412  PNATUDPSocket(
413  PNatMethod::Component component
414  );
415 
416  virtual PString GetName() const;
417  virtual const char * GetNatName() const { return "NAT"; }
418 
419  virtual void GetCandidateInfo(PNatCandidate & candidate);
420 
421  // Get phsyical, non-translated, IP/port for socket.
422  PString GetBaseAddress() const;
423  bool GetBaseAddress(PIPSocketAddressAndPort & addrAndPort) const;
424 
425  PNatMethod::Component GetComponent() const
426  { return m_component; }
427 
428  protected:
429  virtual bool InternalGetBaseAddress(PIPSocketAddressAndPort & addrAndPort);
430 
431  PNatMethod::Component m_component;
432 };
433 
434 
436 
456 class PNatMethod_Fixed : public PNatMethod
457 {
458  PCLASSINFO(PNatMethod_Fixed, PNatMethod);
459  public:
460  enum { DefaultPriority = 50 };
461  PNatMethod_Fixed(unsigned priority = DefaultPriority);
462 
463  static const char * MethodName();
464  virtual PCaselessString GetMethodName() const;
465 
466  virtual PString GetServer() const;
467  virtual bool SetServer(const PString & str);
468  virtual bool GetInterfaceAddress(PIPSocket::Address & addr) const;
469  virtual bool Open(const PIPSocket::Address & addr);
470  virtual bool IsAvailable(const PIPSocket::Address & binding, PObject * context);
471 
472  protected:
473  virtual PNATUDPSocket * InternalCreateSocket(Component component, PObject * context);
474  virtual void InternalUpdate();
475 
476  PIPSocket::Address m_interfaceAddress;
477 };
478 
480 
484 class PNatMethods : public PSortedList<PNatMethod>
485 {
486  typedef PSortedList<PNatMethod> BaseClass;
487  PCLASSINFO(PNatMethods, BaseClass);
488  public :
493  PNatMethods(
494  bool loadFromFactory = false,
495  PPluginManager * pluginMgr = NULL
496  );
498 
503  void LoadAll(PPluginManager * pluginMgr = NULL);
504 
508  virtual PNatMethod * GetMethod(
510  PObject * context = NULL
511  );
512 
516  virtual PNatMethod * GetMethodByName(
517  const PString & name
518  );
519 
522  virtual bool RemoveMethod(
523  const PString & name
524  );
525 
528  virtual bool SetMethodPriority(
529  const PString & name,
530  unsigned priority
531  );
532 
535  virtual bool IsLocalAddress(
536  const PIPSocket::Address & ip
537  ) const;
538 
549  void SetPortRanges(
550  WORD portBase,
551  WORD portMax = 0,
552  WORD portPairBase = 0,
553  WORD portPairMax = 0
554  );
556 
557 
558  PNatMethods & GetNATList() { return *this; } // For backward compatibility
559 };
560 
561 
562 typedef PNatMethods PNatList; // For backward compatibility
563 typedef PNatMethods PNatStrategy; // For backward compatibility
564 
565 
566 
568 //
569 // declare macros and structures needed for NAT plugins
570 //
571 
572 PCREATE_PLUGIN_SERVICE(PNatMethod);
573 
574 #define PCREATE_NAT_PLUGIN(name, friendlyName) \
575  PCREATE_PLUGIN(name, PNatMethod, PNatMethod_##name, PPlugin_PNatMethod, \
576  virtual const char * GetFriendlyName() const { return friendlyName; } \
577  )
578 
579 
580 #define P_NAT_PARAM(...) ,__VA_ARGS__
581 
582 
583 #if P_STUN
584  PPLUGIN_STATIC_LOAD(STUN, PNatMethod);
585 #endif
586 
587 #if P_TURN
588  PPLUGIN_STATIC_LOAD(TURN, PNatMethod);
589 #endif
590 
591 #else // P_NAT
592 
593 #define P_NAT_PARAM(...)
594 
595 #endif // P_NAT
596 
597 #endif // PTLIB_PNAT_H
598 
599 
600 // End Of File ///////////////////////////////////////////////////////////////