PTLib  Version 2.14.3
 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: 31479 $
30  * $Author: rjongbloed $
31  * $Date: 2014-02-15 19:32:46 +1100 (Sat, 15 Feb 2014) $
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 
409  class PortRange {
410  public:
411  PortRange(WORD basePort = 0, WORD maxPort = 0);
412 
414  void Set(
415  unsigned newBase,
416  unsigned newMax,
417  unsigned dfltRange = 0,
418  unsigned dfltBase = 0
419  );
420 
421  bool IsValid() const { return m_base != 0 && m_base <= m_max; }
422  friend ostream & operator<<(ostream & strm, const PortRange & pr) { return strm << pr.m_base << '-' << pr.m_max; }
423 
425  bool Connect(
426  PIPSocket & socket,
427  const Address & addr,
428  const Address & binding = GetDefaultIpAny()
429  );
430 
432  bool Listen(
433  PIPSocket & socket,
434  const Address & binding = GetDefaultIpAny(),
435  unsigned queueSize = 5,
437  );
438  bool Listen(
439  PIPSocket ** sockets,
440  PINDEX numSockets = 1,
441  const Address & binding = GetDefaultIpAny(),
442  unsigned queueSize = 5,
444  );
445 
447  WORD GetBase() const { return m_base; }
448 
450  WORD GetMax() const { return m_max; }
451 
452  protected:
454  WORD m_base;
455  WORD m_max;
456  };
457 
469  virtual PBoolean Connect(
470  const PString & address
471  );
472  virtual PBoolean Connect(
473  const Address & addr
474  );
475  virtual PBoolean Connect(
476  WORD localPort,
477  const Address & addr
478  );
479  virtual PBoolean Connect(
480  const Address & iface,
481  const Address & addr
482  );
483  virtual PBoolean Connect(
484  const Address & iface,
485  WORD localPort,
486  const Address & addr
487  );
488 
504  virtual PBoolean Listen(
505  unsigned queueSize = 5,
506  WORD port = 0,
508  ) { return InternalListen(GetDefaultIpAny(), queueSize, port, reuse); }
509 
510  virtual PBoolean Listen(
511  const Address & bind,
512  unsigned queueSize = 5,
513  WORD port = 0,
515  ) { return InternalListen(bind, queueSize, port, reuse); }
517 
527  static PString GetHostName();
528  static PString GetHostName(
529  const PString & hostname
530  );
531  static PString GetHostName(
532  const Address & addr
533  );
534 
541  static PBoolean GetHostAddress(
542  Address & addr
543  );
544  static PBoolean GetHostAddress(
545  const PString & hostname,
549  Address & addr
550  );
551 
563  const PString & hostname
564  );
566  const Address & addr
567  /* Name of host to get address for. This may be either a domain name or
568  an IP number in "dot" format.
569  */
570  );
571 
579  static PBoolean IsLocalHost(
583  const PString & hostname
584  );
585 
591  PString GetLocalAddress() const;
592  bool GetLocalAddress(
593  Address & addr
594  ) const;
595  bool GetLocalAddress(
596  Address & addr,
597  WORD & port
598  ) const;
599  bool GetLocalAddress(
600  AddressAndPort & addr
601  ) const;
602 
609  PString GetPeerAddress() const;
610  bool GetPeerAddress(
611  Address & addr
612  ) const;
613  bool GetPeerAddress(
614  Address & addr,
615  WORD & port
616  ) const;
617  bool GetPeerAddress(
618  AddressAndPort & addr
619  ) const;
620 
627 
634 
637  static void ClearNameCache();
638 
641  class RouteEntry : public PObject
642  {
643  PCLASSINFO(RouteEntry, PObject);
644  public:
646  RouteEntry(const Address & addr) : network(addr) { }
647 
649  Address GetNetwork() const { return network; }
650 
652  Address GetNetMask() const { return net_mask; }
653 
655  Address GetDestination() const { return destination; }
656 
658  const PString & GetInterface() const { return interfaceName; }
659 
661  long GetMetric() const { return metric; }
662 
664  void PrintOn(ostream & strm) const;
665 
666  protected:
671  long metric;
672 
673  friend class PIPSocket;
674  };
675 
676  PARRAY(RouteTable, RouteEntry);
677 
683  static PBoolean GetRouteTable(
684  RouteTable & table
685  );
686 
689  {
690  public:
691  virtual ~RouteTableDetector() { }
692  virtual bool Wait(
693  const PTimeInterval & timeout
694  ) = 0;
695  virtual void Cancel() = 0;
696  };
697 
706  static RouteTableDetector * CreateRouteTableDetector();
707 
710  class InterfaceEntry : public PObject
711  {
713 
714  public:
716  InterfaceEntry();
718  const PString & name,
719  const Address & addr,
720  const Address & mask,
721  const PString & macAddr
722  );
723 
725  virtual void PrintOn(
726  ostream &strm // Stream to print the object into.
727  ) const;
728 
737  const PString & GetName() const { return m_name; }
738 
740  Address GetAddress() const { return m_ipAddress; }
741 
743  Address GetNetMask() const { return m_netMask; }
744 
746  const PString & GetMACAddress() const { return m_macAddress; }
747 
749  static void SanitiseName(PString & name);
750 
751  protected:
756 
757  friend class PIPSocket;
758  };
759 
760  PARRAY(InterfaceTable, InterfaceEntry);
761 
767  InterfaceTable & table,
768  PBoolean includeDown = false
769  );
770 
773  static PString GetInterface(
774  const Address & addr
775  );
776 
780  const PString & ifName,
781  unsigned version = 4
782  );
783 
787  const char * ifName = NULL
788  );
789 
797  unsigned version = 4
798  );
799 
811  static Address GetGatewayAddress(
812  unsigned version = 4
813  );
814 
827  unsigned version = 4
828  );
829 
842  unsigned version = 4
843  );
844 
853  const Address & remoteAddress
854  );
855 
857  P_DECLARE_ENUM(QoSType,
858  BackgroundQoS,
859  BestEffortQoS,
860  ExcellentEffortQoS,
861  CriticalQoS,
862  VideoQoS,
863  VoiceQoS,
864  ControlQoS
865  );
872  struct QoS
873  {
874  QoS(QoSType type = BestEffortQoS);
875  QoS(const PString & str);
876 
877  QoSType m_type;
878  int m_dscp; // If between 0 and 63, is used instead of default for QoSType.
879 
881 
882  struct Flow {
883  Flow() { memset(this, 0, sizeof(*this)); }
884  unsigned m_maxBandwidth; // bits/second, includes IP overhead
885  unsigned m_maxPacketSize; // Bytes, includes IP overhead
886  unsigned m_maxLatency; // Microseconds
887  unsigned m_maxJitter; // Microseconds
889 
890  friend ostream & operator<<(ostream & strm, const PIPSocket::QoS & qos);
891  friend istream & operator>>(istream & strm, PIPSocket::QoS & qos);
892  };
893 
895  virtual bool SetQoS(
896  const QoS & qos
897  );
898 
900  const QoS & GetQoS() const { return m_qos; }
902 
903  virtual bool InternalGetLocalAddress(AddressAndPort & addrAndPort);
904  virtual bool InternalGetPeerAddress(AddressAndPort & addrAndPort);
905  virtual bool InternalListen(const Address & bind, unsigned queueSize, WORD port, Reusability reuse);
906 
907 // Include platform dependent part of class
908 #ifdef _WIN32
909 #include "msos/ptlib/ipsock.h"
910 #else
911 #include "unix/ptlib/ipsock.h"
912 #endif
913 
914  protected:
916 
918  {
919  public:
921  sockaddr_wrapper(const AddressAndPort & ipPort);
922  sockaddr_wrapper(const Address & ip, WORD port);
923 
924  sockaddr* operator->() const { return addr; }
925  operator sockaddr*() const { return addr; }
926  socklen_t GetSize() const;
927 
928  PIPSocket::Address GetIP() const;
929  WORD GetPort() const;
930 
931  private:
932  void Construct(const Address & ip, WORD port);
933 
934  sockaddr_storage storage;
935  union {
936  sockaddr_storage * ptr;
937  sockaddr * addr;
938  sockaddr_in * addr4;
939  #if P_HAS_IPV6
940  sockaddr_in6 * addr6;
941  #endif
942  };
943  };
944 };
945 
949 
950 typedef std::vector<PIPSocket::AddressAndPort> PIPSocketAddressAndPortVector;
951 
952 
953 #endif // PTLIB_IPSOCKET_H
954 
955 
956 // End Of File ///////////////////////////////////////////////////////////////