/*
 * Bind Socket to an Address (We then get a unique local port assigned to the Socket)
 * We need to do this for TCP or UDP before Opening a QoS Channel with the Socket
 * This is so QoS Channel Sockets can be identified from one another
 */
void CMultipleArray::BindL(TInt aExtraSocksToJoin)
	{
	TInt result, err;

	if (iProtocol[aExtraSocksToJoin] == KProtocolInetUdp)
		result = (GetSocketHandle(aExtraSocksToJoin))->SetOpt(KSoUdpSynchronousSend, KSolInetUdp, 1 );
	
	// Bind to Local address for both TCP and UDP
	result = GetSocketHandle(aExtraSocksToJoin)->Bind(iScrAddr[aExtraSocksToJoin]);
	if (result!=KErrNone)
		{
		iQoSStep->iQoSSuite->Log(_L("Failed to bind socket: return value = <%d>"), result);
		User::Leave(result);
		}

	// Set Bind to True so we know we have already done a Bind
	err = iBind.Insert(ETrue, aExtraSocksToJoin);
	if (err!=KErrNone)
		{
		iQoSStep->iQoSSuite->Log(_L("Failed to insert value into iBind RArray : return value = <%d>"), err);
		User::Leave(err);
		}
	}
Beispiel #2
0
	bool IOCPConnection::PendRecvRequest()
	{
		if( !IsConnected() )
			return false;

		m_recvCS.Lock();

		bool bRtn = true;

		if( m_pRecvQueue->Size() + m_pRecvQueue->FreeSize() > m_pRecvQueue->GetReservedSize() )
		{
			// TODO+ 에러! 큐 Overflow!
		}

		if( m_pRecvQueue->FreeSize() == 0 )
		{
			m_pRecvQueue->Reserve( m_pRecvQueue->GetReservedSize() );
		}

		m_recvWSABUF.buf = const_cast<char*>( m_pRecvQueue->GetBuf() + m_pRecvQueue->Size() );
		m_recvWSABUF.len = m_pRecvQueue->FreeSize();

		assert( GetPendingRecvCount() < 1 );
		InterlockedIncrement( &m_pendingRecvQueryCount );

		m_dwRecvFlag = 0;
		int nRtn = WSARecv( GetSocketHandle(), &m_recvWSABUF, 1, &m_pRecvOverlapped->dwSize, &m_dwRecvFlag, m_pRecvOverlapped, NULL );

		int nErr = 0;
		if( nRtn == SOCKET_ERROR )
		{
			nErr = WSAGetLastError();
			if( nErr == WSA_IO_PENDING )
			{
			}
			else
			{
				bRtn = false;
				InterlockedDecrement( &m_pendingRecvQueryCount );

				//m_lastError = nErr;
				OnDisconnect( -2 );
			}
		}

		return bRtn;
	}
Beispiel #3
0
	bool IOCPConnection::ProcWriteFile()
	{
		if( !IsConnected() ) return false;
		if( m_bDisconnectSignal ) return false;
		if( m_bDisconnectEventPosted ) return false;

		InterlockedIncrement( &m_pendingSendQueryCount );

		int len = m_pSendQueue->Size() - m_sendingBytes;
		int sendSize = (IOCP::BUFFER_SIZE > len ? len : IOCP::BUFFER_SIZE);

		OverlappedIO* pSendOverlapped = m_pSendOverlapped;

		m_dwSendFlag = 0;
		m_sendWSABUF.buf = const_cast<char*>( m_pSendQueue->GetBuf() + m_sendingBytes);
		m_sendWSABUF.len = sendSize;

		int nRtn = ::WSASend( GetSocketHandle(), &m_sendWSABUF, 1, &pSendOverlapped->dwSize, m_dwSendFlag, pSendOverlapped, NULL );
		if( nRtn == SOCKET_ERROR )
		{
			DWORD nErr = ::WSAGetLastError();
			if( nErr == WSA_IO_PENDING )
			{
			}
			else
			{
				InterlockedDecrement( &m_pendingSendQueryCount );

				//this->SetLastError( nErr );
				OnDisconnect( -3 );
				return false;
			}
		}

		m_bSendPending = true;

		m_sendingBytes += sendSize;

		return true;
	}
