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: 19008 $
00027  * $Author: rjongbloed $
00028  * $Date: 2007-11-29 09:17:41 +0000 (Thu, 29 Nov 2007) $
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 
00052 
00061 class PInterfaceMonitor : public PObject
00062 {
00063   PCLASSINFO(PInterfaceMonitor, PObject);
00064   public: 
00065     enum {
00066       DefaultRefreshInterval = 5000
00067     };
00068 
00069     PInterfaceMonitor(
00070       unsigned refreshInterval = DefaultRefreshInterval,
00071       PBoolean runMonitorThread = PTrue
00072     );
00073     virtual ~PInterfaceMonitor();
00074 
00076     static PInterfaceMonitor & GetInstance();
00077 
00079     PBoolean Start();
00080 
00082     void Stop();
00083 
00084     typedef PIPSocket::InterfaceEntry InterfaceEntry;
00085 
00090     PStringArray GetInterfaces(
00091       PBoolean includeLoopBack = PFalse,  
00092       const PIPSocket::Address & destination = PIPSocket::GetDefaultIpAny()
00093     );
00094 
00100     PBoolean IsValidBindingForDestination(
00101       const PIPSocket::Address & binding,
00102       const PIPSocket::Address & destination
00103     );
00104 
00109     PBoolean GetInterfaceInfo(
00110       const PString & iface,  
00111       InterfaceEntry & info   
00112     );
00113     
00118     static PBoolean IsMatchingInterface(
00119       const PString & iface,        
00120       const InterfaceEntry & entry  
00121     );
00122     
00126     void SetInterfaceFilter(PInterfaceFilter * filter);
00127     
00128     virtual void RefreshInterfaceList();
00129     
00130     void OnRemoveSTUNClient(const PSTUNClient *stun);
00131 
00132   protected:
00133     void UpdateThreadMain();
00134 
00135     void AddClient(PInterfaceMonitorClient *);
00136     void RemoveClient(PInterfaceMonitorClient *);
00137     
00138     virtual void OnInterfacesChanged(const PIPSocket::InterfaceTable & addedInterfaces, const PIPSocket::InterfaceTable & removedInterfaces);
00139 
00140     typedef PSmartPtr<PInterfaceMonitorClient> ClientPtr;
00141 
00142     typedef std::list<PInterfaceMonitorClient *> ClientList_T;
00143     ClientList_T              currentClients;
00144     PIPSocket::InterfaceTable currentInterfaces;
00145 
00146     PBoolean runMonitorThread;
00147     PTimeInterval  refreshInterval;
00148     PMutex         mutex;
00149     PThread      * updateThread;
00150     PSyncPoint     threadRunning;
00151     
00152     PInterfaceFilter * interfaceFilter;
00153 
00154   friend class PInterfaceMonitorClient;
00155 };
00156 
00157 
00159 
00165 class PInterfaceMonitorClient : public PSafeObject
00166 {
00167   PCLASSINFO(PInterfaceMonitorClient, PSafeObject);
00168   public:
00169     enum {
00170       DefaultPriority = 50,
00171     };
00172     PInterfaceMonitorClient(PINDEX priority = DefaultPriority);
00173     ~PInterfaceMonitorClient();
00174 
00175     typedef PIPSocket::InterfaceEntry InterfaceEntry;
00176 
00183     virtual PStringArray GetInterfaces(
00184       PBoolean includeLoopBack = PFalse,  
00185       const PIPSocket::Address & destination = PIPSocket::GetDefaultIpAny() 
00186     );
00187 
00192     virtual PBoolean GetInterfaceInfo(
00193       const PString & iface,  
00194       InterfaceEntry & info   
00195     );
00196     
00201     PINDEX GetPriority() const { return priority; }
00202 
00203   protected:
00205     virtual void OnAddInterface(const InterfaceEntry & entry) = 0;
00206 
00208     virtual void OnRemoveInterface(const InterfaceEntry & entry) = 0;
00209     
00211     virtual void OnRemoveSTUNClient(const PSTUNClient * /*stun*/) { }
00212     
00213     PINDEX priority;
00214 
00215   friend class PInterfaceMonitor;
00216 };
00217 
00218 
00220 
00221 class PInterfaceFilter : public PObject {
00222   PCLASSINFO(PInterfaceFilter, PObject);
00223   
00224   public:
00225     virtual PIPSocket::InterfaceTable FilterInterfaces(const PIPSocket::Address & destination,
00226                                                        PIPSocket::InterfaceTable & interfaces) const = 0;
00227 };
00228 
00229 
00231 
00237 class PMonitoredSockets : public PInterfaceMonitorClient
00238 {
00239   PCLASSINFO(PMonitoredSockets, PInterfaceMonitorClient);
00240   protected:
00241     PMonitoredSockets(
00242       PBoolean reuseAddr,
00243       PSTUNClient * stunClient
00244     );
00245 
00246   public:
00253     virtual PBoolean Open(
00254       WORD port
00255     ) = 0;
00256 
00258     PBoolean IsOpen() const { return opened; }
00259 
00261     virtual PBoolean Close() = 0;
00262 
00264     WORD GetPort() const { return localPort; }
00265 
00267     virtual PBoolean GetAddress(
00268       const PString & iface,        
00269       PIPSocket::Address & address, 
00270       WORD & port,                  
00271       PBoolean usingNAT                 
00272     ) const = 0;
00273 
00279     virtual PChannel::Errors WriteToBundle(
00280       const void * buffer,              
00281       PINDEX length,                    
00282       const PIPSocket::Address & addr,  
00283       WORD port,                        
00284       const PString & iface,            
00285       PINDEX & lastWriteCount
00286     ) = 0;
00287 
00294     virtual PChannel::Errors ReadFromBundle(
00295       void * buffer,                
00296       PINDEX length,                
00297       PIPSocket::Address & addr,    
00298       WORD & port,                  
00299       PString & iface,              
00300       PINDEX & lastReadCount,       
00301       const PTimeInterval & timeout 
00302     ) = 0;
00303 
00305     void SetSTUN(
00306       PSTUNClient * stunClient
00307     ) { stun = stunClient; }
00308 
00309     // Get the current STUN server
00310     PSTUNClient * GetSTUN() const { return stun; }
00311 
00316     static PMonitoredSockets * Create(
00317       const PString & iface,            
00318       PBoolean reuseAddr = PFalse,           
00319       PSTUNClient * stunClient = NULL   
00320     );
00321 
00322   protected:
00323     virtual void OnRemoveSTUNClient(const PSTUNClient *stun);
00324     struct SocketInfo {
00325       SocketInfo()
00326         : socket(NULL)
00327         , inUse(false)
00328       { }
00329       PUDPSocket * socket;
00330       bool         inUse;
00331     };
00332 
00333     PBoolean CreateSocket(
00334       SocketInfo & info,
00335       const PIPSocket::Address & binding
00336     );
00337     PBoolean DestroySocket(SocketInfo & info);
00338     PBoolean GetSocketAddress(
00339       const SocketInfo & info,
00340       PIPSocket::Address & address,
00341       WORD & port,
00342       PBoolean usingNAT
00343     ) const;
00344 
00345     PChannel::Errors WriteToSocket(
00346       const void * buf,
00347       PINDEX len,
00348       const PIPSocket::Address & addr,
00349       WORD port,
00350       const SocketInfo & info,
00351       PINDEX & lastWriteCount
00352     );
00353     PChannel::Errors ReadFromSocket(
00354       SocketInfo & info,
00355       void * buf,
00356       PINDEX len,
00357       PIPSocket::Address & addr,
00358       WORD & port,
00359       PINDEX & lastReadCount,
00360       const PTimeInterval & timeout
00361     );
00362 
00363     WORD          localPort;
00364     PBoolean          reuseAddress;
00365     PSTUNClient * stun;
00366 
00367     bool          opened;
00368     PUDPSocket    interfaceAddedSignal;
00369 };
00370 
00371 typedef PSafePtr<PMonitoredSockets> PMonitoredSocketsPtr;
00372 
00373 
00375 
00379 class PMonitoredSocketChannel : public PChannel
00380 {
00381   PCLASSINFO(PMonitoredSocketChannel, PChannel);
00382   public:
00385 
00386     PMonitoredSocketChannel(
00387       const PMonitoredSocketsPtr & sockets,  
00388       PBoolean shared                            
00389     );
00391 
00394     virtual PBoolean IsOpen() const;
00395     virtual PBoolean Close();
00396 
00399     virtual PBoolean Read(
00400       void * buffer,
00401       PINDEX length
00402     );
00403 
00404     virtual PBoolean Write(
00407       const void * buffer,
00408       PINDEX length
00409     );
00411 
00417     void SetInterface(
00418       const PString & iface   
00419     );
00420 
00422     const PString & GetInterface();
00423 
00426     PBoolean GetLocal(
00427       PIPSocket::Address & address, 
00428       WORD & port,                  
00429       PBoolean usingNAT                 
00430     );
00431 
00433     void SetRemote(
00434       const PIPSocket::Address & address, 
00435       WORD port                           
00436     );
00437 
00439     void SetRemote(
00440       const PString & hostAndPort 
00441     );
00442 
00444     void GetRemote(
00445       PIPSocket::Address & addr,  
00446       WORD & port                 
00447     ) const { addr = remoteAddress; port = remotePort; }
00448 
00453     void SetPromiscuous(
00454       PBoolean flag   
00455     ) { promiscuousReads = flag; }
00456 
00458     bool GetPromiscuous() { return promiscuousReads; }
00459 
00460     // Get the IP address and port of the last received UDP data.
00461     void GetLastReceived(
00462       PIPSocket::Address & addr,  
00463       WORD & port                 
00464     ) const { addr = lastReceivedAddress; port = lastReceivedPort; }
00465 
00467     const PMonitoredSocketsPtr & GetMonitoredSockets() const { return socketBundle; }
00469 
00470   protected:
00471     PMonitoredSocketsPtr socketBundle;
00472     PBoolean                 sharedBundle;
00473     PString              currentInterface;
00474     PBoolean                 promiscuousReads;
00475     PIPSocket::Address   remoteAddress;
00476     PBoolean                 closing;
00477     WORD                 remotePort;
00478     PIPSocket::Address   lastReceivedAddress;
00479     WORD                 lastReceivedPort;
00480 };
00481 
00482 
00484 
00488 class PMonitoredSocketBundle : public PMonitoredSockets
00489 {
00490   PCLASSINFO(PMonitoredSocketBundle, PMonitoredSockets);
00491   public:
00492     PMonitoredSocketBundle(
00493       PBoolean reuseAddr = PFalse,
00494       PSTUNClient * stunClient = NULL
00495     );
00496     ~PMonitoredSocketBundle();
00497 
00504     virtual PBoolean Open(
00505       WORD port
00506     );
00507 
00509     virtual PBoolean Close();
00510 
00512     virtual PBoolean GetAddress(
00513       const PString & iface,        
00514       PIPSocket::Address & address, 
00515       WORD & port,                  
00516       PBoolean usingNAT                 
00517     ) const;
00518 
00524     virtual PChannel::Errors WriteToBundle(
00525       const void * buf,
00526       PINDEX len,
00527       const PIPSocket::Address & addr,
00528       WORD port,
00529       const PString & iface,
00530       PINDEX & lastWriteCount
00531     );
00532 
00539     virtual PChannel::Errors ReadFromBundle(
00540       void * buf,
00541       PINDEX len,
00542       PIPSocket::Address & addr,
00543       WORD & port,
00544       PString & iface,
00545       PINDEX & lastReadCount,
00546       const PTimeInterval & timeout
00547     );
00548 
00549   protected:
00551     virtual void OnAddInterface(const InterfaceEntry & entry);
00552 
00554     virtual void OnRemoveInterface(const InterfaceEntry & entry);
00555 
00556     typedef std::map<std::string, SocketInfo> SocketInfoMap_T;
00557 
00558     void OpenSocket(const PString & iface);
00559     void CloseSocket(const SocketInfoMap_T::iterator & iterSocket);
00560 
00561     SocketInfoMap_T socketInfoMap;
00562 };
00563 
00564 
00566 
00571 class PSingleMonitoredSocket : public PMonitoredSocketBundle
00572 {
00573   PCLASSINFO(PSingleMonitoredSocket, PMonitoredSocketBundle);
00574   public:
00575     PSingleMonitoredSocket(
00576       const PString & theInterface,
00577       PBoolean reuseAddr = PFalse,
00578       PSTUNClient * stunClient = NULL
00579     );
00580     ~PSingleMonitoredSocket();
00581 
00586     virtual PStringArray GetInterfaces(
00587       PBoolean includeLoopBack = PFalse,  
00588       const PIPSocket::Address & destination = PIPSocket::GetDefaultIpAny()
00589     );
00590 
00597     virtual PBoolean Open(
00598       WORD port
00599     );
00600 
00602     virtual PBoolean Close();
00603 
00605     virtual PBoolean GetAddress(
00606       const PString & iface,        
00607       PIPSocket::Address & address, 
00608       WORD & port,                  
00609       PBoolean usingNAT                 
00610     ) const;
00611 
00617     virtual PChannel::Errors WriteToBundle(
00618       const void * buf,
00619       PINDEX len,
00620       const PIPSocket::Address & addr,
00621       WORD port,
00622       const PString & iface,
00623       PINDEX & lastWriteCount
00624     );
00625 
00632     virtual PChannel::Errors ReadFromBundle(
00633       void * buf,
00634       PINDEX len,
00635       PIPSocket::Address & addr,
00636       WORD & port,
00637       PString & iface,
00638       PINDEX & lastReadCount,
00639       const PTimeInterval & timeout
00640     );
00641 
00642 
00643   protected:
00645     virtual void OnAddInterface(const InterfaceEntry & entry);
00646 
00648     virtual void OnRemoveInterface(const InterfaceEntry & entry);
00649 
00650     PBoolean IsInterface(const PString & iface) const;
00651 
00652     PString        theInterface;
00653     InterfaceEntry theEntry;
00654     SocketInfo     theInfo;
00655 };
00656 
00657 #endif

Generated on Mon Dec 10 11:18:57 2007 for PTLib by  doxygen 1.5.1