void CCheckForUpdatesDlg::FillChangelog(CAutoConfig& versioncheck, bool official) { ProjectProperties pp; pp.lProjectLanguage = -1; if (versioncheck.GetString(_T("tortoisegit.issuesurl"), pp.sUrl)) pp.sUrl = _T("https://tortoisegit.org/issue/%BUGID%"); if (!pp.sUrl.IsEmpty()) { pp.SetCheckRe(_T("[Ii]ssues?:?(\\s*(,|and)?\\s*#?\\d+)+")); pp.SetBugIDRe(_T("(\\d+)")); } m_cLogMessage.Init(pp); CString sChangelogURL; versioncheck.GetString(_T("TortoiseGit.changelogurl"), sChangelogURL); if (sChangelogURL.IsEmpty()) sChangelogURL = _T("https://versioncheck.tortoisegit.org/changelog.txt"); else { CString tmp(sChangelogURL); sChangelogURL.FormatMessage(tmp, TGIT_VERMAJOR, TGIT_VERMINOR, TGIT_VERMICRO, m_updateDownloader->m_sWindowsPlatform, m_updateDownloader->m_sWindowsVersion, m_updateDownloader->m_sWindowsServicePack); } CString tempchangelogfile = CTempFiles::Instance().GetTempFilePath(true).GetWinPathString(); DWORD err; if ((err = m_updateDownloader->DownloadFile(sChangelogURL, tempchangelogfile, false)) != ERROR_SUCCESS) { CString msg = _T("Could not load changelog.\r\nError: ") + GetWinINetError(err) + _T(" (on ") + sChangelogURL + _T(")"); ::SendMessage(m_hWnd, WM_USER_FILLCHANGELOG, 0, reinterpret_cast<LPARAM>((LPCTSTR)msg)); return; } if (official) { CString signatureTempfile = CTempFiles::Instance().GetTempFilePath(true).GetWinPathString(); if ((err = m_updateDownloader->DownloadFile(sChangelogURL + SIGNATURE_FILE_ENDING, signatureTempfile, false)) != ERROR_SUCCESS || VerifyIntegrity(tempchangelogfile, signatureTempfile, m_updateDownloader)) { CString error = _T("Could not verify digital signature."); if (err) error += _T("\r\nError: ") + GetWinINetError(err) + _T(" (on ") + sChangelogURL + SIGNATURE_FILE_ENDING + _T(")"); ::SendMessage(m_hWnd, WM_USER_FILLCHANGELOG, 0, reinterpret_cast<LPARAM>((LPCTSTR)error)); DeleteUrlCacheEntry(sChangelogURL); DeleteUrlCacheEntry(sChangelogURL + SIGNATURE_FILE_ENDING); return; } } CString temp; CStdioFile file; if (file.Open(tempchangelogfile, CFile::modeRead | CFile::typeBinary)) { auto buf = std::make_unique<BYTE[]>((UINT)file.GetLength()); UINT read = file.Read(buf.get(), (UINT)file.GetLength()); bool skipBom = read >= 3 && buf[0] == 0xEF && buf[1] == 0xBB && buf[2] == 0xBF; CGit::StringAppend(&temp, buf.get() + (skipBom ? 3 : 0), CP_UTF8, read - (skipBom ? 3 : 0)); } else temp = _T("Could not open downloaded changelog file."); ::SendMessage(m_hWnd, WM_USER_FILLCHANGELOG, 0, reinterpret_cast<LPARAM>((LPCTSTR)temp)); }
TEST(UpdateCrypto, Binary) { CAutoTempDir tempdir; CString testFile = tempdir.GetTempDir() + L"\\test.bin"; unsigned char binaryFile[99] = // based on link.png { 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A, 0x00, 0x00, 0x00, 0x0D, 0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x01, 0x03, 0x00, 0x00, 0x00, 0xFE, 0xC1, 0x2C, 0xC8, 0x00, 0x00, 0x00, 0x06, 0x50, 0x4C, 0x54, 0x45, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xA5, 0xD9, 0x9F, 0xDD, 0x00, 0x00, 0x00, 0x18, 0x49, 0x44, 0x41, 0x54, 0x78, 0x5E, 0x63, 0xF8, 0xC0, 0xF0, 0x87, 0xE1, 0x17, 0x83, 0x18, 0x43, 0x3E, 0x43, 0x38, 0x43, 0x39, 0x03, 0x3B, 0x00, 0x2C, 0x98, 0x04, 0x41, 0xFA, 0xEC, 0xE7, 0x75, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4E, 0x44, 0xAE, 0x42, 0x60, 0x82, }; CAutoFile file = ::CreateFile(testFile, GENERIC_WRITE, 0, nullptr, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, nullptr); ASSERT_TRUE(file.IsValid()); DWORD written = 0; EXPECT_TRUE(::WriteFile(file, binaryFile, sizeof(binaryFile), &written, nullptr)); EXPECT_EQ(sizeof(binaryFile), written); EXPECT_TRUE(file.CloseHandle()); CString testFileSignature = testFile + _T(".rsa.asc"); EXPECT_TRUE(CStringUtils::WriteStringToTextFile((LPCTSTR)testFileSignature, L"-----BEGIN PGP SIGNATURE-----\nVersion: GnuPG v2\n\niQIcBAABCgAGBQJVxPvgAAoJEPfxez+d2VOerKsP/iQlt4S20LdUknT5udD8fFpT\nEFhZDPTXMRWkd8OhCLxa+t5b/ijyxFKWNz808Q7BDQcQoOQtC19NDvVmAcfqXflt\nR4Z+ugCG/lqP+3y0xBrL9m4UT9fNzQCiUY8Xpaih+6riLGnXVVpUe29BgVZppEWn\nMG9RVXpXwC+M3VQ0yQWu1F2Yy5OjdH4Ww5kpluoseZMOPhT6VaSfXeyQmg2DrBbw\nUfVV+w718noZ5znDH9MiD5y+sd4o7vqN2YFdg6FNvTjHyha39aFV8UCpPX1lH9ME\nN9v1vt5IWGCWL0zsZ6umHqibGG3Q2S3mlqktFhKJGWci+Swy4cNMpXDHIKY6e5v7\nxPIP92djyFtbjdixcSqBaYFC/Dd0KuCa1eYmyi2KxzUP29rZ+EHWoazfbeL1Y2Pu\nkSBrVFv64j0URzSMxUpJMqYXZRC5QW7vdbVwHGAPzoS+0rBBddwfSKteBQjagcHA\nkLk3sAIZNj1JaP5dcGL2K4Wxlaae0WgwI48lZSBMoL8SaInQvcKq9iL64xfpU+FU\nG0mzbidvTfZpyEU3eeSNiFi+6z4XLQ3NUFxsOr5jEPVKvgRoPljhJ4nCx034KQRQ\nHbVF9KYgMJSroKN9bNi/UFkC45Pc4wVov/XyH82XCVS30Du4hsVXsTdAiiXb3i6w\nkrWIJWYRxx76XGtQoHrR\n=PlFQ\n-----END PGP SIGNATURE-----")); EXPECT_EQ(0, VerifyIntegrity(testFile, testFileSignature, nullptr)); // signature is shorter than pubkey; did not work w/o commit 941c103c00e48b0ffe592ab4d87d40ff48f899f6 EXPECT_TRUE(CStringUtils::WriteStringToTextFile((LPCTSTR)testFileSignature, L"-----BEGIN PGP SIGNATURE-----\nVersion: GnuPG v2\n\niQIbBAABCgAGBQJVxQQOAAoJEPfxez+d2VOe7GoP+KflvYJVpNXSwnteXyDc1zTo\nJAyAJFtW6mgqCLrN6KoMrncEvd0cHrD07hT5mxULkbP6zy9fGaFYF0gHO0mOqErF\nIIbDcpPTWooJWUHMbnuQjf2I0x70Cr8ikycZQ7uDg7scZx7E8EIwHOJX60dcfdVX\nK1SQ+c+VIvo1uxL1PndloACaeINz6rL0Pj504lVDJaaGBvzdAV6KEIcjjm+Jb4r0\n6CYEntmt1i3Mc8FM6Xp1QfGtJqp4ogjv6o89hvtaBBLihB54EVQn66/2qIjdhX8W\nkdqJE6+pmFTfuD02XNECwl6stDIZcxXCw6EE87/1hdHip8oW9enIVTxKWB3fUWHl\n236eE2qb8zAN/WWGx/2Cvi6ctyosy9Cc/1hopnmV0KgZFfmDJWw0lISlC/3ZYWEe\nQFiXs5FPzLwfKnkq4REpoOKKfbZNk329J2iLFnwrF0mlL4vUZ1m26BBBk6lhm41J\nnjOSFWhJG/AqBbR5DqdJfXMqnxpfVZfaE5cry2rhjI4mfzw0xzrgvL4M9FZ7R9F8\njVHAV11CMqtp/7gMHXu6ljkTEBBQ7cgbU5DEAwfWddaJF+R30jmNSVliN2JW2FAk\nIbE8yV+uPiyXebn49CmRzkOWOAZqx+DShqriXGam37qjhdys147wPMMiwk8lZKjP\n4V66gTFw45UvBpophyg=\n=0bmW\n-----END PGP SIGNATURE-----")); EXPECT_EQ(0, VerifyIntegrity(testFile, testFileSignature, nullptr)); }
TEST(UpdateCrypto, BinarySignature) { CAutoTempDir tempdir; CString testFile = tempdir.GetTempDir() + L"\\test.txt"; EXPECT_TRUE(CStringUtils::WriteStringToTextFile((LPCTSTR)testFile, L"Text with\r\nNewline")); unsigned char binarySignature[543] = { 0x89, 0x02, 0x1C, 0x04, 0x00, 0x01, 0x0A, 0x00, 0x06, 0x05, 0x02, 0x55, 0xC5, 0x03, 0x29, 0x00, 0x0A, 0x09, 0x10, 0xF7, 0xF1, 0x7B, 0x3F, 0x9D, 0xD9, 0x53, 0x9E, 0x1E, 0xDF, 0x0F, 0xFF, 0x6C, 0xE9, 0x7B, 0xE0, 0xD6, 0x97, 0x1A, 0xC0, 0x07, 0x77, 0x1C, 0xAB, 0x63, 0x67, 0x9A, 0x75, 0x34, 0xF7, 0x17, 0x84, 0xE2, 0x52, 0xD8, 0x79, 0x4E, 0x35, 0x60, 0xF6, 0x2D, 0x30, 0x1D, 0xF1, 0x09, 0x55, 0x56, 0x4D, 0x00, 0x2E, 0xBF, 0x2C, 0x1A, 0xCA, 0xDE, 0xEF, 0xA2, 0x86, 0xF5, 0xE1, 0x07, 0x7B, 0x48, 0xB5, 0x42, 0x73, 0x59, 0x7D, 0xE0, 0xC9, 0x57, 0x86, 0x06, 0x12, 0xAE, 0xF0, 0xC4, 0xF1, 0x73, 0x9B, 0x23, 0xB8, 0xF8, 0x67, 0x99, 0xB0, 0xB3, 0xCA, 0x0F, 0xF9, 0x1F, 0xD1, 0x5D, 0xD3, 0xFD, 0x44, 0x5C, 0x30, 0x17, 0x4D, 0x84, 0x3A, 0x4E, 0x7B, 0x01, 0xB4, 0x07, 0x37, 0x70, 0x0F, 0x5D, 0xE1, 0x8C, 0x1A, 0x6B, 0xAE, 0x7D, 0x5E, 0x58, 0x6F, 0x16, 0xE8, 0xBD, 0x3D, 0xC1, 0x83, 0x89, 0x52, 0x56, 0x57, 0x5E, 0x3A, 0xA6, 0xD1, 0x5E, 0xC6, 0xB0, 0x3F, 0x8D, 0xDC, 0xA8, 0xAF, 0x32, 0xC4, 0x30, 0x33, 0x9A, 0x5F, 0x5F, 0xF9, 0xAA, 0xFE, 0xCE, 0xBA, 0x4C, 0x86, 0xFD, 0xC1, 0x46, 0x85, 0x0B, 0x0B, 0x5F, 0xF3, 0x78, 0x55, 0x74, 0x85, 0x13, 0x0D, 0xA0, 0x4B, 0xEF, 0x36, 0x37, 0xB0, 0xC8, 0x8B, 0x16, 0x10, 0x2D, 0x97, 0xBD, 0x9E, 0x83, 0x14, 0x70, 0x76, 0xD5, 0x3C, 0xC1, 0x70, 0x35, 0xEF, 0xD1, 0x0D, 0xDA, 0x0B, 0xEA, 0x2B, 0x3F, 0x31, 0x24, 0x26, 0xF8, 0x6E, 0x2F, 0x43, 0x4B, 0xDD, 0xC2, 0x2F, 0x7B, 0x98, 0x3B, 0x1B, 0x6B, 0x3B, 0x12, 0x6D, 0x94, 0xC2, 0x04, 0x41, 0x16, 0xF0, 0xB7, 0xE1, 0xBD, 0x2B, 0x35, 0x3F, 0x0D, 0x3A, 0x8B, 0x2D, 0xE0, 0x1A, 0x07, 0x3E, 0x51, 0xB6, 0xD7, 0x06, 0x27, 0x2E, 0x71, 0x8F, 0x88, 0x0A, 0xC0, 0xF9, 0xE4, 0x0D, 0x71, 0x86, 0x9F, 0x80, 0xCB, 0x72, 0xC4, 0x8F, 0x2E, 0x4E, 0x7B, 0x83, 0x35, 0xBA, 0xAD, 0x73, 0xAB, 0x8A, 0x69, 0xEE, 0xCE, 0xA7, 0x34, 0x69, 0x88, 0xF7, 0x39, 0x13, 0xE9, 0x67, 0xE5, 0x4E, 0x74, 0x16, 0xAB, 0xA4, 0x84, 0xD4, 0x7A, 0x19, 0x5A, 0x71, 0x72, 0xC9, 0xCD, 0x52, 0xFA, 0xE8, 0x16, 0x33, 0xAF, 0x0B, 0x78, 0xC8, 0xA9, 0x05, 0x57, 0xD1, 0x6A, 0x0D, 0x46, 0x36, 0x46, 0x45, 0x4A, 0xC4, 0x64, 0x81, 0xC8, 0x0E, 0x8A, 0xDC, 0xF3, 0x75, 0xD2, 0x5D, 0x60, 0x86, 0xE9, 0x23, 0x02, 0xFA, 0x9C, 0xF5, 0x95, 0xEE, 0x80, 0x47, 0x7F, 0xD1, 0xEE, 0xCC, 0xCF, 0x2D, 0x62, 0x3E, 0x8A, 0x29, 0xEE, 0x8E, 0x43, 0x5F, 0x74, 0xED, 0xB1, 0x8D, 0xC7, 0x41, 0x5A, 0x51, 0xC8, 0xE6, 0xCE, 0xCE, 0x03, 0x77, 0x86, 0x60, 0xEA, 0x73, 0xFC, 0x6D, 0x62, 0x62, 0xAF, 0x6C, 0x2A, 0x1F, 0x84, 0xC4, 0x10, 0x61, 0x78, 0x51, 0x38, 0x8B, 0x4F, 0xE3, 0xDA, 0x39, 0xB6, 0x32, 0x58, 0x84, 0x0C, 0xE7, 0xCD, 0xDF, 0xB1, 0x6D, 0x72, 0xFD, 0xF6, 0x22, 0x50, 0xB0, 0x7F, 0x35, 0x56, 0xF0, 0x9B, 0x47, 0xF1, 0x45, 0x13, 0x06, 0xE5, 0x71, 0x15, 0xE9, 0xB2, 0x5E, 0x78, 0xE0, 0x70, 0xAB, 0x98, 0xBF, 0xF3, 0x15, 0x6A, 0x3D, 0x3E, 0xDF, 0x2D, 0x23, 0xBF, 0x16, 0x96, 0x0D, 0xF3, 0x4F, 0xD4, 0x48, 0x66, 0x2E, 0x52, 0xB0, 0x48, 0x2E, 0x37, 0x7A, 0xCA, 0xFA, 0x89, 0x3B, 0x21, 0xAA, 0xD1, 0x96, 0x1C, 0x2E, 0x28, 0x7A, 0xEF, 0xCB, 0x09, 0x62, 0xF4, 0xC5, 0x3E, 0x81, 0x87, 0xBB, 0x9B, 0x48, 0xAB, 0x1E, 0xD5, 0xAE, 0x3B, 0x20, 0x1A, 0xD1, 0x51, 0x9D, 0xE0, 0x6E, 0x6E, 0xCC, 0x29, 0x24, 0x34, 0xCF, 0x07, 0xF4, 0x33, 0x42, 0x3A, 0xF2, 0x86, 0x4F, 0xFA, 0xEE, 0x5D, 0x0A, 0x6A, 0x33, 0xE0, 0xFC, 0xBB, 0x1C, 0xA0, 0xA4, 0x76, 0xE8, 0xB1, 0x17, 0xF5, 0xE4, }; CString testFileSignature = testFile + _T(".rsa.asc"); CAutoFile file = ::CreateFile(testFileSignature, GENERIC_WRITE, 0, nullptr, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, nullptr); ASSERT_TRUE(file.IsValid()); DWORD written = 0; EXPECT_TRUE(::WriteFile(file, binarySignature, sizeof(binarySignature), &written, nullptr)); EXPECT_EQ(sizeof(binarySignature), written); EXPECT_TRUE(file.CloseHandle()); EXPECT_EQ(0, VerifyIntegrity(testFile, testFileSignature, nullptr)); EXPECT_TRUE(CStringUtils::WriteStringToTextFile((LPCTSTR)testFile, L"Text with\nNewline")); EXPECT_EQ(-1, VerifyIntegrity(testFile, testFileSignature, nullptr)); }
inline bool decodeAgile(std::string& decData, const std::string& encryptedPackage, const EncryptionInfo& info, const std::string& pass, std::string& secretKey) { const CipherParam& keyData = info.keyData; const CipherParam& encryptedKey = info.encryptedKey; if (secretKey.empty()) { if (!getAgileSecretKey(secretKey, info, pass)) return false; if (putSecretKeyInstance()) { printf("secretKey = "); ms::dump(secretKey, false); } if (!VerifyIntegrity(encryptedPackage, keyData, secretKey, keyData.saltValue, info.encryptedHmacKey, info.encryptedHmacValue)) { printf("warning : mac err : data may be broken\n"); // return false; } } std::string encData; const uint64_t decodeSize = GetEncodedData(encData, encryptedPackage); // decode normalizeKey(secretKey, encryptedKey.keyBits / 8); DecContent(decData, encData, encryptedKey, secretKey, keyData.saltValue); decData.resize(decodeSize); return true; }
TEST(UpdateCrypto, NewLine) { CAutoTempDir tempdir; CString testFile = tempdir.GetTempDir() + L"\\.test.txt"; EXPECT_TRUE(CStringUtils::WriteStringToTextFile((LPCTSTR)testFile, L"Text with\nNewline")); CString testFileSignature = testFile + _T(".rsa.asc"); CString signature = L"-----BEGIN PGP SIGNATURE-----\nVersion: GnuPG v2\n\niQIcBAEBCgAGBQJVxPp9AAoJEPfxez+d2VOeGsIQAJYSxXcBeYs7gwz3+NwWSv/D\nUL+d1rJgIwyIXQ46BjiCno0a6NJ7JxPYkhl9Tqj2WenQRzQqqYZNRUPN8xEU0lSC\nS8q2B+uEGopqHG5a+/X/FJh1ijeeK75ey3HKHyn7BpH66IsDU2HZ517w6/FJOsHE\n295s+RwgojR7ghk+dqu+LrkJxldQ3r9jRDujuez5NSj1aPU5IRazyf864vl13W9O\n+7NfyjNyPmZxK/nzYPi9nujsWGXjVKYqomzfEUu7FShv4Ic0vdzHcSQdS4wVsxHc\n9Feo1dfTTaCrXnYo5vSQB+b4C6EQ0DZXW0vGOjwBFHpHCLuAgyOaUccnsyKZDNnx\nmx8QK1hb13gP5oBsShS5VxgBGhl3BP47jTiaSIf9QSGOGZih+kfAzcu0e2VGJ5Xo\nYkTAhAH/x9kRjCRze0qtH7Y3CIY3O/fFTnQmNVGr25Wrhfs7aL0rF80mTk/lwbR+\nGIlrRC2lyQGEl8hfgHfvnau+biW0GRKIINLB/i86VFzUwPS5Y4XoAbKftQoEdyQj\nJ1OaVDQxlIvx/6O0bY2nw/9fflnoeBFWzcgyaYOAV95XwVjid4DkQyInkoLGCC1p\novO/2+3zPnOoab/L8ZlR8lzgDBjn5zzZRxX0CHlgLPPzLpTCFZgxOh8KIzJ04uKU\nY72YA8friiI836RZVoXq\n=i5FK\n-----END PGP SIGNATURE-----"; EXPECT_TRUE(CStringUtils::WriteStringToTextFile((LPCTSTR)testFileSignature, (LPCTSTR)signature)); EXPECT_EQ(0, VerifyIntegrity(testFile, testFileSignature, nullptr)); EXPECT_TRUE(CStringUtils::WriteStringToTextFile((LPCTSTR)testFile, L"Text with\r\nNewline")); EXPECT_EQ(0, VerifyIntegrity(testFile, testFileSignature, nullptr)); EXPECT_EQ(16, signature.Replace(L"\n", L"\r\n")); EXPECT_TRUE(CStringUtils::WriteStringToTextFile((LPCTSTR)testFileSignature, (LPCTSTR)signature)); EXPECT_EQ(0, VerifyIntegrity(testFile, testFileSignature, nullptr)); }
/* static */ nsresult SRICheck::VerifyIntegrity(const SRIMetadata& aMetadata, nsIURI* aRequestURI, const CORSMode aCORSMode, const nsAString& aString, const nsIDocument* aDocument) { NS_ConvertUTF16toUTF8 utf8Hash(aString); return VerifyIntegrity(aMetadata, aRequestURI, aCORSMode, utf8Hash.Length(), (uint8_t*)utf8Hash.get(), aDocument); }
TEST(UpdateCrypto, SimpleVerify) { CAutoTempDir tempdir; CString testFile = tempdir.GetTempDir() + L"\\.test.txt"; EXPECT_TRUE(CStringUtils::WriteStringToTextFile((LPCTSTR)testFile, L"Text")); CString testFileSignature = testFile + _T(".rsa.asc"); EXPECT_EQ(-1, VerifyIntegrity(testFile, testFileSignature, nullptr)); CString signature = L"-----BEGIN PGP SIGNATURE-----\nVersion: GnuPG v2\n\niQIcBAEBCgAGBQJVxPizAAoJEPfxez+d2VOeHrgP/jOQwPGToQOVgpWixwrwhflL\nzK/hpgpBzgKALzPKfQcXd/iL2WvIldmMlGo9inNeEIh+a2ufrzsr/N/CzKqeTPkb\nazSF99LtRiIoFd3ZSf4JPpwUNyCzMn5OfOhsBDbU7vpyu4OCqSjsM4EdGynh6CdW\nLEiZ/25EZB/70ZGkTaQewx5wPi0Kmyv0M52b7TrKixxK8iuOjENviUNtvvpbvjUt\nVfv2lZV/lWkq5lesHFjg8HsDBcwC7LPQbR3M1MSW5wH6Kp/9OPifJh5xkRvRGsr2\nEucLGXKoRZXm8AxFYZ6diN0vai3oQP7nUNEUURZLG9yEQ4kCfoArUwtRvNrqJrrx\nkH57hM9Zft1Yxkj48USxJmi9reM7QahPsUqhWNnb3KUq+752OaOU3Sxd7ZW6YHzk\nSMvwcp0Jj8KczHtMyI4Nhj8CkzBgOs6Bi3ydoXCozGsxcrv6zCs2v1je3CeSP7rM\nK4f6dwstExPGtm46TU4L05EIJYjhneI7EUcgPKgJ0c7AdtaOcwLDZdEjmaDFH83N\nbSJ8Rune2uXwIDFX7BpZSSbSedE5yKt/o7sgnpoFOMHRkRCxjRD/lFgj9c0nlxm2\nFgHYyEM+1o1Ps9vKEZMbmpkzxTV4ZOPaiD/ZUzq1s9yx58Ja6zmVcIaZw79JEhiP\nOKnABUyX8A4V9bPLkQ1M\n=PI7W\n-----END PGP SIGNATURE-----"; EXPECT_TRUE(CStringUtils::WriteStringToTextFile((LPCTSTR)testFileSignature, (LPCTSTR)signature)); EXPECT_EQ(0, VerifyIntegrity(testFile, testFileSignature, nullptr)); EXPECT_TRUE(CStringUtils::WriteStringToTextFile((LPCTSTR)testFileSignature, (LPCTSTR)signature.Left(50))); EXPECT_EQ(-1, VerifyIntegrity(testFile, testFileSignature, nullptr)); EXPECT_TRUE(CStringUtils::WriteStringToTextFile((LPCTSTR)testFile, L"Text\n")); EXPECT_TRUE(CStringUtils::WriteStringToTextFile((LPCTSTR)testFileSignature, (LPCTSTR)signature)); EXPECT_EQ(-1, VerifyIntegrity(testFile, testFileSignature, nullptr)); }
void gmGCColorSet::GrayThisObject(gmGCObjBase* a_obj) { gmGCObjBase* objPrev = a_obj->GetPrev(); gmGCObjBase* objNext = a_obj->GetNext(); // This routine should never get called with a shaded object GM_ASSERT(!m_gc->IsShaded(a_obj)); #if GM_GC_DEBUG GM_ASSERT(a_obj->m_curPosColor == GM_GC_DEBUG_COL_WHITE); a_obj->m_curPosColor = GM_GC_DEBUG_COL_GRAY; #endif //GM_GC_DEBUG // Set object`s color to shaded first. a_obj->SetColor(m_gc->GetCurShadeColor()); // The object must be shaded GM_ASSERT(m_gc->IsShaded(a_obj)); // Splice the object out of the white list // This can be done unconditionally as no set pointers can point to any object in this set. objPrev->SetNext(objNext); objNext->SetPrev(objPrev); // Put the object into the correct place in the gray list #if DEPTH_FIRST // Put the gray object at the head of the gray list. a_obj->SetPrev(m_scan->GetPrev()); a_obj->SetNext(m_scan); m_scan->GetPrev()->SetNext(a_obj); m_scan->SetPrev(a_obj); #else // BREADTH_FIRST // Put the gray object at the tail of the gray list. a_obj->SetPrev(m_gray); a_obj->SetNext(m_gray->GetNext()); m_gray->GetNext()->SetPrev(a_obj); m_gray->SetNext(a_obj); #endif // BREADTH_FIRST #if GM_GC_DEBUG // Slow, paranoid check VerifyIntegrity(); #endif //GM_GC_DEBUG }
int gmGCColorSet::DestructSomeFreeObjects(int a_maxToDestruct) { int numDestructed = 0; // Go through the free list (perhaps over multiple installments in future) and call Destruct() on them. if(m_free != m_white) { gmGCObjBase* beforeFree = m_free->GetPrev(); // Save previous node so we can relink after removing some bool fixScan = false; if(m_scan == m_free) // Will need to fix the scan ptr later if this is so. { fixScan = true; } while(m_free != m_white) { gmGCObjBase* objToRecycle = m_free; m_free = m_free->GetNext(); #if GM_GC_DEBUG //GM_ASSERT(objToRecycle->m_curPosColor == GM_GC_DEBUG_COL_WHITE); GM_ASSERT(objToRecycle->m_curPosColor == GM_GC_DEBUG_COL_FREE); objToRecycle->m_curPosColor = GM_GC_DEBUG_COL_INVALID; #endif //GM_GC_DEBUG #if GM_GC_KEEP_PERSISTANT_SEPARATE GM_ASSERT(!objToRecycle->GetPersist()); #endif //GM_GC_KEEP_PERSISTANT_SEPARATE #if GM_GC_STATS --m_numAllocated; #endif //GM_GC_STATS objToRecycle->Destruct(m_gc->GetVM()); ++numDestructed; --a_maxToDestruct; if(a_maxToDestruct <= 0) { // Relink since we removed elements beforeFree->SetNext(m_free); m_free->SetPrev(beforeFree); if(fixScan) { m_scan = m_free; } return numDestructed; // Work is done for now. } } // Relink since we removed elements beforeFree->SetNext(m_free); m_free->SetPrev(beforeFree); if(fixScan) { m_scan = m_free; } } #if GM_GC_DEBUG // Slow, paranoid check VerifyIntegrity(); #endif //GM_GC_DEBUG return numDestructed; }
void gmGCColorSet::ReclaimGarbage() { GM_ASSERT(m_scan->GetPrev() == m_gray); #if GM_GC_DEBUG // Slow, paranoid check VerifyIntegrity(); #endif //GM_GC_DEBUG #if GM_GC_DEBUG { // Traverse the newly found garbage objects just to make sure there // aren't any live objects in there. Used for debugging only. for(gmGCObjBase* temp = m_white->GetNext(); temp != m_tail; temp = temp->GetNext()) { GM_ASSERT(!m_gc->IsShaded(temp)); } } #endif if (m_white->GetNext() != m_tail) // There are garbage objects { #if GM_GC_DEBUG //flag white->tail as white? for(gmGCObjBase* temp = m_white->GetNext(); temp != m_tail; temp = temp->GetNext()) { GM_ASSERT(temp->m_curPosColor == GM_GC_DEBUG_COL_WHITE); temp->m_curPosColor = GM_GC_DEBUG_COL_FREE; } #endif //GM_GC_DEBUG bool fixScan = false; if( m_scan == m_free ) // There are no black objects { fixScan = true; } // Reclaim the garbage. // Insert old White->Tail at start of Free (Free may == White) gmGCObjBase* firstFree = m_white->GetNext(); firstFree->SetPrev(m_free->GetPrev()); m_free->GetPrev()->SetNext(firstFree); m_tail->GetPrev()->SetNext(m_free); m_free->SetPrev(m_tail->GetPrev()); m_free = firstFree; if( fixScan ) { m_scan = m_free; } m_white->SetNext(m_tail); m_tail->SetPrev(m_white); } // Whiten the live objects. if (m_scan != m_free) // There are live (black) objects { #if GM_GC_DEBUG //flag scan->free as white? for(gmGCObjBase* temp = m_scan;//m_scan->GetNext(); temp != m_free; temp = temp->GetNext()) { GM_ASSERT(temp->m_curPosColor == GM_GC_DEBUG_COL_BLACK); temp->m_curPosColor = GM_GC_DEBUG_COL_WHITE; } #endif //GM_GC_DEBUG GM_ASSERT(m_white->GetNext() == m_tail); GM_ASSERT(m_tail->GetPrev() == m_white); m_scan->GetPrev()->SetNext(m_free); m_free->GetPrev()->SetNext(m_tail); m_tail->SetPrev(m_free->GetPrev()); m_free->SetPrev(m_scan->GetPrev()); m_scan->SetPrev(m_white); m_white->SetNext(m_scan); m_scan = m_free; } GM_ASSERT(m_gray->GetNext() == m_scan); #if GM_GC_DEBUG // Slow, paranoid check VerifyIntegrity(); #endif //GM_GC_DEBUG #if GM_GC_DEBUG { int count = 0; for(gmGCObjBase* temp = m_free; temp != m_white; temp = temp->GetNext()) { ++count; } } #endif }
bool CCheckForUpdatesDlg::Download(CString filename) { CString url = m_sFilesURL + filename; CString destFilename = GetDownloadsDirectory() + filename; if (PathFileExists(destFilename) && PathFileExists(destFilename + SIGNATURE_FILE_ENDING)) { if (VerifyIntegrity(destFilename, destFilename + SIGNATURE_FILE_ENDING, m_updateDownloader) == 0) return true; else { DeleteFile(destFilename); DeleteFile(destFilename + SIGNATURE_FILE_ENDING); DeleteUrlCacheEntry(url); DeleteUrlCacheEntry(url + SIGNATURE_FILE_ENDING); } } m_progress.SetRange32(0, 1); m_progress.SetPos(0); m_progress.ShowWindow(SW_SHOW); if (m_pTaskbarList) { m_pTaskbarList->SetProgressState(m_hWnd, TBPF_NORMAL); m_pTaskbarList->SetProgressValue(m_hWnd, 0, 1); } CString tempfile = CTempFiles::Instance().GetTempFilePath(true).GetWinPathString(); CString signatureTempfile = CTempFiles::Instance().GetTempFilePath(true).GetWinPathString(); DWORD ret = m_updateDownloader->DownloadFile(url, tempfile, true); if (!ret) { ret = m_updateDownloader->DownloadFile(url + SIGNATURE_FILE_ENDING, signatureTempfile, true); if (ret) m_sErrors += url + SIGNATURE_FILE_ENDING + _T(": ") + GetWinINetError(ret) + _T("\r\n"); m_progress.SetPos(m_progress.GetPos() + 1); if (m_pTaskbarList) { m_pTaskbarList->SetProgressState(m_hWnd, TBPF_NORMAL); int minValue, maxValue; m_progress.GetRange(minValue, maxValue); m_pTaskbarList->SetProgressValue(m_hWnd, m_progress.GetPos(), maxValue); } } else m_sErrors += url + _T(": ") + GetWinINetError(ret) + _T("\r\n"); if (!ret) { if (VerifyIntegrity(tempfile, signatureTempfile, m_updateDownloader) == 0) { DeleteFile(destFilename); DeleteFile(destFilename + SIGNATURE_FILE_ENDING); MoveFile(tempfile, destFilename); MoveFile(signatureTempfile, destFilename + SIGNATURE_FILE_ENDING); return true; } m_sErrors += url + SIGNATURE_FILE_ENDING + _T(": Broken digital signature.\r\n"); DeleteUrlCacheEntry(url); DeleteUrlCacheEntry(url + SIGNATURE_FILE_ENDING); } return false; }
UINT CCheckForUpdatesDlg::CheckThread() { m_bThreadRunning = TRUE; CString temp; CString tempfile = CTempFiles::Instance().GetTempFilePath(true).GetWinPathString(); bool official = false; CRegString checkurluser = CRegString(_T("Software\\TortoiseGit\\UpdateCheckURL"), _T("")); CRegString checkurlmachine = CRegString(_T("Software\\TortoiseGit\\UpdateCheckURL"), _T(""), FALSE, HKEY_LOCAL_MACHINE); CString sCheckURL = checkurluser; if (sCheckURL.IsEmpty()) { sCheckURL = checkurlmachine; if (sCheckURL.IsEmpty()) { official = true; bool checkPreview = false; #if PREVIEW checkPreview = true; #else CRegStdDWORD regCheckPreview(L"Software\\TortoiseGit\\VersionCheckPreview", FALSE); if (DWORD(regCheckPreview)) checkPreview = true; #endif if (checkPreview) { sCheckURL = _T("https://versioncheck.tortoisegit.org/version-preview.txt"); SetDlgItemText(IDC_SOURCE, _T("Using preview release channel")); } else sCheckURL = _T("https://versioncheck.tortoisegit.org/version.txt"); } } if (!official && sCheckURL.Find(_T("://versioncheck.tortoisegit.org/")) > 0) official = true; if (!official) SetDlgItemText(IDC_SOURCE, _T("Using (unofficial) release channel: ") + sCheckURL); CString ver; CAutoConfig versioncheck(true); CString errorText; DWORD ret = m_updateDownloader->DownloadFile(sCheckURL, tempfile, false); if (!ret && official) { CString signatureTempfile = CTempFiles::Instance().GetTempFilePath(true).GetWinPathString(); ret = m_updateDownloader->DownloadFile(sCheckURL + SIGNATURE_FILE_ENDING, signatureTempfile, false); if (ret || VerifyIntegrity(tempfile, signatureTempfile, m_updateDownloader)) { CString error = _T("Could not verify digital signature."); if (ret) error += _T("\r\nError: ") + GetWinINetError(ret) + _T(" (on ") + sCheckURL + SIGNATURE_FILE_ENDING + _T(")"); SetDlgItemText(IDC_CHECKRESULT, error); DeleteUrlCacheEntry(sCheckURL); DeleteUrlCacheEntry(sCheckURL + SIGNATURE_FILE_ENDING); goto finish; } } else if (ret) { DeleteUrlCacheEntry(sCheckURL); if (CRegDWORD(_T("Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings\\GlobalUserOffline"), 0)) errorText.LoadString(IDS_OFFLINEMODE); // offline mode enabled else errorText.Format(IDS_CHECKNEWER_NETERROR_FORMAT, (LPCTSTR)(GetWinINetError(ret) + _T(" URL: ") + sCheckURL), ret); SetDlgItemText(IDC_CHECKRESULT, errorText); goto finish; } git_config_add_file_ondisk(versioncheck, CUnicodeUtils::GetUTF8(tempfile), GIT_CONFIG_LEVEL_GLOBAL, 0); unsigned int major, minor, micro, build; major = minor = micro = build = 0; unsigned __int64 version = 0; if (!versioncheck.GetString(_T("tortoisegit.version"), ver)) { CString vertemp = ver; major = _ttoi(vertemp); vertemp = vertemp.Mid(vertemp.Find('.') + 1); minor = _ttoi(vertemp); vertemp = vertemp.Mid(vertemp.Find('.') + 1); micro = _ttoi(vertemp); vertemp = vertemp.Mid(vertemp.Find('.') + 1); build = _ttoi(vertemp); version = major; version <<= 16; version += minor; version <<= 16; version += micro; version <<= 16; version += build; if (version == 0) { temp.LoadString(IDS_CHECKNEWER_NETERROR); SetDlgItemText(IDC_CHECKRESULT, temp); goto finish; } // another versionstring for the filename can be provided // this is needed for preview releases vertemp.Empty(); versioncheck.GetString(_T("tortoisegit.versionstring"), vertemp); if (!vertemp.IsEmpty()) ver = vertemp; } else { errorText = _T("Could not parse version check file: ") + g_Git.GetLibGit2LastErr(); SetDlgItemText(IDC_CHECKRESULT, errorText); DeleteUrlCacheEntry(sCheckURL); goto finish; } { BOOL bNewer = FALSE; if (m_bForce) bNewer = TRUE; else if (major > TGIT_VERMAJOR) bNewer = TRUE; else if ((minor > TGIT_VERMINOR) && (major == TGIT_VERMAJOR)) bNewer = TRUE; else if ((micro > TGIT_VERMICRO) && (minor == TGIT_VERMINOR) && (major == TGIT_VERMAJOR)) bNewer = TRUE; else if ((build > TGIT_VERBUILD) && (micro == TGIT_VERMICRO) && (minor == TGIT_VERMINOR) && (major == TGIT_VERMAJOR)) bNewer = TRUE; CString versionstr; versionstr.Format(_T("%u.%u.%u.%u"), major, minor, micro, build); if (versionstr != ver) versionstr += _T(" (") + ver + _T(")"); temp.Format(IDS_CHECKNEWER_CURRENTVERSION, (LPCTSTR)versionstr); SetDlgItemText(IDC_CURRENTVERSION, temp); if (bNewer) { versioncheck.GetString(_T("tortoisegit.infotext"), temp); if (!temp.IsEmpty()) { CString tempLink; versioncheck.GetString(_T("tortoisegit.infotexturl"), tempLink); if (!tempLink.IsEmpty()) // find out the download link-URL, if any m_sUpdateDownloadLink = tempLink; } else temp.LoadString(IDS_CHECKNEWER_NEWERVERSIONAVAILABLE); SetDlgItemText(IDC_CHECKRESULT, temp); FillChangelog(versioncheck, official); FillDownloads(versioncheck, ver); // Show download controls RECT rectWindow, rectProgress, rectGroupDownloads, rectOKButton; GetWindowRect(&rectWindow); m_progress.GetWindowRect(&rectProgress); GetDlgItem(IDC_GROUP_DOWNLOADS)->GetWindowRect(&rectGroupDownloads); GetDlgItem(IDOK)->GetWindowRect(&rectOKButton); LONG bottomDistance = rectWindow.bottom - rectOKButton.bottom; OffsetRect(&rectOKButton, 0, (rectGroupDownloads.bottom + (rectGroupDownloads.bottom - rectProgress.bottom)) - rectOKButton.top); rectWindow.bottom = rectOKButton.bottom + bottomDistance; MoveWindow(&rectWindow); ::MapWindowPoints(nullptr, GetSafeHwnd(), (LPPOINT)&rectOKButton, 2); if (CRegDWORD(_T("Software\\TortoiseGit\\VersionCheck"), TRUE) != FALSE && !m_bForce && !m_bShowInfo) { GetDlgItem(IDC_DONOTASKAGAIN)->ShowWindow(SW_SHOW); rectOKButton.left += 60; temp.LoadString(IDS_REMINDMELATER); GetDlgItem(IDOK)->SetWindowText(temp); rectOKButton.right += 160; } GetDlgItem(IDOK)->MoveWindow(&rectOKButton); m_ctrlFiles.ShowWindow(SW_SHOW); GetDlgItem(IDC_GROUP_DOWNLOADS)->ShowWindow(SW_SHOW); CenterWindow(); m_bShowInfo = TRUE; } else if (m_bShowInfo) { temp.LoadString(IDS_CHECKNEWER_YOURUPTODATE); SetDlgItemText(IDC_CHECKRESULT, temp); FillChangelog(versioncheck, official); } } finish: if (!m_sUpdateDownloadLink.IsEmpty()) { m_link.ShowWindow(SW_SHOW); m_link.SetURL(m_sUpdateDownloadLink); } m_bThreadRunning = FALSE; DialogEnableWindow(IDOK, TRUE); return 0; }
int main(int argc, char **argv) { FILE *out; /* Output data file */ char s[255],s2[255],delim[255],*pstr; /* Generic strings */ int *memcache; /* used to flush cache */ int len_buf_align, /* meaningful when args.cache is 0. buflen */ /* rounded up to be divisible by 8 */ num_buf_align; /* meaningful when args.cache is 0. number */ /* of aligned buffers in memtmp */ int c, /* option index */ i, j, n, nq, /* Loop indices */ asyncReceive=0, /* Pre-post a receive buffer? */ bufalign=16*1024,/* Boundary to align buffer to */ errFlag, /* Error occurred in inner testing loop */ nrepeat, /* Number of time to do the transmission */ nrepeat_const=0,/* Set if we are using a constant nrepeat */ len, /* Number of bytes to be transmitted */ inc=0, /* Increment value */ perturbation=DEFPERT, /* Perturbation value */ pert, start= 1, /* Starting value for signature curve */ end=MAXINT, /* Ending value for signature curve */ streamopt=0, /* Streaming mode flag */ reset_connection;/* Reset the connection between trials */ ArgStruct args; /* Arguments for all the calls */ double t, t0, t1, t2, /* Time variables */ tlast, /* Time for the last transmission */ latency; /* Network message latency */ Data bwdata[NSAMP]; /* Bandwidth curve data */ int integCheck=0; /* Integrity check */ /* Initialize vars that may change from default due to arguments */ strcpy(s, "np.out"); /* Default output file */ /* Let modules initialize related vars, and possibly call a library init function that requires argc and argv */ Init(&args, &argc, &argv); /* This will set args.tr and args.rcv */ args.preburst = 0; /* Default to not bursting preposted receives */ args.bidir = 0; /* Turn bi-directional mode off initially */ args.cache = 1; /* Default to use cache */ args.upper = end; args.host = NULL; args.soffset=0; /* default to no offsets */ args.roffset=0; args.syncflag=0; /* use normal mpi_send */ args.port = DEFPORT; /* just in case the user doesn't set this. */ /* TCGMSG launches NPtcgmsg with a -master master_hostname * argument, so ignore all arguments and set them manually * in netpipe.c instead. */ #if ! defined(TCGMSG) /* Parse the arguments. See Usage for description */ while ((c = getopt(argc, argv, "SO:rIiszgfaB2h:p:o:l:u:b:m:n:t:c:d:D:P:")) != -1) { switch(c) { case 'O': strcpy(s2,optarg); strcpy(delim,","); if((pstr=strtok(s2,delim))!=NULL) { args.soffset=atoi(pstr); if((pstr=strtok((char *)NULL,delim))!=NULL) args.roffset=atoi(pstr); else /* only got one token */ args.roffset=args.soffset; } else { args.soffset=0; args.roffset=0; } printf("Transmit buffer offset: %d\nReceive buffer offset: %d\n",args.soffset,args.roffset); break; case 'p': perturbation = atoi(optarg); if( perturbation > 0 ) { printf("Using a perturbation value of %d\n\n", perturbation); } else { perturbation = 0; printf("Using no perturbations\n\n"); } break; case 'B': if(integCheck == 1) { fprintf(stderr, "Integrity check not supported with prepost burst\n"); exit(-1); } args.preburst = 1; asyncReceive = 1; printf("Preposting all receives before a timed run.\n"); printf("Some would consider this cheating,\n"); printf("but it is needed to match some vendor tests.\n"); fflush(stdout); break; case 'I': args.cache = 0; printf("Performance measured without cache effects\n\n"); fflush(stdout); break; case 'o': strcpy(s,optarg); printf("Sending output to %s\n", s); fflush(stdout); break; case 's': streamopt = 1; printf("Streaming in one direction only.\n\n"); #if defined(TCP) && ! defined(INFINIBAND) printf("Sockets are reset between trials to avoid\n"); printf("degradation from a collapsing window size.\n\n"); #endif args.reset_conn = 1; printf("Streaming does not provide an accurate\n"); printf("measurement of the latency since small\n"); printf("messages may get bundled together.\n\n"); if( args.bidir == 1 ) { printf("You can't use -s and -2 together\n"); exit(0); } fflush(stdout); break; case 'l': start = atoi(optarg); if (start < 1) { fprintf(stderr,"Need a starting value >= 1\n"); exit(0); } break; case 'u': end = atoi(optarg); break; #if defined(TCP) && ! defined(INFINIBAND) case 'b': /* -b # resets the buffer size, -b 0 keeps system defs */ args.prot.sndbufsz = args.prot.rcvbufsz = atoi(optarg); break; #endif case '2': args.bidir = 1; /* Both procs are transmitters */ /* end will be maxed at sndbufsz+rcvbufsz */ printf("Passing data in both directions simultaneously.\n"); printf("Output is for the combined bandwidth.\n"); #if defined(TCP) && ! defined(INFINIBAND) printf("The socket buffer size limits the maximum test size.\n\n"); #endif if( streamopt ) { printf("You can't use -s and -2 together\n"); exit(0); } break; case 'h': args.tr = 1; /* -h implies transmit node */ args.rcv = 0; args.host = (char *)malloc(strlen(optarg)+1); strcpy(args.host, optarg); break; #ifdef DISK case 'd': args.tr = 1; /* -d to specify input/output file */ args.rcv = 0; args.prot.read = 0; args.prot.read_type = 'c'; args.prot.dfile_name = (char *)malloc(strlen(optarg)+1); strcpy(args.prot.dfile_name, optarg); break; case 'D': if( optarg[0] == 'r' ) args.prot.read = 1; else args.prot.read = 0; args.prot.read_type = optarg[1]; break; #endif case 'i': if(args.preburst == 1) { fprintf(stderr, "Integrity check not supported with prepost burst\n"); exit(-1); } integCheck = 1; perturbation = 0; start = sizeof(int)+1; /* Start with integer size */ printf("Doing an integrity check instead of measuring performance\n"); fflush(stdout); break; #if defined(MPI) case 'z': args.source_node = -1; printf("Receive using the ANY_SOURCE flag\n"); fflush(stdout); break; case 'a': asyncReceive = 1; printf("Preposting asynchronous receives\n"); fflush(stdout); break; case 'S': args.syncflag=1; fprintf(stderr,"Using synchronous sends\n"); break; #endif #if defined(MPI2) case 'g': if(args.prot.no_fence == 1) { fprintf(stderr, "-f cannot be used with -g\n"); exit(-1); } args.prot.use_get = 1; printf("Using MPI-2 Get instead of Put\n"); break; case 'f': if(args.prot.use_get == 1) { fprintf(stderr, "-f cannot be used with -g\n"); exit(-1); } args.prot.no_fence = 1; bufalign = 0; printf("Buffer alignment off (Required for no fence)\n"); break; #endif /* MPI2 */ #if defined(INFINIBAND) case 'm': switch(atoi(optarg)) { case 256: args.prot.ib_mtu = MTU256; break; case 512: args.prot.ib_mtu = MTU512; break; case 1024: args.prot.ib_mtu = MTU1024; break; case 2048: args.prot.ib_mtu = MTU2048; break; case 4096: args.prot.ib_mtu = MTU4096; break; default: fprintf(stderr, "Invalid MTU size, must be one of " "256, 512, 1024, 2048, 4096\n"); exit(-1); } break; case 't': if( !strcmp(optarg, "send_recv") ) { printf("Using Send/Receive communications\n"); args.prot.commtype = NP_COMM_SENDRECV; } else if( !strcmp(optarg, "send_recv_with_imm") ) { printf("Using Send/Receive communications with immediate data\n"); args.prot.commtype = NP_COMM_SENDRECV_WITH_IMM; } else if( !strcmp(optarg, "rdma_write") ) { printf("Using RDMA Write communications\n"); args.prot.commtype = NP_COMM_RDMAWRITE; } else if( !strcmp(optarg, "rdma_write_with_imm") ) { printf("Using RDMA Write communications with immediate data\n"); args.prot.commtype = NP_COMM_RDMAWRITE_WITH_IMM; } else { fprintf(stderr, "Invalid transfer type " "specified, please choose one of:\n\n" "\tsend_recv\t\tUse Send/Receive communications\t(default)\n" "\tsend_recv_with_imm\tSame as above with immediate data\n" "\trdma_write\t\tUse RDMA Write communications\n" "\trdma_write_with_imm\tSame as above with immediate data\n\n"); exit(-1); } break; case 'c': if( !strcmp(optarg, "local_poll") ) { printf("Using local polling completion\n"); args.prot.comptype = NP_COMP_LOCALPOLL; } else if( !strcmp(optarg, "vapi_poll") ) { printf("Using VAPI polling completion\n"); args.prot.comptype = NP_COMP_VAPIPOLL; } else if( !strcmp(optarg, "event") ) { printf("Using VAPI event completion\n"); args.prot.comptype = NP_COMP_EVENT; } else { fprintf(stderr, "Invalid completion type specified, " "please choose one of:\n\n" "\tlocal_poll\tWait for last byte of data\t(default)\n" "\tvapi_poll\tUse VAPI polling function\n" "\tevent\t\tUse VAPI event handling function\n\n"); exit(-1); } break; #endif case 'n': nrepeat_const = atoi(optarg); break; #if defined(TCP) && ! defined(INFINIBAND) case 'r': args.reset_conn = 1; printf("Resetting connection after every trial\n"); break; #endif case 'P': args.port = atoi(optarg); break; default: PrintUsage(); exit(-12); } } #endif /* ! defined TCGMSG */ #if defined(INFINIBAND) asyncReceive = 1; fprintf(stderr, "Preposting asynchronous receives (required for Infiniband)\n"); if(args.bidir && ( (args.cache && args.prot.commtype == NP_COMM_RDMAWRITE) || /* rdma_write only works with no-cache mode */ (!args.preburst && args.prot.commtype != NP_COMM_RDMAWRITE) || /* anything besides rdma_write requires prepost burst */ (args.preburst && args.prot.comptype == NP_COMP_LOCALPOLL && args.cache) || /* preburst with local polling in cache mode doesn't work */ 0)) { fprintf(stderr, "\n" "Bi-directional mode currently only works with a subset of the\n" "Infiniband options. Restrictions are:\n" "\n" " RDMA write (-t rdma_write) requires no-cache mode (-I).\n" "\n" " Local polling (-c local_poll, default if no -c given) requires\n" " no-cache mode (-I), and if not using RDMA write communication,\n" " burst mode (-B).\n" "\n" " Any other communication type and any other completion type\n" " require burst mode (-B). No-cache mode (-I) may be used\n" " optionally.\n" "\n" " All other option combinations will fail.\n" "\n"); exit(-1); } #endif if (start > end) { fprintf(stderr, "Start MUST be LESS than end\n"); exit(420132); } args.nbuff = TRIALS; Setup(&args); if( args.bidir && end > args.upper ) { end = args.upper; if( args.tr ) { printf("The upper limit is being set to %d Bytes\n", end); #if defined(TCP) && ! defined(INFINIBAND) printf("due to socket buffer size limitations\n\n"); #endif } } #if defined(GM) if(streamopt && (!nrepeat_const || nrepeat_const > args.prot.num_stokens)) { printf("\nGM is currently limited by the driver software to %d\n", args.prot.num_stokens); printf("outstanding sends. The number of repeats will be set\n"); printf("to this limit for every trial in streaming mode. You\n"); printf("may use the -n switch to set a smaller number of repeats\n\n"); nrepeat_const = args.prot.num_stokens; } #endif if( args.tr ) /* Primary transmitter */ { if ((out = fopen(s, "w")) == NULL) { fprintf(stderr,"Can't open %s for output\n", s); exit(1); } } else out = stdout; /* Set a starting value for the message size increment. */ inc = (start > 1) ? start / 2 : 1; nq = (start > 1) ? 1 : 0; /* Test the timing to set tlast for the first test */ args.bufflen = start; MyMalloc(&args, args.bufflen, 0, 0); InitBufferData(&args, args.bufflen, 0, 0); if(args.cache) args.s_buff = args.r_buff; args.r_ptr = args.r_buff_orig = args.r_buff; args.s_ptr = args.s_buff_orig = args.s_buff; AfterAlignmentInit(&args); /* MPI-2 needs this to create a window */ /* Infiniband requires use of asynchronous communications, so we need * the PrepareToReceive calls below */ if( asyncReceive ) PrepareToReceive(&args); Sync(&args); /* Sync to prevent race condition in armci module */ /* For simplicity's sake, even if the real test below will be done in * bi-directional mode, we still do the ping-pong one-way-at-a-time test * here to estimate the one-way latency. Unless it takes significantly * longer to send data in both directions at once than it does to send data * one way at a time, this shouldn't be too far off anyway. */ t0 = When(); for( n=0; n<100; n++) { if( args.tr) { SendData(&args); RecvData(&args); if( asyncReceive && n<99 ) PrepareToReceive(&args); } else if( args.rcv) { RecvData(&args); if( asyncReceive && n<99 ) PrepareToReceive(&args); SendData(&args); } } tlast = (When() - t0)/200; /* Sync up and Reset before freeing the buffers */ Sync(&args); Reset(&args); /* Free the buffers and any other module-specific resources. */ if(args.cache) FreeBuff(args.r_buff_orig, NULL); else FreeBuff(args.r_buff_orig, args.s_buff_orig); /* Do setup for no-cache mode, using two distinct buffers. */ if (!args.cache) { /* Allocate dummy pool of memory to flush cache with */ if ( (memcache = (int *)malloc(MEMSIZE)) == NULL) { perror("malloc"); exit(1); } mymemset(memcache, 0, MEMSIZE/sizeof(int)); /* Allocate large memory pools */ MyMalloc(&args, MEMSIZE+bufalign, args.soffset, args.roffset); /* Save buffer addresses */ args.s_buff_orig = args.s_buff; args.r_buff_orig = args.r_buff; /* Align buffers */ args.s_buff = AlignBuffer(args.s_buff, bufalign); args.r_buff = AlignBuffer(args.r_buff, bufalign); /* Post alignment initialization */ AfterAlignmentInit(&args); /* Initialize send buffer pointer */ /* both soffset and roffset should be zero if we don't have any offset stuff, so this should be fine */ args.s_ptr = args.s_buff+args.soffset; args.r_ptr = args.r_buff+args.roffset; } /************************** * Main loop of benchmark * **************************/ if( args.tr ) fprintf(stderr,"Now starting the main loop\n"); for ( n = 0, len = start, errFlag = 0; n < NSAMP - 3 && tlast < STOPTM && len <= end && !errFlag; len = len + inc, nq++ ) { /* Exponentially increase the block size. */ if (nq > 2) inc = ((nq % 2))? inc + inc: inc; /* This is a perturbation loop to test nearby values */ for (pert = ((perturbation > 0) && (inc > perturbation+1)) ? -perturbation : 0; pert <= perturbation; n++, pert += ((perturbation > 0) && (inc > perturbation+1)) ? perturbation : perturbation+1) { Sync(&args); /* Sync to prevent race condition in armci module */ /* Calculate how many times to repeat the experiment. */ if( args.tr ) { if (nrepeat_const) { nrepeat = nrepeat_const; /* } else if (len == start) {*/ /* nrepeat = MAX( RUNTM/( 0.000020 + start/(8*1000) ), TRIALS);*/ } else { nrepeat = MAX((RUNTM / ((double)args.bufflen / (args.bufflen - inc + 1.0) * tlast)),TRIALS); } SendRepeat(&args, nrepeat); } else if( args.rcv ) { RecvRepeat(&args, &nrepeat); } args.bufflen = len + pert; if( args.tr ) fprintf(stderr,"%3d: %7d bytes %6d times --> ", n,args.bufflen,nrepeat); if (args.cache) /* Allow cache effects. We use only one buffer */ { /* Allocate the buffer with room for alignment*/ MyMalloc(&args, args.bufflen+bufalign, args.soffset, args.roffset); /* Save buffer address */ args.r_buff_orig = args.r_buff; args.s_buff_orig = args.r_buff; /* Align buffer */ args.r_buff = AlignBuffer(args.r_buff, bufalign); args.s_buff = args.r_buff; /* Initialize buffer with data * * NOTE: The buffers should be initialized with some sort of * valid data, whether it is actually used for anything else, * to get accurate results. Performance increases noticeably * if the buffers are left uninitialized, but this does not * give very useful results as realworld apps tend to actually * have data stored in memory. We are not sure what causes * the difference in performance at this time. */ InitBufferData(&args, args.bufflen, args.soffset, args.roffset); /* Post-alignment initialization */ AfterAlignmentInit(&args); /* Initialize buffer pointers (We use r_ptr and s_ptr for * compatibility with no-cache mode, as this makes the code * simpler) */ /* offsets are zero by default so this saves an #ifdef */ args.r_ptr = args.r_buff+args.roffset; args.s_ptr = args.r_buff+args.soffset; } else /* Eliminate cache effects. We use two distinct buffers */ { /* this isn't truly set up for offsets yet */ /* Size of an aligned memory block including trailing padding */ len_buf_align = args.bufflen; if(bufalign != 0) len_buf_align += bufalign - args.bufflen % bufalign; /* Initialize the buffers with data * * See NOTE above. */ InitBufferData(&args, MEMSIZE, args.soffset, args.roffset); /* Reset buffer pointers to beginning of pools */ args.r_ptr = args.r_buff+args.roffset; args.s_ptr = args.s_buff+args.soffset; } bwdata[n].t = LONGTIME; /* t2 = t1 = 0;*/ /* Finally, we get to transmit or receive and time */ /* NOTE: If a module is running that uses only one process (e.g. * memcpy), we assume that it will always have the args.tr flag * set. Thus we make some special allowances in the transmit * section that are not in the receive section. */ if( args.tr || args.bidir ) { /* This is the transmitter: send the block TRIALS times, and if we are not streaming, expect the receiver to return each block. */ for (i = 0; i < (integCheck ? 1 : TRIALS); i++) { if(args.preburst && asyncReceive && !streamopt) { /* We need to save the value of the recv ptr so * we can reset it after we do the preposts, in case * the module needs to use the same ptr values again * so it can wait on the last byte to change to indicate * the recv is finished. */ SaveRecvPtr(&args); for(j=0; j<nrepeat; j++) { PrepareToReceive(&args); if(!args.cache) AdvanceRecvPtr(&args, len_buf_align); } ResetRecvPtr(&args); } /* Flush the cache using the dummy buffer */ if (!args.cache) flushcache(memcache, MEMSIZE/sizeof(int)); Sync(&args); t0 = When(); for (j = 0; j < nrepeat; j++) { if (!args.preburst && asyncReceive && !streamopt) { PrepareToReceive(&args); } if (integCheck) SetIntegrityData(&args); SendData(&args); if (!streamopt) { RecvData(&args); if (integCheck) VerifyIntegrity(&args); if(!args.cache) AdvanceRecvPtr(&args, len_buf_align); } /* Wait to advance send pointer in case RecvData uses * it (e.g. memcpy module). */ if (!args.cache) AdvanceSendPtr(&args, len_buf_align); } /* t is the 1-directional trasmission time */ t = (When() - t0)/ nrepeat; if( !streamopt && !args.bidir) t /= 2; /* Normal ping-pong */ Reset(&args); /* NOTE: NetPIPE does each data point TRIALS times, bouncing the message * nrepeats times for each trial, then reports the lowest of the TRIALS * times. -Dave Turner */ bwdata[n].t = MIN(bwdata[n].t, t); /* t1 += t;*/ /* t2 += t*t;*/ } if (streamopt){ /* Get time info from Recv node */ RecvTime(&args, &bwdata[n].t); /* RecvTime(&args, &t1);*/ /* RecvTime(&args, &t2);*/ } /* Calculate variance after completing this set of trials */ /* bwdata[n].variance = t2/TRIALS - t1/TRIALS * t1/TRIALS;*/ } else if( args.rcv ) { /* This is the receiver: receive the block TRIALS times, and if we are not streaming, send the block back to the sender. */ for (i = 0; i < (integCheck ? 1 : TRIALS); i++) { if (asyncReceive) { if (args.preburst) { /* We need to save the value of the recv ptr so * we can reset it after we do the preposts, in case * the module needs to use the same ptr values again * so it can wait on the last byte to change to * indicate the recv is finished. */ SaveRecvPtr(&args); for (j=0; j < nrepeat; j++) { PrepareToReceive(&args); if (!args.cache) AdvanceRecvPtr(&args, len_buf_align); } ResetRecvPtr(&args); } else { PrepareToReceive(&args); } } /* Flush the cache using the dummy buffer */ if (!args.cache) flushcache(memcache, MEMSIZE/sizeof(int)); Sync(&args); t0 = When(); for (j = 0; j < nrepeat; j++) { RecvData(&args); if (integCheck) VerifyIntegrity(&args); if (!args.cache) { AdvanceRecvPtr(&args, len_buf_align); } if (!args.preburst && asyncReceive && (j < nrepeat-1)) { PrepareToReceive(&args); } if (!streamopt) { if (integCheck) SetIntegrityData(&args); SendData(&args); if(!args.cache) AdvanceSendPtr(&args, len_buf_align); } } t = (When() - t0)/ nrepeat; if( !streamopt && !args.bidir) t /= 2; /* Normal ping-pong */ Reset(&args); bwdata[n].t = MIN(bwdata[n].t, t); /* t1 += t;*/ /* t2 += t*t;*/ } if (streamopt){ /* Recv proc calcs time and sends to Trans */ SendTime(&args, &bwdata[n].t); /* SendTime(&args, &t1);*/ /* SendTime(&args, &t2);*/ } } else /* Just going along for the ride */ { for (i = 0; i < (integCheck ? 1 : TRIALS); i++) { Sync(&args); } } /* Streaming mode doesn't really calculate correct latencies * for small message sizes, and on some nics we can get * zero second latency after doing the math. Protect against * this. */ if(bwdata[n].t == 0.0) { bwdata[n].t = 0.000001; } tlast = bwdata[n].t; bwdata[n].bits = args.bufflen * CHARSIZE * (1+args.bidir); bwdata[n].bps = bwdata[n].bits / (bwdata[n].t * 1024 * 1024); bwdata[n].repeat = nrepeat; if (args.tr) { if(integCheck) { fprintf(out,"%8d %d", bwdata[n].bits / 8, nrepeat); } else { fprintf(out,"%8d %lf %12.8lf", bwdata[n].bits / 8, bwdata[n].bps, bwdata[n].t); } fprintf(out, "\n"); fflush(out); } /* Free using original buffer addresses since we may have aligned r_buff and s_buff */ if (args.cache) FreeBuff(args.r_buff_orig, NULL); if ( args.tr ) { if(integCheck) { fprintf(stderr, " Integrity check passed\n"); } else { fprintf(stderr," %8.2lf Mbps in %10.2lf usec\n", bwdata[n].bps, tlast*1.0e6); } } } /* End of perturbation loop */ } /* End of main loop */ /* Free using original buffer addresses since we may have aligned r_buff and s_buff */ if (!args.cache) { FreeBuff(args.s_buff_orig, args.r_buff_orig); } if (args.tr) fclose(out); CleanUp(&args); return 0; }