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 _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
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 bool Start();
00083
00085 void Stop();
00086
00087 typedef PIPSocket::InterfaceEntry InterfaceEntry;
00088
00093 PStringArray GetInterfaces(
00094 bool includeLoopBack = false,
00095 const PIPSocket::Address & destination = PIPSocket::GetDefaultIpAny()
00096 );
00097
00103 bool IsValidBindingForDestination(
00104 const PIPSocket::Address & binding,
00105 const PIPSocket::Address & destination
00106 );
00107
00112 bool GetInterfaceInfo(
00113 const PString & iface,
00114 InterfaceEntry & info
00115 );
00116
00121 static bool IsMatchingInterface(
00122 const PString & iface,
00123 const InterfaceEntry & entry
00124 );
00125
00129 void SetInterfaceFilter(PInterfaceFilter * filter);
00130
00131 virtual void RefreshInterfaceList();
00132
00133 void OnRemoveSTUNClient(const PSTUNClient *stun);
00134
00135 protected:
00136 virtual void OnShutdown();
00137
00138 void UpdateThreadMain();
00139
00140 void AddClient(PInterfaceMonitorClient *);
00141 void RemoveClient(PInterfaceMonitorClient *);
00142
00143 virtual void OnInterfacesChanged(const PIPSocket::InterfaceTable & addedInterfaces, const PIPSocket::InterfaceTable & removedInterfaces);
00144
00145 typedef PSmartPtr<PInterfaceMonitorClient> ClientPtr;
00146
00147 typedef std::list<PInterfaceMonitorClient *> ClientList_T;
00148 ClientList_T currentClients;
00149 PIPSocket::InterfaceTable currentInterfaces;
00150
00151 bool runMonitorThread;
00152 PTimeInterval refreshInterval;
00153 PMutex mutex;
00154 PThread * updateThread;
00155 PSyncPoint threadRunning;
00156
00157 PInterfaceFilter * interfaceFilter;
00158
00159 friend class PInterfaceMonitorClient;
00160 };
00161
00162
00164
00170 class PInterfaceMonitorClient : public PSafeObject
00171 {
00172 PCLASSINFO(PInterfaceMonitorClient, PSafeObject);
00173 public:
00174 enum {
00175 DefaultPriority = 50,
00176 };
00177 PInterfaceMonitorClient(PINDEX priority = DefaultPriority);
00178 ~PInterfaceMonitorClient();
00179
00180 typedef PIPSocket::InterfaceEntry InterfaceEntry;
00181
00188 virtual PStringArray GetInterfaces(
00189 bool includeLoopBack = false,
00190 const PIPSocket::Address & destination = PIPSocket::GetDefaultIpAny()
00191 );
00192
00197 virtual PBoolean GetInterfaceInfo(
00198 const PString & iface,
00199 InterfaceEntry & info
00200 );
00201
00206 PINDEX GetPriority() const { return priority; }
00207
00208 protected:
00210 virtual void OnAddInterface(const InterfaceEntry & entry) = 0;
00211
00213 virtual void OnRemoveInterface(const InterfaceEntry & entry) = 0;
00214
00216 virtual void OnRemoveSTUNClient(const PSTUNClient * ) { }
00217
00218 PINDEX priority;
00219
00220 friend class PInterfaceMonitor;
00221 };
00222
00223
00225
00226 class PInterfaceFilter : public PObject {
00227 PCLASSINFO(PInterfaceFilter, PObject);
00228
00229 public:
00230 virtual PIPSocket::InterfaceTable FilterInterfaces(const PIPSocket::Address & destination,
00231 PIPSocket::InterfaceTable & interfaces) const = 0;
00232 };
00233
00234
00236
00242 class PMonitoredSockets : public PInterfaceMonitorClient
00243 {
00244 PCLASSINFO(PMonitoredSockets, PInterfaceMonitorClient);
00245 protected:
00246 PMonitoredSockets(
00247 bool reuseAddr,
00248 PSTUNClient * stunClient
00249 );
00250
00251 public:
00258 virtual PBoolean Open(
00259 WORD port
00260 ) = 0;
00261
00263 PBoolean IsOpen() const { return opened; }
00264
00266 virtual PBoolean Close() = 0;
00267
00269 WORD GetPort() const { return localPort; }
00270
00272 virtual PBoolean GetAddress(
00273 const PString & iface,
00274 PIPSocket::Address & address,
00275 WORD & port,
00276 PBoolean usingNAT
00277 ) const = 0;
00278
00284 virtual PChannel::Errors WriteToBundle(
00285 const void * buffer,
00286 PINDEX length,
00287 const PIPSocket::Address & addr,
00288 WORD port,
00289 const PString & iface,
00290 PINDEX & lastWriteCount
00291 ) = 0;
00292
00299 virtual PChannel::Errors ReadFromBundle(
00300 void * buffer,
00301 PINDEX length,
00302 PIPSocket::Address & addr,
00303 WORD & port,
00304 PString & iface,
00305 PINDEX & lastReadCount,
00306 const PTimeInterval & timeout
00307 ) = 0;
00308
00310 void SetSTUN(
00311 PSTUNClient * stunClient
00312 ) { stun = stunClient; }
00313
00314
00315 PSTUNClient * GetSTUN() const { return stun; }
00316
00321 static PMonitoredSockets * Create(
00322 const PString & iface,
00323 bool reuseAddr = false,
00324 PSTUNClient * stunClient = NULL
00325 );
00326
00327 protected:
00328 virtual void OnRemoveSTUNClient(const PSTUNClient *stun);
00329 struct SocketInfo {
00330 SocketInfo()
00331 : socket(NULL)
00332 , inUse(false)
00333 { }
00334 PUDPSocket * socket;
00335 bool inUse;
00336 };
00337
00338 bool CreateSocket(
00339 SocketInfo & info,
00340 const PIPSocket::Address & binding
00341 );
00342 bool DestroySocket(SocketInfo & info);
00343 bool GetSocketAddress(
00344 const SocketInfo & info,
00345 PIPSocket::Address & address,
00346 WORD & port,
00347 bool usingNAT
00348 ) const;
00349
00350 PChannel::Errors WriteToSocket(
00351 const void * buf,
00352 PINDEX len,
00353 const PIPSocket::Address & addr,
00354 WORD port,
00355 const SocketInfo & info,
00356 PINDEX & lastWriteCount
00357 );
00358 PChannel::Errors ReadFromSocket(
00359 SocketInfo & info,
00360 void * buf,
00361 PINDEX len,
00362 PIPSocket::Address & addr,
00363 WORD & port,
00364 PINDEX & lastReadCount,
00365 const PTimeInterval & timeout
00366 );
00367 PChannel::Errors ReadFromSocket(
00368 PSocket::SelectList & readers,
00369 PUDPSocket * & socket,
00370 void * buf,
00371 PINDEX len,
00372 PIPSocket::Address & addr,
00373 WORD & port,
00374 PINDEX & lastReadCount,
00375 const PTimeInterval & timeout
00376 );
00377
00378 WORD localPort;
00379 bool reuseAddress;
00380 PSTUNClient * stun;
00381
00382 bool opened;
00383 PUDPSocket interfaceAddedSignal;
00384 };
00385
00386 typedef PSafePtr<PMonitoredSockets> PMonitoredSocketsPtr;
00387
00388
00390
00394 class PMonitoredSocketChannel : public PChannel
00395 {
00396 PCLASSINFO(PMonitoredSocketChannel, PChannel);
00397 public:
00400
00401 PMonitoredSocketChannel(
00402 const PMonitoredSocketsPtr & sockets,
00403 bool shared
00404 );
00406
00409 virtual PBoolean IsOpen() const;
00410 virtual PBoolean Close();
00411
00414 virtual PBoolean Read(
00415 void * buffer,
00416 PINDEX length
00417 );
00418
00419 virtual PBoolean Write(
00422 const void * buffer,
00423 PINDEX length
00424 );
00426
00432 void SetInterface(
00433 const PString & iface
00434 );
00435
00437 const PString & GetInterface();
00438
00441 bool GetLocal(
00442 PIPSocket::Address & address,
00443 WORD & port,
00444 bool usingNAT
00445 );
00446
00448 void SetRemote(
00449 const PIPSocket::Address & address,
00450 WORD port
00451 );
00452
00454 void SetRemote(
00455 const PString & hostAndPort
00456 );
00457
00459 void GetRemote(
00460 PIPSocket::Address & addr,
00461 WORD & port
00462 ) const { addr = remoteAddress; port = remotePort; }
00463
00468 void SetPromiscuous(
00469 bool flag
00470 ) { promiscuousReads = flag; }
00471
00473 bool GetPromiscuous() { return promiscuousReads; }
00474
00476 void GetLastReceived(
00477 PIPSocket::Address & addr,
00478 WORD & port
00479 ) const { addr = lastReceivedAddress; port = lastReceivedPort; }
00480
00482 PString GetLastReceivedInterface() const { return lastReceivedInterface; }
00483
00485 const PMonitoredSocketsPtr & GetMonitoredSockets() const { return socketBundle; }
00487
00488 protected:
00489 PMonitoredSocketsPtr socketBundle;
00490 bool sharedBundle;
00491 PString currentInterface;
00492 bool promiscuousReads;
00493 PIPSocket::Address remoteAddress;
00494 bool closing;
00495 WORD remotePort;
00496 PIPSocket::Address lastReceivedAddress;
00497 WORD lastReceivedPort;
00498 PString lastReceivedInterface;
00499 };
00500
00501
00503
00507 class PMonitoredSocketBundle : public PMonitoredSockets
00508 {
00509 PCLASSINFO(PMonitoredSocketBundle, PMonitoredSockets);
00510 public:
00511 PMonitoredSocketBundle(
00512 bool reuseAddr = false,
00513 PSTUNClient * stunClient = NULL
00514 );
00515 ~PMonitoredSocketBundle();
00516
00523 virtual PBoolean Open(
00524 WORD port
00525 );
00526
00528 virtual PBoolean Close();
00529
00531 virtual PBoolean GetAddress(
00532 const PString & iface,
00533 PIPSocket::Address & address,
00534 WORD & port,
00535 PBoolean usingNAT
00536 ) const;
00537
00543 virtual PChannel::Errors WriteToBundle(
00544 const void * buf,
00545 PINDEX len,
00546 const PIPSocket::Address & addr,
00547 WORD port,
00548 const PString & iface,
00549 PINDEX & lastWriteCount
00550 );
00551
00558 virtual PChannel::Errors ReadFromBundle(
00559 void * buf,
00560 PINDEX len,
00561 PIPSocket::Address & addr,
00562 WORD & port,
00563 PString & iface,
00564 PINDEX & lastReadCount,
00565 const PTimeInterval & timeout
00566 );
00567
00568 protected:
00570 virtual void OnAddInterface(const InterfaceEntry & entry);
00571
00573 virtual void OnRemoveInterface(const InterfaceEntry & entry);
00574
00575 typedef std::map<std::string, SocketInfo> SocketInfoMap_T;
00576
00577 void OpenSocket(const PString & iface);
00578 void CloseSocket(const SocketInfoMap_T::iterator & iterSocket);
00579
00580 SocketInfoMap_T socketInfoMap;
00581 };
00582
00583
00585
00590 class PSingleMonitoredSocket : public PMonitoredSockets
00591 {
00592 PCLASSINFO(PSingleMonitoredSocket, PMonitoredSockets);
00593 public:
00594 PSingleMonitoredSocket(
00595 const PString & theInterface,
00596 bool reuseAddr = false,
00597 PSTUNClient * stunClient = NULL
00598 );
00599 ~PSingleMonitoredSocket();
00600
00605 virtual PStringArray GetInterfaces(
00606 PBoolean includeLoopBack = false,
00607 const PIPSocket::Address & destination = PIPSocket::GetDefaultIpAny()
00608 );
00609
00616 virtual PBoolean Open(
00617 WORD port
00618 );
00619
00621 virtual PBoolean Close();
00622
00624 virtual PBoolean GetAddress(
00625 const PString & iface,
00626 PIPSocket::Address & address,
00627 WORD & port,
00628 PBoolean usingNAT
00629 ) const;
00630
00636 virtual PChannel::Errors WriteToBundle(
00637 const void * buf,
00638 PINDEX len,
00639 const PIPSocket::Address & addr,
00640 WORD port,
00641 const PString & iface,
00642 PINDEX & lastWriteCount
00643 );
00644
00651 virtual PChannel::Errors ReadFromBundle(
00652 void * buf,
00653 PINDEX len,
00654 PIPSocket::Address & addr,
00655 WORD & port,
00656 PString & iface,
00657 PINDEX & lastReadCount,
00658 const PTimeInterval & timeout
00659 );
00660
00661
00662 protected:
00664 virtual void OnAddInterface(const InterfaceEntry & entry);
00665
00667 virtual void OnRemoveInterface(const InterfaceEntry & entry);
00668
00669 bool IsInterface(const PString & iface) const;
00670
00671 PString theInterface;
00672 InterfaceEntry theEntry;
00673 SocketInfo theInfo;
00674 };
00675
00676 #endif