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
00052
00061 class PInterfaceMonitor : public PObject
00062 {
00063 PCLASSINFO(PInterfaceMonitor, PObject);
00064 public:
00065 enum {
00066 DefaultRefreshInterval = 5000
00067 };
00068
00069 PInterfaceMonitor(
00070 unsigned refreshInterval = DefaultRefreshInterval,
00071 PBoolean runMonitorThread = PTrue
00072 );
00073 virtual ~PInterfaceMonitor();
00074
00076 static PInterfaceMonitor & GetInstance();
00077
00079 PBoolean Start();
00080
00082 void Stop();
00083
00084 typedef PIPSocket::InterfaceEntry InterfaceEntry;
00085
00090 PStringArray GetInterfaces(
00091 PBoolean includeLoopBack = PFalse,
00092 const PIPSocket::Address & destination = PIPSocket::GetDefaultIpAny()
00093 );
00094
00100 PBoolean IsValidBindingForDestination(
00101 const PIPSocket::Address & binding,
00102 const PIPSocket::Address & destination
00103 );
00104
00109 PBoolean GetInterfaceInfo(
00110 const PString & iface,
00111 InterfaceEntry & info
00112 );
00113
00118 static PBoolean IsMatchingInterface(
00119 const PString & iface,
00120 const InterfaceEntry & entry
00121 );
00122
00126 void SetInterfaceFilter(PInterfaceFilter * filter);
00127
00128 virtual void RefreshInterfaceList();
00129
00130 void OnRemoveSTUNClient(const PSTUNClient *stun);
00131
00132 protected:
00133 void UpdateThreadMain();
00134
00135 void AddClient(PInterfaceMonitorClient *);
00136 void RemoveClient(PInterfaceMonitorClient *);
00137
00138 virtual void OnInterfacesChanged(const PIPSocket::InterfaceTable & addedInterfaces, const PIPSocket::InterfaceTable & removedInterfaces);
00139
00140 typedef PSmartPtr<PInterfaceMonitorClient> ClientPtr;
00141
00142 typedef std::list<PInterfaceMonitorClient *> ClientList_T;
00143 ClientList_T currentClients;
00144 PIPSocket::InterfaceTable currentInterfaces;
00145
00146 PBoolean runMonitorThread;
00147 PTimeInterval refreshInterval;
00148 PMutex mutex;
00149 PThread * updateThread;
00150 PSyncPoint threadRunning;
00151
00152 PInterfaceFilter * interfaceFilter;
00153
00154 friend class PInterfaceMonitorClient;
00155 };
00156
00157
00159
00165 class PInterfaceMonitorClient : public PSafeObject
00166 {
00167 PCLASSINFO(PInterfaceMonitorClient, PSafeObject);
00168 public:
00169 enum {
00170 DefaultPriority = 50,
00171 };
00172 PInterfaceMonitorClient(PINDEX priority = DefaultPriority);
00173 ~PInterfaceMonitorClient();
00174
00175 typedef PIPSocket::InterfaceEntry InterfaceEntry;
00176
00183 virtual PStringArray GetInterfaces(
00184 PBoolean includeLoopBack = PFalse,
00185 const PIPSocket::Address & destination = PIPSocket::GetDefaultIpAny()
00186 );
00187
00192 virtual PBoolean GetInterfaceInfo(
00193 const PString & iface,
00194 InterfaceEntry & info
00195 );
00196
00201 PINDEX GetPriority() const { return priority; }
00202
00203 protected:
00205 virtual void OnAddInterface(const InterfaceEntry & entry) = 0;
00206
00208 virtual void OnRemoveInterface(const InterfaceEntry & entry) = 0;
00209
00211 virtual void OnRemoveSTUNClient(const PSTUNClient * ) { }
00212
00213 PINDEX priority;
00214
00215 friend class PInterfaceMonitor;
00216 };
00217
00218
00220
00221 class PInterfaceFilter : public PObject {
00222 PCLASSINFO(PInterfaceFilter, PObject);
00223
00224 public:
00225 virtual PIPSocket::InterfaceTable FilterInterfaces(const PIPSocket::Address & destination,
00226 PIPSocket::InterfaceTable & interfaces) const = 0;
00227 };
00228
00229
00231
00237 class PMonitoredSockets : public PInterfaceMonitorClient
00238 {
00239 PCLASSINFO(PMonitoredSockets, PInterfaceMonitorClient);
00240 protected:
00241 PMonitoredSockets(
00242 PBoolean reuseAddr,
00243 PSTUNClient * stunClient
00244 );
00245
00246 public:
00253 virtual PBoolean Open(
00254 WORD port
00255 ) = 0;
00256
00258 PBoolean IsOpen() const { return opened; }
00259
00261 virtual PBoolean Close() = 0;
00262
00264 WORD GetPort() const { return localPort; }
00265
00267 virtual PBoolean GetAddress(
00268 const PString & iface,
00269 PIPSocket::Address & address,
00270 WORD & port,
00271 PBoolean usingNAT
00272 ) const = 0;
00273
00279 virtual PChannel::Errors WriteToBundle(
00280 const void * buffer,
00281 PINDEX length,
00282 const PIPSocket::Address & addr,
00283 WORD port,
00284 const PString & iface,
00285 PINDEX & lastWriteCount
00286 ) = 0;
00287
00294 virtual PChannel::Errors ReadFromBundle(
00295 void * buffer,
00296 PINDEX length,
00297 PIPSocket::Address & addr,
00298 WORD & port,
00299 PString & iface,
00300 PINDEX & lastReadCount,
00301 const PTimeInterval & timeout
00302 ) = 0;
00303
00305 void SetSTUN(
00306 PSTUNClient * stunClient
00307 ) { stun = stunClient; }
00308
00309
00310 PSTUNClient * GetSTUN() const { return stun; }
00311
00316 static PMonitoredSockets * Create(
00317 const PString & iface,
00318 PBoolean reuseAddr = PFalse,
00319 PSTUNClient * stunClient = NULL
00320 );
00321
00322 protected:
00323 virtual void OnRemoveSTUNClient(const PSTUNClient *stun);
00324 struct SocketInfo {
00325 SocketInfo()
00326 : socket(NULL)
00327 , inUse(false)
00328 { }
00329 PUDPSocket * socket;
00330 bool inUse;
00331 };
00332
00333 PBoolean CreateSocket(
00334 SocketInfo & info,
00335 const PIPSocket::Address & binding
00336 );
00337 PBoolean DestroySocket(SocketInfo & info);
00338 PBoolean GetSocketAddress(
00339 const SocketInfo & info,
00340 PIPSocket::Address & address,
00341 WORD & port,
00342 PBoolean usingNAT
00343 ) const;
00344
00345 PChannel::Errors WriteToSocket(
00346 const void * buf,
00347 PINDEX len,
00348 const PIPSocket::Address & addr,
00349 WORD port,
00350 const SocketInfo & info,
00351 PINDEX & lastWriteCount
00352 );
00353 PChannel::Errors ReadFromSocket(
00354 SocketInfo & info,
00355 void * buf,
00356 PINDEX len,
00357 PIPSocket::Address & addr,
00358 WORD & port,
00359 PINDEX & lastReadCount,
00360 const PTimeInterval & timeout
00361 );
00362
00363 WORD localPort;
00364 PBoolean reuseAddress;
00365 PSTUNClient * stun;
00366
00367 bool opened;
00368 PUDPSocket interfaceAddedSignal;
00369 };
00370
00371 typedef PSafePtr<PMonitoredSockets> PMonitoredSocketsPtr;
00372
00373
00375
00379 class PMonitoredSocketChannel : public PChannel
00380 {
00381 PCLASSINFO(PMonitoredSocketChannel, PChannel);
00382 public:
00385
00386 PMonitoredSocketChannel(
00387 const PMonitoredSocketsPtr & sockets,
00388 PBoolean shared
00389 );
00391
00394 virtual PBoolean IsOpen() const;
00395 virtual PBoolean Close();
00396
00399 virtual PBoolean Read(
00400 void * buffer,
00401 PINDEX length
00402 );
00403
00404 virtual PBoolean Write(
00407 const void * buffer,
00408 PINDEX length
00409 );
00411
00417 void SetInterface(
00418 const PString & iface
00419 );
00420
00422 const PString & GetInterface();
00423
00426 PBoolean GetLocal(
00427 PIPSocket::Address & address,
00428 WORD & port,
00429 PBoolean usingNAT
00430 );
00431
00433 void SetRemote(
00434 const PIPSocket::Address & address,
00435 WORD port
00436 );
00437
00439 void SetRemote(
00440 const PString & hostAndPort
00441 );
00442
00444 void GetRemote(
00445 PIPSocket::Address & addr,
00446 WORD & port
00447 ) const { addr = remoteAddress; port = remotePort; }
00448
00453 void SetPromiscuous(
00454 PBoolean flag
00455 ) { promiscuousReads = flag; }
00456
00458 bool GetPromiscuous() { return promiscuousReads; }
00459
00460
00461 void GetLastReceived(
00462 PIPSocket::Address & addr,
00463 WORD & port
00464 ) const { addr = lastReceivedAddress; port = lastReceivedPort; }
00465
00467 const PMonitoredSocketsPtr & GetMonitoredSockets() const { return socketBundle; }
00469
00470 protected:
00471 PMonitoredSocketsPtr socketBundle;
00472 PBoolean sharedBundle;
00473 PString currentInterface;
00474 PBoolean promiscuousReads;
00475 PIPSocket::Address remoteAddress;
00476 PBoolean closing;
00477 WORD remotePort;
00478 PIPSocket::Address lastReceivedAddress;
00479 WORD lastReceivedPort;
00480 };
00481
00482
00484
00488 class PMonitoredSocketBundle : public PMonitoredSockets
00489 {
00490 PCLASSINFO(PMonitoredSocketBundle, PMonitoredSockets);
00491 public:
00492 PMonitoredSocketBundle(
00493 PBoolean reuseAddr = PFalse,
00494 PSTUNClient * stunClient = NULL
00495 );
00496 ~PMonitoredSocketBundle();
00497
00504 virtual PBoolean Open(
00505 WORD port
00506 );
00507
00509 virtual PBoolean Close();
00510
00512 virtual PBoolean GetAddress(
00513 const PString & iface,
00514 PIPSocket::Address & address,
00515 WORD & port,
00516 PBoolean usingNAT
00517 ) const;
00518
00524 virtual PChannel::Errors WriteToBundle(
00525 const void * buf,
00526 PINDEX len,
00527 const PIPSocket::Address & addr,
00528 WORD port,
00529 const PString & iface,
00530 PINDEX & lastWriteCount
00531 );
00532
00539 virtual PChannel::Errors ReadFromBundle(
00540 void * buf,
00541 PINDEX len,
00542 PIPSocket::Address & addr,
00543 WORD & port,
00544 PString & iface,
00545 PINDEX & lastReadCount,
00546 const PTimeInterval & timeout
00547 );
00548
00549 protected:
00551 virtual void OnAddInterface(const InterfaceEntry & entry);
00552
00554 virtual void OnRemoveInterface(const InterfaceEntry & entry);
00555
00556 typedef std::map<std::string, SocketInfo> SocketInfoMap_T;
00557
00558 void OpenSocket(const PString & iface);
00559 void CloseSocket(const SocketInfoMap_T::iterator & iterSocket);
00560
00561 SocketInfoMap_T socketInfoMap;
00562 };
00563
00564
00566
00571 class PSingleMonitoredSocket : public PMonitoredSocketBundle
00572 {
00573 PCLASSINFO(PSingleMonitoredSocket, PMonitoredSocketBundle);
00574 public:
00575 PSingleMonitoredSocket(
00576 const PString & theInterface,
00577 PBoolean reuseAddr = PFalse,
00578 PSTUNClient * stunClient = NULL
00579 );
00580 ~PSingleMonitoredSocket();
00581
00586 virtual PStringArray GetInterfaces(
00587 PBoolean includeLoopBack = PFalse,
00588 const PIPSocket::Address & destination = PIPSocket::GetDefaultIpAny()
00589 );
00590
00597 virtual PBoolean Open(
00598 WORD port
00599 );
00600
00602 virtual PBoolean Close();
00603
00605 virtual PBoolean GetAddress(
00606 const PString & iface,
00607 PIPSocket::Address & address,
00608 WORD & port,
00609 PBoolean usingNAT
00610 ) const;
00611
00617 virtual PChannel::Errors WriteToBundle(
00618 const void * buf,
00619 PINDEX len,
00620 const PIPSocket::Address & addr,
00621 WORD port,
00622 const PString & iface,
00623 PINDEX & lastWriteCount
00624 );
00625
00632 virtual PChannel::Errors ReadFromBundle(
00633 void * buf,
00634 PINDEX len,
00635 PIPSocket::Address & addr,
00636 WORD & port,
00637 PString & iface,
00638 PINDEX & lastReadCount,
00639 const PTimeInterval & timeout
00640 );
00641
00642
00643 protected:
00645 virtual void OnAddInterface(const InterfaceEntry & entry);
00646
00648 virtual void OnRemoveInterface(const InterfaceEntry & entry);
00649
00650 PBoolean IsInterface(const PString & iface) const;
00651
00652 PString theInterface;
00653 InterfaceEntry theEntry;
00654 SocketInfo theInfo;
00655 };
00656
00657 #endif