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: 19616 $
00027  * $Author: rjongbloed $
00028  * $Date: 2008-02-28 01:27:54 +0000 (Thu, 28 Feb 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 PSTUNClient;
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 OnRemoveSTUNClient(const PSTUNClient *stun);
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 OnRemoveSTUNClient(const PSTUNClient * /*stun*/) { }
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       PSTUNClient * stunClient
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 SetSTUN(
00311       PSTUNClient * stunClient
00312     ) { stun = stunClient; }
00313 
00314     // Get the current STUN server
00315     PSTUNClient * GetSTUN() const { return stun; }
00316 
00321     static PMonitoredSockets * Create(
00322       const PString & iface,            
00323       bool reuseAddr = false,           
00324       PSTUNClient * stunClient = NULL   
00325     );
00326 
00327   protected:
00328     virtual void OnRemoveSTUNClient(const PSTUNClient *stun);
00329     struct SocketInfo {
00330       SocketInfo()
00331         : socket(NULL)
00332         , inUse(false)
00333       { }
00334       PUDPSocket * socket;
00335       bool         inUse;
00336     };
00337 
00338     bool CreateSocket(
00339       SocketInfo & info,
00340       const PIPSocket::Address & binding
00341     );
00342     bool DestroySocket(SocketInfo & info);
00343     bool GetSocketAddress(
00344       const SocketInfo & info,
00345       PIPSocket::Address & address,
00346       WORD & port,
00347       bool usingNAT
00348     ) const;
00349 
00350     PChannel::Errors WriteToSocket(
00351       const void * buf,
00352       PINDEX len,
00353       const PIPSocket::Address & addr,
00354       WORD port,
00355       const SocketInfo & info,
00356       PINDEX & lastWriteCount
00357     );
00358     PChannel::Errors ReadFromSocket(
00359       SocketInfo & info,
00360       void * buf,
00361       PINDEX len,
00362       PIPSocket::Address & addr,
00363       WORD & port,
00364       PINDEX & lastReadCount,
00365       const PTimeInterval & timeout
00366     );
00367     PChannel::Errors ReadFromSocket(
00368       PSocket::SelectList & readers,
00369       PUDPSocket * & socket,
00370       void * buf,
00371       PINDEX len,
00372       PIPSocket::Address & addr,
00373       WORD & port,
00374       PINDEX & lastReadCount,
00375       const PTimeInterval & timeout
00376     );
00377 
00378     WORD          localPort;
00379     bool          reuseAddress;
00380     PSTUNClient * stun;
00381 
00382     bool          opened;
00383     PUDPSocket    interfaceAddedSignal;
00384 };
00385 
00386 typedef PSafePtr<PMonitoredSockets> PMonitoredSocketsPtr;
00387 
00388 
00390 
00394 class PMonitoredSocketChannel : public PChannel
00395 {
00396   PCLASSINFO(PMonitoredSocketChannel, PChannel);
00397   public:
00400 
00401     PMonitoredSocketChannel(
00402       const PMonitoredSocketsPtr & sockets,  
00403       bool shared                            
00404     );
00406 
00409     virtual PBoolean IsOpen() const;
00410     virtual PBoolean Close();
00411 
00414     virtual PBoolean Read(
00415       void * buffer,
00416       PINDEX length
00417     );
00418 
00419     virtual PBoolean Write(
00422       const void * buffer,
00423       PINDEX length
00424     );
00426 
00432     void SetInterface(
00433       const PString & iface   
00434     );
00435 
00437     const PString & GetInterface();
00438 
00441     bool GetLocal(
00442       PIPSocket::Address & address, 
00443       WORD & port,                  
00444       bool usingNAT                 
00445     );
00446 
00448     void SetRemote(
00449       const PIPSocket::Address & address, 
00450       WORD port                           
00451     );
00452 
00454     void SetRemote(
00455       const PString & hostAndPort 
00456     );
00457 
00459     void GetRemote(
00460       PIPSocket::Address & addr,  
00461       WORD & port                 
00462     ) const { addr = remoteAddress; port = remotePort; }
00463 
00468     void SetPromiscuous(
00469       bool flag   
00470     ) { promiscuousReads = flag; }
00471 
00473     bool GetPromiscuous() { return promiscuousReads; }
00474 
00476     void GetLastReceived(
00477       PIPSocket::Address & addr,  
00478       WORD & port                 
00479     ) const { addr = lastReceivedAddress; port = lastReceivedPort; }
00480 
00482     PString GetLastReceivedInterface() const { return lastReceivedInterface; }
00483 
00485     const PMonitoredSocketsPtr & GetMonitoredSockets() const { return socketBundle; }
00487 
00488   protected:
00489     PMonitoredSocketsPtr socketBundle;
00490     bool                 sharedBundle;
00491     PString              currentInterface;
00492     bool                 promiscuousReads;
00493     PIPSocket::Address   remoteAddress;
00494     bool                 closing;
00495     WORD                 remotePort;
00496     PIPSocket::Address   lastReceivedAddress;
00497     WORD                 lastReceivedPort;
00498     PString              lastReceivedInterface;
00499 };
00500 
00501 
00503 
00507 class PMonitoredSocketBundle : public PMonitoredSockets
00508 {
00509   PCLASSINFO(PMonitoredSocketBundle, PMonitoredSockets);
00510   public:
00511     PMonitoredSocketBundle(
00512       bool reuseAddr = false,
00513       PSTUNClient * stunClient = NULL
00514     );
00515     ~PMonitoredSocketBundle();
00516 
00523     virtual PBoolean Open(
00524       WORD port
00525     );
00526 
00528     virtual PBoolean Close();
00529 
00531     virtual PBoolean GetAddress(
00532       const PString & iface,        
00533       PIPSocket::Address & address, 
00534       WORD & port,                  
00535       PBoolean usingNAT                 
00536     ) const;
00537 
00543     virtual PChannel::Errors WriteToBundle(
00544       const void * buf,
00545       PINDEX len,
00546       const PIPSocket::Address & addr,
00547       WORD port,
00548       const PString & iface,
00549       PINDEX & lastWriteCount
00550     );
00551 
00558     virtual PChannel::Errors ReadFromBundle(
00559       void * buf,
00560       PINDEX len,
00561       PIPSocket::Address & addr,
00562       WORD & port,
00563       PString & iface,
00564       PINDEX & lastReadCount,
00565       const PTimeInterval & timeout
00566     );
00567 
00568   protected:
00570     virtual void OnAddInterface(const InterfaceEntry & entry);
00571 
00573     virtual void OnRemoveInterface(const InterfaceEntry & entry);
00574 
00575     typedef std::map<std::string, SocketInfo> SocketInfoMap_T;
00576 
00577     void OpenSocket(const PString & iface);
00578     void CloseSocket(const SocketInfoMap_T::iterator & iterSocket);
00579 
00580     SocketInfoMap_T socketInfoMap;
00581 };
00582 
00583 
00585 
00590 class PSingleMonitoredSocket : public PMonitoredSockets
00591 {
00592   PCLASSINFO(PSingleMonitoredSocket, PMonitoredSockets);
00593   public:
00594     PSingleMonitoredSocket(
00595       const PString & theInterface,
00596       bool reuseAddr = false,
00597       PSTUNClient * stunClient = NULL
00598     );
00599     ~PSingleMonitoredSocket();
00600 
00605     virtual PStringArray GetInterfaces(
00606       PBoolean includeLoopBack = false,  
00607       const PIPSocket::Address & destination = PIPSocket::GetDefaultIpAny()
00608     );
00609 
00616     virtual PBoolean Open(
00617       WORD port
00618     );
00619 
00621     virtual PBoolean Close();
00622 
00624     virtual PBoolean GetAddress(
00625       const PString & iface,        
00626       PIPSocket::Address & address, 
00627       WORD & port,                  
00628       PBoolean usingNAT                 
00629     ) const;
00630 
00636     virtual PChannel::Errors WriteToBundle(
00637       const void * buf,
00638       PINDEX len,
00639       const PIPSocket::Address & addr,
00640       WORD port,
00641       const PString & iface,
00642       PINDEX & lastWriteCount
00643     );
00644 
00651     virtual PChannel::Errors ReadFromBundle(
00652       void * buf,
00653       PINDEX len,
00654       PIPSocket::Address & addr,
00655       WORD & port,
00656       PString & iface,
00657       PINDEX & lastReadCount,
00658       const PTimeInterval & timeout
00659     );
00660 
00661 
00662   protected:
00664     virtual void OnAddInterface(const InterfaceEntry & entry);
00665 
00667     virtual void OnRemoveInterface(const InterfaceEntry & entry);
00668 
00669     bool IsInterface(const PString & iface) const;
00670 
00671     PString        theInterface;
00672     InterfaceEntry theEntry;
00673     SocketInfo     theInfo;
00674 };
00675 
00676 #endif

Generated on Wed May 7 00:47:56 2008 for PTLib by  doxygen 1.5.1