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 bool Start();
00086
00088 void Stop();
00089
00090 typedef PIPSocket::InterfaceEntry InterfaceEntry;
00091
00096 PStringArray GetInterfaces(
00097 bool includeLoopBack = false,
00098 const PIPSocket::Address & destination = PIPSocket::GetDefaultIpAny()
00099 );
00100
00106 bool IsValidBindingForDestination(
00107 const PIPSocket::Address & binding,
00108 const PIPSocket::Address & destination
00109 );
00110
00115 bool GetInterfaceInfo(
00116 const PString & iface,
00117 InterfaceEntry & info
00118 );
00119
00124 static bool IsMatchingInterface(
00125 const PString & iface,
00126 const InterfaceEntry & entry
00127 );
00128
00132 void SetInterfaceFilter(PInterfaceFilter * filter);
00133
00134 virtual void RefreshInterfaceList();
00135
00136 void OnRemoveNatMethod(const PNatMethod * natMethod);
00137
00138 protected:
00139 virtual void OnShutdown();
00140
00141 void UpdateThreadMain();
00142
00143 void AddClient(PInterfaceMonitorClient *);
00144 void RemoveClient(PInterfaceMonitorClient *);
00145
00146 virtual void OnInterfacesChanged(const PIPSocket::InterfaceTable & addedInterfaces, const PIPSocket::InterfaceTable & removedInterfaces);
00147
00148 typedef PSmartPtr<PInterfaceMonitorClient> ClientPtr;
00149
00150 typedef std::list<PInterfaceMonitorClient *> ClientList_T;
00151 ClientList_T currentClients;
00152 PIPSocket::InterfaceTable currentInterfaces;
00153
00154 bool runMonitorThread;
00155 PTimeInterval refreshInterval;
00156 PMutex mutex;
00157 PThread * updateThread;
00158 PSyncPoint threadRunning;
00159
00160 PInterfaceFilter * interfaceFilter;
00161
00162 friend class PInterfaceMonitorClient;
00163 };
00164
00165
00167
00173 class PInterfaceMonitorClient : public PSafeObject
00174 {
00175 PCLASSINFO(PInterfaceMonitorClient, PSafeObject);
00176 public:
00177 enum {
00178 DefaultPriority = 50,
00179 };
00180 PInterfaceMonitorClient(PINDEX priority = DefaultPriority);
00181 ~PInterfaceMonitorClient();
00182
00183 typedef PIPSocket::InterfaceEntry InterfaceEntry;
00184
00191 virtual PStringArray GetInterfaces(
00192 bool includeLoopBack = false,
00193 const PIPSocket::Address & destination = PIPSocket::GetDefaultIpAny()
00194 );
00195
00200 virtual PBoolean GetInterfaceInfo(
00201 const PString & iface,
00202 InterfaceEntry & info
00203 );
00204
00209 PINDEX GetPriority() const { return priority; }
00210
00211 protected:
00213 virtual void OnAddInterface(const InterfaceEntry & entry) = 0;
00214
00216 virtual void OnRemoveInterface(const InterfaceEntry & entry) = 0;
00217
00219 virtual void OnRemoveNatMethod(const PNatMethod * ) { }
00220
00221 PINDEX priority;
00222
00223 friend class PInterfaceMonitor;
00224 };
00225
00226
00228
00229 class PInterfaceFilter : public PObject {
00230 PCLASSINFO(PInterfaceFilter, PObject);
00231
00232 public:
00233 virtual PIPSocket::InterfaceTable FilterInterfaces(const PIPSocket::Address & destination,
00234 PIPSocket::InterfaceTable & interfaces) const = 0;
00235 };
00236
00237
00239
00245 class PMonitoredSockets : public PInterfaceMonitorClient
00246 {
00247 PCLASSINFO(PMonitoredSockets, PInterfaceMonitorClient);
00248 protected:
00249 PMonitoredSockets(
00250 bool reuseAddr,
00251 PNatMethod * natMethod
00252 );
00253
00254 public:
00261 virtual PBoolean Open(
00262 WORD port
00263 ) = 0;
00264
00266 PBoolean IsOpen() const { return opened; }
00267
00269 virtual PBoolean Close() = 0;
00270
00272 WORD GetPort() const { return localPort; }
00273
00275 virtual PBoolean GetAddress(
00276 const PString & iface,
00277 PIPSocket::Address & address,
00278 WORD & port,
00279 PBoolean usingNAT
00280 ) const = 0;
00281
00287 virtual PChannel::Errors WriteToBundle(
00288 const void * buffer,
00289 PINDEX length,
00290 const PIPSocket::Address & addr,
00291 WORD port,
00292 const PString & iface,
00293 PINDEX & lastWriteCount
00294 ) = 0;
00295
00302 virtual PChannel::Errors ReadFromBundle(
00303 void * buffer,
00304 PINDEX length,
00305 PIPSocket::Address & addr,
00306 WORD & port,
00307 PString & iface,
00308 PINDEX & lastReadCount,
00309 const PTimeInterval & timeout
00310 ) = 0;
00311
00313 void SetNatMethod(
00314 PNatMethod * method
00315 ) { natMethod = method; }
00316
00317
00318
00319 PNatMethod * GetNatMethod() const { return natMethod; }
00320
00325 static PMonitoredSockets * Create(
00326 const PString & iface,
00327 bool reuseAddr = false,
00328 PNatMethod * natMethod = NULL
00329 );
00330
00331 protected:
00332 virtual void OnRemoveNatMethod(
00333 const PNatMethod * natMethod
00334 );
00335
00336 struct SocketInfo {
00337 SocketInfo()
00338 : socket(NULL)
00339 , inUse(false)
00340 { }
00341 PUDPSocket * socket;
00342 bool inUse;
00343 };
00344
00345 bool CreateSocket(
00346 SocketInfo & info,
00347 const PIPSocket::Address & binding
00348 );
00349 bool DestroySocket(SocketInfo & info);
00350 bool GetSocketAddress(
00351 const SocketInfo & info,
00352 PIPSocket::Address & address,
00353 WORD & port,
00354 bool usingNAT
00355 ) const;
00356
00357 PChannel::Errors WriteToSocket(
00358 const void * buf,
00359 PINDEX len,
00360 const PIPSocket::Address & addr,
00361 WORD port,
00362 const SocketInfo & info,
00363 PINDEX & lastWriteCount
00364 );
00365 PChannel::Errors ReadFromSocket(
00366 SocketInfo & info,
00367 void * buf,
00368 PINDEX len,
00369 PIPSocket::Address & addr,
00370 WORD & port,
00371 PINDEX & lastReadCount,
00372 const PTimeInterval & timeout
00373 );
00374 PChannel::Errors ReadFromSocket(
00375 PSocket::SelectList & readers,
00376 PUDPSocket * & socket,
00377 void * buf,
00378 PINDEX len,
00379 PIPSocket::Address & addr,
00380 WORD & port,
00381 PINDEX & lastReadCount,
00382 const PTimeInterval & timeout
00383 );
00384
00385 WORD localPort;
00386 bool reuseAddress;
00387 PNatMethod * natMethod;
00388
00389 bool opened;
00390 PUDPSocket interfaceAddedSignal;
00391 };
00392
00393 typedef PSafePtr<PMonitoredSockets> PMonitoredSocketsPtr;
00394
00395
00397
00401 class PMonitoredSocketChannel : public PChannel
00402 {
00403 PCLASSINFO(PMonitoredSocketChannel, PChannel);
00404 public:
00407
00408 PMonitoredSocketChannel(
00409 const PMonitoredSocketsPtr & sockets,
00410 bool shared
00411 );
00413
00416 virtual PBoolean IsOpen() const;
00417 virtual PBoolean Close();
00418
00421 virtual PBoolean Read(
00422 void * buffer,
00423 PINDEX length
00424 );
00425
00426 virtual PBoolean Write(
00429 const void * buffer,
00430 PINDEX length
00431 );
00433
00439 void SetInterface(
00440 const PString & iface
00441 );
00442
00444 PString GetInterface();
00445
00448 bool GetLocal(
00449 PIPSocket::Address & address,
00450 WORD & port,
00451 bool usingNAT
00452 );
00453
00455 void SetRemote(
00456 const PIPSocket::Address & address,
00457 WORD port
00458 );
00459
00461 void SetRemote(
00462 const PString & hostAndPort
00463 );
00464
00466 void GetRemote(
00467 PIPSocket::Address & addr,
00468 WORD & port
00469 ) const { addr = remoteAddress; port = remotePort; }
00470
00475 void SetPromiscuous(
00476 bool flag
00477 ) { promiscuousReads = flag; }
00478
00480 bool GetPromiscuous() { return promiscuousReads; }
00481
00483 void GetLastReceived(
00484 PIPSocket::Address & addr,
00485 WORD & port
00486 ) const { addr = lastReceivedAddress; port = lastReceivedPort; }
00487
00489 PString GetLastReceivedInterface() const { return lastReceivedInterface; }
00490
00492 const PMonitoredSocketsPtr & GetMonitoredSockets() const { return socketBundle; }
00494
00495 protected:
00496 PMonitoredSocketsPtr socketBundle;
00497 bool sharedBundle;
00498 PString currentInterface;
00499 bool promiscuousReads;
00500 PIPSocket::Address remoteAddress;
00501 bool closing;
00502 WORD remotePort;
00503 PIPSocket::Address lastReceivedAddress;
00504 WORD lastReceivedPort;
00505 PString lastReceivedInterface;
00506 PMutex mutex;
00507 };
00508
00509
00511
00515 class PMonitoredSocketBundle : public PMonitoredSockets
00516 {
00517 PCLASSINFO(PMonitoredSocketBundle, PMonitoredSockets);
00518 public:
00519 PMonitoredSocketBundle(
00520 bool reuseAddr = false,
00521 PNatMethod * natMethod = NULL
00522 );
00523 ~PMonitoredSocketBundle();
00524
00531 virtual PBoolean Open(
00532 WORD port
00533 );
00534
00536 virtual PBoolean Close();
00537
00539 virtual PBoolean GetAddress(
00540 const PString & iface,
00541 PIPSocket::Address & address,
00542 WORD & port,
00543 PBoolean usingNAT
00544 ) const;
00545
00551 virtual PChannel::Errors WriteToBundle(
00552 const void * buf,
00553 PINDEX len,
00554 const PIPSocket::Address & addr,
00555 WORD port,
00556 const PString & iface,
00557 PINDEX & lastWriteCount
00558 );
00559
00566 virtual PChannel::Errors ReadFromBundle(
00567 void * buf,
00568 PINDEX len,
00569 PIPSocket::Address & addr,
00570 WORD & port,
00571 PString & iface,
00572 PINDEX & lastReadCount,
00573 const PTimeInterval & timeout
00574 );
00575
00576 protected:
00578 virtual void OnAddInterface(const InterfaceEntry & entry);
00579
00581 virtual void OnRemoveInterface(const InterfaceEntry & entry);
00582
00583 typedef std::map<std::string, SocketInfo> SocketInfoMap_T;
00584
00585 void OpenSocket(const PString & iface);
00586 void CloseSocket(SocketInfoMap_T::iterator iterSocket);
00587
00588 SocketInfoMap_T socketInfoMap;
00589 };
00590
00591
00593
00598 class PSingleMonitoredSocket : public PMonitoredSockets
00599 {
00600 PCLASSINFO(PSingleMonitoredSocket, PMonitoredSockets);
00601 public:
00602 PSingleMonitoredSocket(
00603 const PString & theInterface,
00604 bool reuseAddr = false,
00605 PNatMethod * natMethod = NULL
00606 );
00607 ~PSingleMonitoredSocket();
00608
00613 virtual PStringArray GetInterfaces(
00614 PBoolean includeLoopBack = false,
00615 const PIPSocket::Address & destination = PIPSocket::GetDefaultIpAny()
00616 );
00617
00624 virtual PBoolean Open(
00625 WORD port
00626 );
00627
00629 virtual PBoolean Close();
00630
00632 virtual PBoolean GetAddress(
00633 const PString & iface,
00634 PIPSocket::Address & address,
00635 WORD & port,
00636 PBoolean usingNAT
00637 ) const;
00638
00644 virtual PChannel::Errors WriteToBundle(
00645 const void * buf,
00646 PINDEX len,
00647 const PIPSocket::Address & addr,
00648 WORD port,
00649 const PString & iface,
00650 PINDEX & lastWriteCount
00651 );
00652
00659 virtual PChannel::Errors ReadFromBundle(
00660 void * buf,
00661 PINDEX len,
00662 PIPSocket::Address & addr,
00663 WORD & port,
00664 PString & iface,
00665 PINDEX & lastReadCount,
00666 const PTimeInterval & timeout
00667 );
00668
00669
00670 protected:
00672 virtual void OnAddInterface(const InterfaceEntry & entry);
00673
00675 virtual void OnRemoveInterface(const InterfaceEntry & entry);
00676
00677 bool IsInterface(const PString & iface) const;
00678
00679 PString theInterface;
00680 InterfaceEntry theEntry;
00681 SocketInfo theInfo;
00682 };
00683
00684 #endif