├── .gitattributes ├── .gitignore ├── H31DHT.cpp ├── H31DHT.h ├── H31DHT.rc ├── H31DHT.sln ├── H31DHT.vcproj ├── H31DHTDlg.cpp ├── H31DHTDlg.h ├── Md5.cpp ├── Md5.h ├── README.md ├── ReadMe.txt ├── SHA1.cpp ├── SHA1.h ├── ThreadWrapper.cpp ├── ThreadWrapper.h ├── dht-example.cpp ├── dht.cpp ├── dht.h ├── res ├── H31DHT.ico └── H31DHT.rc2 ├── resource.h ├── stdafx.cpp └── stdafx.h /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | 4 | # Custom for Visual Studio 5 | *.cs diff=csharp 6 | *.sln merge=union 7 | *.csproj merge=union 8 | *.vbproj merge=union 9 | *.fsproj merge=union 10 | *.dbproj merge=union 11 | 12 | # Standard to msysgit 13 | *.doc diff=astextplain 14 | *.DOC diff=astextplain 15 | *.docx diff=astextplain 16 | *.DOCX diff=astextplain 17 | *.dot diff=astextplain 18 | *.DOT diff=astextplain 19 | *.pdf diff=astextplain 20 | *.PDF diff=astextplain 21 | *.rtf diff=astextplain 22 | *.RTF diff=astextplain 23 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ################# 2 | ## Eclipse 3 | ################# 4 | 5 | *.pydevproject 6 | .project 7 | .metadata 8 | bin/ 9 | tmp/ 10 | *.tmp 11 | *.bak 12 | *.swp 13 | *~.nib 14 | local.properties 15 | .classpath 16 | .settings/ 17 | .loadpath 18 | 19 | # External tool builders 20 | .externalToolBuilders/ 21 | 22 | # Locally stored "Eclipse launch configurations" 23 | *.launch 24 | 25 | # CDT-specific 26 | .cproject 27 | 28 | # PDT-specific 29 | .buildpath 30 | 31 | 32 | ################# 33 | ## Visual Studio 34 | ################# 35 | 36 | ## Ignore Visual Studio temporary files, build results, and 37 | ## files generated by popular Visual Studio add-ons. 38 | 39 | # User-specific files 40 | *.suo 41 | *.user 42 | *.sln.docstates 43 | 44 | # Build results 45 | 46 | [Dd]ebug/ 47 | [Rr]elease/ 48 | x64/ 49 | build/ 50 | [Bb]in/ 51 | [Oo]bj/ 52 | 53 | # MSTest test Results 54 | [Tt]est[Rr]esult*/ 55 | [Bb]uild[Ll]og.* 56 | 57 | *_i.c 58 | *_p.c 59 | *.ilk 60 | *.meta 61 | *.obj 62 | *.pch 63 | *.pdb 64 | *.pgc 65 | *.pgd 66 | *.rsp 67 | *.sbr 68 | *.tlb 69 | *.tli 70 | *.tlh 71 | *.tmp 72 | *.tmp_proj 73 | *.log 74 | *.vspscc 75 | *.vssscc 76 | .builds 77 | *.pidb 78 | *.log 79 | *.scc 80 | 81 | # Visual C++ cache files 82 | ipch/ 83 | *.aps 84 | *.ncb 85 | *.opensdf 86 | *.sdf 87 | *.cachefile 88 | 89 | # Visual Studio profiler 90 | *.psess 91 | *.vsp 92 | *.vspx 93 | 94 | # Guidance Automation Toolkit 95 | *.gpState 96 | 97 | # ReSharper is a .NET coding add-in 98 | _ReSharper*/ 99 | *.[Rr]e[Ss]harper 100 | 101 | # TeamCity is a build add-in 102 | _TeamCity* 103 | 104 | # DotCover is a Code Coverage Tool 105 | *.dotCover 106 | 107 | # NCrunch 108 | *.ncrunch* 109 | .*crunch*.local.xml 110 | 111 | # Installshield output folder 112 | [Ee]xpress/ 113 | 114 | # DocProject is a documentation generator add-in 115 | DocProject/buildhelp/ 116 | DocProject/Help/*.HxT 117 | DocProject/Help/*.HxC 118 | DocProject/Help/*.hhc 119 | DocProject/Help/*.hhk 120 | DocProject/Help/*.hhp 121 | DocProject/Help/Html2 122 | DocProject/Help/html 123 | 124 | # Click-Once directory 125 | publish/ 126 | 127 | # Publish Web Output 128 | *.Publish.xml 129 | *.pubxml 130 | 131 | # NuGet Packages Directory 132 | ## TODO: If you have NuGet Package Restore enabled, uncomment the next line 133 | #packages/ 134 | 135 | # Windows Azure Build Output 136 | csx 137 | *.build.csdef 138 | 139 | # Windows Store app package directory 140 | AppPackages/ 141 | 142 | # Others 143 | sql/ 144 | *.Cache 145 | ClientBin/ 146 | [Ss]tyle[Cc]op.* 147 | ~$* 148 | *~ 149 | *.dbmdl 150 | *.[Pp]ublish.xml 151 | *.pfx 152 | *.publishsettings 153 | 154 | # RIA/Silverlight projects 155 | Generated_Code/ 156 | 157 | # Backup & report files from converting an old project file to a newer 158 | # Visual Studio version. Backup files are not needed, because we have git ;-) 159 | _UpgradeReport_Files/ 160 | Backup*/ 161 | UpgradeLog*.XML 162 | UpgradeLog*.htm 163 | 164 | # SQL Server files 165 | App_Data/*.mdf 166 | App_Data/*.ldf 167 | 168 | ############# 169 | ## Windows detritus 170 | ############# 171 | 172 | # Windows image file caches 173 | Thumbs.db 174 | ehthumbs.db 175 | 176 | # Folder config file 177 | Desktop.ini 178 | 179 | # Recycle Bin used on file shares 180 | $RECYCLE.BIN/ 181 | 182 | # Mac crap 183 | .DS_Store 184 | 185 | 186 | ############# 187 | ## Python 188 | ############# 189 | 190 | *.py[co] 191 | 192 | # Packages 193 | *.egg 194 | *.egg-info 195 | dist/ 196 | build/ 197 | eggs/ 198 | parts/ 199 | var/ 200 | sdist/ 201 | develop-eggs/ 202 | .installed.cfg 203 | 204 | # Installer logs 205 | pip-log.txt 206 | 207 | # Unit test / coverage reports 208 | .coverage 209 | .tox 210 | 211 | #Translations 212 | *.mo 213 | 214 | #Mr Developer 215 | .mr.developer.cfg 216 | -------------------------------------------------------------------------------- /H31DHT.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/h31h31/H31DHTDEMO/c5c14f5832ab4ef5bbaa1211e421f69ed66a8116/H31DHT.cpp -------------------------------------------------------------------------------- /H31DHT.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/h31h31/H31DHTDEMO/c5c14f5832ab4ef5bbaa1211e421f69ed66a8116/H31DHT.h -------------------------------------------------------------------------------- /H31DHT.rc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/h31h31/H31DHTDEMO/c5c14f5832ab4ef5bbaa1211e421f69ed66a8116/H31DHT.rc -------------------------------------------------------------------------------- /H31DHT.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 9.00 3 | # Visual Studio 2005 4 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "H31DHT", "H31DHT.vcproj", "{CCB0CA24-F493-4BA6-8B8C-43D9B662015B}" 5 | EndProject 6 | Global 7 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 8 | Debug|Win32 = Debug|Win32 9 | Release|Win32 = Release|Win32 10 | EndGlobalSection 11 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 12 | {CCB0CA24-F493-4BA6-8B8C-43D9B662015B}.Debug|Win32.ActiveCfg = Debug|Win32 13 | {CCB0CA24-F493-4BA6-8B8C-43D9B662015B}.Debug|Win32.Build.0 = Debug|Win32 14 | {CCB0CA24-F493-4BA6-8B8C-43D9B662015B}.Release|Win32.ActiveCfg = Release|Win32 15 | {CCB0CA24-F493-4BA6-8B8C-43D9B662015B}.Release|Win32.Build.0 = Release|Win32 16 | EndGlobalSection 17 | GlobalSection(SolutionProperties) = preSolution 18 | HideSolutionNode = FALSE 19 | EndGlobalSection 20 | EndGlobal 21 | -------------------------------------------------------------------------------- /H31DHT.vcproj: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/h31h31/H31DHTDEMO/c5c14f5832ab4ef5bbaa1211e421f69ed66a8116/H31DHT.vcproj -------------------------------------------------------------------------------- /H31DHTDlg.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/h31h31/H31DHTDEMO/c5c14f5832ab4ef5bbaa1211e421f69ed66a8116/H31DHTDlg.cpp -------------------------------------------------------------------------------- /H31DHTDlg.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/h31h31/H31DHTDEMO/c5c14f5832ab4ef5bbaa1211e421f69ed66a8116/H31DHTDlg.h -------------------------------------------------------------------------------- /Md5.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/h31h31/H31DHTDEMO/c5c14f5832ab4ef5bbaa1211e421f69ed66a8116/Md5.cpp -------------------------------------------------------------------------------- /Md5.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/h31h31/H31DHTDEMO/c5c14f5832ab4ef5bbaa1211e421f69ed66a8116/Md5.h -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 代码的文章介绍参考:http://www.cnblogs.com/miao31/ 2 | 出售商业网站代码,效果如http://h31bt.com,万元起,非诚勿扰,谢谢. 3 | 联系h31h31 at 163.com 4 | -------------------------------------------------------------------------------- /ReadMe.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/h31h31/H31DHTDEMO/c5c14f5832ab4ef5bbaa1211e421f69ed66a8116/ReadMe.txt -------------------------------------------------------------------------------- /SHA1.cpp: -------------------------------------------------------------------------------- 1 | // If compiling with MFC, you might want to add #include "StdAfx.h" 2 | #include "StdAfx.h" 3 | #define _CRT_SECURE_NO_WARNINGS 4 | #include "SHA1.h" 5 | 6 | #define SHA1_MAX_FILE_BUFFER (32 * 20 * 820) 7 | 8 | // Rotate p_val32 by p_nBits bits to the left 9 | #ifndef ROL32 10 | #ifdef _MSC_VER 11 | #define ROL32(p_val32,p_nBits) _rotl(p_val32,p_nBits) 12 | #else 13 | #define ROL32(p_val32,p_nBits) (((p_val32)<<(p_nBits))|((p_val32)>>(32-(p_nBits)))) 14 | #endif 15 | #endif 16 | 17 | #ifdef SHA1_LITTLE_ENDIAN 18 | #define SHABLK0(i) (m_block->l[i] = \ 19 | (ROL32(m_block->l[i],24) & 0xFF00FF00) | (ROL32(m_block->l[i],8) & 0x00FF00FF)) 20 | #else 21 | #define SHABLK0(i) (m_block->l[i]) 22 | #endif 23 | 24 | #define SHABLK(i) (m_block->l[i&15] = ROL32(m_block->l[(i+13)&15] ^ \ 25 | m_block->l[(i+8)&15] ^ m_block->l[(i+2)&15] ^ m_block->l[i&15],1)) 26 | 27 | // SHA-1 rounds 28 | #define S_R0(v,w,x,y,z,i) {z+=((w&(x^y))^y)+SHABLK0(i)+0x5A827999+ROL32(v,5);w=ROL32(w,30);} 29 | #define S_R1(v,w,x,y,z,i) {z+=((w&(x^y))^y)+SHABLK(i)+0x5A827999+ROL32(v,5);w=ROL32(w,30);} 30 | #define S_R2(v,w,x,y,z,i) {z+=(w^x^y)+SHABLK(i)+0x6ED9EBA1+ROL32(v,5);w=ROL32(w,30);} 31 | #define S_R3(v,w,x,y,z,i) {z+=(((w|x)&y)|(w&x))+SHABLK(i)+0x8F1BBCDC+ROL32(v,5);w=ROL32(w,30);} 32 | #define S_R4(v,w,x,y,z,i) {z+=(w^x^y)+SHABLK(i)+0xCA62C1D6+ROL32(v,5);w=ROL32(w,30);} 33 | 34 | #pragma warning(push) 35 | // Disable compiler warning 'Conditional expression is constant' 36 | #pragma warning(disable: 4127) 37 | 38 | CSHA1::CSHA1() 39 | { 40 | m_block = (SHA1_WORKSPACE_BLOCK*)m_workspace; 41 | 42 | Reset(); 43 | } 44 | 45 | #ifdef SHA1_WIPE_VARIABLES 46 | CSHA1::~CSHA1() 47 | { 48 | Reset(); 49 | } 50 | #endif 51 | 52 | void CSHA1::Reset() 53 | { 54 | // SHA1 initialization constants 55 | m_state[0] = 0x67452301; 56 | m_state[1] = 0xEFCDAB89; 57 | m_state[2] = 0x98BADCFE; 58 | m_state[3] = 0x10325476; 59 | m_state[4] = 0xC3D2E1F0; 60 | 61 | m_count[0] = 0; 62 | m_count[1] = 0; 63 | } 64 | 65 | void CSHA1::Transform(UINT_32* pState, const UINT_8* pBuffer) 66 | { 67 | UINT_32 a = pState[0], b = pState[1], c = pState[2], d = pState[3], e = pState[4]; 68 | 69 | memcpy(m_block, pBuffer, 64); 70 | 71 | // 4 rounds of 20 operations each, loop unrolled 72 | S_R0(a,b,c,d,e, 0); S_R0(e,a,b,c,d, 1); S_R0(d,e,a,b,c, 2); S_R0(c,d,e,a,b, 3); 73 | S_R0(b,c,d,e,a, 4); S_R0(a,b,c,d,e, 5); S_R0(e,a,b,c,d, 6); S_R0(d,e,a,b,c, 7); 74 | S_R0(c,d,e,a,b, 8); S_R0(b,c,d,e,a, 9); S_R0(a,b,c,d,e,10); S_R0(e,a,b,c,d,11); 75 | S_R0(d,e,a,b,c,12); S_R0(c,d,e,a,b,13); S_R0(b,c,d,e,a,14); S_R0(a,b,c,d,e,15); 76 | S_R1(e,a,b,c,d,16); S_R1(d,e,a,b,c,17); S_R1(c,d,e,a,b,18); S_R1(b,c,d,e,a,19); 77 | S_R2(a,b,c,d,e,20); S_R2(e,a,b,c,d,21); S_R2(d,e,a,b,c,22); S_R2(c,d,e,a,b,23); 78 | S_R2(b,c,d,e,a,24); S_R2(a,b,c,d,e,25); S_R2(e,a,b,c,d,26); S_R2(d,e,a,b,c,27); 79 | S_R2(c,d,e,a,b,28); S_R2(b,c,d,e,a,29); S_R2(a,b,c,d,e,30); S_R2(e,a,b,c,d,31); 80 | S_R2(d,e,a,b,c,32); S_R2(c,d,e,a,b,33); S_R2(b,c,d,e,a,34); S_R2(a,b,c,d,e,35); 81 | S_R2(e,a,b,c,d,36); S_R2(d,e,a,b,c,37); S_R2(c,d,e,a,b,38); S_R2(b,c,d,e,a,39); 82 | S_R3(a,b,c,d,e,40); S_R3(e,a,b,c,d,41); S_R3(d,e,a,b,c,42); S_R3(c,d,e,a,b,43); 83 | S_R3(b,c,d,e,a,44); S_R3(a,b,c,d,e,45); S_R3(e,a,b,c,d,46); S_R3(d,e,a,b,c,47); 84 | S_R3(c,d,e,a,b,48); S_R3(b,c,d,e,a,49); S_R3(a,b,c,d,e,50); S_R3(e,a,b,c,d,51); 85 | S_R3(d,e,a,b,c,52); S_R3(c,d,e,a,b,53); S_R3(b,c,d,e,a,54); S_R3(a,b,c,d,e,55); 86 | S_R3(e,a,b,c,d,56); S_R3(d,e,a,b,c,57); S_R3(c,d,e,a,b,58); S_R3(b,c,d,e,a,59); 87 | S_R4(a,b,c,d,e,60); S_R4(e,a,b,c,d,61); S_R4(d,e,a,b,c,62); S_R4(c,d,e,a,b,63); 88 | S_R4(b,c,d,e,a,64); S_R4(a,b,c,d,e,65); S_R4(e,a,b,c,d,66); S_R4(d,e,a,b,c,67); 89 | S_R4(c,d,e,a,b,68); S_R4(b,c,d,e,a,69); S_R4(a,b,c,d,e,70); S_R4(e,a,b,c,d,71); 90 | S_R4(d,e,a,b,c,72); S_R4(c,d,e,a,b,73); S_R4(b,c,d,e,a,74); S_R4(a,b,c,d,e,75); 91 | S_R4(e,a,b,c,d,76); S_R4(d,e,a,b,c,77); S_R4(c,d,e,a,b,78); S_R4(b,c,d,e,a,79); 92 | 93 | // Add the working vars back into state 94 | pState[0] += a; 95 | pState[1] += b; 96 | pState[2] += c; 97 | pState[3] += d; 98 | pState[4] += e; 99 | 100 | // Wipe variables 101 | #ifdef SHA1_WIPE_VARIABLES 102 | a = b = c = d = e = 0; 103 | #endif 104 | } 105 | 106 | void CSHA1::Update(const UINT_8* pbData, UINT_32 uLen) 107 | { 108 | UINT_32 j = ((m_count[0] >> 3) & 0x3F); 109 | 110 | if((m_count[0] += (uLen << 3)) < (uLen << 3)) 111 | ++m_count[1]; // Overflow 112 | 113 | m_count[1] += (uLen >> 29); 114 | 115 | UINT_32 i; 116 | if((j + uLen) > 63) 117 | { 118 | i = 64 - j; 119 | memcpy(&m_buffer[j], pbData, i); 120 | Transform(m_state, m_buffer); 121 | 122 | for( ; (i + 63) < uLen; i += 64) 123 | Transform(m_state, &pbData[i]); 124 | 125 | j = 0; 126 | } 127 | else i = 0; 128 | 129 | if((uLen - i) != 0) 130 | memcpy(&m_buffer[j], &pbData[i], uLen - i); 131 | } 132 | 133 | #ifdef SHA1_UTILITY_FUNCTIONS 134 | bool CSHA1::HashFile(const TCHAR* tszFileName) 135 | { 136 | if(tszFileName == NULL) return false; 137 | 138 | FILE* fpIn = _tfopen(tszFileName, _T("rb")); 139 | if(fpIn == NULL) return false; 140 | 141 | UINT_8* pbData = new UINT_8[SHA1_MAX_FILE_BUFFER]; 142 | if(pbData == NULL) { fclose(fpIn); return false; } 143 | 144 | bool bSuccess = true; 145 | while(true) 146 | { 147 | const size_t uRead = fread(pbData, 1, SHA1_MAX_FILE_BUFFER, fpIn); 148 | 149 | if(uRead > 0) 150 | Update(pbData, static_cast(uRead)); 151 | 152 | if(uRead < SHA1_MAX_FILE_BUFFER) 153 | { 154 | if(feof(fpIn) == 0) bSuccess = false; 155 | break; 156 | } 157 | } 158 | 159 | fclose(fpIn); 160 | delete[] pbData; 161 | return bSuccess; 162 | } 163 | #endif 164 | 165 | void CSHA1::Final() 166 | { 167 | UINT_32 i; 168 | 169 | UINT_8 pbFinalCount[8]; 170 | for(i = 0; i < 8; ++i) 171 | pbFinalCount[i] = static_cast((m_count[((i >= 4) ? 0 : 1)] >> 172 | ((3 - (i & 3)) * 8) ) & 0xFF); // Endian independent 173 | 174 | Update((UINT_8*)"\200", 1); 175 | 176 | while((m_count[0] & 504) != 448) 177 | Update((UINT_8*)"\0", 1); 178 | 179 | Update(pbFinalCount, 8); // Cause a Transform() 180 | 181 | for(i = 0; i < 20; ++i) 182 | m_digest[i] = static_cast((m_state[i >> 2] >> ((3 - 183 | (i & 3)) * 8)) & 0xFF); 184 | 185 | // Wipe variables for security reasons 186 | #ifdef SHA1_WIPE_VARIABLES 187 | memset(m_buffer, 0, 64); 188 | memset(m_state, 0, 20); 189 | memset(m_count, 0, 8); 190 | memset(pbFinalCount, 0, 8); 191 | Transform(m_state, m_buffer); 192 | #endif 193 | } 194 | 195 | #ifdef SHA1_UTILITY_FUNCTIONS 196 | bool CSHA1::ReportHash(TCHAR* tszReport, REPORT_TYPE rtReportType) const 197 | { 198 | if(tszReport == NULL) return false; 199 | 200 | TCHAR tszTemp[16]; 201 | 202 | if((rtReportType == REPORT_HEX) || (rtReportType == REPORT_HEX_SHORT)) 203 | { 204 | _sntprintf(tszTemp, 15, _T("%02X"), m_digest[0]); 205 | _tcscpy(tszReport, tszTemp); 206 | 207 | const TCHAR* lpFmt = ((rtReportType == REPORT_HEX) ? _T(" %02X") : _T("%02X")); 208 | for(size_t i = 1; i < 20; ++i) 209 | { 210 | _sntprintf(tszTemp, 15, lpFmt, m_digest[i]); 211 | _tcscat(tszReport, tszTemp); 212 | } 213 | } 214 | else if(rtReportType == REPORT_DIGIT) 215 | { 216 | _sntprintf(tszTemp, 15, _T("%u"), m_digest[0]); 217 | _tcscpy(tszReport, tszTemp); 218 | 219 | for(size_t i = 1; i < 20; ++i) 220 | { 221 | _sntprintf(tszTemp, 15, _T(" %u"), m_digest[i]); 222 | _tcscat(tszReport, tszTemp); 223 | } 224 | } 225 | else return false; 226 | 227 | return true; 228 | } 229 | #endif 230 | 231 | #ifdef SHA1_STL_FUNCTIONS 232 | bool CSHA1::ReportHashStl(std::basic_string& strOut, REPORT_TYPE rtReportType) const 233 | { 234 | TCHAR tszOut[84]; 235 | const bool bResult = ReportHash(tszOut, rtReportType); 236 | if(bResult) strOut = tszOut; 237 | return bResult; 238 | } 239 | #endif 240 | 241 | bool CSHA1::GetHash(UINT_8* pbDest20) const 242 | { 243 | if(pbDest20 == NULL) return false; 244 | memcpy(pbDest20, m_digest, 20); 245 | return true; 246 | } 247 | 248 | #pragma warning(pop) 249 | -------------------------------------------------------------------------------- /SHA1.h: -------------------------------------------------------------------------------- 1 | #ifndef SHA1_H_A545E61D43E9404E8D736869AB3CBFE7 2 | #define SHA1_H_A545E61D43E9404E8D736869AB3CBFE7 3 | 4 | #if !defined(SHA1_UTILITY_FUNCTIONS) && !defined(SHA1_NO_UTILITY_FUNCTIONS) 5 | #define SHA1_UTILITY_FUNCTIONS 6 | #endif 7 | 8 | #if !defined(SHA1_STL_FUNCTIONS) && !defined(SHA1_NO_STL_FUNCTIONS) 9 | #define SHA1_STL_FUNCTIONS 10 | #if !defined(SHA1_UTILITY_FUNCTIONS) 11 | #error STL functions require SHA1_UTILITY_FUNCTIONS. 12 | #endif 13 | #endif 14 | 15 | #include 16 | #include 17 | 18 | #ifdef SHA1_UTILITY_FUNCTIONS 19 | #include 20 | #include 21 | #endif 22 | 23 | #ifdef SHA1_STL_FUNCTIONS 24 | #include 25 | #endif 26 | 27 | #ifdef _MSC_VER 28 | #include 29 | #endif 30 | 31 | // You can define the endian mode in your files without modifying the SHA-1 32 | // source files. Just #define SHA1_LITTLE_ENDIAN or #define SHA1_BIG_ENDIAN 33 | // in your files, before including the SHA1.h header file. If you don't 34 | // define anything, the class defaults to little endian. 35 | #if !defined(SHA1_LITTLE_ENDIAN) && !defined(SHA1_BIG_ENDIAN) 36 | #define SHA1_LITTLE_ENDIAN 37 | #endif 38 | 39 | // If you want variable wiping, #define SHA1_WIPE_VARIABLES, if not, 40 | // #define SHA1_NO_WIPE_VARIABLES. If you don't define anything, it 41 | // defaults to wiping. 42 | #if !defined(SHA1_WIPE_VARIABLES) && !defined(SHA1_NO_WIPE_VARIABLES) 43 | #define SHA1_WIPE_VARIABLES 44 | #endif 45 | 46 | #if defined(SHA1_HAS_TCHAR) 47 | #include 48 | #else 49 | #ifdef _MSC_VER 50 | #include 51 | #else 52 | #ifndef TCHAR 53 | #define TCHAR char 54 | #endif 55 | #ifndef _T 56 | #define _T(__x) (__x) 57 | #define _tmain main 58 | #define _tprintf printf 59 | #define _getts gets 60 | #define _tcslen strlen 61 | #define _tfopen fopen 62 | #define _tcscpy strcpy 63 | #define _tcscat strcat 64 | #define _sntprintf snprintf 65 | #endif 66 | #endif 67 | #endif 68 | 69 | /////////////////////////////////////////////////////////////////////////// 70 | // Define variable types 71 | 72 | #ifndef UINT_8 73 | #ifdef _MSC_VER // Compiling with Microsoft compiler 74 | #define UINT_8 unsigned __int8 75 | #else // !_MSC_VER 76 | #define UINT_8 unsigned char 77 | #endif // _MSC_VER 78 | #endif 79 | 80 | #ifndef UINT_32 81 | #ifdef _MSC_VER // Compiling with Microsoft compiler 82 | #define UINT_32 unsigned __int32 83 | #else // !_MSC_VER 84 | #if (ULONG_MAX == 0xFFFFFFFFUL) 85 | #define UINT_32 unsigned long 86 | #else 87 | #define UINT_32 unsigned int 88 | #endif 89 | #endif // _MSC_VER 90 | #endif // UINT_32 91 | 92 | #ifndef INT_64 93 | #ifdef _MSC_VER // Compiling with Microsoft compiler 94 | #define INT_64 __int64 95 | #else // !_MSC_VER 96 | #define INT_64 long long 97 | #endif // _MSC_VER 98 | #endif // INT_64 99 | 100 | #ifndef UINT_64 101 | #ifdef _MSC_VER // Compiling with Microsoft compiler 102 | #define UINT_64 unsigned __int64 103 | #else // !_MSC_VER 104 | #define UINT_64 unsigned long long 105 | #endif // _MSC_VER 106 | #endif // UINT_64 107 | 108 | /////////////////////////////////////////////////////////////////////////// 109 | // Declare SHA-1 workspace 110 | 111 | typedef union 112 | { 113 | UINT_8 c[64]; 114 | UINT_32 l[16]; 115 | } SHA1_WORKSPACE_BLOCK; 116 | 117 | class CSHA1 118 | { 119 | public: 120 | #ifdef SHA1_UTILITY_FUNCTIONS 121 | // Different formats for ReportHash(Stl) 122 | enum REPORT_TYPE 123 | { 124 | REPORT_HEX = 0, 125 | REPORT_DIGIT = 1, 126 | REPORT_HEX_SHORT = 2 127 | }; 128 | #endif 129 | 130 | // Constructor and destructor 131 | CSHA1(); 132 | 133 | #ifdef SHA1_WIPE_VARIABLES 134 | ~CSHA1(); 135 | #endif 136 | 137 | void Reset(); 138 | 139 | // Hash in binary data and strings 140 | void Update(const UINT_8* pbData, UINT_32 uLen); 141 | 142 | #ifdef SHA1_UTILITY_FUNCTIONS 143 | // Hash in file contents 144 | bool HashFile(const TCHAR* tszFileName); 145 | #endif 146 | 147 | // Finalize hash; call it before using ReportHash(Stl) 148 | void Final(); 149 | 150 | #ifdef SHA1_UTILITY_FUNCTIONS 151 | bool ReportHash(TCHAR* tszReport, REPORT_TYPE rtReportType = REPORT_HEX) const; 152 | #endif 153 | 154 | #ifdef SHA1_STL_FUNCTIONS 155 | bool ReportHashStl(std::basic_string& strOut, REPORT_TYPE rtReportType = 156 | REPORT_HEX) const; 157 | #endif 158 | 159 | // Get the raw message digest (20 bytes) 160 | bool GetHash(UINT_8* pbDest20) const; 161 | 162 | private: 163 | // Private SHA-1 transformation 164 | void Transform(UINT_32* pState, const UINT_8* pBuffer); 165 | 166 | // Member variables 167 | UINT_32 m_state[5]; 168 | UINT_32 m_count[2]; 169 | UINT_32 m_reserved0[1]; // Memory alignment padding 170 | UINT_8 m_buffer[64]; 171 | UINT_8 m_digest[20]; 172 | UINT_32 m_reserved1[3]; // Memory alignment padding 173 | 174 | UINT_8 m_workspace[64]; 175 | SHA1_WORKSPACE_BLOCK* m_block; // SHA1 pointer to the byte array above 176 | }; 177 | 178 | #endif // SHA1_H_A545E61D43E9404E8D736869AB3CBFE7 179 | -------------------------------------------------------------------------------- /ThreadWrapper.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/h31h31/H31DHTDEMO/c5c14f5832ab4ef5bbaa1211e421f69ed66a8116/ThreadWrapper.cpp -------------------------------------------------------------------------------- /ThreadWrapper.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/h31h31/H31DHTDEMO/c5c14f5832ab4ef5bbaa1211e421f69ed66a8116/ThreadWrapper.h -------------------------------------------------------------------------------- /dht-example.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | 3 | 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | #include "io.h" 12 | #include "dht.h" 13 | #include "winsock2.h" 14 | #include "ws2tcpip.h" 15 | #include "SHA1.h" 16 | 17 | #define MAX_BOOTSTRAP_NODES 20 18 | static struct sockaddr_storage bootstrap_nodes[MAX_BOOTSTRAP_NODES]; 19 | static int num_bootstrap_nodes = 0; 20 | 21 | static volatile int dumping = 0; 22 | static volatile int searching = 0; 23 | static volatile int exiting = 0; 24 | 25 | //static void sigdump(int signo) 26 | //{ 27 | // dumping = 1; 28 | //} 29 | // 30 | //static void sigtest(int signo) 31 | //{ 32 | // searching = 1; 33 | //} 34 | // 35 | //static void sigexit(int signo) 36 | //{ 37 | // exiting = 1; 38 | //} 39 | 40 | static void init_signals(void) 41 | { 42 | // struct sigaction sa; 43 | // sigset_t ss; 44 | // 45 | // sigemptyset(&ss); 46 | // sa.sa_handler = sigdump; 47 | // sa.sa_mask = ss; 48 | // sa.sa_flags = 0; 49 | // sigaction(SIGUSR1, &sa, NULL); 50 | // 51 | // sigemptyset(&ss); 52 | // sa.sa_handler = sigtest; 53 | // sa.sa_mask = ss; 54 | // sa.sa_flags = 0; 55 | // sigaction(SIGUSR2, &sa, NULL); 56 | // 57 | // sigemptyset(&ss); 58 | // sa.sa_handler = sigexit; 59 | // sa.sa_mask = ss; 60 | // sa.sa_flags = 0; 61 | // sigaction(SIGINT, &sa, NULL); 62 | } 63 | 64 | const unsigned char hash[20] = { 65 | 0x54, 0x57, 0x87, 0x89, 0xdf, 0xc4, 0x23, 0xee, 0xf6, 0x03, 66 | 0x1f, 0x81, 0x94, 0xa9, 0x3a, 0x16, 0x98, 0x8b, 0x72, 0x7b 67 | }; 68 | 69 | /* The call-back function is called by the DHT whenever something 70 | interesting happens. Right now, it only happens when we get a new value or 71 | when a search completes, but this may be extended in future versions. */ 72 | static void 73 | callback(void *closure, 74 | int event, 75 | unsigned char *info_hash, 76 | void *data, size_t data_len) 77 | { 78 | if(event == DHT_EVENT_SEARCH_DONE) 79 | printf("Search done.\n"); 80 | else if(event == DHT_EVENT_VALUES) 81 | printf("Received %d values.\n", (int)(data_len / 6)); 82 | } 83 | 84 | static char buf[4096]; 85 | 86 | int 87 | main(int argc, char **argv) 88 | { 89 | int i, rc, fd; 90 | int s = -1, s6 = -1, port; 91 | int have_id = 0; 92 | unsigned char myid[20]; 93 | time_t tosleep = 0; 94 | char *id_file = "dht-example.id"; 95 | int opt; 96 | int quiet = 0, ipv4 = 1, ipv6 = 1; 97 | struct sockaddr_in sin; 98 | struct sockaddr_in6 sin6; 99 | struct sockaddr_storage from; 100 | socklen_t fromlen; 101 | 102 | memset(&sin, 0, sizeof(sin)); 103 | sin.sin_family = AF_INET; 104 | 105 | memset(&sin6, 0, sizeof(sin6)); 106 | sin6.sin6_family = AF_INET6; 107 | 108 | 109 | 110 | //while(1) { 111 | // opt = getopt(argc, argv, "q46b:i:"); 112 | // if(opt < 0) 113 | // break; 114 | 115 | // switch(opt) { 116 | // case 'q': quiet = 1; break; 117 | // case '4': ipv6 = 0; break; 118 | // case '6': ipv4 = 0; break; 119 | // case 'b': { 120 | // char buf[16]; 121 | // int rc; 122 | // rc = inet_pton(AF_INET, optarg, buf); 123 | // if(rc == 1) { 124 | // memcpy(&sin.sin_addr, buf, 4); 125 | // break; 126 | // } 127 | // rc = inet_pton(AF_INET6, optarg, buf); 128 | // if(rc == 1) { 129 | // memcpy(&sin6.sin6_addr, buf, 16); 130 | // break; 131 | // } 132 | // goto usage; 133 | // } 134 | // break; 135 | // case 'i': 136 | // id_file = optarg; 137 | // break; 138 | // default: 139 | // goto usage; 140 | // } 141 | //} 142 | 143 | /* Ids need to be distributed evenly, so you cannot just use your 144 | bittorrent id. Either generate it randomly, or take the SHA-1 of 145 | something. */ 146 | fd = open(id_file, O_RDONLY); 147 | if(fd >= 0) { 148 | rc = read(fd, myid, 20); 149 | if(rc == 20) 150 | have_id = 1; 151 | close(fd); 152 | } 153 | 154 | fd = open("/dev/urandom", O_RDONLY); 155 | if(fd < 0) { 156 | perror("open(random)"); 157 | exit(1); 158 | } 159 | 160 | if(!have_id) { 161 | int ofd; 162 | 163 | rc = read(fd, myid, 20); 164 | if(rc < 0) { 165 | perror("read(random)"); 166 | exit(1); 167 | } 168 | have_id = 1; 169 | close(fd); 170 | 171 | ofd = open(id_file, O_WRONLY | O_CREAT | O_TRUNC, 0666); 172 | if(ofd >= 0) { 173 | rc = write(ofd, myid, 20); 174 | if(rc < 20) 175 | unlink(id_file); 176 | close(ofd); 177 | } 178 | } 179 | 180 | { 181 | unsigned seed; 182 | read(fd, &seed, sizeof(seed)); 183 | //srandom(seed); 184 | } 185 | 186 | close(fd); 187 | 188 | if(argc < 2) 189 | goto usage; 190 | 191 | //i = optind; 192 | 193 | if(argc < i + 1) 194 | goto usage; 195 | 196 | port = atoi(argv[i++]); 197 | if(port <= 0 || port >= 0x10000) 198 | goto usage; 199 | 200 | while(i < argc) 201 | { 202 | struct addrinfo hints, *info, *infop; 203 | memset(&hints, 0, sizeof(hints)); 204 | hints.ai_socktype = SOCK_DGRAM; 205 | if(!ipv6) 206 | hints.ai_family = AF_INET; 207 | else if(!ipv4) 208 | hints.ai_family = AF_INET6; 209 | else 210 | hints.ai_family = 0; 211 | rc = getaddrinfo(argv[i], argv[i + 1], &hints, &info); 212 | if(rc != 0) { 213 | fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rc)); 214 | exit(1); 215 | } 216 | 217 | i++; 218 | if(i >= argc) 219 | goto usage; 220 | 221 | infop = info; 222 | while(infop) { 223 | memcpy(&bootstrap_nodes[num_bootstrap_nodes],infop->ai_addr, infop->ai_addrlen); 224 | infop = infop->ai_next; 225 | num_bootstrap_nodes++; 226 | } 227 | freeaddrinfo(info); 228 | 229 | i++; 230 | } 231 | 232 | /* If you set dht_debug to a stream, every action taken by the DHT will 233 | be logged. */ 234 | if(!quiet) 235 | dht_debug = stdout; 236 | 237 | /* We need an IPv4 and an IPv6 socket, bound to a stable port. Rumour 238 | has it that uTorrent works better when it is the same as your 239 | Bittorrent port. */ 240 | if(ipv4) { 241 | s = socket(PF_INET, SOCK_DGRAM, 0); 242 | if(s < 0) { 243 | perror("socket(IPv4)"); 244 | } 245 | } 246 | 247 | if(ipv6) { 248 | s6 = socket(PF_INET6, SOCK_DGRAM, 0); 249 | if(s6 < 0) { 250 | perror("socket(IPv6)"); 251 | } 252 | } 253 | 254 | if(s < 0 && s6 < 0) { 255 | fprintf(stderr, "Eek!"); 256 | exit(1); 257 | } 258 | 259 | 260 | if(s >= 0) { 261 | sin.sin_port = htons(port); 262 | rc = bind(s, (struct sockaddr*)&sin, sizeof(sin)); 263 | if(rc < 0) { 264 | perror("bind(IPv4)"); 265 | exit(1); 266 | } 267 | } 268 | 269 | if(s6 >= 0) { 270 | int rc; 271 | int val = 1; 272 | 273 | //rc = setsockopt(s6, IPPROTO_IPV6, IPV6_V6ONLY, 274 | // (char *)&val, sizeof(val)); 275 | if(rc < 0) { 276 | perror("setsockopt(IPV6_V6ONLY)"); 277 | exit(1); 278 | } 279 | 280 | /* BEP-32 mandates that we should bind this socket to one of our 281 | global IPv6 addresses. In this simple example, this only 282 | happens if the user used the -b flag. */ 283 | 284 | sin6.sin6_port = htons(port); 285 | rc = bind(s6, (struct sockaddr*)&sin6, sizeof(sin6)); 286 | if(rc < 0) { 287 | perror("bind(IPv6)"); 288 | exit(1); 289 | } 290 | } 291 | 292 | /* Init the dht. This sets the socket into non-blocking mode. */ 293 | rc = dht_init(s, s6, myid, (unsigned char*)"JC\0\0"); 294 | if(rc < 0) { 295 | perror("dht_init"); 296 | exit(1); 297 | } 298 | 299 | init_signals(); 300 | 301 | /* For bootstrapping, we need an initial list of nodes. This could be 302 | hard-wired, but can also be obtained from the nodes key of a torrent 303 | file, or from the PORT bittorrent message. 304 | 305 | Dht_ping_node is the brutal way of bootstrapping -- it actually 306 | sends a message to the peer. If you're going to bootstrap from 307 | a massive number of nodes (for example because you're restoring from 308 | a dump) and you already know their ids, it's better to use 309 | dht_insert_node. If the ids are incorrect, the DHT will recover. */ 310 | for(i = 0; i < num_bootstrap_nodes; i++) { 311 | dht_ping_node((struct sockaddr*)&bootstrap_nodes[i], 312 | sizeof(bootstrap_nodes[i])); 313 | Sleep(random() % 1000); 314 | } 315 | 316 | while(1) { 317 | struct timeval tv; 318 | fd_set readfds; 319 | tv.tv_sec = tosleep; 320 | tv.tv_usec = random() % 1000000; 321 | 322 | FD_ZERO(&readfds); 323 | if(s >= 0) 324 | FD_SET(s, &readfds); 325 | if(s6 >= 0) 326 | FD_SET(s6, &readfds); 327 | rc = select(s > s6 ? s + 1 : s6 + 1, &readfds, NULL, NULL, &tv); 328 | if(rc < 0) { 329 | if(errno != EINTR) { 330 | perror("select"); 331 | Sleep(1000); 332 | } 333 | } 334 | 335 | if(exiting) 336 | break; 337 | 338 | if(rc > 0) { 339 | fromlen = sizeof(from); 340 | if(s >= 0 && FD_ISSET(s, &readfds)) 341 | rc = recvfrom(s, buf, sizeof(buf) - 1, 0, 342 | (struct sockaddr*)&from, &fromlen); 343 | else if(s6 >= 0 && FD_ISSET(s6, &readfds)) 344 | rc = recvfrom(s6, buf, sizeof(buf) - 1, 0, 345 | (struct sockaddr*)&from, &fromlen); 346 | else 347 | abort(); 348 | } 349 | 350 | if(rc > 0) { 351 | buf[rc] = '\0'; 352 | rc = dht_periodic(buf, rc, (struct sockaddr*)&from, fromlen, 353 | &tosleep, callback, NULL); 354 | } else { 355 | rc = dht_periodic(NULL, 0, NULL, 0, &tosleep, callback, NULL); 356 | } 357 | if(rc < 0) { 358 | if(errno == EINTR) { 359 | continue; 360 | } else { 361 | perror("dht_periodic"); 362 | if(rc == EINVAL || rc == EFAULT) 363 | abort(); 364 | tosleep = 1; 365 | } 366 | } 367 | 368 | /* This is how you trigger a search for a torrent hash. If port 369 | (the second argument) is non-zero, it also performs an announce. 370 | Since peers expire announced data after 30 minutes, it's a good 371 | idea to reannounce every 28 minutes or so. */ 372 | if(searching) { 373 | if(s >= 0) 374 | dht_search(hash, 0, AF_INET, callback, NULL); 375 | if(s6 >= 0) 376 | dht_search(hash, 0, AF_INET6, callback, NULL); 377 | searching = 0; 378 | } 379 | 380 | /* For debugging, or idle curiosity. */ 381 | if(dumping) { 382 | dht_dump_tables(stdout); 383 | dumping = 0; 384 | } 385 | } 386 | 387 | { 388 | struct sockaddr_in sin[500]; 389 | struct sockaddr_in6 sin6[500]; 390 | int num = 500, num6 = 500; 391 | int i; 392 | i = dht_get_nodes(sin, &num, sin6, &num6); 393 | printf("Found %d (%d + %d) good nodes.\n", i, num, num6); 394 | } 395 | 396 | dht_uninit(); 397 | return 0; 398 | 399 | usage: 400 | printf("Usage: dht-example [-q] [-4] [-6] [-i filename] [-b address]...\n" 401 | " port [address port]...\n"); 402 | exit(1); 403 | } 404 | 405 | /* Functions called by the DHT. */ 406 | 407 | int 408 | dht_blacklisted(const struct sockaddr *sa, int salen) 409 | { 410 | return 0; 411 | } 412 | 413 | /* We need to provide a reasonably strong cryptographic hashing function. 414 | Here's how we'd do it if we had RSA's MD5 code. */ 415 | #if 0 416 | void 417 | dht_hash(void *hash_return, int hash_size, 418 | const void *v1, int len1, 419 | const void *v2, int len2, 420 | const void *v3, int len3) 421 | { 422 | static MD5_CTX ctx; 423 | MD5Init(&ctx); 424 | MD5Update(&ctx, v1, len1); 425 | MD5Update(&ctx, v2, len2); 426 | MD5Update(&ctx, v3, len3); 427 | MD5Final(&ctx); 428 | if(hash_size > 16) 429 | memset((char*)hash_return + 16, 0, hash_size - 16); 430 | memcpy(hash_return, ctx.digest, hash_size > 16 ? 16 : hash_size); 431 | } 432 | #else 433 | /* But for this example, we might as well use something weaker. */ 434 | void dht_hash(void *hash_return, int hash_size, 435 | const void *v1, int len1, 436 | const void *v2, int len2, 437 | const void *v3, int len3) 438 | { 439 | // const char *c1 = v1, *c2 = v2, *c3 = v3; 440 | // char key[9]; /* crypt is limited to 8 characters */ 441 | // int i; 442 | // 443 | // memset(key, 0, 9); 444 | //#define CRYPT_HAPPY(c) ((c % 0x60) + 0x20) 445 | // 446 | // for(i = 0; i < 2 && i < len1; i++) 447 | // key[i] = CRYPT_HAPPY(c1[i]); 448 | // for(i = 0; i < 4 && i < len1; i++) 449 | // key[2 + i] = CRYPT_HAPPY(c2[i]); 450 | // for(i = 0; i < 2 && i < len1; i++) 451 | // key[6 + i] = CRYPT_HAPPY(c3[i]); 452 | // strncpy(hash_return, crypt(key, "jc"), hash_size); 453 | } 454 | #endif 455 | 456 | int dht_random_bytes(void *buf, size_t size) 457 | { 458 | srand(time(NULL)); 459 | int maxint=(int)(pow(10.0,(double)size)-1); 460 | int rnd=rand(); 461 | int i=rnd%maxint; 462 | 463 | unsigned char p1[41]; 464 | unsigned char p[20]; 465 | memcpy(p,&i,sizeof(i)); 466 | CSHA1 sha1; 467 | sha1.Reset(); 468 | sha1.Update(p,sizeof(i)); 469 | sha1.Final(); 470 | 471 | sha1.ReportHash((TCHAR*)p1, CSHA1::REPORT_HEX_SHORT); 472 | memcpy(buf,p1,size); 473 | return 1; 474 | }; 475 | int random(void) 476 | { 477 | return rand(); 478 | }; 479 | -------------------------------------------------------------------------------- /dht.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/h31h31/H31DHTDEMO/c5c14f5832ab4ef5bbaa1211e421f69ed66a8116/dht.cpp -------------------------------------------------------------------------------- /dht.h: -------------------------------------------------------------------------------- 1 | 2 | #include "typeinfo" 3 | #define _O_RDWR 0x0002 /* open for reading and writing */ 4 | #define _O_CREAT 0x0100 /* create and open file */ 5 | #define _O_BINARY 0x8000 /* file mode is binary (untranslated) */ 6 | 7 | 8 | 9 | typedef void dht_callback(void *closure, int event,unsigned char *info_hash,void *data, size_t data_len); 10 | 11 | #define DHT_EVENT_NONE 0 12 | #define DHT_EVENT_VALUES 1 13 | #define DHT_EVENT_VALUES6 2 14 | #define DHT_EVENT_SEARCH_DONE 3 15 | #define DHT_EVENT_SEARCH_DONE6 4 16 | #define DHT_EVENT_PONG_VALUES 5 17 | #define DHT_EVENT_ANNOUNCE_PEER_VALUES 6 18 | #define DHT_EVENT_FINDNODE_VALUES 7 19 | #define DHT_EVENT_GETPEER_VALUES 8 20 | 21 | 22 | int dht_init(int s, int s6, const unsigned char *id, const unsigned char *v); 23 | int dht_insert_node(const unsigned char *id, struct sockaddr *sa, int salen); 24 | int dht_ping_node(struct sockaddr *sa, int salen); 25 | int dht_periodic(const void *buf, size_t buflen,const struct sockaddr *from, int fromlen,time_t *tosleep, dht_callback *callback, void *closure); 26 | void make_tid(unsigned char *tid_return, const char *prefix, unsigned short seqno); 27 | int send_get_peers(const struct sockaddr *sa, int salen,unsigned char *tid, int tid_len,unsigned char *infohash, int want, int confirm); 28 | int send_find_node(const struct sockaddr *sa, int salen,const unsigned char *tid, int tid_len,const unsigned char *target, int want, int confirm); 29 | int dht_search(const unsigned char *id, int port, int af, dht_callback *callback, void *closure); 30 | int dht_nodes(int af,int *good_return, int *dubious_return, int *cached_return,int *incoming_return); 31 | void dht_dump_tables(FILE *f); 32 | int dht_get_nodes(struct sockaddr_in *sin, int *num,int *numno,struct sockaddr_in6 *sin6, int *num6, int *num6no); 33 | int dht_uninit(void); 34 | 35 | int random(void); 36 | /* This must be provided by the user. */ 37 | int dht_blacklisted(const struct sockaddr *sa, int salen); 38 | void dht_hash(unsigned char *hash_return, int hash_size,char *v1, int len1,char *v2, int len2,char *v3, int len3); 39 | int dht_random_bytes(void *buf, size_t size); 40 | 41 | -------------------------------------------------------------------------------- /res/H31DHT.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/h31h31/H31DHTDEMO/c5c14f5832ab4ef5bbaa1211e421f69ed66a8116/res/H31DHT.ico -------------------------------------------------------------------------------- /res/H31DHT.rc2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/h31h31/H31DHTDEMO/c5c14f5832ab4ef5bbaa1211e421f69ed66a8116/res/H31DHT.rc2 -------------------------------------------------------------------------------- /resource.h: -------------------------------------------------------------------------------- 1 | //{{NO_DEPENDENCIES}} 2 | // Microsoft Visual C++ generated include file. 3 | // Used by H31DHT.rc 4 | // 5 | #define IDM_ABOUTBOX 0x0010 6 | #define IDD_ABOUTBOX 100 7 | #define IDS_ABOUTBOX 101 8 | #define IDD_H31DHT_DIALOG 102 9 | #define IDR_MAINFRAME 128 10 | #define IDC_EDIT1 1000 11 | #define IDC_BUTTON_GETID 1001 12 | #define IDC_EDIT_SHOWID 1002 13 | #define IDC_BEGIN 1003 14 | #define IDC_STOP 1004 15 | #define IDC_EDIT_LOG 1005 16 | #define IDC_EDIT2 1006 17 | #define IDC_EDIT_HASH 1007 18 | 19 | // Next default values for new objects 20 | // 21 | #ifdef APSTUDIO_INVOKED 22 | #ifndef APSTUDIO_READONLY_SYMBOLS 23 | #define _APS_NEXT_RESOURCE_VALUE 129 24 | #define _APS_NEXT_COMMAND_VALUE 32771 25 | #define _APS_NEXT_CONTROL_VALUE 1007 26 | #define _APS_NEXT_SYMED_VALUE 101 27 | #endif 28 | #endif 29 | -------------------------------------------------------------------------------- /stdafx.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/h31h31/H31DHTDEMO/c5c14f5832ab4ef5bbaa1211e421f69ed66a8116/stdafx.cpp -------------------------------------------------------------------------------- /stdafx.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/h31h31/H31DHTDEMO/c5c14f5832ab4ef5bbaa1211e421f69ed66a8116/stdafx.h --------------------------------------------------------------------------------