oex::oexBOOL CSqSSLPortFactory::CSqSSLPort::OnAttach()
{_STT();

	oexAutoLock ll( m_lock ); 
	if ( !ll.IsLocked() ) 
		return oex::oexFALSE;

	if ( !m_ctx )
		return oex::oexFALSE;

	// Create ssl object for this connection
	m_ssl = SSL_new( m_ctx );
	if ( !m_ssl )
	{	m_sLastError = ERR_error_string( ERR_get_error(), 0 );
//		oexSHOW( m_sLastError.c_str() );
		return oex::oexFALSE;
	} // end if

	// Set socket handle
	if ( !SSL_set_fd( m_ssl, oexPtrToInt( GetSocketHandle() ) ) )
	{	m_sLastError = ERR_error_string( ERR_get_error(), 0 );
		OnClose();
//		oexSHOW( m_sLastError.c_str() );
		return oex::oexFALSE;
	} // end if

	int err = 0;
	oex::os::CTimeout to; to.SetMs( oexDEFAULT_WAIT_TIMEOUT );
	do
	{
		// Wait for data?
		if ( err )
		{	ll.Unlock();
			oexSleep( 15 );
			if ( !ll.Lock( m_lock ) )
			{	OnClose();
				return oex::oexFALSE;
			} // end if
		} // end if

		// SSL accept
		if( -1 == SSL_accept( m_ssl ) )
			err = SSL_get_error( m_ssl, -1 );
		else
			err = 0;

	} while ( to.IsValid() && ( SSL_ERROR_WANT_READ == err || SSL_ERROR_WANT_WRITE == err ) );

	if ( err )
	{	m_sLastError = sqbind::oex2std( oexMks( oexT( "SSL_accept() failed : " ), err ) );
//		oexSHOW( m_sLastError.c_str() );
		OnClose();
		return oex::oexFALSE;
	} // end if

	oex::CPropertyBag pb;
	long lVerify = SSL_get_verify_result( m_ssl );
	pb[ oexT( "cert_verify" ) ] = ( X509_V_OK == lVerify );

	// Get peer certificate
	m_cert = SSL_get_peer_certificate( m_ssl );
	pb[ oexT( "cert_valid" ) ] = ( X509_V_OK == lVerify ) && m_cert;
	
	// +++ Fill in certificate information
/*	if ( m_cert )
	{	X509_NAME *pName = X509_get_subject_name( m_cert );
		if ( pName )
			for ( int i = 0; i < X509_NAME_entry_count( pName ); i++ )
			{	X509_NAME_ENTRY *e = X509_NAME_get_entry( pName, i );
				
			} // end for
	} // end if
*/
	// Set port properties string
	m_sProperties = oex::CParser::Serialize( pb );

	return oex::oexTRUE;
}
//		Created: 2003/08/06
//
// --------------------------------------------------------------------------
void SocketStreamTLS::Handshake(const TLSContext &rContext, bool IsServer)
{
	if(mpBIO || mpSSL) {THROW_EXCEPTION(ServerException, TLSAlreadyHandshaked)}

	// Create a BIO for this socket
	mpBIO = ::BIO_new(::BIO_s_socket());
	if(mpBIO == 0)
	{
		CryptoUtils::LogError("creating socket bio");
		THROW_EXCEPTION(ServerException, TLSAllocationFailed)
	}

	tOSSocketHandle socket = GetSocketHandle();
	BIO_set_fd(mpBIO, socket, BIO_NOCLOSE);

	// Then the SSL object
	mpSSL = ::SSL_new(rContext.GetRawContext());
	if(mpSSL == 0)
	{
		CryptoUtils::LogError("creating SSL object");
		THROW_EXCEPTION(ServerException, TLSAllocationFailed)
	}

	// Make the socket non-blocking so timeouts on Read work

#ifdef WIN32
	u_long nonblocking = 1;
	ioctlsocket(socket, FIONBIO, &nonblocking);
void CMultipleArray::SendAndRecvL(TInt aExtraSocksToJoin)
	{
	TRequestStatus stat;
	TBuf8<50> Data;

	// set up data buffers
	HBufC8 * writebuf = HBufC8::NewMaxLC( iPacketSize[aExtraSocksToJoin] );
	HBufC8 * readbuf  = HBufC8::NewMaxLC( iPacketSize[aExtraSocksToJoin] );
	TPtr8 ptrWritebuf = writebuf->Des();
	TPtr8 ptrReadbuf = readbuf->Des();

	TInt recvCount = 0;

	// Send / Recv TCP
	if (iProtocol[aExtraSocksToJoin] == KProtocolInetTcp)
		{
		for (TInt i = 0; i < iPackets[aExtraSocksToJoin]; i++)
			{
			iQoSStep->iQoSSuite->Log( _L("Sending TCP data, %d packets of %d bytes = %d"), 
			iPackets[aExtraSocksToJoin], iPacketSize[aExtraSocksToJoin], iPackets[aExtraSocksToJoin] * iPacketSize[aExtraSocksToJoin]);

			// initialise data
			Data.Format(_L8("TCP-packet:%d helloworld"),i);
			ptrWritebuf.Repeat( Data );

			// write data
			GetSocketHandle(aExtraSocksToJoin)->Write(ptrWritebuf, stat);
			User::WaitForRequest(stat);
			if (stat!=KErrNone)
				{
				iQoSStep->iQoSSuite->Log(_L("Failed to write tcp data to destination: return value = <%d>"), stat);
				User::Leave(stat.Int());
				}

			// read data
			GetSocketHandle(aExtraSocksToJoin)->Read(ptrReadbuf, stat);
			User::WaitForRequest(stat); //, TimerStatus);
			if (stat!=KErrNone)
				{
				iQoSStep->iQoSSuite->Log(_L("Failed to read tcp data from destination: return value = <%d>"), stat);
				User::Leave(stat.Int());
				}

			// compare the data
			if (ptrWritebuf.Compare( ptrReadbuf ) != 0)
				{
				iQoSStep->iQoSSuite->Log(_L("Data written to and read from destination address do not match in size"));
//				return Fail;
				}

			recvCount+=ptrReadbuf.Length();
			}

		CleanupStack::PopAndDestroy(2);	//	writebuf and readbuf
		} 

	// Send / Recv UDP 
	if (iProtocol[aExtraSocksToJoin] == KProtocolInetUdp)
		{
		iQoSStep->iQoSSuite->Log( _L("Send Udp Data, %d packets of %d bytes = %d"), 
		iPackets[aExtraSocksToJoin], iPacketSize[aExtraSocksToJoin], iPackets[aExtraSocksToJoin] * iPacketSize[aExtraSocksToJoin]);
	
		for (TInt i = 0; i < iPackets[aExtraSocksToJoin]; i++)
			{
			// initialise data
			Data.Format(_L8("UDP-packet:%d helloworld"),i);
			ptrWritebuf.Repeat( Data );	

			// write data
			GetSocketHandle(aExtraSocksToJoin)->Send(ptrWritebuf, 0, stat);
			User::WaitForRequest(stat);
			if (stat!=KErrNone)
				{
				iQoSStep->iQoSSuite->Log(_L("Failed to write udp data to destination: return value = <%d>"), stat);
				User::Leave(stat.Int());
				}

			GetSocketHandle(aExtraSocksToJoin)->Recv(ptrReadbuf, 0, stat);
			User::WaitForRequest(stat);
			if (stat!=KErrNone)
				{
				iQoSStep->iQoSSuite->Log(_L("Failed to read udp data from destination: return value = <%d>"), stat);
				User::Leave(stat.Int());
				}

			// compare the data
			if (ptrWritebuf.Compare( ptrReadbuf ) != 0 )
				{
				iQoSStep->iQoSSuite->Log(_L("Data written to and read from destination address do not match in sizevalue"));
//				return Fail;
				}
			recvCount += ptrReadbuf.Length();
			}

		// get rid of the old buffers 
		CleanupStack::PopAndDestroy(2);	//	writebuf and readbuf
		}


	// check the total received (95 per cent is allowable for us)
	if (recvCount*iPacketSize[aExtraSocksToJoin] < (0.95*(iPackets[aExtraSocksToJoin]*iPacketSize[aExtraSocksToJoin])))
		{
		iQoSStep->iQoSSuite->Log(_L("The total packets received is less than 95 per cent of the overall packets sent"));
//		return Fail;
		}
	}
/*
 *  Connect TCP / Bind UDP then Connect
 */
void CMultipleArray::ConnectL(TInt aExtraSocksToJoin)
{
	/* Set to an IPv4 or IPv6 address
	 * Set to a listening port
	 * Connect to the address on listening port n 
	 */
	TRequestStatus stat;
	TInt result, err;

	// Connect TCP
	if (iProtocol[aExtraSocksToJoin] == KProtocolInetTcp)
		{
		// Get Destination Address and Set the Destination Port
		iDestAddr[aExtraSocksToJoin].SetPort(iPort[aExtraSocksToJoin]);
		
		// Connect to the Destination Address
		GetSocketHandle(aExtraSocksToJoin)->Connect(iDestAddr[aExtraSocksToJoin], stat);
		User::WaitForRequest(stat);
		if (stat!=KErrNone)
		{
		iQoSStep->iQoSSuite->Log(_L("Failed to connect socket: return value = <%d>"), stat);
		User::Leave(stat.Int());
		}

		// Set Bind to True so we know we have already done a Bind, Connect does a bind for us
		err = iBind.Insert(ETrue, aExtraSocksToJoin);
		if (err!=KErrNone)
			{
			iQoSStep->iQoSSuite->Log(_L("Failed to insert value into iBind RArray : return value = <%d>"), err);
			User::Leave(err);
			}
	
		// Set iConnect to True so we know we have made a connection for later
		err = iConnect.Insert(ETrue, aExtraSocksToJoin);
		if (err!=KErrNone)
			{
			iQoSStep->iQoSSuite->Log(_L("Failed to insert value into iConnect RArray : return value = <%d>"), err);
			User::Leave(err);
			}
		}

	// Connect UDP
	else if (iProtocol[aExtraSocksToJoin] == KProtocolInetUdp)
		{
		// Get Destination Address and Set the Destination Port
		iDestAddr[aExtraSocksToJoin].SetPort(iPort[aExtraSocksToJoin]);
		// Check to see if we have done a Bind on the Local Address allready
		if (iBind[aExtraSocksToJoin] != 1)
			{
			result = (GetSocketHandle(aExtraSocksToJoin))->SetOpt(KSoUdpSynchronousSend, KSolInetUdp, 1 );
			// Bind to Local address
			result = GetSocketHandle(aExtraSocksToJoin)->Bind(iScrAddr[aExtraSocksToJoin]);
			if (result!=KErrNone)
				{
				iQoSStep->iQoSSuite->Log(_L("Failed to bind socket to local address: return value = <%d>"), result);
				User::Leave(result);
				}
				
			// Set Bind to True so we know we have already done a Bind
			err = iBind.Insert(ETrue, aExtraSocksToJoin);
			if (err!=KErrNone)
				{
				iQoSStep->iQoSSuite->Log(_L("Failed to insert value into iBind RArray : return value = <%d>"), err);
				User::Leave(err);
				}
			}

		// Connect to the Destination Address
		GetSocketHandle(aExtraSocksToJoin)->Connect(iDestAddr[aExtraSocksToJoin], stat);
		User::WaitForRequest(stat);
		if (stat!=KErrNone)
			{
			iQoSStep->iQoSSuite->Log(_L("Failed to connect socket to destination address: return value = <%d>"), stat);
			User::Leave(stat.Int());
			}

		// Set iConnect to True so we know we have made a connection for later
		err = iConnect.Insert(ETrue, aExtraSocksToJoin);
		if (err!=KErrNone)
			{
			iQoSStep->iQoSSuite->Log(_L("Failed to insert value into iConnect RArray : return value = <%d>"), err);
			User::Leave(err);
			}
		}
	}