📄 staftcpconnprovider.cpp
字号:
tcpData.options->put(sServerCertificate, tcpData.serverCertificate); tcpData.options->put(sServerKey, tcpData.serverKey); tcpData.options->put(sCACertificate, tcpData.CACertificate); }#endif#ifdef STAF_USE_IPV6 if (tcpData.family == PF_INET) tcpData.options->put(sProtocol, sIPv4); else if (tcpData.family == PF_INET6) tcpData.options->put(sProtocol, sIPv6); else // if (tcpData.family == PF_UNSPEC) tcpData.options->put(sProtocol, sIPv4_IPv6); #else tcpData.options->put(sProtocol, sIPv4);#endif // Setup property values tcpData.portProperty = STAFString(kUTF8_AT) + tcpData.port; tcpData.isSecureProperty = STAFString("0"); // Get logical identifier (the host name) and physical identifier (the // IP address) STAFString_t machineNameImpl = 0; STAFString_t ipAddressImpl = 0; STAFString_t errorBuffer2 = 0; STAFRC_t hostRC = STAFSocketGetMyHostInfo(&machineNameImpl, &ipAddressImpl, &errorBuffer2); if (hostRC != 0) { STAFString error( "Could not determine logical/physical identifier." "Error code: " + STAFString(hostRC) + STAFString(" Reason: ") + STAFString(errorBuffer2, STAFString::kShallow)); if (errorBuffer) *errorBuffer = error.adoptImpl(); errorBuffer2 = 0; //XXX: Is this the right RC? return kSTAFInvalidValue; } tcpData.logicalNetworkID = STAFString(machineNameImpl); tcpData.physicalNetworkID = STAFString(ipAddressImpl); rc = STAFSocketInit(errorBuffer); if (rc != kSTAFOk) return rc; *provider = new STAFTCPConnectionProviderImpl(tcpData);#ifdef STAF_USE_SSL if (tcpData.secure.isEqualTo(sYes, kSTAFStringCaseInsensitive)) { // generate random seed int seed_int[100]; srand( (unsigned)time( NULL ) ); for( int j = 0; j < 100; j++ ) seed_int[j] = rand(); RAND_seed(seed_int, sizeof(seed_int)); // SSL preliminaries. We keep the certificate and key with the context. OpenSSL_add_all_algorithms(); SSL_load_error_strings(); // Prepare server side SSL context (*provider)->server_ctx = SSL_CTX_new(TLSv1_server_method()); if (!(*provider)->server_ctx) HANDLE_START_ERROR(ERR_reason_error_string(ERR_get_error()), "SSL_CTX_new()"); if ((*provider)->serverCertificate.length() != 0) { char name[256] = ""; memcpy(name, (*provider)->serverCertificate.buffer(), (*provider)->serverCertificate.length()); if(SSL_CTX_use_certificate_chain_file((*provider)->server_ctx, name) <= 0) HANDLE_START_ERROR(ERR_error_string(ERR_get_error(), NULL), "SSL_CTX_use_certificate_file()"); } if ((*provider)->serverKey.length() != 0) { char name[256] = ""; memcpy(name, (*provider)->serverKey.buffer(), (*provider)->serverKey.length()); SSL_CTX_set_default_passwd_cb((*provider)->server_ctx, password_cb); if (SSL_CTX_use_PrivateKey_file((*provider)->server_ctx, name, SSL_FILETYPE_PEM) <= 0) HANDLE_START_ERROR(ERR_error_string(ERR_get_error(), NULL), "SSL_CTX_use_PrivateKey_file()"); } if ((*provider)->serverKey.length() != 0 || (*provider)->serverCertificate.length() != 0) { if (!SSL_CTX_check_private_key((*provider)->server_ctx)) HANDLE_START_ERROR(ERR_error_string(ERR_get_error(), NULL), "SSL_CTX_check_private_key()"); } if (!SSL_CTX_set_cipher_list((*provider)->server_ctx,"AES128-SHA")) HANDLE_START_ERROR(ERR_error_string(ERR_get_error(), NULL), "SSL_CTX_set_cipher_list()"); // Prepare client side SSL context (*provider)->client_ctx = SSL_CTX_new(TLSv1_client_method()); if (!(*provider)->client_ctx) HANDLE_START_ERROR(ERR_error_string(ERR_get_error(), NULL), "SSL_CTX_new()"); SSL_CTX_set_verify((*provider)->client_ctx, SSL_VERIFY_PEER, NULL); char name[256] = ""; memcpy(name, (*provider)->CACertificate.buffer(), (*provider)->CACertificate.length()); if (SSL_CTX_load_verify_locations((*provider)->client_ctx, name, NULL) <= 0) HANDLE_START_ERROR(ERR_error_string(ERR_get_error(), NULL), "SSL_CTX_load_verify_locations()"); }#endif return kSTAFOk; } CATCH_STANDARD("STAFConnectionProviderConstruct"); return kSTAFUnknownError;} #ifdef STAF_OS_TYPE_WIN32#define SET_SOCKET_IPv6_ONLY \ ;#else#define SET_SOCKET_IPv6_ONLY \ if (openIPv6OnlySocket)\ {\ int on = 1;\ if (setsockopt(provider->serverSocketIPv6, IPPROTO_IPV6, \ openIPv6OnlySocket, &on, sizeof(on)) < 0) \ {\ HANDLE_START_ERROR("Error setting to IP6 only: IPv6", \ "socket()");\ }\ }#endifSTAFRC_t STAFConnectionProviderStartIPv4(STAFConnectionProvider_t baseProvider, STAFString_t *errorBuffer){ STAFTCPConnectionProviderImpl *provider = static_cast<STAFTCPConnectionProviderImpl *>(baseProvider); provider->serverSocket = socket(PF_INET, SOCK_STREAM, 0); if (!STAFUtilIsValidSocket(provider->serverSocket)) HANDLE_START_ERROR("No socket available", "socket()"); // Set the socket to be non-inheritable unsigned int osRC = 0; STAFSocket_t newSocket; if (STAFUtilGetNonInheritableSocket(provider->serverSocket, &newSocket, &osRC)) { HANDLE_START_ERROR("Error getting non-inheritable server socket", "STAFUtilGetNonInheritableSocket()"); } provider->serverSocket = newSocket; struct sockaddr_in serverAddress = { 0 }; serverAddress.sin_family = AF_INET; serverAddress.sin_port = htons(provider->port); serverAddress.sin_addr.s_addr = INADDR_ANY; int bindRC = bind(provider->serverSocket, reinterpret_cast<struct sockaddr *>(&serverAddress), sizeof(serverAddress)); if (bindRC != 0) HANDLE_START_ERROR("Error binding server socket", "bind()"); int listenRC = listen(provider->serverSocket, SOMAXCONN); if (listenRC != 0) HANDLE_START_ERROR("Error listening on server socket", "listen()"); return kSTAFOk; }STAFRC_t STAFConnectionProviderStartIPv6(STAFConnectionProvider_t baseProvider, STAFString_t *errorBuffer){#ifdef STAF_USE_IPV6 STAFTCPConnectionProviderImpl *provider = static_cast<STAFTCPConnectionProviderImpl *>(baseProvider); struct addrinfo hints = { 0 }; hints.ai_flags = AI_PASSIVE; // Any address is accepted hints.ai_family = PF_UNSPEC; // Any family is accepted hints.ai_socktype = SOCK_STREAM; hints.ai_protocol = 0; // Any protocol is accepted struct addrinfo *resipv4 = NULL, *resipv6 = NULL; STAFNetworkAddress na; int rc = getaddrinfo(NULL, (STAFString(provider->port) + STAFString(kUTF8_NULL)).buffer(), &hints, na.getBuffer()); if (rc != 0) HANDLE_START_ERROR("No address info available", "getaddrinfo()"); while (na.next()) { if (na.getCurrent()->ai_family == PF_INET6) { resipv6 = na.getCurrent(); } else if (na.getCurrent()->ai_family == PF_INET) { resipv4 = na.getCurrent(); } } // On Solaris, an IPv6 socket will accept IPv4 calls, and give them as // mapped addresses. However, if an IPv4 socket is also listening on // all interfaces, calls are directed to the appropriate socket. // On (some versions of) Linux (kernel earlier than 2.4.20), an IPv6 // socket will accept IPv4 calls, and give them as mapped addresses, // but an attempt also to listen on an IPv4 socket on all interfaces // causes an error. Kernel later than 2.4.20, it has the IPV6_V6ONLY // socket option. // On OpenBSD, an IPv6 socket will not accept IPv4 calls. You have to // set up two sockets if you want to accept both kinds of call. // FreeBSD is like OpenBSD, but it has the IPV6_V6ONLY socket option, // which can be turned off, to make it behave like the versions of // Linux described above. // Windows is like OpenBSD. // IPv6 only, when connection provider working in a IPv4 and IPv6 mixed // mode, handle IPv6 first if (provider->family == PF_INET6 || provider->family == PF_UNSPEC) { if (resipv6 == NULL) HANDLE_START_ERROR("No supported IPv6 address", "resipv6"); provider->serverSocketIPv6 = socket(resipv6->ai_family, resipv6->ai_socktype, resipv6->ai_protocol); if (!STAFUtilIsValidSocket(provider->serverSocketIPv6)) HANDLE_START_ERROR("No socket available: IPv6", "socket()"); // Set the socket to be non-inheritable unsigned int osRC = 0; STAFSocket_t newSocket; if (STAFUtilGetNonInheritableSocket(provider->serverSocketIPv6, &newSocket, &osRC)) { HANDLE_START_ERROR("Error getting non-inheritable server socket:" " IPv6", "STAFUtilGetNonInheritableSocket()"); } provider->serverSocketIPv6 = newSocket; SET_SOCKET_IPv6_ONLY; int bindRC = bind(provider->serverSocketIPv6, resipv6->ai_addr, resipv6->ai_addrlen); if (bindRC != 0) HANDLE_START_ERROR("Error binding server socket: IPv6", "bind()"); int listenRC = listen(provider->serverSocketIPv6, SOMAXCONN); if (listenRC != 0) HANDLE_START_ERROR("Error listening on server socket : IPv6", "listen()"); } // IPv4 only if (provider->family == PF_INET || provider->family == PF_UNSPEC) { if (resipv4 == NULL) HANDLE_START_ERROR("No supported IPv4 address", "resipv4"); provider->serverSocket = socket(resipv4->ai_family, resipv4->ai_socktype, resipv4->ai_protocol); if (!STAFUtilIsValidSocket(provider->serverSocket)) HANDLE_START_ERROR("No socket available", "socket()"); // Set the socket to be non-inheritable unsigned int osRC = 0; STAFSocket_t newSocket; if (STAFUtilGetNonInheritableSocket(provider->serverSocket, &newSocket, &osRC)) { HANDLE_START_ERROR("Error getting non-inheritable server socket: " "IPv4", "STAFUtilGetNonInheritableSocket()"); } provider->serverSocket = newSocket; int bindRC = bind(provider->serverSocket, resipv4->ai_addr, resipv4->ai_addrlen); if (bindRC != 0) { if (STAFSocketGetLastError() == EADDRINUSE && STAFUtilIsValidSocket(provider->serverSocketIPv6)) { // Since IPv6 socket is already opened, assume it // also accepts IPv4 traffic, so we close the IPv4 // socket and stop binding. STAFSocketClose(provider->serverSocket); provider->serverSocket = -1; } else HANDLE_START_ERROR("Error binding server socket", "bind()"); } else { int listenRC = listen(provider->serverSocket, SOMAXCONN); if (listenRC != 0) HANDLE_START_ERROR("Error listening on server socket", "listen()"); } }#endif return kSTAFOk;}STAFRC_t STAFConnectionProviderStart(STAFConnectionProvider_t baseProvider, void *startInfo, unsigned int startInfoLevel, STAFString_t *errorBuffer){ if (baseProvider == 0) return kSTAFInvalidObject; if (startInfoLevel != 1) return kSTAFInvalidAPILevel; STAFConnectionProviderStartInfoLevel1 *cpInfo = reinterpret_cast<STAFConnectionProviderStartInfoLevel1 *>(startInfo); try { if (cpInfo->newConnectionFunc == 0) return kSTAFInvalidValue; STAFTCPConnectionProviderImpl *provider = static_cast<STAFTCPConnectionProviderImpl *>(baseProvider); provider->connFunc = cpInfo->newConnectionFunc; provider->data = cpInfo->data;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -