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: 20385 $
00027  * $Author: rjongbloed $
00028  * $Date: 2008-06-04 10:40:38 +0000 (Wed, 04 Jun 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     bool Start();
00083 
00085     void Stop();
00086 
00087     typedef PIPSocket::InterfaceEntry InterfaceEntry;
00088 
00093     PStringArray GetInterfaces(
00094       bool includeLoopBack = false,  
00095       const PIPSocket::Address & destination = PIPSocket::GetDefaultIpAny()
00096     );
00097 
00103     bool IsValidBindingForDestination(
00104       const PIPSocket::Address & binding,
00105       const PIPSocket::Address & destination
00106     );
00107 
00112     bool GetInterfaceInfo(
00113       const PString & iface,  
00114       InterfaceEntry & info   
00115     );
00116     
00121     static bool IsMatchingInterface(
00122       const PString & iface,        
00123       const InterfaceEntry & entry  
00124     );
00125     
00129     void SetInterfaceFilter(PInterfaceFilter * filter);
00130     
00131     virtual void RefreshInterfaceList();
00132     
00133     void OnRemoveNatMethod(const PNatMethod * natMethod);
00134 
00135   protected:
00136     virtual void OnShutdown();
00137 
00138     void UpdateThreadMain();
00139 
00140     void AddClient(PInterfaceMonitorClient *);
00141     void RemoveClient(PInterfaceMonitorClient *);
00142     
00143     virtual void OnInterfacesChanged(const PIPSocket::InterfaceTable & addedInterfaces, const PIPSocket::InterfaceTable & removedInterfaces);
00144 
00145     typedef PSmartPtr<PInterfaceMonitorClient> ClientPtr;
00146 
00147     typedef std::list<PInterfaceMonitorClient *> ClientList_T;
00148     ClientList_T              currentClients;
00149     PIPSocket::InterfaceTable currentInterfaces;
00150 
00151     bool           runMonitorThread;
00152     PTimeInterval  refreshInterval;
00153     PMutex         mutex;
00154     PThread      * updateThread;
00155     PSyncPoint     threadRunning;
00156     
00157     PInterfaceFilter * interfaceFilter;
00158 
00159   friend class PInterfaceMonitorClient;
00160 };
00161 
00162 
00164 
00170 class PInterfaceMonitorClient : public PSafeObject
00171 {
00172   PCLASSINFO(PInterfaceMonitorClient, PSafeObject);
00173   public:
00174     enum {
00175       DefaultPriority = 50,
00176     };
00177     PInterfaceMonitorClient(PINDEX priority = DefaultPriority);
00178     ~PInterfaceMonitorClient();
00179 
00180     typedef PIPSocket::InterfaceEntry InterfaceEntry;
00181 
00188     virtual PStringArray GetInterfaces(
00189       bool includeLoopBack = false,  
00190       const PIPSocket::Address & destination = PIPSocket::GetDefaultIpAny() 
00191     );
00192 
00197     virtual PBoolean GetInterfaceInfo(
00198       const PString & iface,  
00199       InterfaceEntry & info   
00200     );
00201     
00206     PINDEX GetPriority() const { return priority; }
00207 
00208   protected:
00210     virtual void OnAddInterface(const InterfaceEntry & entry) = 0;
00211 
00213     virtual void OnRemoveInterface(const InterfaceEntry & entry) = 0;
00214     
00216     virtual void OnRemoveNatMethod(const PNatMethod * /*natMethod*/) { }
00217     
00218     PINDEX priority;
00219 
00220   friend class PInterfaceMonitor;
00221 };
00222 
00223 
00225 
00226 class PInterfaceFilter : public PObject {
00227   PCLASSINFO(PInterfaceFilter, PObject);
00228   
00229   public:
00230     virtual PIPSocket::InterfaceTable FilterInterfaces(const PIPSocket::Address & destination,
00231                                                        PIPSocket::InterfaceTable & interfaces) const = 0;
00232 };
00233 
00234 
00236 
00242 class PMonitoredSockets : public PInterfaceMonitorClient
00243 {
00244   PCLASSINFO(PMonitoredSockets, PInterfaceMonitorClient);
00245   protected:
00246     PMonitoredSockets(
00247       bool reuseAddr,
00248       PNatMethod * natMethod
00249     );
00250 
00251   public:
00258     virtual PBoolean Open(
00259       WORD port
00260     ) = 0;
00261 
00263     PBoolean IsOpen() const { return opened; }
00264 
00266     virtual PBoolean Close() = 0;
00267 
00269     WORD GetPort() const { return localPort; }
00270 
00272     virtual PBoolean GetAddress(
00273       const PString & iface,        
00274       PIPSocket::Address & address, 
00275       WORD & port,                  
00276       PBoolean usingNAT                 
00277     ) const = 0;
00278 
00284     virtual PChannel::Errors WriteToBundle(
00285       const void * buffer,              
00286       PINDEX length,                    
00287       const PIPSocket::Address & addr,  
00288       WORD port,                        
00289       const PString & iface,            
00290       PINDEX & lastWriteCount
00291     ) = 0;
00292 
00299     virtual PChannel::Errors ReadFromBundle(
00300       void * buffer,                
00301       PINDEX length,                
00302       PIPSocket::Address & addr,    
00303       WORD & port,                  
00304       PString & iface,              
00305       PINDEX & lastReadCount,       
00306       const PTimeInterval & timeout 
00307     ) = 0;
00308 
00310     void SetNatMethod(
00311       PNatMethod * method
00312     ) { natMethod = method; }
00313 
00314 
00315     // Get the current NAT method, eg STUN client pointer
00316     PNatMethod * GetNatMethod() const { return natMethod; }
00317 
00322     static PMonitoredSockets * Create(
00323       const PString & iface,            
00324       bool reuseAddr = false,           
00325       PNatMethod * natMethod = NULL     
00326     );
00327 
00328   protected:
00329     virtual void OnRemoveNatMethod(
00330       const PNatMethod * natMethod
00331     );
00332 
00333     struct SocketInfo {
00334       SocketInfo()
00335         : socket(NULL)
00336         , inUse(false)
00337       { }
00338       PUDPSocket * socket;
00339       bool         inUse;
00340     };
00341 
00342     bool CreateSocket(
00343       SocketInfo & info,
00344       const PIPSocket::Address & binding
00345     );
00346     bool DestroySocket(SocketInfo & info);
00347     bool GetSocketAddress(
00348       const SocketInfo & info,
00349       PIPSocket::Address & address,
00350       WORD & port,
00351       bool usingNAT
00352     ) const;
00353 
00354     PChannel::Errors WriteToSocket(
00355       const void * buf,
00356       PINDEX len,
00357       const PIPSocket::Address & addr,
00358       WORD port,
00359       const SocketInfo & info,
00360       PINDEX & lastWriteCount
00361     );
00362     PChannel::Errors ReadFromSocket(
00363       SocketInfo & info,
00364       void * buf,
00365       PINDEX len,
00366       PIPSocket::Address & addr,
00367       WORD & port,
00368       PINDEX & lastReadCount,
00369       const PTimeInterval & timeout
00370     );
00371     PChannel::Errors ReadFromSocket(
00372       PSocket::SelectList & readers,
00373       PUDPSocket * & socket,
00374       void * buf,
00375       PINDEX len,
00376       PIPSocket::Address & addr,
00377       WORD & port,
00378       PINDEX & lastReadCount,
00379       const PTimeInterval & timeout
00380     );
00381 
00382     WORD          localPort;
00383     bool          reuseAddress;
00384     PNatMethod  * natMethod;
00385 
00386     bool          opened;
00387     PUDPSocket    interfaceAddedSignal;
00388 };
00389 
00390 typedef PSafePtr<PMonitoredSockets> PMonitoredSocketsPtr;
00391 
00392 
00394 
00398 class PMonitoredSocketChannel : public PChannel
00399 {
00400   PCLASSINFO(PMonitoredSocketChannel, PChannel);
00401   public:
00404 
00405     PMonitoredSocketChannel(
00406       const PMonitoredSocketsPtr & sockets,  
00407       bool shared                            
00408     );
00410 
00413     virtual PBoolean IsOpen() const;
00414     virtual PBoolean Close();
00415 
00418     virtual PBoolean Read(
00419       void * buffer,
00420       PINDEX length
00421     );
00422 
00423     virtual PBoolean Write(
00426       const void * buffer,
00427       PINDEX length
00428     );
00430 
00436     void SetInterface(
00437       const PString & iface   
00438     );
00439 
00441     const PString & GetInterface();
00442 
00445     bool GetLocal(
00446       PIPSocket::Address & address, 
00447       WORD & port,                  
00448       bool usingNAT                 
00449     );
00450 
00452     void SetRemote(
00453       const PIPSocket::Address & address, 
00454       WORD port                           
00455     );
00456 
00458     void SetRemote(
00459       const PString & hostAndPort 
00460     );
00461 
00463     void GetRemote(
00464       PIPSocket::Address & addr,  
00465       WORD & port                 
00466     ) const { addr = remoteAddress; port = remotePort; }
00467 
00472     void SetPromiscuous(
00473       bool flag   
00474     ) { promiscuousReads = flag; }
00475 
00477     bool GetPromiscuous() { return promiscuousReads; }
00478 
00480     void GetLastReceived(
00481       PIPSocket::Address & addr,  
00482       WORD & port                 
00483     ) const { addr = lastReceivedAddress; port = lastReceivedPort; }
00484 
00486     PString GetLastReceivedInterface() const { return lastReceivedInterface; }
00487 
00489     const PMonitoredSocketsPtr & GetMonitoredSockets() const { return socketBundle; }
00491 
00492   protected:
00493     PMonitoredSocketsPtr socketBundle;
00494     bool                 sharedBundle;
00495     PString              currentInterface;
00496     bool                 promiscuousReads;
00497     PIPSocket::Address   remoteAddress;
00498     bool                 closing;
00499     WORD                 remotePort;
00500     PIPSocket::Address   lastReceivedAddress;
00501     WORD                 lastReceivedPort;
00502     PString              lastReceivedInterface;
00503 };
00504 
00505 
00507 
00511 class PMonitoredSocketBundle : public PMonitoredSockets
00512 {
00513   PCLASSINFO(PMonitoredSocketBundle, PMonitoredSockets);
00514   public:
00515     PMonitoredSocketBundle(
00516       bool reuseAddr = false,
00517       PNatMethod  * natMethod = NULL
00518     );
00519     ~PMonitoredSocketBundle();
00520 
00527     virtual PBoolean Open(
00528       WORD port
00529     );
00530 
00532     virtual PBoolean Close();
00533 
00535     virtual PBoolean GetAddress(
00536       const PString & iface,        
00537       PIPSocket::Address & address, 
00538       WORD & port,                  
00539       PBoolean usingNAT                 
00540     ) const;
00541 
00547     virtual PChannel::Errors WriteToBundle(
00548       const void * buf,
00549       PINDEX len,
00550       const PIPSocket::Address & addr,
00551       WORD port,
00552       const PString & iface,
00553       PINDEX & lastWriteCount
00554     );
00555 
00562     virtual PChannel::Errors ReadFromBundle(
00563       void * buf,
00564       PINDEX len,
00565       PIPSocket::Address & addr,
00566       WORD & port,
00567       PString & iface,
00568       PINDEX & lastReadCount,
00569       const PTimeInterval & timeout
00570     );
00571 
00572   protected:
00574     virtual void OnAddInterface(const InterfaceEntry & entry);
00575 
00577     virtual void OnRemoveInterface(const InterfaceEntry & entry);
00578 
00579     typedef std::map<std::string, SocketInfo> SocketInfoMap_T;
00580 
00581     void OpenSocket(const PString & iface);
00582     void CloseSocket(SocketInfoMap_T::iterator iterSocket);
00583 
00584     SocketInfoMap_T socketInfoMap;
00585 };
00586 
00587 
00589 
00594 class PSingleMonitoredSocket : public PMonitoredSockets
00595 {
00596   PCLASSINFO(PSingleMonitoredSocket, PMonitoredSockets);
00597   public:
00598     PSingleMonitoredSocket(
00599       const PString & theInterface,
00600       bool reuseAddr = false,
00601       PNatMethod  * natMethod = NULL
00602     );
00603     ~PSingleMonitoredSocket();
00604 
00609     virtual PStringArray GetInterfaces(
00610       PBoolean includeLoopBack = false,  
00611       const PIPSocket::Address & destination = PIPSocket::GetDefaultIpAny()
00612     );
00613 
00620     virtual PBoolean Open(
00621       WORD port
00622     );
00623 
00625     virtual PBoolean Close();
00626 
00628     virtual PBoolean GetAddress(
00629       const PString & iface,        
00630       PIPSocket::Address & address, 
00631       WORD & port,                  
00632       PBoolean usingNAT                 
00633     ) const;
00634 
00640     virtual PChannel::Errors WriteToBundle(
00641       const void * buf,
00642       PINDEX len,
00643       const PIPSocket::Address & addr,
00644       WORD port,
00645       const PString & iface,
00646       PINDEX & lastWriteCount
00647     );
00648 
00655     virtual PChannel::Errors ReadFromBundle(
00656       void * buf,
00657       PINDEX len,
00658       PIPSocket::Address & addr,
00659       WORD & port,
00660       PString & iface,
00661       PINDEX & lastReadCount,
00662       const PTimeInterval & timeout
00663     );
00664 
00665 
00666   protected:
00668     virtual void OnAddInterface(const InterfaceEntry & entry);
00669 
00671     virtual void OnRemoveInterface(const InterfaceEntry & entry);
00672 
00673     bool IsInterface(const PString & iface) const;
00674 
00675     PString        theInterface;
00676     InterfaceEntry theEntry;
00677     SocketInfo     theInfo;
00678 };
00679 
00680 #endif

Generated on Mon Sep 15 01:21:35 2008 for PTLib by  doxygen 1.5.1