Esempio n. 1
0
/**
 *  @brief      Attach this VSocket to a pre-existing socket handle.
 *
 *  @remarks    Attaches this object to an existing socket handle and
 *              enters the processing loop.
 *
 *  @param      pHandle
 *                  Handle to the socket to attach to.
 *------------------------------------------------------------------*/
bool VSocket::Attach(SOCKET pHandle) {
	char    vAddress[51];
	VUSHORT vPort = 0;

	BEG_FUNC("Attach")("%d", pHandle);

	if (mStatus == SS_CONNECTED) {
		VTRACE("Error-socket already connected to %s:%d\n",
				mEndPoint.GetAddr(), mEndPoint.GetPort());
		mError = EISCONN;
		return END_FUNC(false);
	}

	if (mStatus == SS_BOUND) {
		VTRACE("Error-socket already bound to %s:%d\n",
				mLocal.GetAddr(), mLocal.GetPort());
		mError = EISCONN;
		return END_FUNC(false);
	}

	mStatus = SS_ALLOCATED;
	mHandle = pHandle;
	GetPeerName(vAddress, 50, &vPort);
	mEndPoint.SetPort(vPort);
	mEndPoint.SetAddr(vAddress);

	memset(vAddress, 0, 50);
	GetSockName(vAddress, 50, &vPort);
	mLocal.SetPort(vPort);
	mLocal.SetAddr(vAddress);

	mStatus = SS_CONNECTED;

	return END_FUNC(true);
}
Esempio n. 2
0
int CClientSession::DoGetFile( const char* strSrc, const char* strDst )
{
    char buf[MAXPATH+sizeof(CNcpMessage)];
    CNcpMessage* pMsg = (CNcpMessage*)buf;

    //step 1. request passive mode to get the data channel address
    short dataport=0;

    int nRet = DoPassive( &dataport );
    if( FAILED(nRet) )return nRet;

    //step 2. send the put file command.
    pMsg->Init( CM_GETFILE );
    strcpy( pMsg->GetData(), strSrc );
    pMsg->SetDataSize( strlen(strSrc)+1 );
    pMsg->Send( m_sock );

    //wait for the return code and check it
    if( !pMsg->Recv( m_sock, ELEMENTS(buf) ) ) {
        return E_BROKEN;		//broken connection
    }

    ASSERT( pMsg->IsAck() );
    if( pMsg->IsFailed() ) {
        return pMsg->GetRet();
    }

    //step 3. now the server agrees on the file transfer, connect the data channel and send file
    SOCKADDR_IN addr;
    socklen_t nlen = sizeof(SOCKADDR_IN);
    GetPeerName( m_sock, (SOCKADDR*)&addr, &nlen );
    addr.sin_port = htons( dataport );

    SOCKET sockdata;
    //import, must retry the socket initilization a few times.
    int i;
    for( i=0; i<MAXRETRY; i++ ) {
        sockdata = Socket( PF_INET, SOCK_STREAM, 0 );
        ASSERT( sockdata!=INVALID_SOCKET );

        if( ::connect( sockdata, (SOCKADDR*)&addr, sizeof(SOCKADDR_IN) )==0 )break;
        closesocket( sockdata );
    }
    if( i>=MAXRETRY )throw new CSockException();

    int nLen = RecvFileEx( sockdata, strDst, m_nFileMode );
    closesocket( sockdata );

    //step 4. exchange the error code.
    pMsg->Init( CM_ACK, nLen );
    pMsg->Send( m_sock );

    //wait for the return code and check it
    if( !pMsg->Recv( m_sock, ELEMENTS(buf) ) ) {
        return E_BROKEN;		//broken connection
    }

    ASSERT( pMsg->IsAck() );
    return pMsg->GetRet();
}
Esempio n. 3
0
BOOL CAdminSocket::Init()
{
	char *buffer = new char[100];
	char *p = buffer;
	strcpy(buffer, "FZS");
	p += 3;

	*p++ = 0;
	*p++ = 4;
	memcpy(p, &SERVER_VERSION, 4);
	p += 4;

	*p++ = 0;
	*p++ = 4;

	memcpy(p, &PROTOCOL_VERSION, 4);
	p += 4;

	COptions options;
	CStdString pass = options.GetOption(OPTION_ADMINPASS);
	CStdString peerAddress;
	UINT port = 0;
	if (GetPeerName(peerAddress, port) && IsLocalhost(peerAddress) && pass == _T("")) {
		BOOL res = Send(buffer, p-buffer) == p - buffer;
		delete [] buffer;
		if (!res) {
			Close();
			return FALSE;
		}
		return FinishLogon();
	}
	else {
		*p++ = 0;

		DWORD len = 20;
		memcpy(p, &len, 4);
		p += 4;

		*p++ = 0;
		*p++ = 8;

		int i;
		for (i = 0; i < 8; ++i) {
			m_Nonce1[i] = std::uniform_int_distribution<unsigned int>(0, 255)(std::random_device());
			*p++ = m_Nonce1[i];
		}

		*p++ = 0;
		*p++ = 8;

		for (i = 0; i < 8; ++i) {
			m_Nonce2[i] = std::uniform_int_distribution<unsigned int>(0, 255)(std::random_device());
			*p++ = m_Nonce2[i];
		}
	}

	int res = Send(buffer, p-buffer) == p-buffer;
	delete [] buffer;
	return res;
}
Esempio n. 4
0
bool CSocket::GetPeerName(SOCKADDR_IN* lpSockInAddr)
{
	memset(lpSockInAddr, 0, sizeof(SOCKADDR_IN));

	socklen_t nSockAddrLen = sizeof(SOCKADDR_IN);
	return GetPeerName((SOCKADDR*)lpSockInAddr, &nSockAddrLen);
}
Esempio n. 5
0
bool CTcpSocketService::GetPeerData(std::string& Ip, UINT& Port)
{
    bool Success = (GetPeerName(Ip, (int&)Port) != FALSE);

    if(!Success)
        DisplaySocketsError("CTcpSocketService::GetPeerName");
    return Success;
}
Esempio n. 6
0
int DzGetPeerName( int fd, struct sockaddr* addr, socklen_t* addrLen )
{
    DzHost* host = GetHost();
    assert( host );
    assert( fd >= 0 );
    assert( ( fd & HANDLE_HOST_ID_MASK ) == host->hostId );

    return GetPeerName( host, fd, addr, addrLen );
}
Esempio n. 7
0
otError UdpSocket::SendTo(Message &aMessage, const MessageInfo &aMessageInfo)
{
    otError error = OT_ERROR_NONE;
    MessageInfo messageInfoLocal;
    UdpHeader udpHeader;

    messageInfoLocal = aMessageInfo;

    if (messageInfoLocal.GetSockAddr().IsUnspecified())
    {
        messageInfoLocal.SetSockAddr(GetSockName().GetAddress());
    }

    if (GetSockName().mPort == 0)
    {
        GetSockName().mPort = static_cast<Udp *>(mTransport)->GetEphemeralPort();
    }

    if (messageInfoLocal.GetPeerAddr().IsUnspecified())
    {
        VerifyOrExit(!GetPeerName().GetAddress().IsUnspecified(), error = OT_ERROR_INVALID_ARGS);

        messageInfoLocal.SetPeerAddr(GetPeerName().GetAddress());
    }

    if (messageInfoLocal.mPeerPort == 0)
    {
        VerifyOrExit(GetPeerName().mPort != 0, error = OT_ERROR_INVALID_ARGS);
        messageInfoLocal.mPeerPort = GetPeerName().mPort;
    }

    udpHeader.SetSourcePort(GetSockName().mPort);
    udpHeader.SetDestinationPort(messageInfoLocal.mPeerPort);
    udpHeader.SetLength(sizeof(udpHeader) + aMessage.GetLength());
    udpHeader.SetChecksum(0);

    SuccessOrExit(error = aMessage.Prepend(&udpHeader, sizeof(udpHeader)));
    aMessage.SetOffset(0);
    SuccessOrExit(error = static_cast<Udp *>(mTransport)->SendDatagram(aMessage, messageInfoLocal, kProtoUdp));

exit:
    return error;
}
Esempio n. 8
0
bool CSocket::GetPeerName(string& rPeerAddress, UINT& rPeerPort)
{
	SOCKADDR_IN sockAddr;

	bool bResult = GetPeerName(&sockAddr);
	if (bResult)
	{
		rPeerPort = ntohs(sockAddr.sin_port);
		rPeerAddress = inet_ntoa(sockAddr.sin_addr);
	}
	return bResult;
}
Esempio n. 9
0
void CServerSocket::OnConnect(int nErrorCode) {
    CAsyncSocketEx::OnConnect(nErrorCode); // deadlake PROXYSUPPORT - changed to AsyncSocketEx
    switch (nErrorCode) {
    case 0: {
        if (cur_server->HasDynIP()) {
            SOCKADDR_IN sockAddr = {0};
            int nSockAddrLen = sizeof(sockAddr);
            GetPeerName((SOCKADDR*)&sockAddr, &nSockAddrLen);
            cur_server->SetIP(sockAddr.sin_addr.S_un.S_addr);
            CServer* pServer = theApp.serverlist->GetServerByAddress(cur_server->GetAddress(),cur_server->GetPort());
            if (pServer)
                pServer->SetIP(sockAddr.sin_addr.S_un.S_addr);
        }
        SetConnectionState(CS_WAITFORLOGIN);
        break;
    }
    case WSAEADDRNOTAVAIL:
    case WSAECONNREFUSED:
    //case WSAENETUNREACH:	// let this error default to 'fatal error' as it does not inrease the server's failed count
    case WSAETIMEDOUT:
    case WSAEADDRINUSE:
        if (thePrefs.GetVerbose())
            DebugLogError(_T("Failed to connect to server %s; %s"), cur_server->GetAddress(), GetErrorMessage(nErrorCode, 1));
        m_bIsDeleting = true;
        SetConnectionState(CS_SERVERDEAD);
        serverconnect->DestroySocket(this);
        return;
//==> remove PROXY [shadow2004]
#if defined(PROXY)
    // deadlake PROXYSUPPORT
    case WSAECONNABORTED:
        if (m_ProxyConnectFailed)
        {
            if (thePrefs.GetVerbose())
                DebugLogError(_T("Failed to connect to server %s; %s"), cur_server->GetAddress(), GetErrorMessage(nErrorCode, 1));
            m_ProxyConnectFailed = false;
            m_bIsDeleting = true;
            SetConnectionState(CS_SERVERDEAD);
            serverconnect->DestroySocket(this);
            return;
        }
#endif //PROXY
//<== remove PROXY [shadow2004]
    default:
        if (thePrefs.GetVerbose())
            DebugLogError(_T("Failed to connect to server %s; %s"), cur_server->GetAddress(), GetErrorMessage(nErrorCode, 1));
        m_bIsDeleting = true;
        SetConnectionState(CS_FATALERROR);
        serverconnect->DestroySocket(this);
        return;
    }
}
Esempio n. 10
0
CSocketAddress CGSocket::GetPeerName( ) const
{
	struct sockaddr_in SockAddrIn;
	int iRet = GetPeerName( &SockAddrIn );
	if ( iRet )
	{
		return( CSocketAddress( INADDR_BROADCAST, 0 ));	// invalid.
	}
	else
	{
		return( CSocketAddress( SockAddrIn ));
	}
}
Esempio n. 11
0
BOOL CAsyncSocketExLayer::GetPeerNameNext( CString& rPeerAddress, UINT& rPeerPort )
{
  if (m_pNextLayer)
  {
    return m_pNextLayer->GetPeerName(rPeerAddress, rPeerPort);
  }
  else
  {
    SOCKADDR* sockAddr = NULL;
    int nSockAddrLen = 0;

    if (m_nFamily == AF_INET6)
    {
      sockAddr = (SOCKADDR*)new SOCKADDR_IN6;
      nSockAddrLen = sizeof(SOCKADDR_IN6);
    }
    else if (m_nFamily == AF_INET)
    {
      sockAddr = (SOCKADDR*)new SOCKADDR_IN;
      nSockAddrLen = sizeof(SOCKADDR_IN);
    }

    memset(sockAddr, 0, nSockAddrLen);

    BOOL bResult = GetPeerName(sockAddr, &nSockAddrLen);

    if (bResult)
    {
      if (m_nFamily == AF_INET6)
      {
        rPeerPort = ntohs(((SOCKADDR_IN6*)sockAddr)->sin6_port);
        LPTSTR buf = Inet6AddrToString(((SOCKADDR_IN6*)sockAddr)->sin6_addr);
        rPeerAddress = buf;
        nb_free(buf);
      }
      else if (m_nFamily == AF_INET)
      {
        rPeerPort = ntohs(((SOCKADDR_IN*)sockAddr)->sin_port);
        rPeerAddress = inet_ntoa(((SOCKADDR_IN*)sockAddr)->sin_addr);
      }
      else
      {
        delete sockAddr;
        return FALSE;
      }
    }
    delete sockAddr;

    return bResult;
  }
}
Esempio n. 12
0
BOOL CAsyncSocket::GetPeerName(CString& rPeerAddress, UINT& rPeerPort)
{
	SOCKADDR_IN sockAddr;
	memset(&sockAddr, 0, sizeof(sockAddr));

	int nSockAddrLen = sizeof(sockAddr);
	BOOL bResult = GetPeerName((SOCKADDR*)&sockAddr, &nSockAddrLen);
	if (bResult)
	{
		rPeerPort = ntohs(sockAddr.sin_port);
		rPeerAddress = inet_ntoa(sockAddr.sin_addr);
	}
	return bResult;
}
Esempio n. 13
0
//--------------------------------------------------------------------------------
bool CSmallSocket::GetPeerName(CString& rSocketAddress, UINT& rSocketPort)
	{
	if(m_hSocket == INVALID_SOCKET)
		return false;

	SOCKADDR_IN sockAddr;
	memset(&sockAddr, 0, sizeof(sockAddr));

	int nSockAddrLen = sizeof(sockAddr);

	bool bResult = GetPeerName((SOCKADDR*)&sockAddr, &nSockAddrLen);
	if(bResult)
		{
		rSocketPort = ntohs(sockAddr.sin_port);
		rSocketAddress = inet_ntoa(sockAddr.sin_addr);
		}

	return bResult;
	}
