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: 21058 $
00027  * $Author: rjongbloed $
00028  * $Date: 2008-09-18 07:21:37 +0000 (Thu, 18 Sep 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 
00088     bool Start();
00089 
00091     void Stop();
00092 
00093     typedef PIPSocket::InterfaceEntry InterfaceEntry;
00094 
00099     PStringArray GetInterfaces(
00100       bool includeLoopBack = false,  
00101       const PIPSocket::Address & destination = PIPSocket::GetDefaultIpAny()
00102     );
00103 
00109     bool IsValidBindingForDestination(
00110       const PIPSocket::Address & binding,
00111       const PIPSocket::Address & destination
00112     );
00113 
00118     bool GetInterfaceInfo(
00119       const PString & iface,  
00120       InterfaceEntry & info   
00121     );
00122     
00127     static bool IsMatchingInterface(
00128       const PString & iface,        
00129       const InterfaceEntry & entry  
00130     );
00131     
00135     void SetInterfaceFilter(PInterfaceFilter * filter);
00136     bool HasInterfaceFilter() const { return interfaceFilter != NULL; }
00137     
00138     virtual void RefreshInterfaceList();
00139     
00140     void OnRemoveNatMethod(const PNatMethod * natMethod);
00141 
00142   protected:
00143     virtual void OnShutdown();
00144 
00145     void UpdateThreadMain();
00146 
00147     void AddClient(PInterfaceMonitorClient *);
00148     void RemoveClient(PInterfaceMonitorClient *);
00149     
00150     virtual void OnInterfacesChanged(const PIPSocket::InterfaceTable & addedInterfaces, const PIPSocket::InterfaceTable & removedInterfaces);
00151 
00152     typedef PSmartPtr<PInterfaceMonitorClient> ClientPtr;
00153 
00154     typedef std::list<PInterfaceMonitorClient *> ClientList_T;
00155     ClientList_T              currentClients;
00156     PIPSocket::InterfaceTable currentInterfaces;
00157 
00158     bool           runMonitorThread;
00159     PTimeInterval  refreshInterval;
00160     PMutex         mutex;
00161     PThread      * updateThread;
00162     PSyncPoint     threadRunning;
00163     
00164     PInterfaceFilter * interfaceFilter;
00165 
00166   friend class PInterfaceMonitorClient;
00167 };
00168 
00169 
00171 
00177 class PInterfaceMonitorClient : public PSafeObject
00178 {
00179   PCLASSINFO(PInterfaceMonitorClient, PSafeObject);
00180   public:
00181     enum {
00182       DefaultPriority = 50,
00183     };
00184     PInterfaceMonitorClient(PINDEX priority = DefaultPriority);
00185     ~PInterfaceMonitorClient();
00186 
00187     typedef PIPSocket::InterfaceEntry InterfaceEntry;
00188 
00195     virtual PStringArray GetInterfaces(
00196       bool includeLoopBack = false,  
00197       const PIPSocket::Address & destination = PIPSocket::GetDefaultIpAny() 
00198     );
00199 
00204     virtual PBoolean GetInterfaceInfo(
00205       const PString & iface,  
00206       InterfaceEntry & info   
00207     );
00208     
00213     PINDEX GetPriority() const { return priority; }
00214 
00215   protected:
00217     virtual void OnAddInterface(const InterfaceEntry & entry) = 0;
00218 
00220     virtual void OnRemoveInterface(const InterfaceEntry & entry) = 0;
00221     
00223     virtual void OnRemoveNatMethod(const PNatMethod * /*natMethod*/) { }
00224     
00225     PINDEX priority;
00226 
00227   friend class PInterfaceMonitor;
00228 };
00229 
00230 
00232 
00233 class PInterfaceFilter : public PObject {
00234   PCLASSINFO(PInterfaceFilter, PObject);
00235   
00236   public:
00237     virtual PIPSocket::InterfaceTable FilterInterfaces(const PIPSocket::Address & destination,
00238                                                        PIPSocket::InterfaceTable & interfaces) const = 0;
00239 };
00240 
00241 
00243 
00249 class PMonitoredSockets : public PInterfaceMonitorClient
00250 {
00251   PCLASSINFO(PMonitoredSockets, PInterfaceMonitorClient);
00252   protected:
00253     PMonitoredSockets(
00254       bool reuseAddr,
00255       PNatMethod * natMethod
00256     );
00257 
00258   public:
00265     virtual PBoolean Open(
00266       WORD port
00267     ) = 0;
00268 
00270     PBoolean IsOpen() const { return opened; }
00271 
00273     virtual PBoolean Close() = 0;
00274 
00276     WORD GetPort() const { return localPort; }
00277 
00279     virtual PBoolean GetAddress(
00280       const PString & iface,        
00281       PIPSocket::Address & address, 
00282       WORD & port,                  
00283       PBoolean usingNAT                 
00284     ) const = 0;
00285 
00291     virtual PChannel::Errors WriteToBundle(
00292       const void * buffer,              
00293       PINDEX length,                    
00294       const PIPSocket::Address & addr,  
00295       WORD port,                        
00296       const PString & iface,            
00297       PINDEX & lastWriteCount
00298     ) = 0;
00299 
00306     virtual PChannel::Errors ReadFromBundle(
00307       void * buffer,                
00308       PINDEX length,                
00309       PIPSocket::Address & addr,    
00310       WORD & port,                  
00311       PString & iface,              
00312       PINDEX & lastReadCount,       
00313       const PTimeInterval & timeout 
00314     ) = 0;
00315 
00317     void SetNatMethod(
00318       PNatMethod * method
00319     ) { natMethod = method; }
00320 
00321 
00322     // Get the current NAT method, eg STUN client pointer
00323     PNatMethod * GetNatMethod() const { return natMethod; }
00324 
00329     static PMonitoredSockets * Create(
00330       const PString & iface,            
00331       bool reuseAddr = false,           
00332       PNatMethod * natMethod = NULL     
00333     );
00334 
00335   protected:
00336     virtual void OnRemoveNatMethod(
00337       const PNatMethod * natMethod
00338     );
00339 
00340     struct SocketInfo {
00341       SocketInfo()
00342         : socket(NULL)
00343         , inUse(false)
00344       { }
00345       PUDPSocket * socket;
00346       bool         inUse;
00347     };
00348 
00349     bool CreateSocket(
00350       SocketInfo & info,
00351       const PIPSocket::Address & binding
00352     );
00353     bool DestroySocket(SocketInfo & info);
00354     bool GetSocketAddress(
00355       const SocketInfo & info,
00356       PIPSocket::Address & address,
00357       WORD & port,
00358       bool usingNAT
00359     ) const;
00360 
00361     PChannel::Errors WriteToSocket(
00362       const void * buf,
00363       PINDEX len,
00364       const PIPSocket::Address & addr,
00365       WORD port,
00366       const SocketInfo & info,
00367       PINDEX & lastWriteCount
00368     );
00369     PChannel::Errors ReadFromSocket(
00370       SocketInfo & info,
00371       void * buf,
00372       PINDEX len,
00373       PIPSocket::Address & addr,
00374       WORD & port,
00375       PINDEX & lastReadCount,
00376       const PTimeInterval & timeout
00377     );
00378     PChannel::Errors ReadFromSocket(
00379       PSocket::SelectList & readers,
00380       PUDPSocket * & socket,
00381       void * buf,
00382       PINDEX len,
00383       PIPSocket::Address & addr,
00384       WORD & port,
00385       PINDEX & lastReadCount,
00386       const PTimeInterval & timeout
00387     );
00388 
00389     WORD          localPort;
00390     bool          reuseAddress;
00391     PNatMethod  * natMethod;
00392 
00393     bool          opened;
00394     PUDPSocket    interfaceAddedSignal;
00395 };
00396 
00397 typedef PSafePtr<PMonitoredSockets> PMonitoredSocketsPtr;
00398 
00399 
00401 
00405 class PMonitoredSocketChannel : public PChannel
00406 {
00407   PCLASSINFO(PMonitoredSocketChannel, PChannel);
00408   public:
00411 
00412     PMonitoredSocketChannel(
00413       const PMonitoredSocketsPtr & sockets,  
00414       bool shared                            
00415     );
00417 
00420     virtual PBoolean IsOpen() const;
00421     virtual PBoolean Close();
00422 
00425     virtual PBoolean Read(
00426       void * buffer,
00427       PINDEX length
00428     );
00429 
00430     virtual PBoolean Write(
00433       const void * buffer,
00434       PINDEX length
00435     );
00437 
00443     void SetInterface(
00444       const PString & iface   
00445     );
00446 
00448     PString GetInterface();
00449 
00452     bool GetLocal(
00453       PIPSocket::Address & address, 
00454       WORD & port,                  
00455       bool usingNAT                 
00456     );
00457 
00459     void SetRemote(
00460       const PIPSocket::Address & address, 
00461       WORD port                           
00462     );
00463 
00465     void SetRemote(
00466       const PString & hostAndPort 
00467     );
00468 
00470     void GetRemote(
00471       PIPSocket::Address & addr,  
00472       WORD & port                 
00473     ) const { addr = remoteAddress; port = remotePort; }
00474 
00479     void SetPromiscuous(
00480       bool flag   
00481     ) { promiscuousReads = flag; }
00482 
00484     bool GetPromiscuous() { return promiscuousReads; }
00485 
00487     void GetLastReceived(
00488       PIPSocket::Address & addr,  
00489       WORD & port                 
00490     ) const { addr = lastReceivedAddress; port = lastReceivedPort; }
00491 
00493     PString GetLastReceivedInterface() const { return lastReceivedInterface; }
00494 
00496     const PMonitoredSocketsPtr & GetMonitoredSockets() const { return socketBundle; }
00498 
00499   protected:
00500     PMonitoredSocketsPtr socketBundle;
00501     bool                 sharedBundle;
00502     PString              currentInterface;
00503     bool                 promiscuousReads;
00504     PIPSocket::Address   remoteAddress;
00505     bool                 closing;
00506     WORD                 remotePort;
00507     PIPSocket::Address   lastReceivedAddress;
00508     WORD                 lastReceivedPort;
00509     PString              lastReceivedInterface;
00510     PMutex               mutex;
00511 };
00512 
00513 
00515 
00519 class PMonitoredSocketBundle : public PMonitoredSockets
00520 {
00521   PCLASSINFO(PMonitoredSocketBundle, PMonitoredSockets);
00522   public:
00523     PMonitoredSocketBundle(
00524       bool reuseAddr = false,
00525       PNatMethod  * natMethod = NULL
00526     );
00527     ~PMonitoredSocketBundle();
00528 
00535     virtual PBoolean Open(
00536       WORD port
00537     );
00538 
00540     virtual PBoolean Close();
00541 
00543     virtual PBoolean GetAddress(
00544       const PString & iface,        
00545       PIPSocket::Address & address, 
00546       WORD & port,                  
00547       PBoolean usingNAT                 
00548     ) const;
00549 
00555     virtual PChannel::Errors WriteToBundle(
00556       const void * buf,
00557       PINDEX len,
00558       const PIPSocket::Address & addr,
00559       WORD port,
00560       const PString & iface,
00561       PINDEX & lastWriteCount
00562     );
00563 
00570     virtual PChannel::Errors ReadFromBundle(
00571       void * buf,
00572       PINDEX len,
00573       PIPSocket::Address & addr,
00574       WORD & port,
00575       PString & iface,
00576       PINDEX & lastReadCount,
00577       const PTimeInterval & timeout
00578     );
00579 
00580   protected:
00582     virtual void OnAddInterface(const InterfaceEntry & entry);
00583 
00585     virtual void OnRemoveInterface(const InterfaceEntry & entry);
00586 
00587     typedef std::map<std::string, SocketInfo> SocketInfoMap_T;
00588 
00589     void OpenSocket(const PString & iface);
00590     void CloseSocket(SocketInfoMap_T::iterator iterSocket);
00591 
00592     SocketInfoMap_T socketInfoMap;
00593 };
00594 
00595 
00597 
00602 class PSingleMonitoredSocket : public PMonitoredSockets
00603 {
00604   PCLASSINFO(PSingleMonitoredSocket, PMonitoredSockets);
00605   public:
00606     PSingleMonitoredSocket(
00607       const PString & theInterface,
00608       bool reuseAddr = false,
00609       PNatMethod  * natMethod = NULL
00610     );
00611     ~PSingleMonitoredSocket();
00612 
00617     virtual PStringArray GetInterfaces(
00618       PBoolean includeLoopBack = false,  
00619       const PIPSocket::Address & destination = PIPSocket::GetDefaultIpAny()
00620     );
00621 
00628     virtual PBoolean Open(
00629       WORD port
00630     );
00631 
00633     virtual PBoolean Close();
00634 
00636     virtual PBoolean GetAddress(
00637       const PString & iface,        
00638       PIPSocket::Address & address, 
00639       WORD & port,                  
00640       PBoolean usingNAT                 
00641     ) const;
00642 
00648     virtual PChannel::Errors WriteToBundle(
00649       const void * buf,
00650       PINDEX len,
00651       const PIPSocket::Address & addr,
00652       WORD port,
00653       const PString & iface,
00654       PINDEX & lastWriteCount
00655     );
00656 
00663     virtual PChannel::Errors ReadFromBundle(
00664       void * buf,
00665       PINDEX len,
00666       PIPSocket::Address & addr,
00667       WORD & port,
00668       PString & iface,
00669       PINDEX & lastReadCount,
00670       const PTimeInterval & timeout
00671     );
00672 
00673 
00674   protected:
00676     virtual void OnAddInterface(const InterfaceEntry & entry);
00677 
00679     virtual void OnRemoveInterface(const InterfaceEntry & entry);
00680 
00681     bool IsInterface(const PString & iface) const;
00682 
00683     PString        theInterface;
00684     InterfaceEntry theEntry;
00685     SocketInfo     theInfo;
00686 };
00687 
00688 #endif

Generated on Mon Sep 22 12:07:48 2008 for PTLib by  doxygen 1.5.1