/** * @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); }
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(); }
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; }
bool CSocket::GetPeerName(SOCKADDR_IN* lpSockInAddr) { memset(lpSockInAddr, 0, sizeof(SOCKADDR_IN)); socklen_t nSockAddrLen = sizeof(SOCKADDR_IN); return GetPeerName((SOCKADDR*)lpSockInAddr, &nSockAddrLen); }
bool CTcpSocketService::GetPeerData(std::string& Ip, UINT& Port) { bool Success = (GetPeerName(Ip, (int&)Port) != FALSE); if(!Success) DisplaySocketsError("CTcpSocketService::GetPeerName"); return Success; }
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 ); }
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; }
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; }
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; } }
CSocketAddress CGSocket::GetPeerName( ) const { struct sockaddr_in SockAddrIn; int iRet = GetPeerName( &SockAddrIn ); if ( iRet ) { return( CSocketAddress( INADDR_BROADCAST, 0 )); // invalid. } else { return( CSocketAddress( SockAddrIn )); } }
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; } }
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; }
//-------------------------------------------------------------------------------- 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; }
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); }
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); } }
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)); } } }
int MySocket::GetPeerName() // Retrieves the current name for the remote socket descriptor. // Returns -1 if an error occurs. { return GetPeerName(conn_socket, &remote_sin); }
///////////////////////////////////////////////////////////////////////////// // 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; }
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; } }
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; }
/* ======================== 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(); } }
///////////////////////////////////////////////////////////////////////////// // 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); }