📄 staftcpconnprovider.cpp
字号:
/*****************************************************************************//* Software Testing Automation Framework (STAF) *//* (C) Copyright IBM Corp. 2001, 2004, 2005 *//* *//* This software is licensed under the Common Public License (CPL) V1.0. *//*****************************************************************************/#include "STAF.h"#include "STAFConnectionProvider.h"#include "STAFSocket.h"#include "STAFUtil.h"#include "STAFString.h"#include "STAFEventSem.h"#include "STAFTrace.h"#include "STAFInternalUtil.h"#include "STAFThreadManager.h"#include "STAFFileSystem.h"#include <set>#include <stdlib.h>#include <string.h>#ifdef STAF_USE_SSL#include <crypto.h>#include <openssl/x509v3.h>#include <openssl/pem.h>#include <openssl/ssl.h>#include <openssl/conf.h>#include <openssl/err.h>#include <openssl/rc4.h>#include <openssl/rand.h>#endif#ifdef STAF_OS_TYPE_WIN32#include <conio.h>#else#include <termios.h>#include <stdio.h>#endif#ifdef STAF_USE_IPV6#if defined(STAF_OS_TYPE_WIN32) && !defined(EADDRINUSE)#define EADDRINUSE WSAEADDRINUSE#endif#if defined(IPV6_V6ONLY)int openIPv6OnlySocket = IPV6_V6ONLY;#elseint openIPv6OnlySocket = 0;#endif#endif// XXX: Might want to look at adding someing like kSTAFConnectionError, instead// of using kSTAFBaseOSError in this code. Same goes for Local IPC.#define CATCH_STANDARD(functionString) \catch (STAFException &e)\{\ if (errorBuffer)\ {\ *errorBuffer = getExceptionString(e, "STAFTCPConnProvider.cpp: "\ functionString)\ .adoptImpl();\ }\}\catch (...)\{\ if (errorBuffer)\ {\ STAFString error("STAFTCPConnProvider.cpp: Caught unknown "\ "exception in " functionString "()");\ *errorBuffer = error.adoptImpl();\ }\}#define CATCH_STANDARD_TRACE(functionString) \catch (STAFException &e)\{\ STAFTrace::trace(kSTAFTraceError,\ getExceptionString(e, "STAFTCPConnProvider.cpp: "\ functionString));\}\catch (...)\{\ STAFTrace::trace(kSTAFTraceError,\ "STAFTCPConnProvider.cpp: Caught unknown exception "\ "in " functionString "()");\}#ifdef STAF_OS_NAME_HPUXextern "C"{ void _main();}#endif// PrototypesSTAFRC_t STAFConnectionProviderConstruct(STAFConnectionProvider_t *provider, void *constructInfo, unsigned int constructInfoLevel, STAFString_t *errorBuffer);STAFRC_t STAFConnectionProviderStart(STAFConnectionProvider_t provider, void *startInfo, unsigned int startInfoLevel, STAFString_t *errorBuffer);STAFRC_t STAFConnectionProviderStop(STAFConnectionProvider_t provider, void *stopInfo, unsigned int stopInfoLevel, STAFString_t *errorBuffer);STAFRC_t STAFConnectionProviderDestruct(STAFConnectionProvider_t *provider, void *destructInfo, unsigned int destructInfoLevel, STAFString_t *errorBuffer);STAFRC_t STAFConnectionProviderConnect(STAFConnectionProvider_t provider, STAFConnection_t *connection, void *connectInfo, unsigned int connectInfoLevel, STAFString_t *errorBuffer);STAFRC_t STAFConnectionProviderGetMyNetworkIDs( STAFConnectionProvider_t provider, STAFStringConst_t *logicalID,STAFStringConst_t *physicalD, STAFString_t *errorBuffer);STAFRC_t STAFConnectionProviderGetOptions( STAFConnectionProvider_t provider, STAFObject_t options, STAFString_t *errorBuffer);STAFRC_t STAFConnectionProviderGetProperty( STAFConnectionProvider_t provider, STAFConnectionProviderProperty_t property, STAFStringConst_t *value, STAFString_t *errorBuffer);STAFRC_t STAFConnectionRead( STAFConnection_t connection, void *buffer, unsigned int readLength, STAFString_t *errorBuffer);STAFRC_t STAFConnectionReadUInt( STAFConnection_t connection, unsigned int *uint, STAFString_t *errorBuffer);STAFRC_t STAFConnectionReadSTAFString( STAFConnection_t connection, STAFString_t *stafString, STAFString_t *errorBuffer);STAFRC_t STAFConnectionWrite( STAFConnection_t connection, void *buffer, unsigned int writeLength, STAFString_t *errorBuffer);STAFRC_t STAFConnectionWriteUInt( STAFConnection_t connection, unsigned int uint, STAFString_t *errorBuffer);STAFRC_t STAFConnectionWriteSTAFString( STAFConnection_t connection, STAFStringConst_t stafString, STAFString_t *errorBuffer);STAFRC_t STAFConnectionGetPeerNetworkIDs( STAFConnection_t connection, STAFStringConst_t *logicalID, STAFStringConst_t *physicalD, STAFString_t *errorBuffer);STAFRC_t STAFConnectionDestruct( STAFConnection_t *connection, STAFString_t *errorBuffer);static STAFConnectionProviderFunctionTable gFuncTable ={ STAFConnectionProviderConstruct, STAFConnectionProviderStart, STAFConnectionProviderStop, STAFConnectionProviderDestruct, STAFConnectionProviderConnect, STAFConnectionProviderGetMyNetworkIDs, STAFConnectionProviderGetOptions, STAFConnectionProviderGetProperty, STAFConnectionRead, STAFConnectionReadUInt, STAFConnectionReadSTAFString, STAFConnectionWrite, STAFConnectionWriteUInt, STAFConnectionWriteSTAFString, STAFConnectionGetPeerNetworkIDs, STAFConnectionDestruct};struct STAFTCPConnectionProviderImpl : STAFConnectionProviderImpl{ STAFConnectionProviderMode_t mode; void *data; unsigned short port; unsigned short connectTimeout; STAFSocket_t serverSocket; STAFSocket_t serverSocketIPv6; STAFString logicalNetworkID; STAFString physicalNetworkID; STAFObjectPtr options; STAFString portProperty; STAFString isSecureProperty; STAFConnectionProviderNewConnectionFunc_t connFunc; STAFEventSemPtr syncSem; STAFConnectionProviderState_t state; STAFThreadManagerPtr threadManager; int family; STAFString secure;#ifdef STAF_USE_SSL SSL_CTX *server_ctx; SSL_CTX *client_ctx; STAFString serverCertificate; STAFString serverKey; STAFString CACertificate;#endif};struct STAFTCPConnectionImpl : STAFConnectionImpl{ STAFSocket_t clientSocket; STAFString logicalNetworkID; STAFString physicalNetworkID;#ifdef STAF_USE_SSL SSL *ssl; STAFString secure;#endif // ???: Look at moving this buffer into the read/write functions. It will // make the read/write functions thread safe. Just need to make sure // it doesn't hurt performance. char buffer[4096];};struct TCPConnectionData{ STAFConnectionProviderNewConnectionFunc_t connFunc; STAFTCPConnectionProviderImpl *provider; STAFTCPConnectionImpl *connection;};#ifdef STAF_USE_IPV6class STAFNetworkAddress{public: STAFNetworkAddress() { buffer = NULL; current = NULL; }; struct addrinfo **getBuffer() { return &buffer; }; struct addrinfo *getCurrent() { return current; }; int next() { if (current == NULL) { current = buffer; return 1; } else { current = current->ai_next; if (current == NULL) return 0; else return 1; } }; ~STAFNetworkAddress() { if (buffer != NULL) freeaddrinfo(buffer); };private: struct addrinfo *current, *buffer;};#endif //STAF_USE_IPV6static unsigned short sDefaultSecurePort = 6501;static unsigned short sDefaultNonSecurePort = 6500;static unsigned short sDefaultConnectTimeout = 5000;// These are the valid option names that can be specified (and these names// are the names of the fields stored in the option map)static STAFString sPort = STAFString("Port");static STAFString sProtocol = STAFString("Protocol");static STAFString sConnectTimeout = STAFString("ConnectTimeout");static STAFString sServerCertificate = STAFString("SSL/ServerCertificate");static STAFString sServerKey = STAFString("SSL/ServerKey");static STAFString sCACertificate = STAFString("SSL/CACertificate");static STAFString sSecure = STAFString("Secure");// These are the valid values that can be specified for the PROTOCOL optionstatic STAFString sIPv4 = STAFString("IPv4");static STAFString sIPv6 = STAFString("IPv6");static STAFString sIPv4_IPv6 = STAFString("IPv4_IPv6");// These are the valid values that can be specified for the SECURE optionstatic STAFString sYes = STAFString("Yes");static STAFString sNo = STAFString("No");typedef std::set<STAFConnectionProvider_t> ProviderSet;static STAFMutexSem sActiveProvidersSem;static ProviderSet sActiveProviders;static void atExit(){ ProviderSet activeProvidersCopy; { STAFMutexSemLock lock(sActiveProvidersSem); activeProvidersCopy = sActiveProviders; } for (ProviderSet::iterator iter = activeProvidersCopy.begin(); iter != activeProvidersCopy.end(); ++iter) { STAFConnectionProvider_t thisProvider = *iter; // XXX: Clean up. I.e., kill any threads, etc. }}static void STAFIPv6TCPUpdateConnectionNetworkIDsFromInAddr( STAFConnection_t baseConn, sockaddr *addr, int addrlen){#ifdef STAF_USE_IPV6 STAFTCPConnectionImpl *conn = static_cast<STAFTCPConnectionImpl *>(baseConn); STAFString_t ipAddress = 0; STAFString_t errorBuffer = 0; STAFRC_t ipAddrRC = 0; ipAddrRC = STAFIPv6SocketGetPrintableAddressFromInAddr( addr, addrlen, &ipAddress, &errorBuffer); if (ipAddrRC != kSTAFOk) { STAFString error( "Error getting printable IP address, " "STAFIPv6SocketGetPrintableAddressFromInAddr(), RC: " + STAFString(ipAddrRC) + ", Info: " + STAFString(errorBuffer, STAFString::kShallow)); STAFTrace::trace(kSTAFTraceError, error); errorBuffer = 0; conn->physicalNetworkID = "0.0.0.0"; } else { conn->physicalNetworkID = STAFString(ipAddress, STAFString::kShallow); } STAFString_t hostname = 0; STAFRC_t hostRC = 0; hostRC = STAFIPv6SocketGetNameByInAddr( addr, addrlen, &hostname, &errorBuffer); if (hostRC != kSTAFOk) { STAFString error( "Error getting hostname (for IP address " + conn->physicalNetworkID + "), STAFIPv6SocketGetNameByInAddr(), RC: " + STAFString(ipAddrRC) + ", Info: " + STAFString(errorBuffer, STAFString::kShallow)); STAFTrace::trace(kSTAFTraceWarning, error); conn->logicalNetworkID = conn->physicalNetworkID; } else { conn->logicalNetworkID = STAFString(hostname, STAFString::kShallow); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -