# psockbun.h

Go to the documentation of this file.

    00001 /*
    00002  * psockbun.h
    00003  *
    00004  * Socket and interface bundle code
    00005  *
    00006  * Portable Windows Library
    00007  *
    00008  * Copyright (C) 2007 Post Increment
    00009  *
    00010  * The contents of this file are subject to the Mozilla Public License
    00011  * Version 1.0 (the "License"); you may not use this file except in
    00012  * compliance with the License. You may obtain a copy of the License at
    00013  * http://www.mozilla.org/MPL/
    00014  *
    00015  * Software distributed under the License is distributed on an "AS IS"
    00016  * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
    00017  * the License for the specific language governing rights and limitations
    00018  * under the License.
    00019  *
    00020  * The Original Code is Portable Windows Library.
    00021  *
    00022  * The Initial Developer of the Original Code is Post Increment
    00023  *
    00024  * Contributor(s): ______________________________________.
    00025  *
    00026  * $Revision: 28152 $
    00027  * $Author: rjongbloed $
    00028  * $Date: 2012-08-06 22:03:48 -0500 (Mon, 06 Aug 2012) $
    00029  */
    00030
    00031 #ifndef PTLIB_PSOCKBUN_H
    00032 #define PTLIB_PSOCKBUN_H
    00033
    00034 #ifdef P_USE_PRAGMA
    00035 #pragma interface
    00036 #endif
    00037
    00038
    00039 #include <ptlib.h>
    00040 #include <ptlib/ipsock.h>
    00041 #include <ptlib/sockets.h>
    00042 #include <ptlib/safecoll.h>
    00043 #include <list>
    00044
    00045
    00046 class PNatMethod;
    00047 class PInterfaceMonitorClient;
    00048 class PInterfaceFilter;
    00049
    00050
    00051 #define PINTERFACE_MONITOR_FACTORY_NAME "InterfaceMonitor"
    00052
    00053
    00055
    00064 class PInterfaceMonitor : public PProcessStartup
    00065 {
    00066   PCLASSINFO(PInterfaceMonitor, PProcessStartup);
    00067   public:
    00068     enum {
    00069       DefaultRefreshInterval = 60000
    00070     };
    00071
    00072     PInterfaceMonitor(
    00073       unsigned refreshInterval = DefaultRefreshInterval,
    00074       bool runMonitorThread = true
    00075     );
    00076     virtual ~PInterfaceMonitor();
    00077
    00079     PFACTORY_GET_SINGLETON(PProcessStartupFactory, PInterfaceMonitor);
    00080
    00082     void SetRefreshInterval (unsigned refresh);
    00083
    00085     void SetRunMonitorThread (bool runMonitorThread);
    00086
    00092     void Start();
    00093
    00095     void Stop();
    00096
    00097     typedef PIPSocket::InterfaceEntry InterfaceEntry;
    00098
    00103     PStringArray GetInterfaces(
    00104       bool includeLoopBack = false,
    00105       const PIPSocket::Address & destination = PIPSocket::GetDefaultIpAny()
    00107     );
    00108
    00114     bool IsValidBindingForDestination(
    00115       const PIPSocket::Address & binding,
    00116       const PIPSocket::Address & destination
    00117     );
    00118
    00123     bool GetInterfaceInfo(
    00124       const PString & iface,
    00125       InterfaceEntry & info
    00126     ) const;
    00127
    00132     static bool IsMatchingInterface(
    00133       const PString & iface,
    00134       const InterfaceEntry & entry
    00135     );
    00136
    00140     void SetInterfaceFilter(PInterfaceFilter * filter);
    00141     bool HasInterfaceFilter() const { return m_interfaceFilter != NULL; }
    00142
    00143     virtual void RefreshInterfaceList();
    00144
    00145     void OnRemoveNatMethod(const PNatMethod * natMethod);
    00146
    00147   protected:
    00148     virtual void OnShutdown();
    00149
    00150     void UpdateThreadMain();
    00151
    00152     void AddClient(PInterfaceMonitorClient *);
    00153     void RemoveClient(PInterfaceMonitorClient *);
    00154
    00155     virtual void OnInterfacesChanged(const PIPSocket::InterfaceTable & addedInterfaces, const PIPSocket::InterfaceTable & removedInterfaces);
    00156
    00157     typedef PSmartPtr<PInterfaceMonitorClient> ClientPtr;
    00158
    00159     typedef std::list<PInterfaceMonitorClient *> ClientList_T;
    00160     ClientList_T m_clients;
    00161     PMutex       m_clientsMutex;
    00162
    00163     PIPSocket::InterfaceTable m_interfaces;
    00164     PMutex                    m_interfacesMutex;
    00165
    00166     bool           m_runMonitorThread;
    00167     PTimeInterval  m_refreshInterval;
    00168     PMutex         m_threadMutex;
    00169     PThread      * m_updateThread;
    00170
    00171     PInterfaceFilter * m_interfaceFilter;
    00172     PIPSocket::RouteTableDetector * m_changedDetector;
    00173
    00174   friend class PInterfaceMonitorClient;
    00175 };
    00176
    00177
    00179
    00185 class PInterfaceMonitorClient : public PSafeObject
    00186 {
    00187   PCLASSINFO(PInterfaceMonitorClient, PSafeObject);
    00188   public:
    00189     enum {
    00190       DefaultPriority = 50,
    00191     };
    00192     PInterfaceMonitorClient(PINDEX priority = DefaultPriority);
    00193     ~PInterfaceMonitorClient();
    00194
    00195     typedef PIPSocket::InterfaceEntry InterfaceEntry;
    00196
    00203     virtual PStringArray GetInterfaces(
    00204       bool includeLoopBack = false,
    00205       const PIPSocket::Address & destination = PIPSocket::GetDefaultIpAny()
    00207     );
    00208
    00213     virtual PBoolean GetInterfaceInfo(
    00214       const PString & iface,
    00215       InterfaceEntry & info
    00216     ) const;
    00217
    00222     PINDEX GetPriority() const { return priority; }
    00223
    00224   protected:
    00226     virtual void OnAddInterface(const InterfaceEntry & entry) = 0;
    00227
    00229     virtual void OnRemoveInterface(const InterfaceEntry & entry) = 0;
    00230
    00232     virtual void OnRemoveNatMethod(const PNatMethod * /*natMethod*/) { }
    00233
    00234     PINDEX priority;
    00235
    00236   friend class PInterfaceMonitor;
    00237 };
    00238
    00239
    00241
    00242 class PInterfaceFilter : public PObject {
    00243   PCLASSINFO(PInterfaceFilter, PObject);
    00244
    00245   public:
    00246     virtual PIPSocket::InterfaceTable FilterInterfaces(const PIPSocket::Address & destination,
    00247                                                        PIPSocket::InterfaceTable & interfaces) const = 0;
    00248 };
    00249
    00250
    00252
    00258 class PMonitoredSockets : public PInterfaceMonitorClient
    00259 {
    00260   PCLASSINFO(PMonitoredSockets, PInterfaceMonitorClient);
    00261   protected:
    00262     PMonitoredSockets(
    00263       bool reuseAddr,
    00264       PNatMethod * natMethod
    00265     );
    00266
    00267   public:
    00274     virtual PBoolean Open(
    00275       WORD port
    00276     ) = 0;
    00277
    00279     PBoolean IsOpen() const { return opened; }
    00280
    00282     virtual PBoolean Close() = 0;
    00283
    00285     WORD GetPort() const { return localPort; }
    00286
    00288     virtual PBoolean GetAddress(
    00289       const PString & iface,
    00290       PIPSocket::Address & address,
    00291       WORD & port,
    00292       PBoolean usingNAT
    00293     ) const = 0;
    00294
    00300     virtual PChannel::Errors WriteToBundle(
    00301       const void * buffer,
    00302       PINDEX length,
    00303       const PIPSocket::Address & addr,
    00304       WORD port,
    00305       const PString & iface,
    00306       PINDEX & lastWriteCount
    00307     ) = 0;
    00308
    00315     virtual PChannel::Errors ReadFromBundle(
    00316       void * buffer,
    00317       PINDEX length,
    00318       PIPSocket::Address & addr,
    00319       WORD & port,
    00320       PString & iface,
    00321       PINDEX & lastReadCount,
    00322       const PTimeInterval & timeout
    00323     ) = 0;
    00324
    00326     void SetNatMethod(
    00327       PNatMethod * method
    00328     ) { natMethod = method; }
    00329
    00330
    00331     // Get the current NAT method, eg STUN client pointer
    00332     PNatMethod * GetNatMethod() const { return natMethod; }
    00333
    00338     static PMonitoredSockets * Create(
    00339       const PString & iface,
    00340       bool reuseAddr = false,
    00341       PNatMethod * natMethod = NULL
    00342     );
    00343
    00344   protected:
    00345     virtual void OnRemoveNatMethod(
    00346       const PNatMethod * natMethod
    00347     );
    00348
    00349     struct SocketInfo {
    00350       SocketInfo()
    00351         : socket(NULL)
    00352         , inUse(false)
    00353       { }
    00354       PUDPSocket * socket;
    00355       bool         inUse;
    00356     };
    00357
    00358     bool CreateSocket(
    00359       SocketInfo & info,
    00360       const PIPSocket::Address & binding
    00361     );
    00362     bool DestroySocket(SocketInfo & info);
    00363     bool GetSocketAddress(
    00364       const SocketInfo & info,
    00365       PIPSocket::Address & address,
    00366       WORD & port,
    00367       bool usingNAT
    00368     ) const;
    00369
    00370     PChannel::Errors WriteToSocket(
    00371       const void * buf,
    00372       PINDEX len,
    00373       const PIPSocket::Address & addr,
    00374       WORD port,
    00375       const SocketInfo & info,
    00376       PINDEX & lastWriteCount
    00377     );
    00378     PChannel::Errors ReadFromSocket(
    00379       SocketInfo & info,
    00380       void * buf,
    00381       PINDEX len,
    00382       PIPSocket::Address & addr,
    00383       WORD & port,
    00384       PINDEX & lastReadCount,
    00385       const PTimeInterval & timeout
    00386     );
    00387     PChannel::Errors ReadFromSocket(
    00388       PSocket::SelectList & readers,
    00389       PUDPSocket * & socket,
    00390       void * buf,
    00391       PINDEX len,
    00392       PIPSocket::Address & addr,
    00393       WORD & port,
    00394       PINDEX & lastReadCount,
    00395       const PTimeInterval & timeout
    00396     );
    00397
    00398     WORD          localPort;
    00399     bool          reuseAddress;
    00400     PNatMethod  * natMethod;
    00401
    00402     bool          opened;
    00403     PUDPSocket    interfaceAddedSignal;
    00404 };
    00405
    00406 typedef PSafePtr<PMonitoredSockets> PMonitoredSocketsPtr;
    00407
    00408
    00410
    00414 class PMonitoredSocketChannel : public PChannel
    00415 {
    00416   PCLASSINFO(PMonitoredSocketChannel, PChannel);
    00417   public:
    00420
    00421     PMonitoredSocketChannel(
    00422       const PMonitoredSocketsPtr & sockets,
    00423       bool shared
    00424     );
    00426
    00429     virtual PBoolean IsOpen() const;
    00430     virtual PBoolean Close();
    00431
    00434     virtual PBoolean Read(
    00435       void * buffer,
    00436       PINDEX length
    00437     );
    00438
    00441     virtual PBoolean Write(
    00442       const void * buffer,
    00443       PINDEX length
    00444     );
    00446
    00452     void SetInterface(
    00453       const PString & iface
    00454     );
    00455
    00457     PString GetInterface();
    00458
    00461     bool GetLocal(
    00462       PIPSocket::Address & address,
    00463       WORD & port,
    00464       bool usingNAT
    00465     );
    00466
    00468     void SetRemote(
    00469       const PIPSocket::Address & address,
    00470       WORD port
    00471     );
    00472
    00474     void SetRemote(
    00475       const PString & hostAndPort
    00476     );
    00477
    00479     void GetRemote(
    00480       PIPSocket::Address & addr,
    00481       WORD & port
    00482     ) const { addr = remoteAddress; port = remotePort; }
    00483
    00488     void SetPromiscuous(
    00489       bool flag
    00490     ) { promiscuousReads = flag; }
    00491
    00493     bool GetPromiscuous() { return promiscuousReads; }
    00494
    00496     void GetLastReceived(
    00497       PIPSocket::Address & addr,
    00498       WORD & port
    00499     ) const { addr = lastReceivedAddress; port = lastReceivedPort; }
    00500
    00502     PString GetLastReceivedInterface() const { return lastReceivedInterface; }
    00503
    00505     const PMonitoredSocketsPtr & GetMonitoredSockets() const { return socketBundle; }
    00507
    00508   protected:
    00509     PMonitoredSocketsPtr socketBundle;
    00510     bool                 sharedBundle;
    00511     PString              currentInterface;
    00512     bool                 promiscuousReads;
    00513     PIPSocket::Address   remoteAddress;
    00514     bool                 closing;
    00515     WORD                 remotePort;
    00516     PIPSocket::Address   lastReceivedAddress;
    00517     WORD                 lastReceivedPort;
    00518     PString              lastReceivedInterface;
    00519     PMutex               mutex;
    00520 };
    00521
    00522
    00524
    00528 class PMonitoredSocketBundle : public PMonitoredSockets
    00529 {
    00530   PCLASSINFO(PMonitoredSocketBundle, PMonitoredSockets);
    00531   public:
    00532     PMonitoredSocketBundle(
    00533       bool reuseAddr = false,
    00534       PNatMethod  * natMethod = NULL
    00535     );
    00536     ~PMonitoredSocketBundle();
    00537
    00544     virtual PStringArray GetInterfaces(
    00545       bool includeLoopBack = false,
    00546       const PIPSocket::Address & destination = PIPSocket::GetDefaultIpAny()
    00548     );
    00549
    00556     virtual PBoolean Open(
    00557       WORD port
    00558     );
    00559
    00561     virtual PBoolean Close();
    00562
    00564     virtual PBoolean GetAddress(
    00565       const PString & iface,
    00566       PIPSocket::Address & address,
    00567       WORD & port,
    00568       PBoolean usingNAT
    00569     ) const;
    00570
    00576     virtual PChannel::Errors WriteToBundle(
    00577       const void * buf,
    00578       PINDEX len,
    00579       const PIPSocket::Address & addr,
    00580       WORD port,
    00581       const PString & iface,
    00582       PINDEX & lastWriteCount
    00583     );
    00584
    00591     virtual PChannel::Errors ReadFromBundle(
    00592       void * buf,
    00593       PINDEX len,
    00594       PIPSocket::Address & addr,
    00595       WORD & port,
    00596       PString & iface,
    00597       PINDEX & lastReadCount,
    00598       const PTimeInterval & timeout
    00599     );
    00600
    00601   protected:
    00603     virtual void OnAddInterface(const InterfaceEntry & entry);
    00604
    00606     virtual void OnRemoveInterface(const InterfaceEntry & entry);
    00607
    00608     typedef std::map<std::string, SocketInfo> SocketInfoMap_T;
    00609
    00610     void OpenSocket(const PString & iface);
    00611     void CloseSocket(SocketInfoMap_T::iterator iterSocket);
    00612
    00613     SocketInfoMap_T socketInfoMap;
    00614 };
    00615
    00616
    00618
    00623 class PSingleMonitoredSocket : public PMonitoredSockets
    00624 {
    00625   PCLASSINFO(PSingleMonitoredSocket, PMonitoredSockets);
    00626   public:
    00627     PSingleMonitoredSocket(
    00628       const PString & theInterface,
    00629       bool reuseAddr = false,
    00630       PNatMethod  * natMethod = NULL
    00631     );
    00632     ~PSingleMonitoredSocket();
    00633
    00638     virtual PStringArray GetInterfaces(
    00639       bool includeLoopBack = false,
    00640       const PIPSocket::Address & destination = PIPSocket::GetDefaultIpAny()
    00642     );
    00643
    00650     virtual PBoolean Open(
    00651       WORD port
    00652     );
    00653
    00655     virtual PBoolean Close();
    00656
    00658     virtual PBoolean GetAddress(
    00659       const PString & iface,
    00660       PIPSocket::Address & address,
    00661       WORD & port,
    00662       PBoolean usingNAT
    00663     ) const;
    00664
    00670     virtual PChannel::Errors WriteToBundle(
    00671       const void * buf,
    00672       PINDEX len,
    00673       const PIPSocket::Address & addr,
    00674       WORD port,
    00675       const PString & iface,
    00676       PINDEX & lastWriteCount
    00677     );
    00678
    00685     virtual PChannel::Errors ReadFromBundle(
    00686       void * buf,
    00687       PINDEX len,
    00688       PIPSocket::Address & addr,
    00689       WORD & port,
    00690       PString & iface,
    00691       PINDEX & lastReadCount,
    00692       const PTimeInterval & timeout
    00693     );
    00694
    00695
    00696   protected:
    00698     virtual void OnAddInterface(const InterfaceEntry & entry);
    00699
    00701     virtual void OnRemoveInterface(const InterfaceEntry & entry);
    00702
    00703     bool IsInterface(const PString & iface) const;
    00704
    00705     PString        theInterface;
    00706     InterfaceEntry theEntry;
    00707     SocketInfo     theInfo;
    00708 };
    00709
    00710
    00711 #endif // PTLIB_PSOCKBUN_H
    00712
    00713
    00714 // End Of File ///////////////////////////////////////////////////////////////