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 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 OnRemoveNatMethod(const PNatMethod * natMethod);
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 OnRemoveNatMethod(const PNatMethod * ) { }
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 PNatMethod * natMethod
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 SetNatMethod(
00311 PNatMethod * method
00312 ) { natMethod = method; }
00313
00314
00315
00316 PNatMethod * GetNatMethod() const { return natMethod; }
00317
00322 static PMonitoredSockets * Create(
00323 const PString & iface,
00324 bool reuseAddr = false,
00325 PNatMethod * natMethod = NULL
00326 );
00327
00328 protected:
00329 virtual void OnRemoveNatMethod(
00330 const PNatMethod * natMethod
00331 );
00332
00333 struct SocketInfo {
00334 SocketInfo()
00335 : socket(NULL)
00336 , inUse(false)
00337 { }
00338 PUDPSocket * socket;
00339 bool inUse;
00340 };
00341
00342 bool CreateSocket(
00343 SocketInfo & info,
00344 const PIPSocket::Address & binding
00345 );
00346 bool DestroySocket(SocketInfo & info);
00347 bool GetSocketAddress(
00348 const SocketInfo & info,
00349 PIPSocket::Address & address,
00350 WORD & port,
00351 bool usingNAT
00352 ) const;
00353
00354 PChannel::Errors WriteToSocket(
00355 const void * buf,
00356 PINDEX len,
00357 const PIPSocket::Address & addr,
00358 WORD port,
00359 const SocketInfo & info,
00360 PINDEX & lastWriteCount
00361 );
00362 PChannel::Errors ReadFromSocket(
00363 SocketInfo & info,
00364 void * buf,
00365 PINDEX len,
00366 PIPSocket::Address & addr,
00367 WORD & port,
00368 PINDEX & lastReadCount,
00369 const PTimeInterval & timeout
00370 );
00371 PChannel::Errors ReadFromSocket(
00372 PSocket::SelectList & readers,
00373 PUDPSocket * & socket,
00374 void * buf,
00375 PINDEX len,
00376 PIPSocket::Address & addr,
00377 WORD & port,
00378 PINDEX & lastReadCount,
00379 const PTimeInterval & timeout
00380 );
00381
00382 WORD localPort;
00383 bool reuseAddress;
00384 PNatMethod * natMethod;
00385
00386 bool opened;
00387 PUDPSocket interfaceAddedSignal;
00388 };
00389
00390 typedef PSafePtr<PMonitoredSockets> PMonitoredSocketsPtr;
00391
00392
00394
00398 class PMonitoredSocketChannel : public PChannel
00399 {
00400 PCLASSINFO(PMonitoredSocketChannel, PChannel);
00401 public:
00404
00405 PMonitoredSocketChannel(
00406 const PMonitoredSocketsPtr & sockets,
00407 bool shared
00408 );
00410
00413 virtual PBoolean IsOpen() const;
00414 virtual PBoolean Close();
00415
00418 virtual PBoolean Read(
00419 void * buffer,
00420 PINDEX length
00421 );
00422
00423 virtual PBoolean Write(
00426 const void * buffer,
00427 PINDEX length
00428 );
00430
00436 void SetInterface(
00437 const PString & iface
00438 );
00439
00441 const PString & GetInterface();
00442
00445 bool GetLocal(
00446 PIPSocket::Address & address,
00447 WORD & port,
00448 bool usingNAT
00449 );
00450
00452 void SetRemote(
00453 const PIPSocket::Address & address,
00454 WORD port
00455 );
00456
00458 void SetRemote(
00459 const PString & hostAndPort
00460 );
00461
00463 void GetRemote(
00464 PIPSocket::Address & addr,
00465 WORD & port
00466 ) const { addr = remoteAddress; port = remotePort; }
00467
00472 void SetPromiscuous(
00473 bool flag
00474 ) { promiscuousReads = flag; }
00475
00477 bool GetPromiscuous() { return promiscuousReads; }
00478
00480 void GetLastReceived(
00481 PIPSocket::Address & addr,
00482 WORD & port
00483 ) const { addr = lastReceivedAddress; port = lastReceivedPort; }
00484
00486 PString GetLastReceivedInterface() const { return lastReceivedInterface; }
00487
00489 const PMonitoredSocketsPtr & GetMonitoredSockets() const { return socketBundle; }
00491
00492 protected:
00493 PMonitoredSocketsPtr socketBundle;
00494 bool sharedBundle;
00495 PString currentInterface;
00496 bool promiscuousReads;
00497 PIPSocket::Address remoteAddress;
00498 bool closing;
00499 WORD remotePort;
00500 PIPSocket::Address lastReceivedAddress;
00501 WORD lastReceivedPort;
00502 PString lastReceivedInterface;
00503 };
00504
00505
00507
00511 class PMonitoredSocketBundle : public PMonitoredSockets
00512 {
00513 PCLASSINFO(PMonitoredSocketBundle, PMonitoredSockets);
00514 public:
00515 PMonitoredSocketBundle(
00516 bool reuseAddr = false,
00517 PNatMethod * natMethod = NULL
00518 );
00519 ~PMonitoredSocketBundle();
00520
00527 virtual PBoolean Open(
00528 WORD port
00529 );
00530
00532 virtual PBoolean Close();
00533
00535 virtual PBoolean GetAddress(
00536 const PString & iface,
00537 PIPSocket::Address & address,
00538 WORD & port,
00539 PBoolean usingNAT
00540 ) const;
00541
00547 virtual PChannel::Errors WriteToBundle(
00548 const void * buf,
00549 PINDEX len,
00550 const PIPSocket::Address & addr,
00551 WORD port,
00552 const PString & iface,
00553 PINDEX & lastWriteCount
00554 );
00555
00562 virtual PChannel::Errors ReadFromBundle(
00563 void * buf,
00564 PINDEX len,
00565 PIPSocket::Address & addr,
00566 WORD & port,
00567 PString & iface,
00568 PINDEX & lastReadCount,
00569 const PTimeInterval & timeout
00570 );
00571
00572 protected:
00574 virtual void OnAddInterface(const InterfaceEntry & entry);
00575
00577 virtual void OnRemoveInterface(const InterfaceEntry & entry);
00578
00579 typedef std::map<std::string, SocketInfo> SocketInfoMap_T;
00580
00581 void OpenSocket(const PString & iface);
00582 void CloseSocket(SocketInfoMap_T::iterator iterSocket);
00583
00584 SocketInfoMap_T socketInfoMap;
00585 };
00586
00587
00589
00594 class PSingleMonitoredSocket : public PMonitoredSockets
00595 {
00596 PCLASSINFO(PSingleMonitoredSocket, PMonitoredSockets);
00597 public:
00598 PSingleMonitoredSocket(
00599 const PString & theInterface,
00600 bool reuseAddr = false,
00601 PNatMethod * natMethod = NULL
00602 );
00603 ~PSingleMonitoredSocket();
00604
00609 virtual PStringArray GetInterfaces(
00610 PBoolean includeLoopBack = false,
00611 const PIPSocket::Address & destination = PIPSocket::GetDefaultIpAny()
00612 );
00613
00620 virtual PBoolean Open(
00621 WORD port
00622 );
00623
00625 virtual PBoolean Close();
00626
00628 virtual PBoolean GetAddress(
00629 const PString & iface,
00630 PIPSocket::Address & address,
00631 WORD & port,
00632 PBoolean usingNAT
00633 ) const;
00634
00640 virtual PChannel::Errors WriteToBundle(
00641 const void * buf,
00642 PINDEX len,
00643 const PIPSocket::Address & addr,
00644 WORD port,
00645 const PString & iface,
00646 PINDEX & lastWriteCount
00647 );
00648
00655 virtual PChannel::Errors ReadFromBundle(
00656 void * buf,
00657 PINDEX len,
00658 PIPSocket::Address & addr,
00659 WORD & port,
00660 PString & iface,
00661 PINDEX & lastReadCount,
00662 const PTimeInterval & timeout
00663 );
00664
00665
00666 protected:
00668 virtual void OnAddInterface(const InterfaceEntry & entry);
00669
00671 virtual void OnRemoveInterface(const InterfaceEntry & entry);
00672
00673 bool IsInterface(const PString & iface) const;
00674
00675 PString theInterface;
00676 InterfaceEntry theEntry;
00677 SocketInfo theInfo;
00678 };
00679
00680 #endif