Esempio n. 14
0
void CClientSocket::OnConnect(int nErrorCode)
{
	UINT port;
	CString csPeerPort;
	pcwnd=AfxGetApp()->GetMainWnd();
	if (nErrorCode==0)
	{
		GetSockName(localIp,port);
		GetPeerName(thePeerIp,thePeerPort);
		csPeerPort.Format("%d",thePeerPort);
		localPort.Format("%u",port);
		CString msg;
		msg.Format("<?PlainMsg?>:%s comes in",localIp);
		Send(msg.GetBuffer(0),msg.GetLength()+1);
		pcwnd->GetDlgItem(IDC_BUTTON_CONNECT)->EnableWindow(FALSE);
		pcwnd->SetDlgItemText(IDC_BUTTON_CONNECT,"连接已建立");

		/*CListCtrl *lc=(CListCtrl*)pcwnd->GetDlgItem(IDC_LIST_CLIENT);
		int itemNumber=lc->GetItemCount();
		
		lc->InsertItem(itemNumber,NULL);
		lc->SetItemText(itemNumber,0,"TCP服务器");
		lc->SetItemText(itemNumber,1,thePeerIp);
		lc->SetItemText(itemNumber,2,csPeerPort);*/
	}
	else
	{
		AfxMessageBox("连接服务器失败",MB_ICONWARNING);
		Close();

		CCSocketDemoDlg* acd=(CCSocketDemoDlg*)pcwnd;
		acd->m_clientListenSocket.Close();
		acd->m_chatSocket.Close();

		pcwnd->GetDlgItem(IDC_IPADDRESS1)->EnableWindow(TRUE);
		pcwnd->GetDlgItem(IDC_BUTTON_ESTAB)->EnableWindow(TRUE);
		pcwnd->GetDlgItem(IDC_BUTTON_CONNECT)->EnableWindow(TRUE);
		pcwnd->SetDlgItemText(IDC_BUTTON_CONNECT,"连接服务器");
	}

	CAsyncSocket::OnConnect(nErrorCode);
}
Esempio n. 15
0
HRESULT HvGetPeerName(const HV_SOCKET_HANDLE& hSocket, DWORD32* pdwIPv4, WORD16* pwPort)
{
    struct hv_sockaddr name;
    int namelen = sizeof(struct hv_sockaddr);

    if ( 0 != GetPeerName(hSocket, &name, &namelen) )
    {
        if (pwPort) *pwPort = 0;
        if (pdwIPv4) *pdwIPv4 = 0;

        return E_FAIL;
    }
    else
    {
        WORD16 wPort = ((struct hv_sockaddr_in*)&name)->sin_port;
        DWORD32 dwIPv4 = ((struct hv_sockaddr_in*)&name)->sin_addr.s_addr;

        if(pwPort) *pwPort = ntohs(wPort);
        if(pdwIPv4) *pdwIPv4 = dwIPv4;

        return S_OK;
    }
}
void CSocketServer::OnReceive(int nErrorCode)
{
	// TODO: Add your specialized code here and/or call the base class
	char s[1024]; CString szIP; UINT szPort;

	GetPeerName(szIP,szPort);
	int nLen = Receive(s,1024);
	s[nLen]=L'\0';
	CString strText(s);

	SetInfoReceive(strText);
	SetClientIP(szIP);
	SetClientPort(szPort);
	if (strText.GetLength()>3 && (strText.Left(3) == L"con"))
	{
		CStaticClass::m_bControl = true;
		CStaticClass::m_csReceiveInfo = strText;
		SetEvent(CStaticClass::m_hEventRecieve);
	}


	CSocket::OnReceive(nErrorCode);
}
///////////////////////////////////////////////////////////////////////////////
// Run
///////////////////////////////////////////////////////////////////////////////
// DESCRIPTION:
//      This function runs the main thread loop
//      this implementation can be overloaded.
//      This function calls CSocketComm::OnDataReceived() (Virtual Function)
// PARAMETERS:
// NOTES:
//      You should not wait on the thread to end in this function or overloads
///////////////////////////////////////////////////////////////////////////////
void CSocketComm::Run()
{
    stMessageProxy stMsgProxy;
    DWORD   dwBytes  = 0L;
    DWORD   dwTimeout = INFINITE;
    LPBYTE  lpData  = (LPBYTE)&stMsgProxy;
    DWORD   dwSize  = sizeof(stMsgProxy);

    bool bSmartAddressing = IsSmartAddressing();
    if ( !bSmartAddressing )
    {
        lpData = stMsgProxy.byData;
        dwSize = sizeof(stMsgProxy.byData);
    }

    // Should we run as server mode
    if (IsServer() && !bSmartAddressing)
    {
        if (!IsBroadcast())
        {
            SOCKET sock = (SOCKET) m_hComm;
            sock = WaitForConnection( sock );

            // Get new connection socket
            if (sock != INVALID_SOCKET)
            {
                ShutdownConnection( (SOCKET) m_hComm);
                m_hComm = (HANDLE) sock;
                OnEvent( EVT_CONSUCCESS, NULL ); // connect
            }
            else
            {
                // Do not send event if we are closing
                if (IsOpen())
                    OnEvent( EVT_CONFAILURE, NULL ); // wait fail
                return;
            }
        }
    }
    else
    {
        GetPeerName( stMsgProxy.address );
    }

    while( IsOpen() )
    {
        // Blocking mode: Wait for event
        dwBytes = ReadComm(lpData, dwSize, dwTimeout);

        // Error? - need to signal error
        if (dwBytes == (DWORD)-1L)
        {
            // Do not send event if we are closing
            if (IsOpen())
            {
                if ( bSmartAddressing )
                {
                    RemoveFromList( stMsgProxy.address );
                }
                OnEvent( EVT_CONDROP, &stMsgProxy.address ); // lost connection
            }

            // special case for UDP, alert about the event but do not stop
            if ( bSmartAddressing )
                continue;
            else
                break;
        }

        // Chars received?
        if ( bSmartAddressing && dwBytes == sizeof(SOCKADDR_IN))
        {
            OnEvent( EVT_ZEROLENGTH, NULL );
        }
        else if (dwBytes > 0L)
        {
            OnDataReceived( lpData, dwBytes);
        }

        //Sleep(0);
    }
}
Esempio n. 18
0
void CWin32Socket::ServiceL(TWin32Message& aMessage)
	{
	switch (aMessage.OppCode())
		{
		case EConnect:
			{
			Connect(aMessage);
			break;
			}
		case ECancelConnect:
			{
			if (iConnectMessage)
				{
				Complete(iConnectMessage, KErrCancel);
				}
			break;
			}
		case ESend:
			{
			Send(aMessage);
			break;
			}
		case ECancelSend:
			{
			if (iSendMessage)
				{
				Complete(iSendMessage, KErrCancel);
				}
			break;
			}
		case ESendTo:
			{
			SendTo(aMessage);
			break;
			}
		case ECancelSendTo:
			{
			if (iSendMessage)
				{
				Complete(iSendMessage, KErrCancel);
				}
			break;
			}
		case EReceive:
			{
			Receive(aMessage);
			break;
			}
		case ECancelReceive:
			{
			if (iReceiveMessage)
				{
				Complete(iReceiveMessage, KErrCancel);
				}
			break;
			}
		case EReceiveFrom:
			{
			ReceiveFrom(aMessage);
			break;
			}
		case ECancelReceiveFrom:
			{
			if (iReceiveMessage)
				{
				Complete(iReceiveMessage, KErrCancel);
				}
			break;
			}
		case EGetSocketName:
			{
			GetSocketName(aMessage);
			break;
			}
		case EBind:
			{
			Bind(aMessage);
			break;
			}
		case EGetPeerName:
			{
			GetPeerName(aMessage);
			break;
			}
		case EListen:
			{
			Listen(aMessage);
			break;
			}
		case EAccept:
			{
			Accept(aMessage);
			break;
			}
		case ECancelAccept:
			{
			if (iAcceptMessage)
				{
				Complete(iAcceptMessage, KErrCancel);
				}
			break;
			}
		case EGetOption:
			{
			GetOption(aMessage);
			break;
			}
		case ESetOption:
			{
			SetOption(aMessage);
			break;
			}
		default:
			{
			__ASSERT_DEBUG(EFalse, Panic(EWinSockPrtInvalidSocketOppCode));
			}
		}
	}
