00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
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 static PInterfaceMonitor & GetInstance();
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 * ) { }
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
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