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: 20944 $
00027  * $Author: dsandras $
00028  * $Date: 2008-09-13 16:41:48 +0000 (Sat, 13 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     bool Start();
00086 
00088     void Stop();
00089 
00090     typedef PIPSocket::InterfaceEntry InterfaceEntry;
00091 
00096     PStringArray GetInterfaces(
00097       bool includeLoopBack = false,  
00098       const PIPSocket::Address & destination = PIPSocket::GetDefaultIpAny()
00099     );
00100 
00106     bool IsValidBindingForDestination(
00107       const PIPSocket::Address & binding,
00108       const PIPSocket::Address & destination
00109     );
00110 
00115     bool GetInterfaceInfo(
00116       const PString & iface,  
00117       InterfaceEntry & info   
00118     );
00119     
00124     static bool IsMatchingInterface(
00125       const PString & iface,        
00126       const InterfaceEntry & entry  
00127     );
00128     
00132     void SetInterfaceFilter(PInterfaceFilter * filter);
00133     
00134     virtual void RefreshInterfaceList();
00135     
00136     void OnRemoveNatMethod(const PNatMethod * natMethod);
00137 
00138   protected:
00139     virtual void OnShutdown();
00140 
00141     void UpdateThreadMain();
00142 
00143     void AddClient(PInterfaceMonitorClient *);
00144     void RemoveClient(PInterfaceMonitorClient *);
00145     
00146     virtual void OnInterfacesChanged(const PIPSocket::InterfaceTable & addedInterfaces, const PIPSocket::InterfaceTable & removedInterfaces);
00147 
00148     typedef PSmartPtr<PInterfaceMonitorClient> ClientPtr;
00149 
00150     typedef std::list<PInterfaceMonitorClient *> ClientList_T;
00151     ClientList_T              currentClients;
00152     PIPSocket::InterfaceTable currentInterfaces;
00153 
00154     bool           runMonitorThread;
00155     PTimeInterval  refreshInterval;
00156     PMutex         mutex;
00157     PThread      * updateThread;
00158     PSyncPoint     threadRunning;
00159     
00160     PInterfaceFilter * interfaceFilter;
00161 
00162   friend class PInterfaceMonitorClient;
00163 };
00164 
00165 
00167 
00173 class PInterfaceMonitorClient : public PSafeObject
00174 {
00175   PCLASSINFO(PInterfaceMonitorClient, PSafeObject);
00176   public:
00177     enum {
00178       DefaultPriority = 50,
00179     };
00180     PInterfaceMonitorClient(PINDEX priority = DefaultPriority);
00181     ~PInterfaceMonitorClient();
00182 
00183     typedef PIPSocket::InterfaceEntry InterfaceEntry;
00184 
00191     virtual PStringArray GetInterfaces(
00192       bool includeLoopBack = false,  
00193       const PIPSocket::Address & destination = PIPSocket::GetDefaultIpAny() 
00194     );
00195 
00200     virtual PBoolean GetInterfaceInfo(
00201       const PString & iface,  
00202       InterfaceEntry & info   
00203     );
00204     
00209     PINDEX GetPriority() const { return priority; }
00210 
00211   protected:
00213     virtual void OnAddInterface(const InterfaceEntry & entry) = 0;
00214 
00216     virtual void OnRemoveInterface(const InterfaceEntry & entry) = 0;
00217     
00219     virtual void OnRemoveNatMethod(const PNatMethod * /*natMethod*/) { }
00220     
00221     PINDEX priority;
00222 
00223   friend class PInterfaceMonitor;
00224 };
00225 
00226 
00228 
00229 class PInterfaceFilter : public PObject {
00230   PCLASSINFO(PInterfaceFilter, PObject);
00231   
00232   public:
00233     virtual PIPSocket::InterfaceTable FilterInterfaces(const PIPSocket::Address & destination,
00234                                                        PIPSocket::InterfaceTable & interfaces) const = 0;
00235 };
00236 
00237 
00239 
00245 class PMonitoredSockets : public PInterfaceMonitorClient
00246 {
00247   PCLASSINFO(PMonitoredSockets, PInterfaceMonitorClient);
00248   protected:
00249     PMonitoredSockets(
00250       bool reuseAddr,
00251       PNatMethod * natMethod
00252     );
00253 
00254   public:
00261     virtual PBoolean Open(
00262       WORD port
00263     ) = 0;
00264 
00266     PBoolean IsOpen() const { return opened; }
00267 
00269     virtual PBoolean Close() = 0;
00270 
00272     WORD GetPort() const { return localPort; }
00273 
00275     virtual PBoolean GetAddress(
00276       const PString & iface,        
00277       PIPSocket::Address & address, 
00278       WORD & port,                  
00279       PBoolean usingNAT                 
00280     ) const = 0;
00281 
00287     virtual PChannel::Errors WriteToBundle(
00288       const void * buffer,              
00289       PINDEX length,                    
00290       const PIPSocket::Address & addr,  
00291       WORD port,                        
00292       const PString & iface,            
00293       PINDEX & lastWriteCount
00294     ) = 0;
00295 
00302     virtual PChannel::Errors ReadFromBundle(
00303       void * buffer,                
00304       PINDEX length,                
00305       PIPSocket::Address & addr,    
00306       WORD & port,                  
00307       PString & iface,              
00308       PINDEX & lastReadCount,       
00309       const PTimeInterval & timeout 
00310     ) = 0;
00311 
00313     void SetNatMethod(
00314       PNatMethod * method
00315     ) { natMethod = method; }
00316 
00317 
00318     // Get the current NAT method, eg STUN client pointer
00319     PNatMethod * GetNatMethod() const { return natMethod; }
00320 
00325     static PMonitoredSockets * Create(
00326       const PString & iface,            
00327       bool reuseAddr = false,           
00328       PNatMethod * natMethod = NULL     
00329     );
00330 
00331   protected:
00332     virtual void OnRemoveNatMethod(
00333       const PNatMethod * natMethod
00334     );
00335 
00336     struct SocketInfo {
00337       SocketInfo()
00338         : socket(NULL)
00339         , inUse(false)
00340       { }
00341       PUDPSocket * socket;
00342       bool         inUse;
00343     };
00344 
00345     bool CreateSocket(
00346       SocketInfo & info,
00347       const PIPSocket::Address & binding
00348     );
00349     bool DestroySocket(SocketInfo & info);
00350     bool GetSocketAddress(
00351       const SocketInfo & info,
00352       PIPSocket::Address & address,
00353       WORD & port,
00354       bool usingNAT
00355     ) const;
00356 
00357     PChannel::Errors WriteToSocket(
00358       const void * buf,
00359       PINDEX len,
00360       const PIPSocket::Address & addr,
00361       WORD port,
00362       const SocketInfo & info,
00363       PINDEX & lastWriteCount
00364     );
00365     PChannel::Errors ReadFromSocket(
00366       SocketInfo & info,
00367       void * buf,
00368       PINDEX len,
00369       PIPSocket::Address & addr,
00370       WORD & port,
00371       PINDEX & lastReadCount,
00372       const PTimeInterval & timeout
00373     );
00374     PChannel::Errors ReadFromSocket(
00375       PSocket::SelectList & readers,
00376       PUDPSocket * & socket,
00377       void * buf,
00378       PINDEX len,
00379       PIPSocket::Address & addr,
00380       WORD & port,
00381       PINDEX & lastReadCount,
00382       const PTimeInterval & timeout
00383     );
00384 
00385     WORD          localPort;
00386     bool          reuseAddress;
00387     PNatMethod  * natMethod;
00388 
00389     bool          opened;
00390     PUDPSocket    interfaceAddedSignal;
00391 };
00392 
00393 typedef PSafePtr<PMonitoredSockets> PMonitoredSocketsPtr;
00394 
00395 
00397 
00401 class PMonitoredSocketChannel : public PChannel
00402 {
00403   PCLASSINFO(PMonitoredSocketChannel, PChannel);
00404   public:
00407 
00408     PMonitoredSocketChannel(
00409       const PMonitoredSocketsPtr & sockets,  
00410       bool shared                            
00411     );
00413 
00416     virtual PBoolean IsOpen() const;
00417     virtual PBoolean Close();
00418 
00421     virtual PBoolean Read(
00422       void * buffer,
00423       PINDEX length
00424     );
00425 
00426     virtual PBoolean Write(
00429       const void * buffer,
00430       PINDEX length
00431     );
00433 
00439     void SetInterface(
00440       const PString & iface   
00441     );
00442 
00444     PString GetInterface();
00445 
00448     bool GetLocal(
00449       PIPSocket::Address & address, 
00450       WORD & port,                  
00451       bool usingNAT                 
00452     );
00453 
00455     void SetRemote(
00456       const PIPSocket::Address & address, 
00457       WORD port                           
00458     );
00459 
00461     void SetRemote(
00462       const PString & hostAndPort 
00463     );
00464 
00466     void GetRemote(
00467       PIPSocket::Address & addr,  
00468       WORD & port                 
00469     ) const { addr = remoteAddress; port = remotePort; }
00470 
00475     void SetPromiscuous(
00476       bool flag   
00477     ) { promiscuousReads = flag; }
00478 
00480     bool GetPromiscuous() { return promiscuousReads; }
00481 
00483     void GetLastReceived(
00484       PIPSocket::Address & addr,  
00485       WORD & port                 
00486     ) const { addr = lastReceivedAddress; port = lastReceivedPort; }
00487 
00489     PString GetLastReceivedInterface() const { return lastReceivedInterface; }
00490 
00492     const PMonitoredSocketsPtr & GetMonitoredSockets() const { return socketBundle; }
00494 
00495   protected:
00496     PMonitoredSocketsPtr socketBundle;
00497     bool                 sharedBundle;
00498     PString              currentInterface;
00499     bool                 promiscuousReads;
00500     PIPSocket::Address   remoteAddress;
00501     bool                 closing;
00502     WORD                 remotePort;
00503     PIPSocket::Address   lastReceivedAddress;
00504     WORD                 lastReceivedPort;
00505     PString              lastReceivedInterface;
00506     PMutex               mutex;
00507 };
00508 
00509 
00511 
00515 class PMonitoredSocketBundle : public PMonitoredSockets
00516 {
00517   PCLASSINFO(PMonitoredSocketBundle, PMonitoredSockets);
00518   public:
00519     PMonitoredSocketBundle(
00520       bool reuseAddr = false,
00521       PNatMethod  * natMethod = NULL
00522     );
00523     ~PMonitoredSocketBundle();
00524 
00531     virtual PBoolean Open(
00532       WORD port
00533     );
00534 
00536     virtual PBoolean Close();
00537 
00539     virtual PBoolean GetAddress(
00540       const PString & iface,        
00541       PIPSocket::Address & address, 
00542       WORD & port,                  
00543       PBoolean usingNAT                 
00544     ) const;
00545 
00551     virtual PChannel::Errors WriteToBundle(
00552       const void * buf,
00553       PINDEX len,
00554       const PIPSocket::Address & addr,
00555       WORD port,
00556       const PString & iface,
00557       PINDEX & lastWriteCount
00558     );
00559 
00566     virtual PChannel::Errors ReadFromBundle(
00567       void * buf,
00568       PINDEX len,
00569       PIPSocket::Address & addr,
00570       WORD & port,
00571       PString & iface,
00572       PINDEX & lastReadCount,
00573       const PTimeInterval & timeout
00574     );
00575 
00576   protected:
00578     virtual void OnAddInterface(const InterfaceEntry & entry);
00579 
00581     virtual void OnRemoveInterface(const InterfaceEntry & entry);
00582 
00583     typedef std::map<std::string, SocketInfo> SocketInfoMap_T;
00584 
00585     void OpenSocket(const PString & iface);
00586     void CloseSocket(SocketInfoMap_T::iterator iterSocket);
00587 
00588     SocketInfoMap_T socketInfoMap;
00589 };
00590 
00591 
00593 
00598 class PSingleMonitoredSocket : public PMonitoredSockets
00599 {
00600   PCLASSINFO(PSingleMonitoredSocket, PMonitoredSockets);
00601   public:
00602     PSingleMonitoredSocket(
00603       const PString & theInterface,
00604       bool reuseAddr = false,
00605       PNatMethod  * natMethod = NULL
00606     );
00607     ~PSingleMonitoredSocket();
00608 
00613     virtual PStringArray GetInterfaces(
00614       PBoolean includeLoopBack = false,  
00615       const PIPSocket::Address & destination = PIPSocket::GetDefaultIpAny()
00616     );
00617 
00624     virtual PBoolean Open(
00625       WORD port
00626     );
00627 
00629     virtual PBoolean Close();
00630 
00632     virtual PBoolean GetAddress(
00633       const PString & iface,        
00634       PIPSocket::Address & address, 
00635       WORD & port,                  
00636       PBoolean usingNAT                 
00637     ) const;
00638 
00644     virtual PChannel::Errors WriteToBundle(
00645       const void * buf,
00646       PINDEX len,
00647       const PIPSocket::Address & addr,
00648       WORD port,
00649       const PString & iface,
00650       PINDEX & lastWriteCount
00651     );
00652 
00659     virtual PChannel::Errors ReadFromBundle(
00660       void * buf,
00661       PINDEX len,
00662       PIPSocket::Address & addr,
00663       WORD & port,
00664       PString & iface,
00665       PINDEX & lastReadCount,
00666       const PTimeInterval & timeout
00667     );
00668 
00669 
00670   protected:
00672     virtual void OnAddInterface(const InterfaceEntry & entry);
00673 
00675     virtual void OnRemoveInterface(const InterfaceEntry & entry);
00676 
00677     bool IsInterface(const PString & iface) const;
00678 
00679     PString        theInterface;
00680     InterfaceEntry theEntry;
00681     SocketInfo     theInfo;
00682 };
00683 
00684 #endif

Generated on Mon Sep 15 08:27:59 2008 for PTLib by  doxygen 1.5.1