PTLib  Version 2.12.9
 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: 29076 $
30  * $Author: rjongbloed $
31  * $Date: 2013-02-12 19:30:20 +1100 (Tue, 12 Feb 2013) $
32  */
33 
34 #ifndef PTLIB_PNAT_H
35 #define PTLIB_PNAT_H
36 
37 #include <ptbuildopts.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 {
62  NatPortStart = 49152,
63  NatPortEnd = 65535
64  };
65 
66  enum Component {
67  eComponent_RTP = 1,
68  eComponent_RTCP = 2,
69  eComponent_Unknown = 255,
70  };
71 
73  UnknownNat,
74  OpenNat,
75  ConeNat,
84  RestrictedNat,
96  PortRestrictedNat,
110  SymmetricNat,
122  PartiallyBlocked,
128  BlockedNat
132  );
133 
138  PNatMethod();
139 
142  ~PNatMethod();
144 
145 
148  virtual void PrintOn(
149  ostream & strm
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 PString GetName() const = 0;
172 
175  virtual PString GetServer() const = 0;
176 
179  virtual bool GetServerAddress(
180  PIPSocket::Address & address,
181  WORD & port
182  ) const;
183  virtual bool GetServerAddress(
184  PIPSocketAddressAndPort & externalAddressAndPort
185  ) const;
186 
187  __inline NatTypes GetNatType(
188  const PTimeInterval & maxAge
189  ) { return InternalGetNatType(false, maxAge); }
190 
191  __inline NatTypes GetNatType(
192  bool force = false
193  ) { return InternalGetNatType(force, PMaxTimeInterval); }
194 
198  PString GetNatTypeName(
199  bool force = false
200  ) { return GetNatTypeString(GetNatType(force)); }
201 
205  virtual bool SetServer(const PString & server);
206 
209  virtual void SetCredentials(
210  const PString & username,
211  const PString & password,
212  const PString & realm
213  );
214 
217  virtual bool GetExternalAddress(
218  PIPSocket::Address & externalAddress,
219  const PTimeInterval & maxAge = 1000
220  );
221 
224  virtual bool GetInterfaceAddress(
225  PIPSocket::Address & internalAddress
226  ) const;
227 
230  virtual bool Open(
231  const PIPSocket::Address & ifaceAddr
232  );
233 
236  virtual void Close() { }
237 
251  virtual PBoolean CreateSocket(
252  PUDPSocket * & socket,
254  WORD localPort = 0
255  ) { return CreateSocket(eComponent_Unknown, socket, binding, localPort); }
256  virtual bool CreateSocket(
257  Component component,
258  PUDPSocket * & socket,
260  WORD localPort = 0
261  );
262 
276  virtual bool CreateSocketPair(
277  PUDPSocket * & socket1,
278  PUDPSocket * & socket2,
280  );
281 
295  virtual bool CreateSocketPair(
296  PUDPSocket * & socket1,
297  PUDPSocket * & socket2,
298  const PIPSocket::Address & binding,
299  void * userData
300  );
301 
309  virtual bool CreateSocketPairAsync(
310  const PString & token
311  );
312 
320  virtual bool GetSocketPairAsync(
321  const PString & token,
322  PUDPSocket * & socket1,
323  PUDPSocket * & socket2,
325  void * userData = NULL
326  );
327 
331  virtual bool IsAvailable(
332  const PIPSocket::Address & binding
333  );
334 
338  virtual void Activate(bool active);
339 
343  virtual void SetAlternateAddresses(
344  const PStringArray & addresses,
345  void * userData = NULL
346  );
347 
348  P_DECLARE_ENUM(RTPSupportTypes,
349  RTPSupported,
350  RTPIfSendMedia,
351  RTPUnsupported,
352  RTPUnknown
353  );
354 
358  virtual RTPSupportTypes GetRTPSupport(
359  bool force = false
360  );
361 
372  virtual void SetPortRanges(
373  WORD portBase,
374  WORD portMax = 0,
375  WORD portPairBase = 0,
376  WORD portPairMax = 0
377  );
379 
380  struct PortInfo {
381  PortInfo(WORD port = 0)
382  : basePort(port)
383  , maxPort(port)
384  , currentPort(port)
385  {
386  }
387 
388  void SetPorts(
389  WORD start,
390  WORD end
391  );
392 
393  WORD GetNext(
394  unsigned increment
395  );
396 
403  WORD GetRandomPair();
404 
405  PMutex mutex;
406  WORD basePort;
407  WORD maxPort;
408  WORD currentPort;
409  } ;
410 
411  protected:
412  virtual NatTypes InternalGetNatType(bool forced, const PTimeInterval & maxAge) = 0;
413 
414  PortInfo singlePortInfo, pairedPortInfo;
415 };
416 
418 
419 PLIST(PNatList, PNatMethod);
420 
422 
423 class PNatCandidate : public PObject
424 {
425  PCLASSINFO(PNatCandidate, PObject);
426  public:
427  enum {
428  eType_Unknown,
429  eType_Host,
430  eType_ServerReflexive,
431  eType_PeerReflexive,
432  eType_Relay
433  };
434 
435  PNatCandidate();
436  PNatCandidate(int type, PNatMethod::Component component);
437 
438  virtual PString AsString() const;
439 
440  PIPSocketAddressAndPort m_baseAddress;
441  PIPSocketAddressAndPort m_transport;
442  int m_type;
443  PNatMethod::Component m_component;
444 };
445 
446 
450 class PNATUDPSocket : public PUDPSocket
451 {
452  PCLASSINFO(PNATUDPSocket, PUDPSocket);
453 
454  public:
455  PNATUDPSocket(
456  PNatMethod::Component component = PNatMethod::eComponent_Unknown
457  );
458 
459  virtual PNatCandidate GetCandidateInfo();
460 
461  virtual PString GetBaseAddress();
462  virtual bool GetBaseAddress(PIPSocketAddressAndPort & addrAndPort);
463 
464  PNatMethod::Component GetComponent() const
465  { return m_component; }
466 
467  void SetComponent(PNatMethod::Component component)
468  { m_component = component; }
469 
470  protected:
471  virtual bool InternalGetBaseAddress(PIPSocketAddressAndPort & addrAndPort);
472 
473  PNatMethod::Component m_component;
474 };
475 
476 
478 
498 class PNatMethod_Fixed : public PNatMethod
499 {
500  PCLASSINFO(PNatMethod_Fixed, PNatMethod);
501  public:
502  PNatMethod_Fixed();
503 
504  static PString GetNatMethodName();
505  virtual PString GetName() const;
506 
507  virtual PString GetServer() const;
508  virtual bool SetServer(const PString & str);
509  virtual bool GetExternalAddress(PIPSocket::Address & addr ,const PTimeInterval &);
510  virtual bool GetInterfaceAddress(PIPSocket::Address & addr) const;
511  virtual bool Open(const PIPSocket::Address & addr);
512  virtual bool IsAvailable(const PIPSocket::Address &);
513 
514  protected:
515  virtual NatTypes InternalGetNatType(bool forced, const PTimeInterval & maxAge);
516 
517  NatTypes m_type;
518  PIPSocket::Address m_interfaceAddress;
519  PIPSocket::Address m_externalAddress;
520 };
521 
523 
529 class PNatStrategy : public PObject
530 {
531  PCLASSINFO(PNatStrategy,PObject);
532 
533 public :
534 
539  PNatStrategy();
540 
543  ~PNatStrategy();
545 
553  void AddMethod(PNatMethod * method);
554 
560  PNatMethod * GetMethod(const PIPSocket::Address & address = PIPSocket::GetDefaultIpAny());
561 
566  PNatMethod * GetMethodByName(const PString & name);
567 
571  bool RemoveMethod(const PString & meth);
572 
583  void SetPortRanges(
584  WORD portBase,
585  WORD portMax = 0,
586  WORD portPairBase = 0,
587  WORD portPairMax = 0
588  );
589 
592  PNatList & GetNATList() { return natlist; };
593 
594  PNatMethod * LoadNatMethod(const PString & name);
595 
596  static PStringArray GetRegisteredList();
597 
599 
600 private:
601  PNatList natlist;
602  PPluginManager * pluginMgr;
603 };
604 
606 //
607 // declare macros and structures needed for NAT plugins
608 //
609 
610 template <class SVC> class PNatMethodServiceDescriptor : public PDevicePluginServiceDescriptor
611 {
612  public:
613  virtual PObject * CreateInstance(int /*userData*/) const { return new SVC; }
614  virtual PStringArray GetDeviceNames(int /*userData*/) const { return SVC::GetNatMethodName(); }
615  virtual bool ValidateDeviceName(const PString & deviceName, int /*userData*/) const { return SVC::GetNatMethodName() *= deviceName; }
616 };
617 
618 #define PCREATE_NAT_PLUGIN(name) \
619  static PNatMethodServiceDescriptor<PNatMethod_##name> PNatMethod_##name##_descriptor; \
620  PCREATE_PLUGIN(name, PNatMethod, &PNatMethod_##name##_descriptor) \
621 
622 
623 #define P_NAT_PARAM(...) ,__VA_ARGS__
624 
625 
626 #if P_STUN
627 PPLUGIN_STATIC_LOAD(STUN, PNatMethod);
628 #endif
629 
630 #if P_TURN
631 PPLUGIN_STATIC_LOAD(TURN, PNatMethod);
632 #endif
633 
634 #else // P_NAT
635 
636 #define P_NAT_PARAM(...)
637 
638 #endif // P_NAT
639 
640 #endif // PTLIB_PNAT_H
641 
642 
643 // End Of File ///////////////////////////////////////////////////////////////