PTLib
Version 2.10.4
|
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: 26520 $ 00027 * $Author: rjongbloed $ 00028 * $Date: 2011-10-04 23:54:38 -0500 (Tue, 04 Oct 2011) $ 00029 */ 00030 00031 #ifndef PTLIB_PSOCKBUN_H 00032 #define PTLIB_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 PFACTORY_GET_SINGLETON(PProcessStartupFactory, PInterfaceMonitor); 00080 00082 void SetRefreshInterval (unsigned refresh); 00083 00085 void SetRunMonitorThread (bool runMonitorThread); 00086 00092 void Start(); 00093 00095 void Stop(); 00096 00097 typedef PIPSocket::InterfaceEntry InterfaceEntry; 00098 00103 PStringArray GetInterfaces( 00104 bool includeLoopBack = false, 00105 const PIPSocket::Address & destination = PIPSocket::GetDefaultIpAny() 00107 ); 00108 00114 bool IsValidBindingForDestination( 00115 const PIPSocket::Address & binding, 00116 const PIPSocket::Address & destination 00117 ); 00118 00123 bool GetInterfaceInfo( 00124 const PString & iface, 00125 InterfaceEntry & info 00126 ) const; 00127 00132 static bool IsMatchingInterface( 00133 const PString & iface, 00134 const InterfaceEntry & entry 00135 ); 00136 00140 void SetInterfaceFilter(PInterfaceFilter * filter); 00141 bool HasInterfaceFilter() const { return m_interfaceFilter != NULL; } 00142 00143 virtual void RefreshInterfaceList(); 00144 00145 void OnRemoveNatMethod(const PNatMethod * natMethod); 00146 00147 protected: 00148 virtual void OnShutdown(); 00149 00150 void UpdateThreadMain(); 00151 00152 void AddClient(PInterfaceMonitorClient *); 00153 void RemoveClient(PInterfaceMonitorClient *); 00154 00155 virtual void OnInterfacesChanged(const PIPSocket::InterfaceTable & addedInterfaces, const PIPSocket::InterfaceTable & removedInterfaces); 00156 00157 typedef PSmartPtr<PInterfaceMonitorClient> ClientPtr; 00158 00159 typedef std::list<PInterfaceMonitorClient *> ClientList_T; 00160 ClientList_T m_clients; 00161 PMutex m_clientsMutex; 00162 00163 PIPSocket::InterfaceTable m_interfaces; 00164 PMutex m_interfacesMutex; 00165 00166 bool m_runMonitorThread; 00167 PTimeInterval m_refreshInterval; 00168 PMutex m_threadMutex; 00169 PThread * m_updateThread; 00170 00171 PInterfaceFilter * m_interfaceFilter; 00172 PIPSocket::RouteTableDetector * m_changedDetector; 00173 00174 friend class PInterfaceMonitorClient; 00175 }; 00176 00177 00179 00185 class PInterfaceMonitorClient : public PSafeObject 00186 { 00187 PCLASSINFO(PInterfaceMonitorClient, PSafeObject); 00188 public: 00189 enum { 00190 DefaultPriority = 50, 00191 }; 00192 PInterfaceMonitorClient(PINDEX priority = DefaultPriority); 00193 ~PInterfaceMonitorClient(); 00194 00195 typedef PIPSocket::InterfaceEntry InterfaceEntry; 00196 00203 virtual PStringArray GetInterfaces( 00204 bool includeLoopBack = false, 00205 const PIPSocket::Address & destination = PIPSocket::GetDefaultIpAny() 00207 ); 00208 00213 virtual PBoolean GetInterfaceInfo( 00214 const PString & iface, 00215 InterfaceEntry & info 00216 ) const; 00217 00222 PINDEX GetPriority() const { return priority; } 00223 00224 protected: 00226 virtual void OnAddInterface(const InterfaceEntry & entry) = 0; 00227 00229 virtual void OnRemoveInterface(const InterfaceEntry & entry) = 0; 00230 00232 virtual void OnRemoveNatMethod(const PNatMethod * /*natMethod*/) { } 00233 00234 PINDEX priority; 00235 00236 friend class PInterfaceMonitor; 00237 }; 00238 00239 00241 00242 class PInterfaceFilter : public PObject { 00243 PCLASSINFO(PInterfaceFilter, PObject); 00244 00245 public: 00246 virtual PIPSocket::InterfaceTable FilterInterfaces(const PIPSocket::Address & destination, 00247 PIPSocket::InterfaceTable & interfaces) const = 0; 00248 }; 00249 00250 00252 00258 class PMonitoredSockets : public PInterfaceMonitorClient 00259 { 00260 PCLASSINFO(PMonitoredSockets, PInterfaceMonitorClient); 00261 protected: 00262 PMonitoredSockets( 00263 bool reuseAddr, 00264 PNatMethod * natMethod 00265 ); 00266 00267 public: 00274 virtual PBoolean Open( 00275 WORD port 00276 ) = 0; 00277 00279 PBoolean IsOpen() const { return opened; } 00280 00282 virtual PBoolean Close() = 0; 00283 00285 WORD GetPort() const { return localPort; } 00286 00288 virtual PBoolean GetAddress( 00289 const PString & iface, 00290 PIPSocket::Address & address, 00291 WORD & port, 00292 PBoolean usingNAT 00293 ) const = 0; 00294 00300 virtual PChannel::Errors WriteToBundle( 00301 const void * buffer, 00302 PINDEX length, 00303 const PIPSocket::Address & addr, 00304 WORD port, 00305 const PString & iface, 00306 PINDEX & lastWriteCount 00307 ) = 0; 00308 00315 virtual PChannel::Errors ReadFromBundle( 00316 void * buffer, 00317 PINDEX length, 00318 PIPSocket::Address & addr, 00319 WORD & port, 00320 PString & iface, 00321 PINDEX & lastReadCount, 00322 const PTimeInterval & timeout 00323 ) = 0; 00324 00326 void SetNatMethod( 00327 PNatMethod * method 00328 ) { natMethod = method; } 00329 00330 00331 // Get the current NAT method, eg STUN client pointer 00332 PNatMethod * GetNatMethod() const { return natMethod; } 00333 00338 static PMonitoredSockets * Create( 00339 const PString & iface, 00340 bool reuseAddr = false, 00341 PNatMethod * natMethod = NULL 00342 ); 00343 00344 protected: 00345 virtual void OnRemoveNatMethod( 00346 const PNatMethod * natMethod 00347 ); 00348 00349 struct SocketInfo { 00350 SocketInfo() 00351 : socket(NULL) 00352 , inUse(false) 00353 { } 00354 PUDPSocket * socket; 00355 bool inUse; 00356 }; 00357 00358 bool CreateSocket( 00359 SocketInfo & info, 00360 const PIPSocket::Address & binding 00361 ); 00362 bool DestroySocket(SocketInfo & info); 00363 bool GetSocketAddress( 00364 const SocketInfo & info, 00365 PIPSocket::Address & address, 00366 WORD & port, 00367 bool usingNAT 00368 ) const; 00369 00370 PChannel::Errors WriteToSocket( 00371 const void * buf, 00372 PINDEX len, 00373 const PIPSocket::Address & addr, 00374 WORD port, 00375 const SocketInfo & info, 00376 PINDEX & lastWriteCount 00377 ); 00378 PChannel::Errors ReadFromSocket( 00379 SocketInfo & info, 00380 void * buf, 00381 PINDEX len, 00382 PIPSocket::Address & addr, 00383 WORD & port, 00384 PINDEX & lastReadCount, 00385 const PTimeInterval & timeout 00386 ); 00387 PChannel::Errors ReadFromSocket( 00388 PSocket::SelectList & readers, 00389 PUDPSocket * & socket, 00390 void * buf, 00391 PINDEX len, 00392 PIPSocket::Address & addr, 00393 WORD & port, 00394 PINDEX & lastReadCount, 00395 const PTimeInterval & timeout 00396 ); 00397 00398 WORD localPort; 00399 bool reuseAddress; 00400 PNatMethod * natMethod; 00401 00402 bool opened; 00403 PUDPSocket interfaceAddedSignal; 00404 }; 00405 00406 typedef PSafePtr<PMonitoredSockets> PMonitoredSocketsPtr; 00407 00408 00410 00414 class PMonitoredSocketChannel : public PChannel 00415 { 00416 PCLASSINFO(PMonitoredSocketChannel, PChannel); 00417 public: 00420 00421 PMonitoredSocketChannel( 00422 const PMonitoredSocketsPtr & sockets, 00423 bool shared 00424 ); 00426 00429 virtual PBoolean IsOpen() const; 00430 virtual PBoolean Close(); 00431 00434 virtual PBoolean Read( 00435 void * buffer, 00436 PINDEX length 00437 ); 00438 00441 virtual PBoolean Write( 00442 const void * buffer, 00443 PINDEX length 00444 ); 00446 00452 void SetInterface( 00453 const PString & iface 00454 ); 00455 00457 PString GetInterface(); 00458 00461 bool GetLocal( 00462 PIPSocket::Address & address, 00463 WORD & port, 00464 bool usingNAT 00465 ); 00466 00468 void SetRemote( 00469 const PIPSocket::Address & address, 00470 WORD port 00471 ); 00472 00474 void SetRemote( 00475 const PString & hostAndPort 00476 ); 00477 00479 void GetRemote( 00480 PIPSocket::Address & addr, 00481 WORD & port 00482 ) const { addr = remoteAddress; port = remotePort; } 00483 00488 void SetPromiscuous( 00489 bool flag 00490 ) { promiscuousReads = flag; } 00491 00493 bool GetPromiscuous() { return promiscuousReads; } 00494 00496 void GetLastReceived( 00497 PIPSocket::Address & addr, 00498 WORD & port 00499 ) const { addr = lastReceivedAddress; port = lastReceivedPort; } 00500 00502 PString GetLastReceivedInterface() const { return lastReceivedInterface; } 00503 00505 const PMonitoredSocketsPtr & GetMonitoredSockets() const { return socketBundle; } 00507 00508 protected: 00509 PMonitoredSocketsPtr socketBundle; 00510 bool sharedBundle; 00511 PString currentInterface; 00512 bool promiscuousReads; 00513 PIPSocket::Address remoteAddress; 00514 bool closing; 00515 WORD remotePort; 00516 PIPSocket::Address lastReceivedAddress; 00517 WORD lastReceivedPort; 00518 PString lastReceivedInterface; 00519 PMutex mutex; 00520 }; 00521 00522 00524 00528 class PMonitoredSocketBundle : public PMonitoredSockets 00529 { 00530 PCLASSINFO(PMonitoredSocketBundle, PMonitoredSockets); 00531 public: 00532 PMonitoredSocketBundle( 00533 bool reuseAddr = false, 00534 PNatMethod * natMethod = NULL 00535 ); 00536 ~PMonitoredSocketBundle(); 00537 00544 virtual PBoolean Open( 00545 WORD port 00546 ); 00547 00549 virtual PBoolean Close(); 00550 00552 virtual PBoolean GetAddress( 00553 const PString & iface, 00554 PIPSocket::Address & address, 00555 WORD & port, 00556 PBoolean usingNAT 00557 ) const; 00558 00564 virtual PChannel::Errors WriteToBundle( 00565 const void * buf, 00566 PINDEX len, 00567 const PIPSocket::Address & addr, 00568 WORD port, 00569 const PString & iface, 00570 PINDEX & lastWriteCount 00571 ); 00572 00579 virtual PChannel::Errors ReadFromBundle( 00580 void * buf, 00581 PINDEX len, 00582 PIPSocket::Address & addr, 00583 WORD & port, 00584 PString & iface, 00585 PINDEX & lastReadCount, 00586 const PTimeInterval & timeout 00587 ); 00588 00589 protected: 00591 virtual void OnAddInterface(const InterfaceEntry & entry); 00592 00594 virtual void OnRemoveInterface(const InterfaceEntry & entry); 00595 00596 typedef std::map<std::string, SocketInfo> SocketInfoMap_T; 00597 00598 void OpenSocket(const PString & iface); 00599 void CloseSocket(SocketInfoMap_T::iterator iterSocket); 00600 00601 SocketInfoMap_T socketInfoMap; 00602 }; 00603 00604 00606 00611 class PSingleMonitoredSocket : public PMonitoredSockets 00612 { 00613 PCLASSINFO(PSingleMonitoredSocket, PMonitoredSockets); 00614 public: 00615 PSingleMonitoredSocket( 00616 const PString & theInterface, 00617 bool reuseAddr = false, 00618 PNatMethod * natMethod = NULL 00619 ); 00620 ~PSingleMonitoredSocket(); 00621 00626 virtual PStringArray GetInterfaces( 00627 bool includeLoopBack = false, 00628 const PIPSocket::Address & destination = PIPSocket::GetDefaultIpAny() 00630 ); 00631 00638 virtual PBoolean Open( 00639 WORD port 00640 ); 00641 00643 virtual PBoolean Close(); 00644 00646 virtual PBoolean GetAddress( 00647 const PString & iface, 00648 PIPSocket::Address & address, 00649 WORD & port, 00650 PBoolean usingNAT 00651 ) const; 00652 00658 virtual PChannel::Errors WriteToBundle( 00659 const void * buf, 00660 PINDEX len, 00661 const PIPSocket::Address & addr, 00662 WORD port, 00663 const PString & iface, 00664 PINDEX & lastWriteCount 00665 ); 00666 00673 virtual PChannel::Errors ReadFromBundle( 00674 void * buf, 00675 PINDEX len, 00676 PIPSocket::Address & addr, 00677 WORD & port, 00678 PString & iface, 00679 PINDEX & lastReadCount, 00680 const PTimeInterval & timeout 00681 ); 00682 00683 00684 protected: 00686 virtual void OnAddInterface(const InterfaceEntry & entry); 00687 00689 virtual void OnRemoveInterface(const InterfaceEntry & entry); 00690 00691 bool IsInterface(const PString & iface) const; 00692 00693 PString theInterface; 00694 InterfaceEntry theEntry; 00695 SocketInfo theInfo; 00696 }; 00697 00698 00699 #endif // PTLIB_PSOCKBUN_H 00700 00701 00702 // End Of File ///////////////////////////////////////////////////////////////