void Client::Logic() { clock_t time = clock(); clock_t actime = time; SOCKET bsock; SocketBase bcomm; sockaddr_in &bsin = bcomm.Connect( PORT_BROADCAST ); bsock = bcomm.CreateSocket(); bcomm.Bind(); bcomm.SetBroadcast( true ); int keysize = int( key.size() + 1 ); int portsize = sizeof port; char *message = new char[ keysize + portsize ]; //memcpy( message, this.key.c_str(), keysize ); //memcpy( message + keysize, &this.port, portsize ); while ( running ) { LONGLONG flowend = Clock() - flowstart; if ( flowend > 1000000LL ) { flowstart = Clock(); currentdatasent = 0; float l = GetRTT(); if ( l < 0.0001f ) BandWidth += 512; else if ( l > 0.001f ) BandWidth -= 512; } if ( !ServerFound ) { FindServer( bsock, message, portsize, keysize ); } SendPackets(); ReceivePackets(); HandlePackets(); UpdateRTT(); Sleep( 10 ); } }
/*----------------------------------------------------------------------------- -----------------------------------------------------------------------------*/ void CWinInetEvents::OnInternetStatusCallback(HINTERNET hInternet, DWORD_PTR dwContext, DWORD dwInternetStatus, LPVOID lpvStatusInformation, DWORD dwStatusInformationLength) { if( active ) { // locate the request EnterCriticalSection(&cs); CWinInetRequest * r = NULL; winInetRequests.Lookup(hInternet, r); LeaveCriticalSection(&cs); if( r ) { switch(dwInternetStatus) { case INTERNET_STATUS_RESOLVING_NAME: { EnterCriticalSection(&cs); r->valid = true; r->fromNet = true; if( lpvStatusInformation ) r->hostName = (LPCSTR)lpvStatusInformation; if( !r->dnsStart ) QueryPerformanceCounter((LARGE_INTEGER*)&(r->dnsStart)); if( !r->start ) { r->start = r->dnsStart; r->docID = currentDoc; } LeaveCriticalSection(&cs); ATLTRACE(_T("[Pagetest] - (0x%08X) *** 0x%p - INTERNET_STATUS_RESOLVING_NAME : %s\n"), GetCurrentThreadId(), r->hRequest, (LPCTSTR)r->hostName); } break; case INTERNET_STATUS_NAME_RESOLVED: { ATLTRACE(_T("[Pagetest] - (0x%08X) *** 0x%p - INTERNET_STATUS_NAME_RESOLVED\n"), GetCurrentThreadId(), r->hRequest); __int64 now; QueryPerformanceCounter((LARGE_INTEGER*)&now); EnterCriticalSection(&cs); if( r->dnsStart ) { r->dnsEnd = now; r->tmDNS = now <= r->dnsStart ? 0 : (DWORD)((now - r->dnsStart) / msFreq); } LeaveCriticalSection(&cs); } break; case INTERNET_STATUS_CONNECTING_TO_SERVER: { EnterCriticalSection(&cs); r->valid = true; r->fromNet = true; if( !r->socketConnect ) QueryPerformanceCounter((LARGE_INTEGER*)&(r->socketConnect)); if( !r->start ) { r->start = r->socketConnect; r->docID = currentDoc; } // keep track of the current connect on this thread winInetThreadConnects.SetAt(GetCurrentThreadId(), r); LeaveCriticalSection(&cs); ATLTRACE(_T("[Pagetest] - (0x%08X) *** 0x%p - INTERNET_STATUS_CONNECTING_TO_SERVER\n"), GetCurrentThreadId(), r->hRequest); } break; case INTERNET_STATUS_CONNECTED_TO_SERVER: { __int64 now; QueryPerformanceCounter((LARGE_INTEGER*)&now); EnterCriticalSection(&cs); if( r->socketConnect ) { r->socketConnected = now; r->tmSocket = now <= r->socketConnect ? 0 : (DWORD)((now - r->socketConnect) / msFreq); UpdateRTT(r->peer.sin_addr.S_un.S_addr, r->tmSocket); } // remove the pending connect for this thread (no big deal if they don't all get removed in case of failure) winInetThreadConnects.RemoveKey(GetCurrentThreadId()); LeaveCriticalSection(&cs); ATLTRACE(_T("[Pagetest] - (0x%08X) *** 0x%p - INTERNET_STATUS_CONNECTED_TO_SERVER\n"), GetCurrentThreadId(), r->hRequest); } break; case INTERNET_STATUS_SENDING_REQUEST: { r->valid = true; r->fromNet = true; OverrideHost(r); if( !r->requestSent ) QueryPerformanceCounter((LARGE_INTEGER*)&(r->requestSent)); // see if this is the base page that is being requested if( !haveBasePage ) { r->basePage = true; haveBasePage = true; } if( !r->start ) { r->start = r->requestSent; r->docID = currentDoc; } // check if the request is secure DWORD flags = 0; DWORD len = sizeof(flags); if( InternetQueryOption(r->hRequest, INTERNET_OPTION_SECURITY_FLAGS, &flags, &len) ) if( flags & SECURITY_FLAG_SECURE ) r->secure = true; if( r->tmSSL == -1 && r->secure && r->socketConnected ) r->tmSSL = r->requestSent <= r->socketConnected ? 0 : (DWORD)((r->requestSent - r->socketConnected) / msFreq); // get the request headers TCHAR buff[10000]; len = sizeof(buff); DWORD index = 0; memset(buff, 0, len); if( r->outHeaders.IsEmpty() ) if( HttpQueryInfo(r->hRequest, HTTP_QUERY_FLAG_REQUEST_HEADERS | HTTP_QUERY_RAW_HEADERS_CRLF , buff, &len, &index) ) r->outHeaders = buff; // get some specific headers we care about if( !r->host.GetLength() ) { len = sizeof(buff); index = 0; memset(buff, 0, len); if( HttpQueryInfo(r->hRequest, HTTP_QUERY_FLAG_REQUEST_HEADERS | HTTP_QUERY_HOST , buff, &len, &index) ) r->host = buff; } ATLTRACE(_T("[Pagetest] - *** (%d) 0x%p - INTERNET_STATUS_SENDING_REQUEST, socket %d\n"), GetCurrentThreadId(), r->hRequest, r->socketId); } break; case INTERNET_STATUS_REQUEST_SENT: { ATLTRACE(_T("[Pagetest] - *** (%d) 0x%p - INTERNET_STATUS_REQUEST_SENT : %d bytes\n"), GetCurrentThreadId(), r->hRequest, r->out); EnterCriticalSection(&cs); if( dwStatusInformationLength == sizeof(DWORD) && lpvStatusInformation ) r->out += *((LPDWORD)lpvStatusInformation); EnterCriticalSection(&cs); CSocketRequest * s = NULL; winInetThreadSends.Lookup(GetCurrentThreadId(), s); if( s ) { r->linkedRequest = s; s->linkedRequest = r; // copy over the IP information r->peer.sin_addr.S_un.S_un_b.s_b1 = s->ipAddress[0]; r->peer.sin_addr.S_un.S_un_b.s_b2 = s->ipAddress[1]; r->peer.sin_addr.S_un.S_un_b.s_b3 = s->ipAddress[2]; r->peer.sin_addr.S_un.S_un_b.s_b4 = s->ipAddress[3]; r->peer.sin_port = s->port; r->socketId = s->socketId; // zero out the bytes-in s->in = 0; r->in = 0; ATLTRACE(_T("[Pagetest] INTERNET_STATUS_REQUEST_SENT - linked socket request to wininet request for %s%s\n"), (LPCTSTR)r->host, (LPCTSTR)r->object); } else { ATLTRACE(_T("[Pagetest] INTERNET_STATUS_REQUEST_SENT - Failed to link socket request to wininet request on thread %d\n"), GetCurrentThreadId()); } LeaveCriticalSection(&cs); // clean up the mapping of the request that was sending on this thread winInetThreadSends.RemoveKey(GetCurrentThreadId()); LeaveCriticalSection(&cs); } break; case INTERNET_STATUS_RECEIVING_RESPONSE: { ATLTRACE(_T("[Pagetest] - *** (%d) 0x%p - INTERNET_STATUS_RECEIVING_RESPONSE\n"), GetCurrentThreadId(), r->hRequest); } break; case INTERNET_STATUS_REDIRECT: { CString url = CA2T((LPCSTR)lpvStatusInformation); ATLTRACE(_T("[Pagetest] - *** (%d) 0x%p - INTERNET_STATUS_REDIRECT : Redirecting to %s\n"), GetCurrentThreadId(), r->hRequest, (LPCTSTR)url); // get the headers, close out the request and start a new one for the redirect r->Done(); // update the end time if( !r->ignore ) { lastRequest = r->end; lastActivity = r->end; } // update the in and out bytes from the raw socket if( r->linkedRequest ) { r->in = ((CSocketRequest *)r->linkedRequest)->in; r->out = ((CSocketRequest *)r->linkedRequest)->out; } // get the response code and headers TCHAR buff[10000]; DWORD len = sizeof(buff); DWORD index = 0; memset(buff, 0, len); if( r->inHeaders.IsEmpty() ) if( HttpQueryInfo(r->hRequest, HTTP_QUERY_RAW_HEADERS_CRLF , buff, &len, &index) ) r->inHeaders = buff; // get the redirect code DWORD code; len = sizeof(code); index = 0; if( HttpQueryInfo(r->hRequest, HTTP_QUERY_FLAG_NUMBER | HTTP_QUERY_STATUS_CODE , &code, &len, &index) ) r->result = code; // remove it from the lookup OnInternetCloseHandle(r->hRequest); // see if we need to block the new request bool block = false; POSITION pos = blockRequests.GetHeadPosition(); while (pos && !block) { CString blockRequest = blockRequests.GetNext(pos); blockRequest.Trim(); if (blockRequest.GetLength() && url.Find(blockRequest) != -1) { block = true; blockedRequests.AddTail(url); } } if (block) { InternetCloseHandle(r->hRequest); } else { // create a new request CWinInetRequest * req = new CWinInetRequest(currentDoc); // if this is for the base page, move it to the redirected request if( r->basePage ) { basePageRedirects++; r->basePage = false; req->basePage = true; } req->verb = r->verb; req->hRequest = r->hRequest; // split up the url URL_COMPONENTS parts; memset(&parts, 0, sizeof(parts)); TCHAR scheme[10000]; TCHAR host[10000]; TCHAR object[10000]; TCHAR extra[10000]; memset(scheme, 0, sizeof(scheme)); memset(host, 0, sizeof(host)); memset(object, 0, sizeof(object)); memset(extra, 0, sizeof(extra)); parts.lpszScheme = scheme; parts.dwSchemeLength = _countof(scheme); parts.lpszHostName = host; parts.dwHostNameLength = _countof(host); parts.lpszUrlPath = object; parts.dwUrlPathLength = _countof(object); parts.lpszExtraInfo = extra; parts.dwExtraInfoLength = _countof(extra); parts.dwStructSize = sizeof(parts); if( InternetCrackUrl((LPCTSTR)url, url.GetLength(), 0, &parts) ) { req->host = host; req->object = CString(object) + extra; req->scheme = scheme; if (!req->scheme.Left(5).CompareNoCase(_T("https"))) req->secure = true; } EnterCriticalSection(&cs); winInetRequests.SetAt(req->hRequest, req); winInetRequestList.AddHead(req); OverrideHost(req); LeaveCriticalSection(&cs); AddEvent(req); } } break; case INTERNET_STATUS_RESPONSE_RECEIVED: { if( dwStatusInformationLength == sizeof(DWORD) && lpvStatusInformation ) r->in += *((LPDWORD)lpvStatusInformation); r->Done(true); // update the end time if( !r->ignore ) { lastRequest = r->end; lastActivity = r->end; } // update the in and out bytes from the raw socket if( r->linkedRequest ) { r->in = ((CSocketRequest *)r->linkedRequest)->in; r->out = ((CSocketRequest *)r->linkedRequest)->out; } ATLTRACE(_T("[Pagetest] - *** (0x%08X) 0x%p - INTERNET_STATUS_RESPONSE_RECEIVED : %d bytes\n"), GetCurrentThreadId(), r->hRequest, r->in); } break; case INTERNET_STATUS_REQUEST_COMPLETE: { ATLTRACE(_T("[Pagetest] - *** (0x%08X) 0x%p - INTERNET_STATUS_REQUEST_COMPLETE\n"), GetCurrentThreadId(), r->hRequest); LPINTERNET_ASYNC_RESULT result = (LPINTERNET_ASYNC_RESULT)lpvStatusInformation; if( (!r->result || (r->result == -1))&& result && !result->dwResult) { ATLTRACE(_T("[Pagetest] - *** INTERNET_STATUS_REQUEST_COMPLETE Error - %d\n"), result->dwError); r->result = result->dwError; } // get the response code and headers TCHAR buff[10000]; DWORD len = sizeof(buff); DWORD index = 0; memset(buff, 0, len); if( r->inHeaders.IsEmpty() ) if( HttpQueryInfo(r->hRequest, HTTP_QUERY_RAW_HEADERS_CRLF , buff, &len, &index) ) { CString header = r->inHeaders = buff; // get the result code out of the header ourselves index = header.Find(_T(' ')); if( index >= 0 ) { header = header.Mid(index + 1, 10); long code = _ttol((LPCTSTR)header); if( code > 0 ) r->result = (DWORD)code; } } if( !r->result || r->result == -1 ) { DWORD code; len = sizeof(code); index = 0; if( HttpQueryInfo(r->hRequest, HTTP_QUERY_FLAG_NUMBER | HTTP_QUERY_STATUS_CODE , &code, &len, &index) ) r->result = code; } // see if it was a 304 (from cache) unsigned long reqFlags = 0; len = sizeof(reqFlags); if( InternetQueryOption(r->hRequest, INTERNET_OPTION_REQUEST_FLAGS, &reqFlags, &len) ) if( reqFlags & INTERNET_REQFLAG_FROM_CACHE ) { r->result = 304; // Save away the headers we've received previously, which were the cached // headers reported from wininet. Note that wininet does not cache all // headers, so this is just a partial set of the actual headers associated // with the response. r->cachedInHeaders = r->inHeaders; r->inHeaders = _T("HTTP/1.1 304 Not Modified\nFull response not available\n"); } // update the "done" time r->Done(); // update the end time if( !r->ignore ) { lastRequest = r->end; lastActivity = r->end; } // update the in and out bytes from the raw socket if( r->linkedRequest ) { CSocketRequest * req = (CSocketRequest *)r->linkedRequest; r->in = req->in; r->out = req->out; if( req->response.code && req->response.code != -1 ) r->result = req->response.code; } // make sure that we got an IP address for it EnterCriticalSection(&cs); if( r->s && !r->peer.sin_addr.S_un.S_addr ) { CSocketInfo * soc = NULL; openSockets.Lookup(r->s, soc); if( soc ) memcpy( &r->peer, &soc->address, sizeof(SOCKADDR_IN) ); } LeaveCriticalSection(&cs); } break; } // update the activity time if( !r->ignore ) QueryPerformanceCounter((LARGE_INTEGER *)&lastActivity); } CheckStuff(); } ATLTRACE(_T("[Pagetest] - *** (0x%08X) 0x%p - OnInternetStatusCallback - complete\n"), GetCurrentThreadId(), hInternet); }