PTLib  Version 2.12.9
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
psockbun.h
Go to the documentation of this file.
1 /*
2  * psockbun.h
3  *
4  * Socket and interface bundle code
5  *
6  * Portable Windows Library
7  *
8  * Copyright (C) 2007 Post Increment
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 Post Increment
23  *
24  * Contributor(s): ______________________________________.
25  *
26  * $Revision: 30178 $
27  * $Author: rjongbloed $
28  * $Date: 2013-07-29 10:46:41 +1000 (Mon, 29 Jul 2013) $
29  */
30 
31 #ifndef PTLIB_PSOCKBUN_H
32 #define PTLIB_PSOCKBUN_H
33 
34 #ifdef P_USE_PRAGMA
35 #pragma interface
36 #endif
37 
38 
39 #include <ptlib.h>
40 #include <ptlib/ipsock.h>
41 #include <ptlib/sockets.h>
42 #include <ptlib/safecoll.h>
43 #include <ptclib/pnat.h>
44 #include <map>
45 
46 
47 #define PINTERFACE_MONITOR_FACTORY_NAME "InterfaceMonitor"
48 
49 
51 
52 class PInterfaceFilter : public PObject {
53  PCLASSINFO(PInterfaceFilter, PObject);
54 
55  public:
56  virtual PIPSocket::InterfaceTable FilterInterfaces(const PIPSocket::Address & destination,
57  PIPSocket::InterfaceTable & interfaces) const = 0;
58 };
59 
60 
62 
72 {
74  public:
75  enum {
77  };
78 
80  unsigned refreshInterval = DefaultRefreshInterval,
81  bool runMonitorThread = true
82  );
83  virtual ~PInterfaceMonitor();
84 
87 
89  void SetRefreshInterval (unsigned refresh);
90 
92  void SetRunMonitorThread (bool runMonitorThread);
93 
99  void Start();
100 
102  void Stop();
103 
105 
111  bool includeLoopBack = false,
112  const PIPSocket::Address & destination = PIPSocket::GetDefaultIpAny()
114  );
115 
122  const PIPSocket::Address & binding,
123  const PIPSocket::Address & destination
124  );
125 
130  bool GetInterfaceInfo(
131  const PString & iface,
132  InterfaceEntry & info
133  ) const;
134 
139  static bool IsMatchingInterface(
140  const PString & iface,
141  const InterfaceEntry & entry
142  );
143 
147  {
148  InterfaceChange(const InterfaceEntry & entry, bool added)
149  : InterfaceEntry(entry)
150  , m_added(added)
151 #if P_NAT
152  , m_natMethod(NULL)
153 #endif
154  { }
155 
156  const bool m_added;
157 
158 #if P_NAT
159  InterfaceChange(const PNatMethod * natMethod, bool added)
160  : m_added(added), m_natMethod(natMethod) { }
161 
162  const PNatMethod * const m_natMethod;
163 #endif
164  };
165 
168 
170  #define PDECLARE_InterfaceNotifier(cls, fn) PDECLARE_NOTIFIER2(PInterfaceMonitor, cls, fn, PInterfaceMonitor::InterfaceChange)
171 
173  #define PCREATE_InterfaceNotifier(fn) PCREATE_NOTIFIER2(fn, PInterfaceMonitor::InterfaceChange)
174 
175  enum {
177  };
178 
181  void AddNotifier(
182  const Notifier & notifier,
183  unsigned priority = DefaultPriority
184  );
185  void RemoveNotifier(
186  const Notifier & notifier
187  );
188 
192  void SetInterfaceFilter(PInterfaceFilter * filter);
193  bool HasInterfaceFilter() const { return m_interfaceFilter != NULL; }
194 
195 #if P_NAT
196  void OnRemoveNatMethod(const PNatMethod * natMethod);
197 #endif
198 
199  protected:
200  virtual void OnShutdown();
201 
202  void UpdateThreadMain();
203 
204  virtual void RefreshInterfaceList();
205  virtual void OnInterfacesChanged(const PIPSocket::InterfaceTable & addedInterfaces, const PIPSocket::InterfaceTable & removedInterfaces);
206 
207  typedef std::multimap<unsigned, Notifier> Notifiers;
210 
211  PIPSocket::InterfaceTable m_interfaces;
213 
218 
221 
223 };
224 
225 
227 
234 {
235  PCLASSINFO(PMonitoredSockets, PSafeObject);
236  protected:
238  bool reuseAddr
239  P_NAT_PARAM(PNatMethod * natMethod)
240  );
241 
242  public:
244 
251  virtual PBoolean Open(
252  WORD port
253  ) = 0;
254 
256  PBoolean IsOpen() const { return opened; }
257 
259  virtual PBoolean Close() = 0;
260 
262  WORD GetPort() const { return localPort; }
263 
265  virtual PBoolean GetAddress(
266  const PString & iface,
267  PIPSocket::Address & address,
268  WORD & port,
269  PBoolean usingNAT
270  ) const = 0;
271 
272  struct BundleParams {
274  : m_buffer(NULL)
275  , m_length(0)
276  , m_addr(0)
277  , m_port(0)
278  , m_lastCount(0)
279  , m_errorCode(PChannel::NoError)
280  , m_errorNumber(0)
281  { }
282 
283  void * m_buffer;
284  PINDEX m_length;
286  WORD m_port;
288  PINDEX m_lastCount;
292  };
293 
299  virtual void WriteToBundle(
300  BundleParams & param
301  ) = 0;
302 
309  virtual void ReadFromBundle(
310  BundleParams & param
311  ) = 0;
312 
319  virtual PStringArray GetInterfaces(
320  bool includeLoopBack = false,
321  const PIPSocket::Address & destination = PIPSocket::GetDefaultIpAny()
323  );
324 
329  virtual bool GetInterfaceInfo(
330  const PString & iface,
331  InterfaceEntry & info
332  ) const;
333 
334 #if P_NAT
335 
336  void SetNatMethod(
337  PNatMethod * method
338  ) { natMethod = method; }
339 
340  // Get the current NAT method, eg STUN client pointer
341  PNatMethod * GetNatMethod() const { return natMethod; }
342 
343 #endif
344 
361  static PMonitoredSockets * Create(
362  const PString & iface,
363  bool reuseAddr = false
364  P_NAT_PARAM(PNatMethod * natMethod = NULL)
365  );
366 
367  protected:
368 #if P_NAT
369  virtual void OnRemoveNatMethod(
370  const PNatMethod * natMethod
371  );
372 #endif
373 
374  struct SocketInfo {
376  : socket(NULL)
377  , inUse(false)
378  { }
379  void Read(PMonitoredSockets & bundle, BundleParams & param);
380  void Write(BundleParams & param);
381 
383  bool inUse;
384  };
385  friend struct SocketInfo;
386 
387  bool CreateSocket(
388  SocketInfo & info,
389  const PIPSocket::Address & binding
390  );
391  bool DestroySocket(SocketInfo & info);
392  bool GetSocketAddress(
393  const SocketInfo & info,
394  PIPSocket::Address & address,
395  WORD & port,
396  bool usingNAT
397  ) const;
398 
399  void ReadFromSocketList(
400  PSocket::SelectList & readers,
401  PUDPSocket * & socket,
402  BundleParams & param
403  );
404 
405  WORD localPort;
407 #if P_NAT
408  PNatMethod * natMethod;
409 #endif
410 
411  bool opened;
413 };
414 
416 
417 
419 
424 {
425  PCLASSINFO(PMonitoredSocketChannel, PChannel);
426  public:
429 
431  const PMonitoredSocketsPtr & sockets,
432  bool shared
433  );
435 
438  virtual PBoolean IsOpen() const;
439  virtual PBoolean Close();
440 
443  virtual PBoolean Read(
444  void * buffer,
445  PINDEX length
446  );
447 
450  virtual PBoolean Write(
451  const void * buffer,
452  PINDEX length
453  );
455 
461  void SetInterface(
462  const PString & iface
463  );
464 
467 
470  bool GetLocal(
471  PIPSocket::Address & address,
472  WORD & port,
473  bool usingNAT
474  );
475 
477  void SetRemote(
478  const PIPSocket::Address & address,
479  WORD port
480  );
481 
483  void SetRemote(
484  const PString & hostAndPort
485  );
486 
488  void GetRemote(
489  PIPSocket::Address & addr,
490  WORD & port
491  ) const { addr = remoteAddress; port = remotePort; }
492 
498  bool flag
499  ) { promiscuousReads = flag; }
500 
502  bool GetPromiscuous() { return promiscuousReads; }
503 
506  PIPSocket::Address & addr,
507  WORD & port
508  ) const { addr = lastReceivedAddress; port = lastReceivedPort; }
509 
512 
514  const PMonitoredSocketsPtr & GetMonitoredSockets() const { return socketBundle; }
516 
517  protected:
518  PMonitoredSocketsPtr socketBundle;
523  bool closing;
529 };
530 
531 
533 
538 {
540  public:
542  const PString & fixedInterface,
543  unsigned ipVersion,
544  bool reuseAddr
545  P_NAT_PARAM(PNatMethod * natMethod = NULL)
546  );
548 
555  virtual PStringArray GetInterfaces(
556  bool includeLoopBack = false,
557  const PIPSocket::Address & destination = PIPSocket::GetDefaultIpAny()
559  );
560 
567  virtual PBoolean Open(
568  WORD port
569  );
570 
572  virtual PBoolean Close();
573 
575  virtual PBoolean GetAddress(
576  const PString & iface,
577  PIPSocket::Address & address,
578  WORD & port,
579  PBoolean usingNAT
580  ) const;
581 
587  virtual void WriteToBundle(
588  BundleParams & param
589  );
590 
597  virtual void ReadFromBundle(
598  BundleParams & param
599  );
600 
601  protected:
604 
605  typedef std::map<std::string, SocketInfo> SocketInfoMap_T;
606 
607  void OpenSocket(const PString & iface);
608  void CloseSocket(SocketInfoMap_T::iterator iterSocket);
609 
612  unsigned m_ipVersion;
613 };
614 
615 
617 
623 {
625  public:
627  const PString & theInterface,
628  bool reuseAddr
629  P_NAT_PARAM(PNatMethod * natMethod = NULL)
630  );
632 
637  virtual PStringArray GetInterfaces(
638  bool includeLoopBack = false,
639  const PIPSocket::Address & destination = PIPSocket::GetDefaultIpAny()
641  );
642 
649  virtual PBoolean Open(
650  WORD port
651  );
652 
654  virtual PBoolean Close();
655 
657  virtual PBoolean GetAddress(
658  const PString & iface,
659  PIPSocket::Address & address,
660  WORD & port,
661  PBoolean usingNAT
662  ) const;
663 
669  virtual void WriteToBundle(
670  BundleParams & param
671  );
672 
679  virtual void ReadFromBundle(
680  BundleParams & param
681  );
682 
683 
684  protected:
687 
688  bool IsInterface(const PString & iface) const;
689 
693 };
694 
695 
696 #endif // PTLIB_PSOCKBUN_H
697 
698 
699 // End Of File ///////////////////////////////////////////////////////////////