Vault
4.1
|
00001 /* 00002 Copyright c1997-2014 Trygve Isaacson. All rights reserved. 00003 This file is part of the Code Vault version 4.1 00004 http://www.bombaydigital.com/ 00005 License: MIT. See LICENSE.md in the Vault top level directory. 00006 */ 00007 00008 #ifndef vsocket_h 00009 #define vsocket_h 00010 00013 #include "vinstant.h" 00014 #include "vstring.h" 00015 00016 // This pulls in any platform-specific declarations and includes: 00017 #include "vsocket_platform.h" 00018 00049 typedef Vu32 VNetAddr; 00050 00063 class VNetworkInterfaceInfo { 00064 public: 00065 VNetworkInterfaceInfo() : mFamily(0), mName(), mAddress() {} 00066 ~VNetworkInterfaceInfo() {} 00067 int mFamily; 00068 VString mName; 00069 VString mAddress; 00070 }; 00071 typedef std::vector<VNetworkInterfaceInfo> VNetworkInterfaceList; 00072 00073 class VSocketConnectionStrategy; 00074 00124 class VSocket { 00125 public: 00126 00136 static void setPreferredNetworkInterface(const VString& interfaceName); 00152 static void setPreferredLocalIPAddressPrefix(const VString& addressPrefix); 00167 static void getLocalHostIPAddress(VString& ipAddress, bool refresh = false); 00179 static VNetworkInterfaceList enumerateNetworkInterfaces() { return VSocket::_platform_enumerateNetworkInterfaces(); } 00190 static VNetAddr ipAddressStringToNetAddr(const VString& ipAddress); 00201 static void netAddrToIPAddressString(VNetAddr netAddr, VString& ipAddress); 00219 static VStringVector resolveHostName(const VString& hostName); 00227 static bool isIPv4NumericString(const VString& ipAddress); 00234 static bool isIPv6NumericString(const VString& ipAddress); 00243 static bool isIPNumericString(const VString& ipAddress); 00244 00250 VSocket(); 00259 VSocket(VSocketID id); 00263 virtual ~VSocket(); 00264 00273 virtual void connectToIPAddress(const VString& ipAddress, int portNumber); 00284 virtual void connectToHostName(const VString& hostName, int portNumber); 00295 virtual void connectToHostName(const VString& hostName, int portNumber, const VSocketConnectionStrategy& connectionStrategy); 00296 00309 void setSockID(VSocketID id); 00315 virtual void setHostIPAddressAndPort(const VString& hostIPAddress, int portNumber); 00316 00317 // --------------- These are the various utility and accessor methods. 00318 00323 VSocketID getSockID() const; 00329 VString getHostIPAddress() const; 00335 int getPortNumber() const; 00341 const VString& getName() const { return mSocketName; } 00345 void close(); 00350 void setLinger(int val); 00354 void clearReadTimeOut(); 00359 void setReadTimeOut(const struct timeval& timeout); 00363 void clearWriteTimeOut(); 00368 void setWriteTimeOut(const struct timeval& timeout); 00372 void setDefaultSockOpt(); 00377 Vs64 numBytesRead() const; 00382 Vs64 numBytesWritten() const; 00387 VDuration getIdleTime() const; 00388 00389 // --------------- These are the pure virtual methods that only a platform 00390 // subclass can implement. 00391 00398 virtual int available() { return this->_platform_available(); } 00409 virtual int read(Vu8* buffer, int numBytesToRead); 00420 virtual int write(const Vu8* buffer, int numBytesToWrite); 00424 virtual void flush(); 00429 virtual void discoverHostAndPort(); 00433 virtual void closeRead(); 00437 virtual void closeWrite(); 00445 virtual void setSockOpt(int level, int name, void* valuePtr, int valueLength); 00452 void setIntSockOpt(int level, int name, int value); 00453 00454 static const VSocketID kNoSocketID = V_NO_SOCKET_ID_CONSTANT; 00455 static const int kDefaultBufferSize = 65535; 00456 static const int kDefaultServiceType = 0x08; 00457 static const int kDefaultNoDelay = 1; 00458 00459 protected: 00460 00464 virtual void _connectToIPAddress(const VString& ipAddress, int portNumber); 00473 virtual void _listen(const VString& bindAddress, int backlog); 00474 00475 VSocketID mSocketID; 00476 VString mHostIPAddress; 00477 int mPortNumber; 00478 bool mReadTimeOutActive; 00479 struct timeval mReadTimeOut; 00480 bool mWriteTimeOutActive; 00481 struct timeval mWriteTimeOut; 00482 bool mRequireReadAll; 00483 Vs64 mNumBytesRead; 00484 Vs64 mNumBytesWritten; 00485 VInstant mLastEventTime; 00486 VString mSocketName; 00487 00488 static VString gPreferredNetworkInterfaceName; 00489 static VString gPreferredLocalIPAddressPrefix; 00490 static VString gCachedLocalHostIPAddress; 00491 00492 protected: // will be private when complete 00493 00494 static bool gStaticInited; 00495 static bool _platform_staticInit(); 00496 00501 static VNetworkInterfaceList _platform_enumerateNetworkInterfaces(); 00512 static VString _platform_addrinfoToIPAddressString(const VString& hostName, const struct addrinfo* info); 00519 static bool _platform_isSocketIDValid(VSocketID socketID); 00526 int _platform_available(); 00527 }; 00528 00534 class VSocketInfo { 00535 public: 00536 00541 VSocketInfo(const VSocket& socket); 00545 virtual ~VSocketInfo() {} 00546 00547 VSocketID mSocketID; 00548 VString mHostIPAddress; 00549 int mPortNumber; 00550 Vs64 mNumBytesRead; 00551 Vs64 mNumBytesWritten; 00552 VDuration mIdleTime; 00553 }; 00554 00558 typedef std::vector<VSocketInfo> VSocketInfoVector; 00559 00565 class VSocketConnectionStrategy { 00566 00567 public: 00568 VSocketConnectionStrategy() : mDebugIPAddresses() {} 00569 virtual ~VSocketConnectionStrategy() {} 00570 00584 virtual void connect(const VString& hostName, int portNumber, VSocket& socketToConnect) const = 0; 00585 00586 // For testing purposes, you can inject a specific set of IP addresses, which 00587 // will cause the hostName supplied with connect() to be ignored. You could supply 00588 // specific bad IP addresses or slow-to-succeed IP addresses, in order to see 00589 // what happens. Our unit tests do this. 00590 void injectDebugIPAddresses(const VStringVector debugIPAddresses) { mDebugIPAddresses = debugIPAddresses; } 00591 00592 protected: 00593 00594 VStringVector mDebugIPAddresses; 00595 }; 00596 00600 class VSocketConnectionStrategySingle : public VSocketConnectionStrategy { 00601 00602 public: 00603 VSocketConnectionStrategySingle() {} 00604 virtual ~VSocketConnectionStrategySingle() {} 00605 00606 // VSocketConnectionStrategy implementation: 00607 virtual void connect(const VString& hostName, int portNumber, VSocket& socketToConnect) const; 00608 }; 00609 00616 class VSocketConnectionStrategyLinear : public VSocketConnectionStrategy { 00617 00618 public: 00619 VSocketConnectionStrategyLinear(const VDuration& timeout); 00620 virtual ~VSocketConnectionStrategyLinear() {} 00621 00622 // VSocketConnectionStrategy implementation: 00623 virtual void connect(const VString& hostName, int portNumber, VSocket& socketToConnect) const; 00624 00625 private: 00626 const VDuration mTimeout; 00627 }; 00628 00635 class VSocketConnectionStrategyThreaded : public VSocketConnectionStrategy { 00636 00637 public: 00638 VSocketConnectionStrategyThreaded(const VDuration& timeoutInterval, int maxNumThreads = 4); 00639 virtual ~VSocketConnectionStrategyThreaded() {} 00640 00641 // VSocketConnectionStrategy implementation: 00642 virtual void connect(const VString& hostName, int portNumber, VSocket& socketToConnect) const; 00643 00644 private: 00645 00646 VDuration mTimeoutInterval; 00647 int mMaxNumThreads; 00648 }; 00649 00650 #endif /* vsocket_h */ 00651