Exemple #1
0
void SSLSocket::Connect(std::string host, uint32_t port, std::function<void(bool)> connectedCallback)
{
	std::thread([&, host, port, connectedCallback]
	{
		//Setup TCP socket
		//Create socket
		struct sockaddr_in serverAddress;
		sockfd = socket(AF_INET, SOCK_STREAM, 0);
		if (sockfd == INVALID_SOCKET)
		{
			LOGI("Create socket fail");
			if (connectedCallback)
			{
				connectedCallback(FAIL);
			}
			return;
		}
		int opt = 1;
		if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (char*)&opt, sizeof(opt)) < 0)
		{
			LOGI("Set socket options error");
			if (connectedCallback)
			{
				connectedCallback(FAIL);
			}
			return;
		}
		memset(&serverAddress, 0, sizeof(serverAddress));
		serverAddress.sin_family = AF_INET;
#if defined(WIN32) || defined(WIN64)
		if (inet_pton(AF_INET, host.c_str(), &serverAddress.sin_addr.S_un.S_addr) <= 0)
#else
		if (inet_pton(AF_INET, host.c_str(), &serverAddress.sin_addr.s_addr) <= 0)
#endif
		{
			LOGI("Invalid address");
			if (connectedCallback)
			{
				connectedCallback(FAIL);
			}
			return;
		}
		serverAddress.sin_port = htons(port);
		//Connect to server
		if (connect(sockfd, (struct sockaddr*)&serverAddress, sizeof(serverAddress)) < 0)
		{
			LOGI("Failed to connect to server");
			if (connectedCallback)
			{
				connectedCallback(FAIL);
			}
			return;
		}
		
		//Setup socket ssl
		if (SSL_set_fd(ssl, sockfd) != SSL_SUCCESS)
		{
			LOGI("SSL_set_fd error");
			LOGI("%s\n", ERR_error_string(ERR_get_error(), NULL));;
			if (connectedCallback)
			{
				connectedCallback(FAIL);
			}
			return;
		}
		if (SSL_connect(ssl) != SSL_SUCCESS)
		{
			LOGI("SSL_connect error");
			LOGI("%s\n", ERR_error_string(ERR_get_error(), NULL));
			if (connectedCallback)
			{
				connectedCallback(FAIL);
			}
			return;
		}       
		LOGI("SSL connection using %s\n", SSL_get_cipher(ssl));
		LOGI("Connected to server");
		//Set socket nonblocking
		if (!SetSocketBlockingEnabled(false))
		{
			LOGI("Set socket blocking error");
			if (connectedCallback)
			{
				connectedCallback(FAIL);
			}
			return;
		}
		if (connectedCallback)
		{
			connectedCallback(SUCCESS);
		}
		return;
	}).detach();
}
Exemple #2
0
/** 对 url 发出 cmd,接收保存到 res 中.

	 FIXME: 这种接收是有问题的,因为不知道何时接受完成 ...
 */
