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: 21695 $
00027  * $Author: rjongbloed $
00028  * $Date: 2008-12-04 02:01:41 +0000 (Thu, 04 Dec 2008) $
00029  */
00030 
00031 #ifndef _PSOCKBUN_H
00032 #define _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()
00106     );
00107 
00113     bool IsValidBindingForDestination(
00114       const PIPSocket::Address & binding,
00115       const PIPSocket::Address & destination
00116     );
00117 
00122     bool GetInterfaceInfo(
00123       const PString & iface,  
00124       InterfaceEntry & info   
00125     );
00126     
00131     static bool IsMatchingInterface(
00132       const PString & iface,        
00133       const InterfaceEntry & entry  
00134     );
00135     
00139     void SetInterfaceFilter(PInterfaceFilter * filter);
00140     bool HasInterfaceFilter() const { return m_interfaceFilter != NULL; }
00141     
00142     virtual void RefreshInterfaceList();
00143     
00144     void OnRemoveNatMethod(const PNatMethod * natMethod);
00145 
00146   protected:
00147     virtual void OnShutdown();
00148 
00149     void UpdateThreadMain();
00150 
00151     void AddClient(PInterfaceMonitorClient *);
00152     void RemoveClient(PInterfaceMonitorClient *);
00153     
00154     virtual void OnInterfacesChanged(const PIPSocket::InterfaceTable & addedInterfaces, const PIPSocket::InterfaceTable & removedInterfaces);
00155 
00156     typedef PSmartPtr<PInterfaceMonitorClient> ClientPtr;
00157 
00158     typedef std::list<PInterfaceMonitorClient *> ClientList_T;
00159     ClientList_T m_clients;
00160     PMutex       m_clientsMutex;
00161 
00162     PIPSocket::InterfaceTable m_interfaces;
00163     PMutex                    m_interfacesMutex;
00164 
00165     bool           m_runMonitorThread;
00166     PTimeInterval  m_refreshInterval;
00167     PMutex         m_threadMutex;
00168     PThread      * m_updateThread;
00169     PSyncPoint     m_signalUpdate;
00170     bool           m_threadRunning;
00171     
00172     PInterfaceFilter * m_interfaceFilter;
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() 
00206     );
00207 
00212     virtual PBoolean GetInterfaceInfo(
00213       const PString & iface,  
00214       InterfaceEntry & info   
00215     );
00216     
00221     PINDEX GetPriority() const { return priority; }
00222 
00223   protected:
00225     virtual void OnAddInterface(const InterfaceEntry & entry) = 0;
00226 
00228     virtual void OnRemoveInterface(const InterfaceEntry & entry) = 0;
00229     
00231     virtual void OnRemoveNatMethod(const PNatMethod * /*natMethod*/) { }
00232     
00233     PINDEX priority;
00234 
00235   friend class PInterfaceMonitor;
00236 };
00237 
00238 
00240 
00241 class PInterfaceFilter : public PObject {
00242   PCLASSINFO(PInterfaceFilter, PObject);
00243   
00244   public:
00245     virtual PIPSocket::InterfaceTable FilterInterfaces(const PIPSocket::Address & destination,
00246                                                        PIPSocket::InterfaceTable & interfaces) const = 0;
00247 };
00248 
00249 
00251 
00257 class PMonitoredSockets : public PInterfaceMonitorClient
00258 {
00259   PCLASSINFO(PMonitoredSockets, PInterfaceMonitorClient);
00260   protected:
00261     PMonitoredSockets(
00262       bool reuseAddr,
00263       PNatMethod * natMethod
00264     );
00265 
00266   public:
00273     virtual PBoolean Open(
00274       WORD port
00275     ) = 0;
00276 
00278     PBoolean IsOpen() const { return opened; }
00279 
00281     virtual PBoolean Close() = 0;
00282 
00284     WORD GetPort() const { return localPort; }
00285 
00287     virtual PBoolean GetAddress(
00288       const PString & iface,        
00289       PIPSocket::Address & address, 
00290       WORD & port,                  
00291       PBoolean usingNAT                 
00292     ) const = 0;
00293 
00299     virtual PChannel::Errors WriteToBundle(
00300       const void * buffer,              
00301       PINDEX length,                    
00302       const PIPSocket::Address & addr,  
00303       WORD port,                        
00304       const PString & iface,            
00305       PINDEX & lastWriteCount
00306     ) = 0;
00307 
00314     virtual PChannel::Errors ReadFromBundle(
00315       void * buffer,                
00316       PINDEX length,                
00317       PIPSocket::Address & addr,    
00318       WORD & port,                  
00319       PString & iface,              
00320       PINDEX & lastReadCount,       
00321       const PTimeInterval & timeout 
00322     ) = 0;
00323 
00325     void SetNatMethod(
00326       PNatMethod * method
00327     ) { natMethod = method; }
00328 
00329 
00330     // Get the current NAT method, eg STUN client pointer
00331     PNatMethod * GetNatMethod() const { return natMethod; }
00332 
00337     static PMonitoredSockets * Create(
00338       const PString & iface,            
00339       bool reuseAddr = false,           
00340       PNatMethod * natMethod = NULL     
00341     );
00342 
00343   protected:
00344     virtual void OnRemoveNatMethod(
00345       const PNatMethod * natMethod
00346     );
00347 
00348     struct SocketInfo {
00349       SocketInfo()
00350         : socket(NULL)
00351         , inUse(false)
00352       { }
00353       PUDPSocket * socket;
00354       bool         inUse;
00355     };
00356 
00357     bool CreateSocket(
00358       SocketInfo & info,
00359       const PIPSocket::Address & binding
00360     );
00361     bool DestroySocket(SocketInfo & info);
00362     bool GetSocketAddress(
00363       const SocketInfo & info,
00364       PIPSocket::Address & address,
00365       WORD & port,
00366       bool usingNAT
00367     ) const;
00368 
00369     PChannel::Errors WriteToSocket(
00370       const void * buf,
00371       PINDEX len,
00372       const PIPSocket::Address & addr,
00373       WORD port,
00374       const SocketInfo & info,
00375       PINDEX & lastWriteCount
00376     );
00377     PChannel::Errors ReadFromSocket(
00378       SocketInfo & info,
00379       void * buf,
00380       PINDEX len,
00381       PIPSocket::Address & addr,
00382       WORD & port,
00383       PINDEX & lastReadCount,
00384       const PTimeInterval & timeout
00385     );
00386     PChannel::Errors ReadFromSocket(
00387       PSocket::SelectList & readers,
00388       PUDPSocket * & socket,
00389       void * buf,
00390       PINDEX len,
00391       PIPSocket::Address & addr,
00392       WORD & port,
00393       PINDEX & lastReadCount,
00394       const PTimeInterval & timeout
00395     );
00396 
00397     WORD          localPort;
00398     bool          reuseAddress;
00399     PNatMethod  * natMethod;
00400 
00401     bool          opened;
00402     PUDPSocket    interfaceAddedSignal;
00403 };
00404 
00405 typedef PSafePtr<PMonitoredSockets> PMonitoredSocketsPtr;
00406 
00407 
00409 
00413 class PMonitoredSocketChannel : public PChannel
00414 {
00415   PCLASSINFO(PMonitoredSocketChannel, PChannel);
00416   public:
00419 
00420     PMonitoredSocketChannel(
00421       const PMonitoredSocketsPtr & sockets,  
00422       bool shared                            
00423     );
00425 
00428     virtual PBoolean IsOpen() const;
00429     virtual PBoolean Close();
00430 
00433     virtual PBoolean Read(
00434       void * buffer,
00435       PINDEX length
00436     );
00437 
00438     virtual PBoolean Write(
00441       const void * buffer,
00442       PINDEX length
00443     );
00445 
00451     void SetInterface(
00452       const PString & iface   
00453     );
00454 
00456     PString GetInterface();
00457 
00460     bool GetLocal(
00461       PIPSocket::Address & address, 
00462       WORD & port,                  
00463       bool usingNAT                 
00464     );
00465 
00467     void SetRemote(
00468       const PIPSocket::Address & address, 
00469       WORD port                           
00470     );
00471 
00473     void SetRemote(
00474       const PString & hostAndPort 
00475     );
00476 
00478     void GetRemote(
00479       PIPSocket::Address & addr,  
00480       WORD & port                 
00481     ) const { addr = remoteAddress; port = remotePort; }
00482 
00487     void SetPromiscuous(
00488       bool flag   
00489     ) { promiscuousReads = flag; }
00490 
00492     bool GetPromiscuous() { return promiscuousReads; }
00493 
00495     void GetLastReceived(
00496       PIPSocket::Address & addr,  
00497       WORD & port                 
00498     ) const { addr = lastReceivedAddress; port = lastReceivedPort; }
00499 
00501     PString GetLastReceivedInterface() const { return lastReceivedInterface; }
00502 
00504     const PMonitoredSocketsPtr & GetMonitoredSockets() const { return socketBundle; }
00506 
00507   protected:
00508     PMonitoredSocketsPtr socketBundle;
00509     bool                 sharedBundle;
00510     PString              currentInterface;
00511     bool                 promiscuousReads;
00512     PIPSocket::Address   remoteAddress;
00513     bool                 closing;
00514     WORD                 remotePort;
00515     PIPSocket::Address   lastReceivedAddress;
00516     WORD                 lastReceivedPort;
00517     PString              lastReceivedInterface;
00518     PMutex               mutex;
00519 };
00520 
00521 
00523 
00527 class PMonitoredSocketBundle : public PMonitoredSockets
00528 {
00529   PCLASSINFO(PMonitoredSocketBundle, PMonitoredSockets);
00530   public:
00531     PMonitoredSocketBundle(
00532       bool reuseAddr = false,
00533       PNatMethod  * natMethod = NULL
00534     );
00535     ~PMonitoredSocketBundle();
00536 
00543     virtual PBoolean Open(
00544       WORD port
00545     );
00546 
00548     virtual PBoolean Close();
00549 
00551     virtual PBoolean GetAddress(
00552       const PString & iface,        
00553       PIPSocket::Address & address, 
00554       WORD & port,                  
00555       PBoolean usingNAT                 
00556     ) const;
00557 
00563     virtual PChannel::Errors WriteToBundle(
00564       const void * buf,
00565       PINDEX len,
00566       const PIPSocket::Address & addr,
00567       WORD port,
00568       const PString & iface,
00569       PINDEX & lastWriteCount
00570     );
00571 
00578     virtual PChannel::Errors ReadFromBundle(
00579       void * buf,
00580       PINDEX len,
00581       PIPSocket::Address & addr,
00582       WORD & port,
00583       PString & iface,
00584       PINDEX & lastReadCount,
00585       const PTimeInterval & timeout
00586     );
00587 
00588   protected:
00590     virtual void OnAddInterface(const InterfaceEntry & entry);
00591 
00593     virtual void OnRemoveInterface(const InterfaceEntry & entry);
00594 
00595     typedef std::map<std::string, SocketInfo> SocketInfoMap_T;
00596 
00597     void OpenSocket(const PString & iface);
00598     void CloseSocket(SocketInfoMap_T::iterator iterSocket);
00599 
00600     SocketInfoMap_T socketInfoMap;
00601 };
00602 
00603 
00605 
00610 class PSingleMonitoredSocket : public PMonitoredSockets
00611 {
00612   PCLASSINFO(PSingleMonitoredSocket, PMonitoredSockets);
00613   public:
00614     PSingleMonitoredSocket(
00615       const PString & theInterface,
00616       bool reuseAddr = false,
00617       PNatMethod  * natMethod = NULL
00618     );
00619     ~PSingleMonitoredSocket();
00620 
00625     virtual PStringArray GetInterfaces(
00626       PBoolean includeLoopBack = false,  
00627       const PIPSocket::Address & destination = PIPSocket::GetDefaultIpAny()
00628     );
00629 
00636     virtual PBoolean Open(
00637       WORD port
00638     );
00639 
00641     virtual PBoolean Close();
00642 
00644     virtual PBoolean GetAddress(
00645       const PString & iface,        
00646       PIPSocket::Address & address, 
00647       WORD & port,                  
00648       PBoolean usingNAT                 
00649     ) const;
00650 
00656     virtual PChannel::Errors WriteToBundle(
00657       const void * buf,
00658       PINDEX len,
00659       const PIPSocket::Address & addr,
00660       WORD port,
00661       const PString & iface,
00662       PINDEX & lastWriteCount
00663     );
00664 
00671     virtual PChannel::Errors ReadFromBundle(
00672       void * buf,
00673       PINDEX len,
00674       PIPSocket::Address & addr,
00675       WORD & port,
00676       PString & iface,
00677       PINDEX & lastReadCount,
00678       const PTimeInterval & timeout
00679     );
00680 
00681 
00682   protected:
00684     virtual void OnAddInterface(const InterfaceEntry & entry);
00685 
00687     virtual void OnRemoveInterface(const InterfaceEntry & entry);
00688 
00689     bool IsInterface(const PString & iface) const;
00690 
00691     PString        theInterface;
00692     InterfaceEntry theEntry;
00693     SocketInfo     theInfo;
00694 };
00695 
00696 #endif

Generated on Mon Feb 23 01:57:54 2009 for PTLib by  doxygen 1.5.1