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()
00106 );
00107
00113 bool IsValidBindingForDestination(
00114 const PIPSocket::Address & binding,
00115 const PIPSocket::Address & destination
00116 );
00117
00122 bool GetInterfaceInfo(
00123 const PString & iface,
00124 InterfaceEntry & info
00125 ) const;
00126
00131 static bool IsMatchingInterface(
00132 const PString & iface,
00133 const InterfaceEntry & entry
00134 );
00135
00139 void SetInterfaceFilter(PInterfaceFilter * filter);
00140 bool HasInterfaceFilter() const { return m_interfaceFilter != NULL; }
00141
00142 virtual void RefreshInterfaceList();
00143
00144 void OnRemoveNatMethod(const PNatMethod * natMethod);
00145
00146 protected:
00147 virtual void OnShutdown();
00148
00149 void UpdateThreadMain();
00150
00151 void AddClient(PInterfaceMonitorClient *);
00152 void RemoveClient(PInterfaceMonitorClient *);
00153
00154 virtual void OnInterfacesChanged(const PIPSocket::InterfaceTable & addedInterfaces, const PIPSocket::InterfaceTable & removedInterfaces);
00155
00156 typedef PSmartPtr<PInterfaceMonitorClient> ClientPtr;
00157
00158 typedef std::list<PInterfaceMonitorClient *> ClientList_T;
00159 ClientList_T m_clients;
00160 PMutex m_clientsMutex;
00161
00162 PIPSocket::InterfaceTable m_interfaces;
00163 PMutex m_interfacesMutex;
00164
00165 bool m_runMonitorThread;
00166 PTimeInterval m_refreshInterval;
00167 PMutex m_threadMutex;
00168 PThread * m_updateThread;
00169 PSyncPoint m_signalUpdate;
00170 bool m_threadRunning;
00171
00172 PInterfaceFilter * m_interfaceFilter;
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()
00206 );
00207
00212 virtual PBoolean GetInterfaceInfo(
00213 const PString & iface,
00214 InterfaceEntry & info
00215 ) const;
00216
00221 PINDEX GetPriority() const { return priority; }
00222
00223 protected:
00225 virtual void OnAddInterface(const InterfaceEntry & entry) = 0;
00226
00228 virtual void OnRemoveInterface(const InterfaceEntry & entry) = 0;
00229
00231 virtual void OnRemoveNatMethod(const PNatMethod * ) { }
00232
00233 PINDEX priority;
00234
00235 friend class PInterfaceMonitor;
00236 };
00237
00238
00240
00241 class PInterfaceFilter : public PObject {
00242 PCLASSINFO(PInterfaceFilter, PObject);
00243
00244 public:
00245 virtual PIPSocket::InterfaceTable FilterInterfaces(const PIPSocket::Address & destination,
00246 PIPSocket::InterfaceTable & interfaces) const = 0;
00247 };
00248
00249
00251
00257 class PMonitoredSockets : public PInterfaceMonitorClient
00258 {
00259 PCLASSINFO(PMonitoredSockets, PInterfaceMonitorClient);
00260 protected:
00261 PMonitoredSockets(
00262 bool reuseAddr,
00263 PNatMethod * natMethod
00264 );
00265
00266 public:
00273 virtual PBoolean Open(
00274 WORD port
00275 ) = 0;
00276
00278 PBoolean IsOpen() const { return opened; }
00279
00281 virtual PBoolean Close() = 0;
00282
00284 WORD GetPort() const { return localPort; }
00285
00287 virtual PBoolean GetAddress(
00288 const PString & iface,
00289 PIPSocket::Address & address,
00290 WORD & port,
00291 PBoolean usingNAT
00292 ) const = 0;
00293
00299 virtual PChannel::Errors WriteToBundle(
00300 const void * buffer,
00301 PINDEX length,
00302 const PIPSocket::Address & addr,
00303 WORD port,
00304 const PString & iface,
00305 PINDEX & lastWriteCount
00306 ) = 0;
00307
00314 virtual PChannel::Errors ReadFromBundle(
00315 void * buffer,
00316 PINDEX length,
00317 PIPSocket::Address & addr,
00318 WORD & port,
00319 PString & iface,
00320 PINDEX & lastReadCount,
00321 const PTimeInterval & timeout
00322 ) = 0;
00323
00325 void SetNatMethod(
00326 PNatMethod * method
00327 ) { natMethod = method; }
00328
00329
00330
00331 PNatMethod * GetNatMethod() const { return natMethod; }
00332
00337 static PMonitoredSockets * Create(
00338 const PString & iface,
00339 bool reuseAddr = false,
00340 PNatMethod * natMethod = NULL
00341 );
00342
00343 protected:
00344 virtual void OnRemoveNatMethod(
00345 const PNatMethod * natMethod
00346 );
00347
00348 struct SocketInfo {
00349 SocketInfo()
00350 : socket(NULL)
00351 , inUse(false)
00352 { }
00353 PUDPSocket * socket;
00354 bool inUse;
00355 };
00356
00357 bool CreateSocket(
00358 SocketInfo & info,
00359 const PIPSocket::Address & binding
00360 );
00361 bool DestroySocket(SocketInfo & info);
00362 bool GetSocketAddress(
00363 const SocketInfo & info,
00364 PIPSocket::Address & address,
00365 WORD & port,
00366 bool usingNAT
00367 ) const;
00368
00369 PChannel::Errors WriteToSocket(
00370 const void * buf,
00371 PINDEX len,
00372 const PIPSocket::Address & addr,
00373 WORD port,
00374 const SocketInfo & info,
00375 PINDEX & lastWriteCount
00376 );
00377 PChannel::Errors ReadFromSocket(
00378 SocketInfo & info,
00379 void * buf,
00380 PINDEX len,
00381 PIPSocket::Address & addr,
00382 WORD & port,
00383 PINDEX & lastReadCount,
00384 const PTimeInterval & timeout
00385 );
00386 PChannel::Errors ReadFromSocket(
00387 PSocket::SelectList & readers,
00388 PUDPSocket * & socket,
00389 void * buf,
00390 PINDEX len,
00391 PIPSocket::Address & addr,
00392 WORD & port,
00393 PINDEX & lastReadCount,
00394 const PTimeInterval & timeout
00395 );
00396
00397 WORD localPort;
00398 bool reuseAddress;
00399 PNatMethod * natMethod;
00400
00401 bool opened;
00402 PUDPSocket interfaceAddedSignal;
00403 };
00404
00405 typedef PSafePtr<PMonitoredSockets> PMonitoredSocketsPtr;
00406
00407
00409
00413 class PMonitoredSocketChannel : public PChannel
00414 {
00415 PCLASSINFO(PMonitoredSocketChannel, PChannel);
00416 public:
00419
00420 PMonitoredSocketChannel(
00421 const PMonitoredSocketsPtr & sockets,
00422 bool shared
00423 );
00425
00428 virtual PBoolean IsOpen() const;
00429 virtual PBoolean Close();
00430
00433 virtual PBoolean Read(
00434 void * buffer,
00435 PINDEX length
00436 );
00437
00438 virtual PBoolean Write(
00441 const void * buffer,
00442 PINDEX length
00443 );
00445
00451 void SetInterface(
00452 const PString & iface
00453 );
00454
00456 PString GetInterface();
00457
00460 bool GetLocal(
00461 PIPSocket::Address & address,
00462 WORD & port,
00463 bool usingNAT
00464 );
00465
00467 void SetRemote(
00468 const PIPSocket::Address & address,
00469 WORD port
00470 );
00471
00473 void SetRemote(
00474 const PString & hostAndPort
00475 );
00476
00478 void GetRemote(
00479 PIPSocket::Address & addr,
00480 WORD & port
00481 ) const { addr = remoteAddress; port = remotePort; }
00482
00487 void SetPromiscuous(
00488 bool flag
00489 ) { promiscuousReads = flag; }
00490
00492 bool GetPromiscuous() { return promiscuousReads; }
00493
00495 void GetLastReceived(
00496 PIPSocket::Address & addr,
00497 WORD & port
00498 ) const { addr = lastReceivedAddress; port = lastReceivedPort; }
00499
00501 PString GetLastReceivedInterface() const { return lastReceivedInterface; }
00502
00504 const PMonitoredSocketsPtr & GetMonitoredSockets() const { return socketBundle; }
00506
00507 protected:
00508 PMonitoredSocketsPtr socketBundle;
00509 bool sharedBundle;
00510 PString currentInterface;
00511 bool promiscuousReads;
00512 PIPSocket::Address remoteAddress;
00513 bool closing;
00514 WORD remotePort;
00515 PIPSocket::Address lastReceivedAddress;
00516 WORD lastReceivedPort;
00517 PString lastReceivedInterface;
00518 PMutex mutex;
00519 };
00520
00521
00523
00527 class PMonitoredSocketBundle : public PMonitoredSockets
00528 {
00529 PCLASSINFO(PMonitoredSocketBundle, PMonitoredSockets);
00530 public:
00531 PMonitoredSocketBundle(
00532 bool reuseAddr = false,
00533 PNatMethod * natMethod = NULL
00534 );
00535 ~PMonitoredSocketBundle();
00536
00543 virtual PBoolean Open(
00544 WORD port
00545 );
00546
00548 virtual PBoolean Close();
00549
00551 virtual PBoolean GetAddress(
00552 const PString & iface,
00553 PIPSocket::Address & address,
00554 WORD & port,
00555 PBoolean usingNAT
00556 ) const;
00557
00563 virtual PChannel::Errors WriteToBundle(
00564 const void * buf,
00565 PINDEX len,
00566 const PIPSocket::Address & addr,
00567 WORD port,
00568 const PString & iface,
00569 PINDEX & lastWriteCount
00570 );
00571
00578 virtual PChannel::Errors ReadFromBundle(
00579 void * buf,
00580 PINDEX len,
00581 PIPSocket::Address & addr,
00582 WORD & port,
00583 PString & iface,
00584 PINDEX & lastReadCount,
00585 const PTimeInterval & timeout
00586 );
00587
00588 protected:
00590 virtual void OnAddInterface(const InterfaceEntry & entry);
00591
00593 virtual void OnRemoveInterface(const InterfaceEntry & entry);
00594
00595 typedef std::map<std::string, SocketInfo> SocketInfoMap_T;
00596
00597 void OpenSocket(const PString & iface);
00598 void CloseSocket(SocketInfoMap_T::iterator iterSocket);
00599
00600 SocketInfoMap_T socketInfoMap;
00601 };
00602
00603
00605
00610 class PSingleMonitoredSocket : public PMonitoredSockets
00611 {
00612 PCLASSINFO(PSingleMonitoredSocket, PMonitoredSockets);
00613 public:
00614 PSingleMonitoredSocket(
00615 const PString & theInterface,
00616 bool reuseAddr = false,
00617 PNatMethod * natMethod = NULL
00618 );
00619 ~PSingleMonitoredSocket();
00620
00625 virtual PStringArray GetInterfaces(
00626 PBoolean includeLoopBack = false,
00627 const PIPSocket::Address & destination = PIPSocket::GetDefaultIpAny()
00628 );
00629
00636 virtual PBoolean Open(
00637 WORD port
00638 );
00639
00641 virtual PBoolean Close();
00642
00644 virtual PBoolean GetAddress(
00645 const PString & iface,
00646 PIPSocket::Address & address,
00647 WORD & port,
00648 PBoolean usingNAT
00649 ) const;
00650
00656 virtual PChannel::Errors WriteToBundle(
00657 const void * buf,
00658 PINDEX len,
00659 const PIPSocket::Address & addr,
00660 WORD port,
00661 const PString & iface,
00662 PINDEX & lastWriteCount
00663 );
00664
00671 virtual PChannel::Errors ReadFromBundle(
00672 void * buf,
00673 PINDEX len,
00674 PIPSocket::Address & addr,
00675 WORD & port,
00676 PString & iface,
00677 PINDEX & lastReadCount,
00678 const PTimeInterval & timeout
00679 );
00680
00681
00682 protected:
00684 virtual void OnAddInterface(const InterfaceEntry & entry);
00685
00687 virtual void OnRemoveInterface(const InterfaceEntry & entry);
00688
00689 bool IsInterface(const PString & iface) const;
00690
00691 PString theInterface;
00692 InterfaceEntry theEntry;
00693 SocketInfo theInfo;
00694 };
00695
00696
00697 #endif // PTLIB_PSOCKBUN_H
00698
00699
00700