Esempio n. 19
0
int MySocket::GetPeerName()
// Retrieves the current name for the remote socket descriptor.
// Returns -1 if an error occurs.
{
  return GetPeerName(conn_socket, &remote_sin);
}
Esempio n. 20
0
/////////////////////////////////////////////////////////////////////////////
// CClientSocket member functions
void CClientSocket::OnReceive(int nErrorCode)
{
	CString ip;UINT port;
	CString buf,text;
	CString _fileName;
	byte* mybuf=new byte[PACKAGESIZE];
	//Receive(buf.GetBuffer(2056),2056);
	int total=Receive(mybuf,PACKAGESIZE);
	buf.Format("%s",mybuf);
	GetPeerName(ip,port);
	int isTxtMsg=0;

	if (buf.Find("<?Request FILETRANSFER?>")>-1)
	{
		closed=0;
		int pos=buf.Find(":");
		int posEnd=buf.Find(":",pos+1);
		//_fileName=buf.Right(buf.GetLength()-pos-1);
		_fileName=buf.Mid(pos+1,posEnd-pos-1);
		fileLen=buf.Mid(posEnd+1,buf.GetLength()-posEnd-1);
		fileLength=atol(fileLen.GetBuffer(0));
		fileName=_fileName;
		CString request;
		request.Format("来自%s的用户向你发送文件%s,是否接收?",ip,_fileName);
		int ret=MessageBox(pcwnd->GetSafeHwnd(),request,"文件发送请求",MB_ICONQUESTION|MB_YESNO);
		if (ret==IDYES)
		{
			CString suffix=fileName.Right(fileName.GetLength()-fileName.ReverseFind('.')-1);
			CFileDialog dlg(FALSE,suffix,fileName);
			dlg.m_ofn.lpstrTitle="请选择保存位置";
			dlg.m_ofn.lpstrFilter="所有文件类型(*.*)\0*.*\0\0";
			if (IDOK==dlg.DoModal())
			{
				filePath=dlg.GetPathName();
				fileName=dlg.GetFileName();
				destFile.Open(filePath,CFile::modeWrite|CFile::modeNoTruncate|CFile::modeCreate|CFile::typeBinary,NULL);
				if (!fileTran)
				{
					CSendFileDlg *sfDlg=new CSendFileDlg(SOCKETTYPECLIENT,this);
					sfDlg->Create(IDD_SENDFILE_DIALOG,CWnd::FromHandle(::GetDesktopWindow()));
					fileTran=sfDlg;
					fileTran->ShowWindow(SW_SHOW);
 				}
				fileTran->SetDlgItemText(IDC_STATIC_SRCA,thePeerIp);
				fileTran->SetDlgItemText(IDC_STATIC_DESA,localIp);
				fileTran->SetDlgItemText(IDC_STATIC_FINFO,fileName+"\n大小: "+fileLen+" 字节");
				CProgressCtrl *proSF=(CProgressCtrl*)fileTran->GetDlgItem(IDC_PROGRESS_TRANFILE);
				proSF->SetRange32(0,fileLength);
				proSF->SetPos(0);
				Send("<?Response FILETRANSFER?>:ACCEPT",256);
			}
			else
				Send("<?Response FILETRANSFER?>:REFUSE",256);
		}
		else
		{
			Send("<?Response FILETRANSFER?>:REFUSE",256);
		}
	}
	else if (buf.Find("<?PlainMsg?>")>-1)
	{
		tag=1;isTxtMsg=1;
	}
	else if (buf.Find("<?FileStop?>")>-1)
	{
		if (closed==0)
		{
			destFile.Flush();
			destFile.Close();
			closed=1;
		}
	}
	else if (buf.Find("<?Command update client list?>")>-1)
	{
		int tag=1;
		int pos1,pos2;
		BOOL isAdd=FALSE;
		if (buf.Find("<?Command update client list?>+")>-1)
			isAdd=TRUE;
		if (isAdd)//redraw the client list
		{
			CListCtrl *lc=(CListCtrl*)AfxGetMainWnd()->GetDlgItem(IDC_LIST_CLIENT);
			lc->DeleteAllItems();
		}

		buf.Replace('#','+');
		CString sztemp;
		while(tag)
		{
			pos1=buf.Find("+");
			pos2=buf.Find("+",pos1+1);
			if (pos1==-1)
				break;
			if(pos2==-1)
			{
				pos2=buf.GetLength();
				tag=0;
			}
			sztemp=buf.Mid(pos1+1,pos2-pos1-1);
			buf=buf.Right(buf.GetLength()-pos2);
			UpdateClientList(CString("<?Command update client list?>")+sztemp,isAdd);
		}
	}
	else if (buf.Find("<?Command Kick?>")>-1)
	{
		AfxMessageBox("你已被服务器踢出,\n点击 确定 结束程序。",MB_ICONINFORMATION);
		CCSocketDemoDlg *ccd=(CCSocketDemoDlg*)AfxGetMainWnd();
		NOTIFYICONDATA *_nd=&(ccd->nd);
		Shell_NotifyIcon(NIM_DELETE, _nd);
		::PostQuitMessage(0);
	}
	else
	{
		destFile.SeekToEnd();
		destFile.Write(mybuf,total);
		//destFile.Flush();
		CProgressCtrl *proSF=(CProgressCtrl*)fileTran->GetDlgItem(IDC_PROGRESS_TRANFILE);
		proSF->SetPos(proSF->GetPos()+total);
		CString status;
		status.Format("已接收%u 字节中的%d 字节",fileLength,proSF->GetPos());
		fileTran->SetDlgItemText(IDC_STATIC_STATUS,status);
		if (fileLength==proSF->GetPos() &&closed==0)
		{
			destFile.Flush();
			destFile.Close();
			closed=1;
		}
		Send("<?FileContinue?>",256);
	}


	if (isTxtMsg==0)
	{
		delete[] mybuf;
		buf.Empty();
		return;
	}
	if (AfxGetMainWnd()->IsWindowVisible()==FALSE)
		AfxGetMainWnd()->SetTimer(2,800,NULL);//flash icon
	else
		AfxGetMainWnd()->SetTimer(1,800,NULL);//flash window
	PlaySound(MAKEINTRESOURCE(IDR_WAVE_MSG),AfxGetInstanceHandle(),SND_RESOURCE|SND_ASYNC|SND_NOWAIT);

	CRichEditCtrl *m_RichEdit1;
	pcwnd=AfxGetApp()->GetMainWnd();
	m_RichEdit1=(CRichEditCtrl*)pcwnd->GetDlgItem(IDC_RICHEDIT_CONTENT);
	SOCKADDR_IN addrFrom;
	int len=sizeof(SOCKADDR);
	CString msg;
	HOSTENT *pHost;
	DWORD lineCount=m_RichEdit1->GetLineCount();

	CHARFORMAT cf;
	ZeroMemory(&cf, sizeof(CHARFORMAT));
	cf.cbSize = sizeof(CHARFORMAT);
	cf.dwMask = CFM_BOLD | CFM_COLOR | CFM_FACE |
		CFM_ITALIC | CFM_SIZE | CFM_UNDERLINE;
	cf.dwEffects = 0;
	cf.yHeight = 15*15;//文字高度
	cf.crTextColor = RGB(255, 0, 0); //文字颜色
	strcpy(cf.szFaceName ,_T("宋体"));//设置字体
	m_RichEdit1->SetDefaultCharFormat(cf);
	m_RichEdit1->SetBackgroundColor(FALSE,RGB(255,255,255));
	
	//ReceiveFrom(buf.GetBuffer(2056),2056,(SOCKADDR*)&addrFrom,&len);

	DWORD peerIP=inet_addr(ip.GetBuffer(0));  
	pHost=gethostbyaddr((LPSTR)&peerIP,4,AF_INET); 

	buf=buf.Right(buf.GetLength()-13);

	CTime time=CTime::GetCurrentTime();
	CString currentTime;
	currentTime.Format("          %02d:%02d:%02d",time.GetHour(),time.GetMinute(),time.GetSecond());

	host.Format("[系统消息] %s%s",pHost->h_name,currentTime);
	msg.Format("\r\n  %s\r\n",buf);

	cf.yHeight = 13*13;//文字高度
	cf.crTextColor = RGB(0,110,254); //文字颜色
	strcpy(cf.szFaceName ,_T("微软雅黑"));//设置字体
	m_RichEdit1->SetSel(m_RichEdit1->GetTextLength(),m_RichEdit1->GetTextLength());
	m_RichEdit1->ReplaceSel(host);
	m_RichEdit1->SetSel(m_RichEdit1->GetTextLength()-host.GetLength(),m_RichEdit1->GetTextLength());
	m_RichEdit1->SetSelectionCharFormat(cf);
	
	m_RichEdit1->SetSel(-1,-1);
	m_RichEdit1->ReplaceSel(msg);
	cf.yHeight = 14*14;//文字高度
	cf.crTextColor = RGB(204,0,204); //文字颜色
	strcpy(cf.szFaceName ,_T("微软雅黑"));//设置字体
	m_RichEdit1->SetSel(m_RichEdit1->GetTextLength()-msg.GetLength(),m_RichEdit1->GetTextLength());
	m_RichEdit1->SetSelectionCharFormat(cf);
	m_RichEdit1->LineScroll(m_RichEdit1->GetLineCount()-lineCount);
	m_RichEdit1->SetSel(0,0);

	delete[] mybuf;
	buf.Empty();
	CAsyncSocket::OnReceive(nErrorCode);
}
void
TCPSocket::SetConnected()
{
    GetPeerName(cRemoteAddress, iRemotePort);
    bIsConnected = true;
}
Esempio n. 22
0
int CClientSession::DoPutFile( const char* strSrc, const char* strDst, bool bOverwrite )
{
	char buf[MAXPATH+sizeof(CNcpMessage)];
	CNcpMessage* pMsg = (CNcpMessage*)buf;

	if( !IsFileExist( strSrc ) ){
		return E_NOENT;
	}

	//step 1. request passive mode to get the data channel address
	unsigned short dataport = 0;

	int nRet = DoPassive( (short*)&dataport );
	if( FAILED(nRet) )return nRet;

	//step 2. send the put file command.
	pMsg->Init( CM_PUTFILE );
	pMsg->m_nParamRet = bOverwrite;
	strcpy( pMsg->GetData(), strDst );
	pMsg->SetDataSize( strlen(strDst)+1 );

	pMsg->Send( m_sock );

	//wait for the return code and check it
	if( !pMsg->Recv( m_sock, ELEMENTS(buf) ) ){
		return E_BROKEN;		//broken connection
	}

	ASSERT( pMsg->IsAck() );
	if( pMsg->IsFailed() || pMsg->m_nParamRet==S_EXIST ){
		return pMsg->GetRet();
	}

	//step 3. now the server agrees on the file transfer, connect the data channel and send file
	SOCKADDR_IN addr;
	socklen_t nlen = sizeof(SOCKADDR_IN);
	GetPeerName( m_sock, (SOCKADDR*)&addr, &nlen );
	addr.sin_port = htons( dataport );

	SOCKET sockdata;
	//import, must retry the socket initilization a few times. 
	for( int i=0; i<MAXRETRY; i++ ){
		sockdata = Socket( PF_INET, SOCK_STREAM, 0 );
		ASSERT( sockdata!=INVALID_SOCKET );

		if( ::connect( sockdata, (SOCKADDR*)&addr, sizeof(SOCKADDR_IN) )==0 )break;
		closesocket( sockdata );
	}
	if( i>=MAXRETRY )throw new CSockException();

/*	for( int i=0; i<5; i++ ){
		sockdata = Socket( PF_INET, SOCK_STREAM, 0 );
		ASSERT( sockdata!=INVALID_SOCKET );

		struct hostent * phent = gethostbyaddr( (char*)&addr.sin_addr, sizeof(IN_ADDR), AF_INET );
		cdump<<lock<<(int)sockdata<<" connecting data channel at "<<phent->h_name<<"("<<addr.sin_addr.S_un.S_addr<<","<<dataport<<"), "<<endl<<unlock;
		if( ::connect( sockdata, (SOCKADDR*)&addr, sizeof(SOCKADDR_IN) )==0 ){
			break;
		}

		cdump<<lock<<phent->h_name<<" connect failed "<<i<<"\t error:"<<WSAGetLastError()<<endl<<unlock;
		closesocket( sockdata );
	}

	if( i<5 ){
		cdump<<lock<<"connected!"<<endl<<unlock;
	}else{
		throw new CSockException();
	}*/

/*	SOCKET sockdata;
	sockdata = Socket( PF_INET, SOCK_STREAM, 0 );
	ASSERT( sockdata!=INVALID_SOCKET );

	for( int i=0; i<5; i++ ){
		struct hostent * phent = gethostbyaddr( (char*)&addr.sin_addr, sizeof(IN_ADDR), AF_INET );
		cdump<<lock<<(int)sockdata<<" connecting data channel at "<<phent->h_name<<"("<<addr.sin_addr.S_un.S_addr<<","<<dataport<<"), "<<endl<<unlock;
		int nrt = 0;
		if( (nrt=::connect( sockdata, (SOCKADDR*)&addr, sizeof(SOCKADDR_IN) ))==0 ){
			break;
		}
		cdump<<lock<<phent->h_name<<" connect failed "<<i<<"\t error:"<<nrt<<","<<WSAGetLastError()<<endl<<unlock;

		closesocket( sockdata );
		Sleep( 1000*10*(i+1) );

		sockdata = Socket( PF_INET, SOCK_STREAM, 0 );
		ASSERT( sockdata!=INVALID_SOCKET );
	}
	if( i>=5 ){
		struct hostent * phent = gethostbyaddr( (char*)&addr.sin_addr, sizeof(IN_ADDR), AF_INET );
		cdump<<lock<<"connecting data channel at "<<phent->h_name<<"("<<addr.sin_addr.S_un.S_addr<<","<<dataport<<"), "<<endl<<unlock;
		::Connect( sockdata, (SOCKADDR*)&addr, sizeof(SOCKADDR_IN) );
	}
	cdump<<lock<<"connected!"<<endl<<unlock;*/

//	struct hostent * phent = gethostbyaddr( (char*)&addr.sin_addr, sizeof(IN_ADDR), AF_INET );
//	cdump<<lock<<"connecting data channel at "<<phent->h_name<<"("<<addr.sin_addr.S_un.S_addr<<","<<dataport<<"), "<<unlock;
//	::Connect( sockdata, (SOCKADDR*)&addr, sizeof(SOCKADDR_IN) );
//	cdump<<lock<<"connected!"<<endl<<unlock;

	int nLen = SendFileEx( sockdata, strSrc, m_nFileMode );
	closesocket( sockdata );

	//step 4. exchange the error code.
	pMsg->Init( CM_ACK, nLen );
	pMsg->Send( m_sock );

	//wait for the return code and check it
	if( !pMsg->Recv( m_sock, ELEMENTS(buf) ) ){
		return E_BROKEN;		//broken connection
	}

	ASSERT( pMsg->IsAck() );
	return pMsg->GetRet();
}
CString	CEncryptedStreamSocket::DbgGetIPString(){
	SOCKADDR_IN sockAddr = {0};
	int nSockAddrLen = sizeof(sockAddr);
	GetPeerName((SOCKADDR*)&sockAddr, &nSockAddrLen);
	return ipstr(sockAddr.sin_addr.S_un.S_addr);
}
int CEncryptedStreamSocket::Negotiate(const uchar* pBuffer, uint32_t nLen){
	uint32_t nRead = 0;
	ASSERT( m_nReceiveBytesWanted > 0 );
	try{
		while (m_NegotiatingState != ONS_COMPLETE && m_nReceiveBytesWanted > 0){		
			if (m_nReceiveBytesWanted > 512){
				ASSERT( false );
				return 0;
			}
			
			if (m_pfiReceiveBuffer == NULL){
				BYTE* pReceiveBuffer = (BYTE*)malloc(512); // use a fixed size buffer
				if (pReceiveBuffer == NULL)
					AfxThrowMemoryException();
				m_pfiReceiveBuffer = new CSafeMemFile(pReceiveBuffer, 512);
			}
			const uint32_t nToRead =  min(nLen - nRead, m_nReceiveBytesWanted);
			m_pfiReceiveBuffer->Write(pBuffer + nRead, nToRead);
			nRead += nToRead;
			m_nReceiveBytesWanted -= nToRead;
			if (m_nReceiveBytesWanted > 0)
				return nRead;
			const uint32_t nCurrentBytesLen = (uint32_t)m_pfiReceiveBuffer->GetPosition();

			if (m_NegotiatingState != ONS_BASIC_CLIENTA_RANDOMPART && m_NegotiatingState != ONS_BASIC_SERVER_DHANSWER){ // don't have the keys yet
				BYTE* pCryptBuffer = m_pfiReceiveBuffer->Detach();
				RC4Crypt(pCryptBuffer, pCryptBuffer, nCurrentBytesLen, m_pRC4ReceiveKey);
				m_pfiReceiveBuffer->Attach(pCryptBuffer, 512);
			}
			m_pfiReceiveBuffer->SeekToBegin();

			switch (m_NegotiatingState){
				case ONS_NONE: // would be a bug
					ASSERT( false ); 
					return 0;
				case ONS_BASIC_CLIENTA_RANDOMPART:{
					ASSERT( m_pRC4ReceiveKey == NULL );

					uchar achKeyData[21];
					md4cpy(achKeyData, thePrefs.GetUserHash());
					achKeyData[16] = MAGICVALUE_REQUESTER;
					m_pfiReceiveBuffer->Read(achKeyData + 17, 4); // random key part sent from remote client

					MD5Sum md5(achKeyData, sizeof(achKeyData));
					m_pRC4ReceiveKey = RC4CreateKey(md5.GetRawHash(), 16, NULL);
					achKeyData[16] = MAGICVALUE_SERVER;
					md5.Calculate(achKeyData, sizeof(achKeyData));
					m_pRC4SendKey = RC4CreateKey(md5.GetRawHash(), 16, NULL);
						
					m_NegotiatingState = ONS_BASIC_CLIENTA_MAGICVALUE;
					m_nReceiveBytesWanted = 4;
					break;
				}
				case ONS_BASIC_CLIENTA_MAGICVALUE:{
					uint32_t dwValue = m_pfiReceiveBuffer->ReadUInt32();
					if (dwValue == MAGICVALUE_SYNC){
						// yup, the one or the other way it worked, this is an encrypted stream
						//DEBUG_ONLY( DebugLog(_T("Received proper magic value, clientIP: %s"), DbgGetIPString()) );
						// set the receiver key
						m_NegotiatingState = ONS_BASIC_CLIENTA_METHODTAGSPADLEN;
						m_nReceiveBytesWanted = 3;	
					}
					else{
						DebugLogError(_T("CEncryptedStreamSocket: Received wrong magic value from clientIP %s on a supposly encrytped stream / Wrong Header"), DbgGetIPString());
						OnError(ERR_ENCRYPTION);
						return (-1);
					}
					break;
			    }
				case ONS_BASIC_CLIENTA_METHODTAGSPADLEN:
					m_dbgbyEncryptionSupported = m_pfiReceiveBuffer->ReadUInt8();
					m_dbgbyEncryptionRequested = m_pfiReceiveBuffer->ReadUInt8();
					if (m_dbgbyEncryptionRequested != ENM_OBFUSCATION)
						AddDebugLogLine(DLP_LOW, false, _T("CEncryptedStreamSocket: Client %s preffered unsupported encryption method (%i)"), DbgGetIPString(), m_dbgbyEncryptionRequested);
					m_nReceiveBytesWanted = m_pfiReceiveBuffer->ReadUInt8();
					m_NegotiatingState = ONS_BASIC_CLIENTA_PADDING;
					//if (m_nReceiveBytesWanted > 16)
					//	AddDebugLogLine(DLP_LOW, false, _T("CEncryptedStreamSocket: Client %s sent more than 16 (%i) padding bytes"), DbgGetIPString(), m_nReceiveBytesWanted);
					if (m_nReceiveBytesWanted > 0)
						break;
				case ONS_BASIC_CLIENTA_PADDING:{
					// ignore the random bytes, send the response, set status complete
					CSafeMemFile fileResponse(26);
					fileResponse.WriteUInt32(MAGICVALUE_SYNC);
					const uint8_t bySelectedEncryptionMethod = ENM_OBFUSCATION; // we do not support any further encryption in this version, so no need to look which the other client preferred
					fileResponse.WriteUInt8(bySelectedEncryptionMethod);
					
					SOCKADDR_IN sockAddr = {0};
					int nSockAddrLen = sizeof(sockAddr);
					GetPeerName((SOCKADDR*)&sockAddr, &nSockAddrLen);	
					const uint8_t byPaddingLen = theApp.serverconnect->AwaitingTestFromIP(sockAddr.sin_addr.S_un.S_addr) ? 16 : (thePrefs.GetCryptTCPPaddingLength() + 1);
					uint8_t byPadding = (uint8_t)(cryptRandomGen.GenerateByte() % byPaddingLen);
					
					fileResponse.WriteUInt8(byPadding);
					for (int i = 0; i < byPadding; i++)
						fileResponse.WriteUInt8(static_cast<uint8_t>(rand() & 0xFF));
					SendNegotiatingData(fileResponse.GetBuffer(), (uint32_t)fileResponse.GetLength());
					m_NegotiatingState = ONS_COMPLETE;
					m_StreamCryptState = ECS_ENCRYPTING;
					//DEBUG_ONLY( DebugLog(_T("CEncryptedStreamSocket: Finished Obufscation handshake with client %s (incoming)"), DbgGetIPString()) );
					break;
				}
				case ONS_BASIC_CLIENTB_MAGICVALUE:{
					if (m_pfiReceiveBuffer->ReadUInt32() != MAGICVALUE_SYNC){
						DebugLogError(_T("CEncryptedStreamSocket: EncryptedstreamSyncError: Client sent wrong Magic Value as answer, cannot complete handshake (%s)"), DbgGetIPString());
						OnError(ERR_ENCRYPTION);
						return (-1);
					}
					m_NegotiatingState = ONS_BASIC_CLIENTB_METHODTAGSPADLEN;
					m_nReceiveBytesWanted = 2;
					break;
				}
				case ONS_BASIC_CLIENTB_METHODTAGSPADLEN:{
					m_dbgbyEncryptionMethodSet = m_pfiReceiveBuffer->ReadUInt8();
					if (m_dbgbyEncryptionMethodSet != ENM_OBFUSCATION){
						DebugLogError( _T("CEncryptedStreamSocket: Client %s set unsupported encryption method (%i), handshake failed"), DbgGetIPString(), m_dbgbyEncryptionMethodSet);
						OnError(ERR_ENCRYPTION);
						return (-1);						
					}
					m_nReceiveBytesWanted = m_pfiReceiveBuffer->ReadUInt8();
					m_NegotiatingState = ONS_BASIC_CLIENTB_PADDING;
					if (m_nReceiveBytesWanted > 0)
						break;
				}
				case ONS_BASIC_CLIENTB_PADDING:
					// ignore the random bytes, the handshake is complete
					m_NegotiatingState = ONS_COMPLETE;
					m_StreamCryptState = ECS_ENCRYPTING;
					//DEBUG_ONLY( DebugLog(_T("CEncryptedStreamSocket: Finished Obufscation handshake with client %s (outgoing)"), DbgGetIPString()) );
					break;
				case ONS_BASIC_SERVER_DHANSWER:{
					ASSERT( !m_cryptDHA.IsZero() );
					uchar aBuffer[PRIMESIZE_BYTES + 1];
					m_pfiReceiveBuffer->Read(aBuffer, PRIMESIZE_BYTES);
					CryptoPP::Integer cryptDHAnswer((byte*)aBuffer, PRIMESIZE_BYTES);
					CryptoPP::Integer cryptDHPrime((byte*)dh768_p, PRIMESIZE_BYTES);  // our fixed prime
					CryptoPP::Integer cryptResult = CryptoPP::a_exp_b_mod_c(cryptDHAnswer, m_cryptDHA, cryptDHPrime);
					
					m_cryptDHA = 0;
					DEBUG_ONLY( ZeroMemory(aBuffer, sizeof(aBuffer)) );
					ASSERT( cryptResult.MinEncodedSize() <= PRIMESIZE_BYTES );
					
					// create the keys
					cryptResult.Encode(aBuffer, PRIMESIZE_BYTES);					
					aBuffer[PRIMESIZE_BYTES] = MAGICVALUE_REQUESTER;
					MD5Sum md5(aBuffer, sizeof(aBuffer));
					m_pRC4SendKey = RC4CreateKey(md5.GetRawHash(), 16, NULL);
					aBuffer[PRIMESIZE_BYTES] = MAGICVALUE_SERVER;
					md5.Calculate(aBuffer, sizeof(aBuffer));
					m_pRC4ReceiveKey = RC4CreateKey(md5.GetRawHash(), 16, NULL);

					m_NegotiatingState = ONS_BASIC_SERVER_MAGICVALUE;
					m_nReceiveBytesWanted = 4;
					break;
				}
				case ONS_BASIC_SERVER_MAGICVALUE:{
					uint32_t dwValue = m_pfiReceiveBuffer->ReadUInt32();
					if (dwValue == MAGICVALUE_SYNC){
						// yup, the one or the other way it worked, this is an encrypted stream
						DebugLog(_T("Received proper magic value after DH-Agreement from Serverconnection IP: %s"), DbgGetIPString());
						// set the receiver key
						m_NegotiatingState = ONS_BASIC_SERVER_METHODTAGSPADLEN;
						m_nReceiveBytesWanted = 3;	
					}
					else{
						DebugLogError(_T("CEncryptedStreamSocket: Received wrong magic value after DH-Agreement from Serverconnection"), DbgGetIPString());
						OnError(ERR_ENCRYPTION);
						return (-1);
					}
					break;
			    }
				case ONS_BASIC_SERVER_METHODTAGSPADLEN:
					m_dbgbyEncryptionSupported = m_pfiReceiveBuffer->ReadUInt8();
					m_dbgbyEncryptionRequested = m_pfiReceiveBuffer->ReadUInt8();
					if (m_dbgbyEncryptionRequested != ENM_OBFUSCATION)
						AddDebugLogLine(DLP_LOW, false, _T("CEncryptedStreamSocket: Server %s preffered unsupported encryption method (%i)"), DbgGetIPString(), m_dbgbyEncryptionRequested);
					m_nReceiveBytesWanted = m_pfiReceiveBuffer->ReadUInt8();
					m_NegotiatingState = ONS_BASIC_SERVER_PADDING;
					if (m_nReceiveBytesWanted > 16)
						AddDebugLogLine(DLP_LOW, false, _T("CEncryptedStreamSocket: Server %s sent more than 16 (%i) padding bytes"), DbgGetIPString(), m_nReceiveBytesWanted);
					if (m_nReceiveBytesWanted > 0)
						break;
				case ONS_BASIC_SERVER_PADDING:{
					// ignore the random bytes (they are decrypted already), send the response, set status complete
					CSafeMemFile fileResponse(26);
					fileResponse.WriteUInt32(MAGICVALUE_SYNC);
					const uint8_t bySelectedEncryptionMethod = ENM_OBFUSCATION; // we do not support any further encryption in this version, so no need to look which the other client preferred
					fileResponse.WriteUInt8(bySelectedEncryptionMethod);
					uint8_t byPadding = (uint8_t)(cryptRandomGen.GenerateByte() % 16);
					fileResponse.WriteUInt8(byPadding);
					for (int i = 0; i < byPadding; i++)
						fileResponse.WriteUInt8(static_cast<uint8_t>(rand() & 0xFF));
					
					m_NegotiatingState = ONS_BASIC_SERVER_DELAYEDSENDING;
					SendNegotiatingData(fileResponse.GetBuffer(), (uint32_t)fileResponse.GetLength(), 0, true); // don't actually send it right now, store it in our sendbuffer
					m_StreamCryptState = ECS_ENCRYPTING;
					DEBUG_ONLY( DebugLog(_T("CEncryptedStreamSocket: Finished DH Obufscation handshake with Server %s"), DbgGetIPString()) );
					break;
				}
				default:
					ASSERT( false );
			}
			m_pfiReceiveBuffer->SeekToBegin();
		}
		if (m_pfiReceiveBuffer != NULL)
			free(m_pfiReceiveBuffer->Detach());
		delete m_pfiReceiveBuffer;
		m_pfiReceiveBuffer = NULL;
		return nRead;
	}
	catch(CFileException* error){
		// can only be caused by a bug in negationhandling, not by the datastream
		error->Delete();
		ASSERT( false );
		OnError(ERR_ENCRYPTION);
		if (m_pfiReceiveBuffer != NULL)
			free(m_pfiReceiveBuffer->Detach());
		delete m_pfiReceiveBuffer;
		m_pfiReceiveBuffer = NULL;
		return (-1);
	}

}
int CEncryptedStreamSocket::Receive(void* lpBuf, int nBufLen, int nFlags){
	m_nObfuscationBytesReceived = CAsyncSocketEx::Receive(lpBuf, nBufLen, nFlags);
	m_bFullReceive = m_nObfuscationBytesReceived == (uint32_t)nBufLen;

	if(m_nObfuscationBytesReceived == SOCKET_ERROR || m_nObfuscationBytesReceived <= 0){
		return m_nObfuscationBytesReceived;
	}
	switch (m_StreamCryptState) {
		case ECS_NONE: // disabled, just pass it through
			return m_nObfuscationBytesReceived;
		case ECS_PENDING:
		case ECS_PENDING_SERVER:
			ASSERT( false );
			DebugLogError(_T("CEncryptedStreamSocket Received data before sending on outgoing connection"));
			m_StreamCryptState = ECS_NONE;
			return m_nObfuscationBytesReceived;
		case ECS_UNKNOWN:{
			uint32_t nRead = 1;
			bool bNormalHeader = false;
			switch (((uchar*)lpBuf)[0]){
				case OP_EDONKEYPROT:
				case OP_PACKEDPROT:
				case OP_EMULEPROT:
					bNormalHeader = true;
					break;
			}
			if (!bNormalHeader){
				StartNegotiation(false);
				const uint32_t nNegRes = Negotiate((uchar*)lpBuf + nRead, m_nObfuscationBytesReceived - nRead);
				if (nNegRes == (-1))
					return 0;
				nRead += nNegRes;
				if (nRead != (uint32_t)m_nObfuscationBytesReceived){
					// this means we have more data then the current negotiation step required (or there is a bug) and this should never happen
					// (note: even if it just finished the handshake here, there still can be no data left, since the other client didnt received our response yet)
					DebugLogError(_T("CEncryptedStreamSocket: Client %s sent more data then expected while negotiating, disconnecting (1)"), DbgGetIPString());
					OnError(ERR_ENCRYPTION);
				}
				return 0;
			}
			else{
				// doesn't seems to be encrypted
				m_StreamCryptState = ECS_NONE;

				// if we require an encrypted connection, cut the connection here. This shouldn't happen that often
				// at least with other up-to-date eMule clients because they check for incompability before connecting if possible
				if (thePrefs.IsClientCryptLayerRequired()){
					// TODO: Remove me when i have been solved
					// Even if the Require option is enabled, we currently have to accept unencrypted connection which are made
					// for lowid/firewall checks from servers and other from us selected client. Otherwise, this option would
					// always result in a lowid/firewalled status. This is of course not nice, but we can't avoid this walkarround
					// untill servers and kad completely support encryption too, which will at least for kad take a bit
					// only exception is the .ini option ClientCryptLayerRequiredStrict which will even ignore test connections
					// Update: New server now support encrypted callbacks

					SOCKADDR_IN sockAddr = {0};
					int nSockAddrLen = sizeof(sockAddr);
					GetPeerName((SOCKADDR*)&sockAddr, &nSockAddrLen);		
					if (thePrefs.IsClientCryptLayerRequiredStrict() || (!theApp.serverconnect->AwaitingTestFromIP(sockAddr.sin_addr.S_un.S_addr)
						&& !theApp.clientlist->IsKadFirewallCheckIP(sockAddr.sin_addr.S_un.S_addr)) )
					{
#if defined(_DEBUG) || defined(_BETA)
					// TODO: Remove after testing
					AddDebugLogLine(DLP_DEFAULT, false, _T("Rejected incoming connection because Obfuscation was required but not used %s"), DbgGetIPString() );
#endif
						OnError(ERR_ENCRYPTION_NOTALLOWED);
						return 0;
					}
					else
						AddDebugLogLine(DLP_DEFAULT, false, _T("Incoming unencrypted firewallcheck connection permitted despite RequireEncryption setting  - %s"), DbgGetIPString() );
				}

				return m_nObfuscationBytesReceived; // buffer was unchanged, we can just pass it through
			}
		}
		case ECS_ENCRYPTING:
			// basic obfuscation enabled and set, so decrypt and pass along
			RC4Crypt((uchar*)lpBuf, (uchar*)lpBuf, m_nObfuscationBytesReceived, m_pRC4ReceiveKey);
			return m_nObfuscationBytesReceived;
		case ECS_NEGOTIATING:{
			const uint32_t nRead = Negotiate((uchar*)lpBuf, m_nObfuscationBytesReceived);
			if (nRead == (-1))
				return 0;
			else if (nRead != (uint32_t)m_nObfuscationBytesReceived && m_StreamCryptState != ECS_ENCRYPTING){
				// this means we have more data then the current negotiation step required (or there is a bug) and this should never happen
				DebugLogError(_T("CEncryptedStreamSocket: Client %s sent more data then expected while negotiating, disconnecting (2)"), DbgGetIPString());
				OnError(ERR_ENCRYPTION);
				return 0;
			}
			else if (nRead != (uint32_t)m_nObfuscationBytesReceived && m_StreamCryptState == ECS_ENCRYPTING){
				// we finished the handshake and if we this was an outgoing connection it is allowed (but strange and unlikely) that the client sent payload
				DebugLogWarning(_T("CEncryptedStreamSocket: Client %s has finished the handshake but also sent payload on a outgoing connection"), DbgGetIPString());
				memmove(lpBuf, (uchar*)lpBuf + nRead, m_nObfuscationBytesReceived - nRead);
				return m_nObfuscationBytesReceived - nRead;
			}
			else
				return 0;
		}
		default:
			ASSERT( false );
			return m_nObfuscationBytesReceived;
	}
}
Esempio n. 26
0
BOOL CAdminSocket::Init()
{
	char *buffer=new char[100];
	char *p=buffer;
	strcpy(buffer, "FZS");
	p+=3;

	*p++=0;
	*p++=4;
	memcpy(p, &SERVER_VERSION, 4);
	p+=4;
	
	*p++=0;
	*p++=4;

	memcpy(p, &PROTOCOL_VERSION, 4);
	p+=4;

	SOCKADDR_IN sockAddr;
	memset(&sockAddr, 0, sizeof(sockAddr));

	int nSockAddrLen = sizeof(sockAddr);
	
	if (GetPeerName((SOCKADDR*)&sockAddr, &nSockAddrLen) && sockAddr.sin_addr.S_un.S_addr == 0x0100007f)
	{
		BOOL res=Send(buffer, p-buffer) == p-buffer;
		delete [] buffer;
		if (!res)
		{
			Close();
			return FALSE;
		}
		return FinishLogon();		
	}
	else
	{
		*p++=0;
		
		DWORD len = 20;
		memcpy(p, &len, 4);
		p+=4;

		*p++=0;
		*p++=8;
		
		int i;
		for (i=0;i<8; i++)
		{
			m_Nonce1[i]=(rand()*256)/(RAND_MAX+1);
			*p++=m_Nonce1[i];
		}
		
		*p++=0;
		*p++=8;
		
		for (i=0;i<8; i++)
		{
			m_Nonce2[i]=(rand()*256)/(RAND_MAX+1);
			*p++=m_Nonce2[i];
		}
	}

	int res=Send(buffer, p-buffer) == p-buffer;
	delete [] buffer;
	return res;
}
Esempio n. 27
0
/*
========================
idLobby::SendCompletedPendingSnap
========================
*/
void idLobby::SendCompletedPendingSnap( int p )
{

	assert( lobbyType == GetActingGameStateLobbyType() );
	
	int time = Sys_Milliseconds();
	
	peer_t& peer = peers[p];
	
	if( !peer.IsConnected() )
	{
		return;
	}
	
	if( peer.snapProc == NULL || !peer.snapProc->PendingSnapReadyToSend() )
	{
		return;
	}
	
	// If we have a pending snap ready to send, we better have a pending snap
	assert( peer.snapProc->HasPendingSnap() );
	
	// Get the snap data blob now, even if we don't send it.
	// This is somewhat wasteful, but we have to do this to keep the snap job pipe ready to keep doing work
	// If we don't do this, this peer will cause other peers to be starved of snapshots, when they may very well be ready to send a snap
	byte buffer[ MAX_SNAP_SIZE ];
	int maxLength = sizeof( buffer ) - peer.packetProc->GetReliableDataSize() - 128;
	
	int size = peer.snapProc->GetPendingSnapDelta( buffer, maxLength );
	
	if( !CanSendMoreData( p ) )
	{
		return;
	}
	
	// Can't send anymore snapshots until all fragments are sent
	if( peer.packetProc->HasMoreFragments() )
	{
		return;
	}
	
	// If the peer doesn't have the latest resource list, send it to him before sending any new snapshots
	if( SendResources( p ) )
	{
		return;
	}
	
	int timeFromJobSub = time - peer.lastSnapJobTime;
	int timeFromLastSend = time - peer.lastSnapTime;
	
	if( timeFromLastSend > 0 )
	{
		peer.snapHz = 1000.0f / ( float )timeFromLastSend;
	}
	else
	{
		peer.snapHz = 0.0f;
	}
	
	if( net_snapshot_send_warntime.GetInteger() > 0 && peer.lastSnapTime != 0 && net_snapshot_send_warntime.GetInteger() < timeFromLastSend )
	{
		idLib::Printf( "NET: Took %d ms to send peer %d snapshot\n", timeFromLastSend, p );
	}
	
	if( peer.throttleSnapsForXSeconds != 0 )
	{
		if( time < peer.throttleSnapsForXSeconds )
		{
			return;
		}
		
		// If we were trying to recover ping, see if we succeeded
		if( peer.recoverPing != 0 )
		{
			if( peer.lastPingRtt >= peer.recoverPing )
			{
				peer.failedPingRecoveries++;
			}
			else
			{
				const int peer_throttle_minSnapSeq = session->GetTitleStorageInt( "net_peer_throttle_minSnapSeq", net_peer_throttle_minSnapSeq.GetInteger() );
				if( peer.snapProc->GetFullSnapBaseSequence() > idSnapshotProcessor::INITIAL_SNAP_SEQUENCE + peer_throttle_minSnapSeq )
				{
					// If throttling recovered the ping
					int maxRate = common->GetSnapRate() * session->GetTitleStorageInt( "net_peer_throttle_maxSnapRate", net_peer_throttle_maxSnapRate.GetInteger() );
					peer.throttledSnapRate = idMath::ClampInt( common->GetSnapRate(), maxRate, peer.throttledSnapRate + common->GetSnapRate() );
				}
			}
		}
		
		peer.throttleSnapsForXSeconds = 0;
	}
	
	peer.lastSnapTime = time;
	
	if( size != 0 )
	{
		if( size > 0 )
		{
			NET_VERBOSESNAPSHOT_PRINT_LEVEL( 3, va( "NET: (peer %d) Sending snapshot %d delta'd against %d. Since JobSub: %d Since LastSend: %d. Size: %d\n", p, peer.snapProc->GetSnapSequence(), peer.snapProc->GetBaseSequence(), timeFromJobSub, timeFromLastSend, size ) );
			ProcessOutgoingMsg( p, buffer, size, false, 0 );
		}
		else if( size < 0 )  	// Size < 0 indicates the delta buffer filled up
		{
			// There used to be code here that would disconnect peers if they were in game and filled up the buffer
			// This was causing issues in the playtests we were running (Doom 4 MP) and after some conversation
			// determined that it was not needed since a timeout mechanism has been added since
			ProcessOutgoingMsg( p, buffer, -size, false, 0 );
			if( peer.snapProc != NULL )
			{
				NET_VERBOSESNAPSHOT_PRINT( "NET: (peerNum: %d - name: %s) Resending last snapshot delta %d because his delta list filled up. Since JobSub: %d Since LastSend: %d Delta Size: %d\n", p, GetPeerName( p ), peer.snapProc->GetSnapSequence(), timeFromJobSub, timeFromLastSend, size );
			}
		}
	}
	
	// We calculate what our outgoing rate was for each sequence, so we can have a relative comparison
	// for when the client reports what his downstream was in the same timeframe
	if( IsHost() && peer.snapProc != NULL && peer.snapProc->GetSnapSequence() > 0 )
	{
		//NET_VERBOSE_PRINT("^8  %i Rate: %.2f   SnapSeq: %d GetBaseSequence: %d\n", lastAppendedSequence, peer.packetProc->GetOutgoingRateBytes(), peer.snapProc->GetSnapSequence(), peer.snapProc->GetBaseSequence() );
		peer.sentBpsHistory[ peer.snapProc->GetSnapSequence() % MAX_BPS_HISTORY ] = peer.packetProc->GetOutgoingRateBytes();
	}
}
Esempio n. 28
0
/////////////////////////////////////////////////////////////////////////////
// CServerSocket member functions
void CServerSocket::OnReceive(int nErrorCode)
{
	CString host,ip;UINT port;
	CString buf,text;
	CString _fileName;
	Receive(buf.GetBuffer(2056),2056);
	buf.ReleaseBuffer();
	GetPeerName(ip,port);


	if(buf.Find("<?Response FILETRANSFER?>:ACCEPT")>-1)
	{
		//AfxMessageBox("对方同意接收");
		file.Open(filePath,CFile::modeRead|CFile::typeBinary,NULL);
		remainder=file.GetLength();
		CString csRemainder;
		csRemainder.Format("%u",remainder);
		if (!fileTran)
		{
			CSendFileDlg *sfDlg=new CSendFileDlg(SOCKETTYPESERVER,this);
			sfDlg->Create(IDD_SENDFILE_DIALOG,CWnd::FromHandle(::GetDesktopWindow()));
			fileTran=sfDlg;
			fileTran->ShowWindow(SW_SHOW);
		}
		fileTran->SetDlgItemText(IDC_STATIC_SRCA,localIp);
		fileTran->SetDlgItemText(IDC_STATIC_DESA,thePeerIp);
		fileTran->SetDlgItemText(IDC_STATIC_FINFO,fileName+"\n大小: "+csRemainder+" 字节");
		CProgressCtrl *proSF=(CProgressCtrl*)fileTran->GetDlgItem(IDC_PROGRESS_TRANFILE);
		proSF->SetRange32(0,remainder);
		proSF->SetPos(0);


		TransferFile(filePath);
		return;
	}
	else if (buf.Find("<?Response FILETRANSFER?>:REFUSE")>-1)
	{
		AfxMessageBox("对方不同意接收该文件.",MB_ICONWARNING);
		return;
	}
	else if (buf.Find("<?FileContinue?>")>-1)
	{
		if (remainder<=0)
		{
			if (tag==0)
			{
				return;
			}
			tag=0;
			Send("<?FileStop?>",256);
			file.Close();
			AfxMessageBox("发送已完成.",MB_ICONINFORMATION);
			tag=1;
		}
		else
		{
			TransferFile(filePath);
		}
		return;
	}
	else{}


	CRichEditCtrl *m_RichEdit1;
	pcwnd=AfxGetApp()->GetMainWnd();
	m_RichEdit1=(CRichEditCtrl*)pcwnd->GetDlgItem(IDC_RICHEDIT_CONTENT);
	SOCKADDR_IN addrFrom;
	int len=sizeof(SOCKADDR);
	CString msg;
	HOSTENT *pHost;
	DWORD lineCount=m_RichEdit1->GetLineCount();

	CHARFORMAT cf;
	ZeroMemory(&cf, sizeof(CHARFORMAT));
	cf.cbSize = sizeof(CHARFORMAT);
	cf.dwMask = CFM_BOLD | CFM_COLOR | CFM_FACE |
		CFM_ITALIC | CFM_SIZE | CFM_UNDERLINE;
	cf.dwEffects = 0;
	cf.yHeight = 15*15;//文字高度
	cf.crTextColor = RGB(255, 0, 0); //文字颜色
	strcpy(cf.szFaceName ,_T("宋体"));//设置字体
	m_RichEdit1->SetDefaultCharFormat(cf);
	m_RichEdit1->SetBackgroundColor(FALSE,RGB(255,255,255));
	
	//ReceiveFrom(buf.GetBuffer(2056),2056,(SOCKADDR*)&addrFrom,&len);

	DWORD peerIP=inet_addr(ip.GetBuffer(0));  
	pHost=gethostbyaddr((LPSTR)&peerIP,4,AF_INET); 

	int pos=buf.GetLength();
	buf=buf.Right(pos-13);

	CTime time=CTime::GetCurrentTime();
	CString currentTime;
	currentTime.Format("          %02d:%02d:%02d",time.GetHour(),time.GetMinute(),time.GetSecond());
	
	host.Format("%s%s",pHost->h_name,currentTime);
	msg.Format("  \r\n  %s\r\n",buf);

	cf.yHeight = 13*13;//文字高度
	cf.crTextColor = RGB(0,110,254); //文字颜色
	strcpy(cf.szFaceName ,_T("微软雅黑"));//设置字体
	m_RichEdit1->SetSel(m_RichEdit1->GetTextLength(),m_RichEdit1->GetTextLength());
	m_RichEdit1->ReplaceSel(host);
	m_RichEdit1->SetSel(m_RichEdit1->GetTextLength()-host.GetLength(),m_RichEdit1->GetTextLength());
	m_RichEdit1->SetSelectionCharFormat(cf);
	
	m_RichEdit1->SetSel(-1,-1);
	m_RichEdit1->ReplaceSel(msg);
	cf.yHeight = 14*14;//文字高度
	cf.crTextColor = RGB(204,0,204); //文字颜色
	strcpy(cf.szFaceName ,_T("微软雅黑"));//设置字体
	m_RichEdit1->SetSel(m_RichEdit1->GetTextLength()-msg.GetLength(),m_RichEdit1->GetTextLength());
	m_RichEdit1->SetSelectionCharFormat(cf);
	m_RichEdit1->LineScroll(m_RichEdit1->GetLineCount()-lineCount);
	m_RichEdit1->SetSel(0,0);

	CAsyncSocket::OnReceive(nErrorCode);
}