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 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
00088 bool Start();
00089
00091 void Stop();
00092
00093 typedef PIPSocket::InterfaceEntry InterfaceEntry;
00094
00099 PStringArray GetInterfaces(
00100 bool includeLoopBack = false,
00101 const PIPSocket::Address & destination = PIPSocket::GetDefaultIpAny()
00102 );
00103
00109 bool IsValidBindingForDestination(
00110 const PIPSocket::Address & binding,
00111 const PIPSocket::Address & destination
00112 );
00113
00118 bool GetInterfaceInfo(
00119 const PString & iface,
00120 InterfaceEntry & info
00121 );
00122
00127 static bool IsMatchingInterface(
00128 const PString & iface,
00129 const InterfaceEntry & entry
00130 );
00131
00135 void SetInterfaceFilter(PInterfaceFilter * filter);
00136 bool HasInterfaceFilter() const { return interfaceFilter != NULL; }
00137
00138 virtual void RefreshInterfaceList();
00139
00140 void OnRemoveNatMethod(const PNatMethod * natMethod);
00141
00142 protected:
00143 virtual void OnShutdown();
00144
00145 void UpdateThreadMain();
00146
00147 void AddClient(PInterfaceMonitorClient *);
00148 void RemoveClient(PInterfaceMonitorClient *);
00149
00150 virtual void OnInterfacesChanged(const PIPSocket::InterfaceTable & addedInterfaces, const PIPSocket::InterfaceTable & removedInterfaces);
00151
00152 typedef PSmartPtr<PInterfaceMonitorClient> ClientPtr;
00153
00154 typedef std::list<PInterfaceMonitorClient *> ClientList_T;
00155 ClientList_T currentClients;
00156 PIPSocket::InterfaceTable currentInterfaces;
00157
00158 bool runMonitorThread;
00159 PTimeInterval refreshInterval;
00160 PMutex mutex;
00161 PThread * updateThread;
00162 PSyncPoint threadRunning;
00163
00164 PInterfaceFilter * interfaceFilter;
00165
00166 friend class PInterfaceMonitorClient;
00167 };
00168
00169
00171
00177 class PInterfaceMonitorClient : public PSafeObject
00178 {
00179 PCLASSINFO(PInterfaceMonitorClient, PSafeObject);
00180 public:
00181 enum {
00182 DefaultPriority = 50,
00183 };
00184 PInterfaceMonitorClient(PINDEX priority = DefaultPriority);
00185 ~PInterfaceMonitorClient();
00186
00187 typedef PIPSocket::InterfaceEntry InterfaceEntry;
00188
00195 virtual PStringArray GetInterfaces(
00196 bool includeLoopBack = false,
00197 const PIPSocket::Address & destination = PIPSocket::GetDefaultIpAny()
00198 );
00199
00204 virtual PBoolean GetInterfaceInfo(
00205 const PString & iface,
00206 InterfaceEntry & info
00207 );
00208
00213 PINDEX GetPriority() const { return priority; }
00214
00215 protected:
00217 virtual void OnAddInterface(const InterfaceEntry & entry) = 0;
00218
00220 virtual void OnRemoveInterface(const InterfaceEntry & entry) = 0;
00221
00223 virtual void OnRemoveNatMethod(const PNatMethod * ) { }
00224
00225 PINDEX priority;
00226
00227 friend class PInterfaceMonitor;
00228 };
00229
00230
00232
00233 class PInterfaceFilter : public PObject {
00234 PCLASSINFO(PInterfaceFilter, PObject);
00235
00236 public:
00237 virtual PIPSocket::InterfaceTable FilterInterfaces(const PIPSocket::Address & destination,
00238 PIPSocket::InterfaceTable & interfaces) const = 0;
00239 };
00240
00241
00243
00249 class PMonitoredSockets : public PInterfaceMonitorClient
00250 {
00251 PCLASSINFO(PMonitoredSockets, PInterfaceMonitorClient);
00252 protected:
00253 PMonitoredSockets(
00254 bool reuseAddr,
00255 PNatMethod * natMethod
00256 );
00257
00258 public:
00265 virtual PBoolean Open(
00266 WORD port
00267 ) = 0;
00268
00270 PBoolean IsOpen() const { return opened; }
00271
00273 virtual PBoolean Close() = 0;
00274
00276 WORD GetPort() const { return localPort; }
00277
00279 virtual PBoolean GetAddress(
00280 const PString & iface,
00281 PIPSocket::Address & address,
00282 WORD & port,
00283 PBoolean usingNAT
00284 ) const = 0;
00285
00291 virtual PChannel::Errors WriteToBundle(
00292 const void * buffer,
00293 PINDEX length,
00294 const PIPSocket::Address & addr,
00295 WORD port,
00296 const PString & iface,
00297 PINDEX & lastWriteCount
00298 ) = 0;
00299
00306 virtual PChannel::Errors ReadFromBundle(
00307 void * buffer,
00308 PINDEX length,
00309 PIPSocket::Address & addr,
00310 WORD & port,
00311 PString & iface,
00312 PINDEX & lastReadCount,
00313 const PTimeInterval & timeout
00314 ) = 0;
00315
00317 void SetNatMethod(
00318 PNatMethod * method
00319 ) { natMethod = method; }
00320
00321
00322
00323 PNatMethod * GetNatMethod() const { return natMethod; }
00324
00329 static PMonitoredSockets * Create(
00330 const PString & iface,
00331 bool reuseAddr = false,
00332 PNatMethod * natMethod = NULL
00333 );
00334
00335 protected:
00336 virtual void OnRemoveNatMethod(
00337 const PNatMethod * natMethod
00338 );
00339
00340 struct SocketInfo {
00341 SocketInfo()
00342 : socket(NULL)
00343 , inUse(false)
00344 { }
00345 PUDPSocket * socket;
00346 bool inUse;
00347 };
00348
00349 bool CreateSocket(
00350 SocketInfo & info,
00351 const PIPSocket::Address & binding
00352 );
00353 bool DestroySocket(SocketInfo & info);
00354 bool GetSocketAddress(
00355 const SocketInfo & info,
00356 PIPSocket::Address & address,
00357 WORD & port,
00358 bool usingNAT
00359 ) const;
00360
00361 PChannel::Errors WriteToSocket(
00362 const void * buf,
00363 PINDEX len,
00364 const PIPSocket::Address & addr,
00365 WORD port,
00366 const SocketInfo & info,
00367 PINDEX & lastWriteCount
00368 );
00369 PChannel::Errors ReadFromSocket(
00370 SocketInfo & info,
00371 void * buf,
00372 PINDEX len,
00373 PIPSocket::Address & addr,
00374 WORD & port,
00375 PINDEX & lastReadCount,
00376 const PTimeInterval & timeout
00377 );
00378 PChannel::Errors ReadFromSocket(
00379 PSocket::SelectList & readers,
00380 PUDPSocket * & socket,
00381 void * buf,
00382 PINDEX len,
00383 PIPSocket::Address & addr,
00384 WORD & port,
00385 PINDEX & lastReadCount,
00386 const PTimeInterval & timeout
00387 );
00388
00389 WORD localPort;
00390 bool reuseAddress;
00391 PNatMethod * natMethod;
00392
00393 bool opened;
00394 PUDPSocket interfaceAddedSignal;
00395 };
00396
00397 typedef PSafePtr<PMonitoredSockets> PMonitoredSocketsPtr;
00398
00399
00401
00405 class PMonitoredSocketChannel : public PChannel
00406 {
00407 PCLASSINFO(PMonitoredSocketChannel, PChannel);
00408 public:
00411
00412 PMonitoredSocketChannel(
00413 const PMonitoredSocketsPtr & sockets,
00414 bool shared
00415 );
00417
00420 virtual PBoolean IsOpen() const;
00421 virtual PBoolean Close();
00422
00425 virtual PBoolean Read(
00426 void * buffer,
00427 PINDEX length
00428 );
00429
00430 virtual PBoolean Write(
00433 const void * buffer,
00434 PINDEX length
00435 );
00437
00443 void SetInterface(
00444 const PString & iface
00445 );
00446
00448 PString GetInterface();
00449
00452 bool GetLocal(
00453 PIPSocket::Address & address,
00454 WORD & port,
00455 bool usingNAT
00456 );
00457
00459 void SetRemote(
00460 const PIPSocket::Address & address,
00461 WORD port
00462 );
00463
00465 void SetRemote(
00466 const PString & hostAndPort
00467 );
00468
00470 void GetRemote(
00471 PIPSocket::Address & addr,
00472 WORD & port
00473 ) const { addr = remoteAddress; port = remotePort; }
00474
00479 void SetPromiscuous(
00480 bool flag
00481 ) { promiscuousReads = flag; }
00482
00484 bool GetPromiscuous() { return promiscuousReads; }
00485
00487 void GetLastReceived(
00488 PIPSocket::Address & addr,
00489 WORD & port
00490 ) const { addr = lastReceivedAddress; port = lastReceivedPort; }
00491
00493 PString GetLastReceivedInterface() const { return lastReceivedInterface; }
00494
00496 const PMonitoredSocketsPtr & GetMonitoredSockets() const { return socketBundle; }
00498
00499 protected:
00500 PMonitoredSocketsPtr socketBundle;
00501 bool sharedBundle;
00502 PString currentInterface;
00503 bool promiscuousReads;
00504 PIPSocket::Address remoteAddress;
00505 bool closing;
00506 WORD remotePort;
00507 PIPSocket::Address lastReceivedAddress;
00508 WORD lastReceivedPort;
00509 PString lastReceivedInterface;
00510 PMutex mutex;
00511 };
00512
00513
00515
00519 class PMonitoredSocketBundle : public PMonitoredSockets
00520 {
00521 PCLASSINFO(PMonitoredSocketBundle, PMonitoredSockets);
00522 public:
00523 PMonitoredSocketBundle(
00524 bool reuseAddr = false,
00525 PNatMethod * natMethod = NULL
00526 );
00527 ~PMonitoredSocketBundle();
00528
00535 virtual PBoolean Open(
00536 WORD port
00537 );
00538
00540 virtual PBoolean Close();
00541
00543 virtual PBoolean GetAddress(
00544 const PString & iface,
00545 PIPSocket::Address & address,
00546 WORD & port,
00547 PBoolean usingNAT
00548 ) const;
00549
00555 virtual PChannel::Errors WriteToBundle(
00556 const void * buf,
00557 PINDEX len,
00558 const PIPSocket::Address & addr,
00559 WORD port,
00560 const PString & iface,
00561 PINDEX & lastWriteCount
00562 );
00563
00570 virtual PChannel::Errors ReadFromBundle(
00571 void * buf,
00572 PINDEX len,
00573 PIPSocket::Address & addr,
00574 WORD & port,
00575 PString & iface,
00576 PINDEX & lastReadCount,
00577 const PTimeInterval & timeout
00578 );
00579
00580 protected:
00582 virtual void OnAddInterface(const InterfaceEntry & entry);
00583
00585 virtual void OnRemoveInterface(const InterfaceEntry & entry);
00586
00587 typedef std::map<std::string, SocketInfo> SocketInfoMap_T;
00588
00589 void OpenSocket(const PString & iface);
00590 void CloseSocket(SocketInfoMap_T::iterator iterSocket);
00591
00592 SocketInfoMap_T socketInfoMap;
00593 };
00594
00595
00597
00602 class PSingleMonitoredSocket : public PMonitoredSockets
00603 {
00604 PCLASSINFO(PSingleMonitoredSocket, PMonitoredSockets);
00605 public:
00606 PSingleMonitoredSocket(
00607 const PString & theInterface,
00608 bool reuseAddr = false,
00609 PNatMethod * natMethod = NULL
00610 );
00611 ~PSingleMonitoredSocket();
00612
00617 virtual PStringArray GetInterfaces(
00618 PBoolean includeLoopBack = false,
00619 const PIPSocket::Address & destination = PIPSocket::GetDefaultIpAny()
00620 );
00621
00628 virtual PBoolean Open(
00629 WORD port
00630 );
00631
00633 virtual PBoolean Close();
00634
00636 virtual PBoolean GetAddress(
00637 const PString & iface,
00638 PIPSocket::Address & address,
00639 WORD & port,
00640 PBoolean usingNAT
00641 ) const;
00642
00648 virtual PChannel::Errors WriteToBundle(
00649 const void * buf,
00650 PINDEX len,
00651 const PIPSocket::Address & addr,
00652 WORD port,
00653 const PString & iface,
00654 PINDEX & lastWriteCount
00655 );
00656
00663 virtual PChannel::Errors ReadFromBundle(
00664 void * buf,
00665 PINDEX len,
00666 PIPSocket::Address & addr,
00667 WORD & port,
00668 PString & iface,
00669 PINDEX & lastReadCount,
00670 const PTimeInterval & timeout
00671 );
00672
00673
00674 protected:
00676 virtual void OnAddInterface(const InterfaceEntry & entry);
00677
00679 virtual void OnRemoveInterface(const InterfaceEntry & entry);
00680
00681 bool IsInterface(const PString & iface) const;
00682
00683 PString theInterface;
00684 InterfaceEntry theEntry;
00685 SocketInfo theInfo;
00686 };
00687
00688 #endif