static int tcp_req(const char *url, const char *cmd, int cmdlen, char *res, size_t res_buf_len, int timeout)
{
	char host[128], who[64];
	int port;

	if (sscanf(url, "tcp://%[^:]:%d/%s", host, &port, who) != 3) {
		fprintf(stderr, "[libptz] ERR: invalid tcp url format %s\n", url);
		fprintf(stderr, "\tusing: tcp://<host>:<port>/<who>\n\n");
		return -1;
	}

    struct addrinfo ai, *info, *p;
	memset(&ai, 0, sizeof(ai));
	ai.ai_family = AF_INET;
	ai.ai_socktype = SOCK_STREAM;
	ai.ai_protocol = IPPROTO_TCP;

	char service[16];
	snprintf(service, sizeof(service), "%d", port);
	if (getaddrinfo(host, service, &ai, &info) != 0) {
		fprintf(stderr, "[libptz] ERR: getaddrinfo err for %s\n", url);
		return -2;
	}

	bool completed = false;
	char *recvbuf = res;
	int data_len = 0;

	for (p = info; p && !completed; p = p->ai_next) {
		int sock = socket(p->ai_family, p->ai_socktype, p->ai_protocol);
		if (sock < 0) {
			fprintf(stderr, "[libptz] ERR: can't create socket ???\n");
			continue;
		}

        SetSocketBlockingEnabled(sock, false);

		if (connect_t(sock, p->ai_addr, p->ai_addrlen, timeout) < 0) {
			fprintf(stderr, "[libptz] ERR: can't connect to %s\n", url);
			closesocket(sock);
			continue;
		}

		send(sock, cmd, cmdlen, 0); // FIXME: 这一句基本不会出错了 :)

		fd_set r;
		FD_ZERO(&r);
		FD_SET(sock, &r);
		timeval tv = { timeout/1000, timeout % 1000 * 1000 };
		int rc = select(sock+1, &r, 0, 0, &tv);
		if (rc == -1) {
			fprintf(stderr, "[libptz] ERR: select falut??\n");
			closesocket(sock);
			continue;
		}
		else if (rc == 0) {
			fprintf(stderr, "[libptz] ERR: recv timeout\n");
			closesocket(sock);
			continue;
		}
		
		rc = recv(sock, recvbuf, res_buf_len, 0);
		if (rc > 0) {
			completed = true;
			data_len = rc;
			closesocket(sock);
		}
		else if (rc == 0) {
			fprintf(stderr, "[libptz] ERR: peer closed???\n");
			closesocket(sock);
			continue;
		}
		else {
			// FIXME: 应该检查 lasterr ...
			fprintf(stderr, "[libptz] ERR: recv fault!\n");
			closesocket(sock);
			continue;
		}
	}

	freeaddrinfo(info);

	return data_len;
}
Exemple #3
0
StdinDataIO :: StdinDataIO(bool blocking) : _stdinBlocking(blocking)
#ifdef USE_WIN32_STDINDATAIO_IMPLEMENTATION
 , _slaveSocketTag(0)
#else
 , _fdIO(ConstSocketRef(&_stdinSocket, false), true)
