PTLib  Version 2.12.9
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
ipsock.h
Go to the documentation of this file.
1 /*
2  * ipsock.h
3  *
4  * Internet Protocol socket I/O channel class.
5  *
6  * Portable Tools Library
7  *
8  * Copyright (c) 1993-1998 Equivalence Pty. Ltd.
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  * The Original Code is Portable Windows Library.
21  *
22  * The Initial Developer of the Original Code is Equivalence Pty. Ltd.
23  *
24  * Portions are Copyright (C) 1993 Free Software Foundation, Inc.
25  * All Rights Reserved.
26  *
27  * Contributor(s): ______________________________________.
28  *
29  * $Revision: 29742 $
30  * $Author: rjongbloed $
31  * $Date: 2013-05-20 13:27:45 +1000 (Mon, 20 May 2013) $
32  */
33 
34 #ifndef PTLIB_IPSOCKET_H
35 #define PTLIB_IPSOCKET_H
36 
37 #ifdef P_USE_PRAGMA
38 #pragma interface
39 #endif
40 
41 #include <ptlib/socket.h>
42 
43 
51 class PIPSocket : public PSocket
52 {
53  PCLASSINFO(PIPSocket, PSocket);
54  protected:
58  PIPSocket();
59 
60  public:
63  class Address : public PObject {
64  PCLASSINFO_WITH_CLONE(Address, PObject);
65  public:
66 
69 
70  Address();
71 
75  explicit Address(const PString & dotNotation);
76 
78  Address(PINDEX len, const BYTE * bytes, int scope = 0);
79 
81  Address(BYTE b1, BYTE b2, BYTE b3, BYTE b4);
82 
84  Address(DWORD dw);
85 
87  Address(const in_addr & addr);
88 
89 #if P_HAS_IPV6
90 
91  Address(const in6_addr & addr);
92  Address(const in6_addr & addr, int scope);
93 #endif
94 
97  Address(const int ai_family, const int ai_addrlen,struct sockaddr *ai_addr);
98 
99 #ifdef __NUCLEUS_NET__
100  Address(const struct id_struct & addr);
101  Address & operator=(const struct id_struct & addr);
102 #endif
103 
105  Address & operator=(const in_addr & addr);
106 
107 #if P_HAS_IPV6
108 
109  Address & AssignIPV6(const in6_addr & addr, int scope);
110 #endif
111 
113  Address & operator=(const PString & dotNotation);
114 
116  Address & operator=(DWORD dw);
118 
120  Comparison Compare(const PObject & obj) const;
121  bool operator==(const Address & addr) const { return Compare(addr) == EqualTo; }
122  bool operator!=(const Address & addr) const { return Compare(addr) != EqualTo; }
123 #if P_HAS_IPV6
124  bool operator ==(in6_addr & addr) const;
125  bool operator !=(in6_addr & addr) const { return !operator==(addr); }
126 
127  bool EqualIPV6(in6_addr & addr, int scope) const;
128  bool NotEqualIPV6(in6_addr & addr, int scope) const { return !EqualIPV6(addr, scope); }
129 #endif
130  bool operator==(in_addr & addr) const;
131  bool operator!=(in_addr & addr) const { return !operator==(addr); }
132  bool operator==(DWORD dw) const;
133  bool operator!=(DWORD dw) const { return !operator==(dw); }
134 #ifdef P_VXWORKS
135  bool operator==(long unsigned int u) const { return operator==((DWORD)u); }
136  bool operator!=(long unsigned int u) const { return !operator==((DWORD)u); }
137 #endif
138 #ifdef _WIN32
139  bool operator==(unsigned u) const { return operator==((DWORD)u); }
140  bool operator!=(unsigned u) const { return !operator==((DWORD)u); }
141 #endif
142 #ifdef P_RTEMS
143  bool operator==(u_long u) const { return operator==((DWORD)u); }
144  bool operator!=(u_long u) const { return !operator==((DWORD)u); }
145 #endif
146 #ifdef P_BEOS
147  bool operator==(in_addr_t a) const { return operator==((DWORD)a); }
148  bool operator!=(in_addr_t a) const { return !operator==((DWORD)a); }
149 #endif
150  bool operator==(int i) const { return operator==((DWORD)i); }
151  bool operator!=(int i) const { return !operator==((DWORD)i); }
152 
155 #if P_HAS_IPV6
156  bool operator*=(const Address & addr) const;
157 #else
158  bool operator*=(const Address & addr) const { return operator==(addr); }
159 #endif
160 
163  bool bracketIPv6 = false,
164  bool excludeScope = false
165  ) const;
166 
169  const PString & str
170  );
171 
173  operator PString() const;
174 
176  operator in_addr() const;
177 
178 #if P_HAS_IPV6
179 
180  operator in6_addr() const;
181 
182  int GetIPV6Scope() const { return m_scope6; }
183 #endif
184 
186  operator DWORD() const;
187 
189  BYTE Byte1() const;
190 
192  BYTE Byte2() const;
193 
195  BYTE Byte3() const;
196 
198  BYTE Byte4() const;
199 
201  BYTE operator[](PINDEX idx) const;
202 
204  PINDEX GetSize() const;
205 
207  const char * GetPointer() const { return (const char *)&m_v; }
208 
210  unsigned GetVersion() const { return m_version; }
211 
213  bool IsValid() const { return m_version == 4 || m_version == 6; }
215  bool IsAny() const;
216 
218  bool IsLoopback() const;
219 
221  bool IsBroadcast() const;
222 
224  bool IsMulticast() const;
225 
234  bool IsRFC1918() const ;
235 
236 #if P_HAS_IPV6
237 
238  bool IsV4Mapped() const;
239 
241  bool IsLinkLocal() const;
242 
244  bool IsSiteLocal() const;
245 #endif
246 
247  static const Address & GetLoopback(unsigned version = 4);
248  static const Address & GetAny(unsigned version = 4);
249  static const Address GetBroadcast(unsigned version = 4);
250 
251  protected:
253  union {
254  in_addr m_four;
255 #if P_HAS_IPV6
256  in6_addr m_six;
257 #endif
258  } m_v;
259  unsigned m_version;
260  int m_scope6;
261 
268  friend ostream & operator<<(ostream & s, const Address & a);
269 
271  friend istream & operator>>(istream & s, Address & a);
272  };
273 
277  {
278  public:
280  char separator = ':'
281  );
283  WORD defaultPort,
284  char separator = ':'
285  );
287  const PString & str,
288  WORD defaultPort = 0,
289  char separator = ':',
290  const char * proto = NULL
291  );
293  const PIPSocket::Address & addr,
294  WORD defaultPort = 0,
295  char separator = ':'
296  );
298  struct sockaddr *ai_addr,
299  const int ai_addrlen
300  );
301 
302  bool Parse(
303  const PString & str,
304  WORD defaultPort = 0,
305  char separator = ':',
306  const char * proto = NULL
307  );
308 
309  PString AsString(char separator = 0) const;
310 
311  const PIPSocket::Address & GetAddress() const { return m_address; }
312 
313  void SetAddress(
314  const PIPSocket::Address & addr,
315  WORD port = 0
316  );
317 
318  WORD GetPort() const { return m_port; }
319 
320  void SetPort(
321  WORD port
322  ) { m_port = port; }
323 
324  bool IsValid() const
325  {
326  return m_address.IsValid() && m_port != 0;
327  }
328 
329  bool operator==(const AddressAndPort & obj) const
330  {
331  return m_port == obj.m_port && m_address == obj.m_address;
332  }
333 
334  bool operator!=(const AddressAndPort & obj) const
335  {
336  return m_port != obj.m_port || m_address != obj.m_address;
337  }
338 
339  friend ostream & operator<<(ostream & strm, const AddressAndPort & ap)
340  {
341  return strm << ap.AsString();
342  }
343 
344  bool MatchWildcard(
345  const AddressAndPort & wild
346  ) const;
347 
348  protected:
350  WORD m_port;
352  };
353 
354 
355  //**@name Overrides from class PChannel */
357 
364  virtual PString GetName() const;
365 
372  static int GetDefaultIpAddressFamily();
373  static void SetDefaultIpAddressFamily(int ipAdressFamily); // PF_INET, PF_INET6
374  static void SetDefaultIpAddressFamilyV4(); // PF_INET
375 #if P_HAS_IPV6
376  static void SetDefaultIpAddressFamilyV6(); // PF_INET6
377  static PBoolean IsIpAddressFamilyV6Supported();
378 #endif
379  static const PIPSocket::Address & GetDefaultIpAny();
380  static const PIPSocket::Address & GetInvalidAddress();
381 
388  static void SetSuppressCanonicalName(bool suppress);
389 
396  static bool GetSuppressCanonicalName();
397 
400  virtual PBoolean OpenSocket(
401  int ipAdressFamily=PF_INET
402  ) = 0;
404 
418  virtual PBoolean Connect(
419  const PString & address
420  );
421  virtual PBoolean Connect(
422  const Address & addr
423  );
424  virtual PBoolean Connect(
425  WORD localPort,
426  const Address & addr
427  );
428  virtual PBoolean Connect(
429  const Address & iface,
430  const Address & addr
431  );
432  virtual PBoolean Connect(
433  const Address & iface,
434  WORD localPort,
435  const Address & addr
436  );
437 
453  virtual PBoolean Listen(
454  unsigned queueSize = 5,
455  WORD port = 0,
457  ) { return InternalListen(GetDefaultIpAny(), queueSize, port, reuse); }
458 
459  virtual PBoolean Listen(
460  const Address & bind,
461  unsigned queueSize = 5,
462  WORD port = 0,
464  ) { return InternalListen(bind, queueSize, port, reuse); }
466 
476  static PString GetHostName();
477  static PString GetHostName(
478  const PString & hostname
479  );
480  static PString GetHostName(
481  const Address & addr
482  );
483 
490  static PBoolean GetHostAddress(
491  Address & addr
492  );
493  static PBoolean GetHostAddress(
494  const PString & hostname,
498  Address & addr
499  );
500 
512  const PString & hostname
513  );
515  const Address & addr
516  /* Name of host to get address for. This may be either a domain name or
517  an IP number in "dot" format.
518  */
519  );
520 
528  static PBoolean IsLocalHost(
532  const PString & hostname
533  );
534 
541  bool GetLocalAddress(
542  Address & addr
543  );
544  bool GetLocalAddress(
545  Address & addr,
546  WORD & port
547  );
549  AddressAndPort & addr
550  )
551  { return InternalGetLocalAddress(addr); }
552 
560  bool GetPeerAddress(
561  Address & addr
562  );
563  bool GetPeerAddress(
564  Address & addr,
565  WORD & port
566  );
568  AddressAndPort & addr
569  )
570  { return InternalGetPeerAddress(addr); }
571 
578 
585 
588  static void ClearNameCache();
589 
592  class RouteEntry : public PObject
593  {
594  PCLASSINFO(RouteEntry, PObject);
595  public:
597  RouteEntry(const Address & addr) : network(addr) { }
598 
600  Address GetNetwork() const { return network; }
601 
603  Address GetNetMask() const { return net_mask; }
604 
606  Address GetDestination() const { return destination; }
607 
609  const PString & GetInterface() const { return interfaceName; }
610 
612  long GetMetric() const { return metric; }
613 
615  void PrintOn(ostream & strm) const;
616 
617  protected:
622  long metric;
623 
624  friend class PIPSocket;
625  };
626 
627  PARRAY(RouteTable, RouteEntry);
628 
634  static PBoolean GetRouteTable(
635  RouteTable & table
636  );
637 
640  {
641  public:
642  virtual ~RouteTableDetector() { }
643  virtual bool Wait(
644  const PTimeInterval & timeout
645  ) = 0;
646  virtual void Cancel() = 0;
647  };
648 
657  static RouteTableDetector * CreateRouteTableDetector();
658 
661  class InterfaceEntry : public PObject
662  {
664 
665  public:
667  InterfaceEntry();
669  const PString & name,
670  const Address & addr,
671  const Address & mask,
672  const PString & macAddr
673  );
674 
676  virtual void PrintOn(
677  ostream &strm // Stream to print the object into.
678  ) const;
679 
688  const PString & GetName() const { return m_name; }
689 
691  Address GetAddress() const { return m_ipAddress; }
692 
694  Address GetNetMask() const { return m_netMask; }
695 
697  const PString & GetMACAddress() const { return m_macAddress; }
698 
700  static void SanitiseName(PString & name);
701 
702  protected:
707 
708  friend class PIPSocket;
709  };
710 
711  PARRAY(InterfaceTable, InterfaceEntry);
712 
718  InterfaceTable & table,
719  PBoolean includeDown = false
720  );
721 
724  static PString GetInterface(
725  const Address & addr
726  );
727 
731  const PString & ifName,
732  unsigned version = 4
733  );
734 
742  unsigned version = 4
743  );
744 
756  static Address GetGatewayAddress(
757  unsigned version = 4
758  );
759 
772  unsigned version = 4
773  );
774 
787  unsigned version = 4
788  );
789 
798  Address remoteAddress
799  );
800 
802  P_DECLARE_ENUM(QoSType,
803  BackgroundQoS,
804  BestEffortQoS,
805  ExcellentEffortQoS,
806  CriticalQoS,
807  VideoQoS,
808  VoiceQoS,
809  ControlQoS
810  );
817  struct QoS
818  {
819  QoS(QoSType type = BestEffortQoS);
820  QoS(const PString & str);
821 
822  QoSType m_type;
823  int m_dscp; // If between 0 and 63, is used instead of default for QoSType.
824 
826 
827  struct Flow {
828  Flow() { memset(this, 0, sizeof(*this)); }
829  unsigned m_maxBandwidth; // bits/second, includes IP overhead
830  unsigned m_maxPacketSize; // Bytes, includes IP overhead
831  unsigned m_maxLatency; // Microseconds
832  unsigned m_maxJitter; // Microseconds
834 
835  friend ostream & operator<<(ostream & strm, const PIPSocket::QoS & qos);
836  friend istream & operator>>(istream & strm, PIPSocket::QoS & qos);
837  };
838 
840  virtual bool SetQoS(
841  const QoS & qos
842  );
843 
845  const QoS & GetQoS() const { return m_qos; }
847 
848  virtual bool InternalGetLocalAddress(AddressAndPort & addrAndPort);
849  virtual bool InternalGetPeerAddress(AddressAndPort & addrAndPort);
850  virtual bool InternalListen(const Address & bind, unsigned queueSize, WORD port, Reusability reuse);
851 
852 // Include platform dependent part of class
853 #ifdef _WIN32
854 #include "msos/ptlib/ipsock.h"
855 #else
856 #include "unix/ptlib/ipsock.h"
857 #endif
858 
859  protected:
861 
863  {
864  public:
866  sockaddr_wrapper(const AddressAndPort & ipPort);
867  sockaddr_wrapper(const Address & ip, WORD port);
868 
869  sockaddr* operator->() const { return addr; }
870  operator sockaddr*() const { return addr; }
871  socklen_t GetSize() const;
872 
873  PIPSocket::Address GetIP() const;
874  WORD GetPort() const;
875 
876  private:
877  void Construct(const Address & ip, WORD port);
878 
879  sockaddr_storage storage;
880  union {
881  sockaddr_storage * ptr;
882  sockaddr * addr;
883  sockaddr_in * addr4;
884  #if P_HAS_IPV6
885  sockaddr_in6 * addr6;
886  #endif
887  };
888  };
889 };
890 
894 
895 typedef std::vector<PIPSocket::AddressAndPort> PIPSocketAddressAndPortVector;
896 
897 
898 #endif // PTLIB_IPSOCKET_H
899 
900 
901 // End Of File ///////////////////////////////////////////////////////////////