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: 24177 $
00027  * $Author: rjongbloed $
00028  * $Date: 2010-04-05 06:52:04 -0500 (Mon, 05 Apr 2010) $
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     static PInterfaceMonitor & GetInstance();
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 PBoolean Open(
00545       WORD port
00546     );
00547 
00549     virtual PBoolean Close();
00550 
00552     virtual PBoolean GetAddress(
00553       const PString & iface,        
00554       PIPSocket::Address & address, 
00555       WORD & port,                  
00556       PBoolean usingNAT             
00557     ) const;
00558 
00564     virtual PChannel::Errors WriteToBundle(
00565       const void * buf,
00566       PINDEX len,
00567       const PIPSocket::Address & addr,
00568       WORD port,
00569       const PString & iface,
00570       PINDEX & lastWriteCount
00571     );
00572 
00579     virtual PChannel::Errors ReadFromBundle(
00580       void * buf,
00581       PINDEX len,
00582       PIPSocket::Address & addr,
00583       WORD & port,
00584       PString & iface,
00585       PINDEX & lastReadCount,
00586       const PTimeInterval & timeout
00587     );
00588 
00589   protected:
00591     virtual void OnAddInterface(const InterfaceEntry & entry);
00592 
00594     virtual void OnRemoveInterface(const InterfaceEntry & entry);
00595 
00596     typedef std::map<std::string, SocketInfo> SocketInfoMap_T;
00597 
00598     void OpenSocket(const PString & iface);
00599     void CloseSocket(SocketInfoMap_T::iterator iterSocket);
00600 
00601     SocketInfoMap_T socketInfoMap;
00602 };
00603 
00604 
00606 
00611 class PSingleMonitoredSocket : public PMonitoredSockets
00612 {
00613   PCLASSINFO(PSingleMonitoredSocket, PMonitoredSockets);
00614   public:
00615     PSingleMonitoredSocket(
00616       const PString & theInterface,
00617       bool reuseAddr = false,
00618       PNatMethod  * natMethod = NULL
00619     );
00620     ~PSingleMonitoredSocket();
00621 
00626     virtual PStringArray GetInterfaces(
00627       bool includeLoopBack = false,  
00628       const PIPSocket::Address & destination = PIPSocket::GetDefaultIpAny()
00630     );
00631 
00638     virtual PBoolean Open(
00639       WORD port
00640     );
00641 
00643     virtual PBoolean Close();
00644 
00646     virtual PBoolean GetAddress(
00647       const PString & iface,        
00648       PIPSocket::Address & address, 
00649       WORD & port,                  
00650       PBoolean usingNAT             
00651     ) const;
00652 
00658     virtual PChannel::Errors WriteToBundle(
00659       const void * buf,
00660       PINDEX len,
00661       const PIPSocket::Address & addr,
00662       WORD port,
00663       const PString & iface,
00664       PINDEX & lastWriteCount
00665     );
00666 
00673     virtual PChannel::Errors ReadFromBundle(
00674       void * buf,
00675       PINDEX len,
00676       PIPSocket::Address & addr,
00677       WORD & port,
00678       PString & iface,
00679       PINDEX & lastReadCount,
00680       const PTimeInterval & timeout
00681     );
00682 
00683 
00684   protected:
00686     virtual void OnAddInterface(const InterfaceEntry & entry);
00687 
00689     virtual void OnRemoveInterface(const InterfaceEntry & entry);
00690 
00691     bool IsInterface(const PString & iface) const;
00692 
00693     PString        theInterface;
00694     InterfaceEntry theEntry;
00695     SocketInfo     theInfo;
00696 };
00697 
00698 
00699 #endif // PTLIB_PSOCKBUN_H
00700 
00701 
00702 // End Of File ///////////////////////////////////////////////////////////////

Generated on Fri Oct 14 01:44:09 2011 for PTLib by  doxygen 1.4.7