#endif
{
#ifdef USE_WIN32_STDINDATAIO_IMPLEMENTATION
   if (_stdinBlocking == false)
   {
      // For non-blocking I/O, we need to handle stdin in a separate thread. 
      // note that I freopen stdin to "nul" so that other code (read: Python)
      // won't try to muck about with stdin and interfere with StdinDataIO's
      // operation.  I don't know of any good way to restore it again after,
      // though... so a side effect of StdinDataIO under Windows is that
      // stdin gets redirected to nul... once you've created one non-blocking
      // StdinDataIO, you'll need to continue accessing stdin only via
      // non-blocking StdinDataIOs.
      bool okay = false;
      ConstSocketRef slaveSocket;
      if ((CreateConnectedSocketPair(_masterSocket, slaveSocket, false) == B_NO_ERROR)&&(SetSocketBlockingEnabled(slaveSocket, true) == B_NO_ERROR)&&(_slaveSocketsMutex.Lock() == B_NO_ERROR))
      {
         bool threadCreated = false;
         if (_stdinThreadStatus == STDIN_THREAD_STATUS_UNINITIALIZED)
         {
            DWORD junkThreadID;
#if __STDC_WANT_SECURE_LIB__
            FILE * junkFD;
#endif
            _stdinThreadStatus = ((DuplicateHandle(GetCurrentProcess(), GetStdHandle(STD_INPUT_HANDLE), GetCurrentProcess(), &_stdinHandle, 0, false, DUPLICATE_SAME_ACCESS))&&
#if __STDC_WANT_SECURE_LIB__
               (freopen_s(&junkFD, "nul", "r", stdin) == 0)
#else
               (freopen("nul", "r", stdin) != NULL)
#endif
               &&((_slaveThread = (::HANDLE) _beginthreadex(NULL, 0, StdinThreadEntryFunc, NULL, CREATE_SUSPENDED, (unsigned *) &junkThreadID)) != 0)) ? STDIN_THREAD_STATUS_RUNNING : STDIN_THREAD_STATUS_EXITED;
            threadCreated = (_stdinThreadStatus == STDIN_THREAD_STATUS_RUNNING);
         }
         if ((_stdinThreadStatus == STDIN_THREAD_STATUS_RUNNING)&&(_slaveSockets.Put(_slaveSocketTag = (++_slaveSocketTagCounter), slaveSocket) == B_NO_ERROR)) okay = true;
                                                                                                                                                        else LogTime(MUSCLE_LOG_ERROR, "StdinDataIO:  Could not start stdin thread!\n");
         _slaveSocketsMutex.Unlock();

         // We don't start the thread running until here, that way there's no chance of race conditions if the thread exits immediately
         if (threadCreated) ResumeThread(_slaveThread);
      }
      else LogTime(MUSCLE_LOG_ERROR, "StdinDataIO:  Error setting up I/O sockets!\n");

      if (okay == false) Close();
   }
#endif
}
Exemple #4
0
/** receive data from tcp connection, using session ID */
long Network::TCPServer::TCPReceive(int iSession_ID, char ** ucBufferReceive, int iLenBufferReceive, int * iOutLenDataReceive, bool bAllowAllocate)
{
	if(!m_bConnected)
	{
		return TCP_ERR_SERV_NOT_CONNECT;
	}
	if(!m_bAccepted)
	{
		return TCP_ERR_SERV_NOT_ACCEPTED;
	}

	int iSizeBuffer = 0;
	char * pBuffer = NULL;
	char * pReallocBuffer = NULL;
	char cTempBuffer[TCP_MAX_DATA];
	memset(cTempBuffer, 0x00, TCP_MAX_DATA);

	// Put the socket in non-blocking mode:
	SetSocketBlockingEnabled(iSession_ID, false);
	
	int i_total_received = 0;
	int nb_recept = 1;
	int i_try_to_receive_counter = 0;

	do
	{
		nb_recept = recv(iSession_ID, cTempBuffer, TCP_MAX_DATA, 0);
		if(nb_recept > 0)
		{
			// need to increase buffer size
			if(iSizeBuffer <= (i_total_received + nb_recept))
			{
				iSizeBuffer += TCP_MAX_DATA;
				pReallocBuffer = (char*) realloc(pBuffer, iSizeBuffer * sizeof(char));
				if(NULL == pReallocBuffer)
				{
#ifdef _WINDOWS
					WSACleanup();
#endif // _WINDOWS
					free(pBuffer);
					return TCP_ERR_SERV_INVALID_PT;
				}
				pBuffer = pReallocBuffer;
			}
			
			memcpy(pBuffer+i_total_received, cTempBuffer, nb_recept);
			i_total_received += nb_recept;

		} else {
			i_try_to_receive_counter++;
			Timing::Timing::sleepInMilliSecond(100);
		}

	} while( (nb_recept > 0) || (i_try_to_receive_counter < MAX_TRY_RECEIVED) );

	// copy output data if data buffer size is efficient
	if( false == bAllowAllocate && (i_total_received > iLenBufferReceive) ) 
	{
#ifdef _WINDOWS
		WSACleanup();
#endif // _WINDOWS
		free(pBuffer);
		return TCP_ERR_SERV_RECV;
	}
	if(i_total_received > 0)
	{
		*iOutLenDataReceive = i_total_received;
		if(!bAllowAllocate)
		{
			int maxCopy = TCP_MAX_DATA;
			if(i_total_received < maxCopy) {
				maxCopy = i_total_received;
			}
			memcpy(*ucBufferReceive, pBuffer, maxCopy);
		}
		else 
		{
			*ucBufferReceive = (char*)malloc(i_total_received * sizeof(char));
			memcpy(*ucBufferReceive, pBuffer, i_total_received);
		}
		free(pBuffer);
	}
	else
	{
		free(pBuffer);
		return TCP_ERR_SERV_RECV;
	}

	return TCP_SERVER_SUCCESS;
}