@@ -293,6 +293,8 @@ struct parsed_message {
293293 unsigned char values6 [PARSE_VALUES6_LEN ];
294294 unsigned short values6_len ;
295295 unsigned short want ;
296+ unsigned char ip [18 ];
297+ unsigned short ip_len ;
296298};
297299
298300static int parse_message (const unsigned char * buf , int buflen ,
@@ -315,6 +317,9 @@ static int have_v = 0;
315317static unsigned char my_v [9 ];
316318static unsigned char secret [8 ];
317319static unsigned char oldsecret [8 ];
320+ static unsigned char ext_ip [18 ];
321+ static unsigned char ext_ip_len = 0 ;
322+ static unsigned int ext_ip_votes = 0 ;
318323
319324static struct bucket * buckets = NULL ;
320325static struct bucket * buckets6 = NULL ;
@@ -341,6 +346,111 @@ static time_t expire_stuff_time;
341346static time_t token_bucket_time ;
342347static int token_bucket_tokens ;
343348
349+ static const uint32_t crc32c_table [256 ] = {
350+ 0x00000000L , 0xF26B8303L , 0xE13B70F7L , 0x1350F3F4L ,
351+ 0xC79A971FL , 0x35F1141CL , 0x26A1E7E8L , 0xD4CA64EBL ,
352+ 0x8AD958CFL , 0x78B2DBCCL , 0x6BE22838L , 0x9989AB3BL ,
353+ 0x4D43CFD0L , 0xBF284CD3L , 0xAC78BF27L , 0x5E133C24L ,
354+ 0x105EC76FL , 0xE235446CL , 0xF165B798L , 0x030E349BL ,
355+ 0xD7C45070L , 0x25AFD373L , 0x36FF2087L , 0xC494A384L ,
356+ 0x9A879FA0L , 0x68EC1CA3L , 0x7BBCEF57L , 0x89D76C54L ,
357+ 0x5D1D08BFL , 0xAF768BBCL , 0xBC267848L , 0x4E4DFB4BL ,
358+ 0x20BD8EDEL , 0xD2D60DDDL , 0xC186FE29L , 0x33ED7D2AL ,
359+ 0xE72719C1L , 0x154C9AC2L , 0x061C6936L , 0xF477EA35L ,
360+ 0xAA64D611L , 0x580F5512L , 0x4B5FA6E6L , 0xB93425E5L ,
361+ 0x6DFE410EL , 0x9F95C20DL , 0x8CC531F9L , 0x7EAEB2FAL ,
362+ 0x30E349B1L , 0xC288CAB2L , 0xD1D83946L , 0x23B3BA45L ,
363+ 0xF779DEAEL , 0x05125DADL , 0x1642AE59L , 0xE4292D5AL ,
364+ 0xBA3A117EL , 0x4851927DL , 0x5B016189L , 0xA96AE28AL ,
365+ 0x7DA08661L , 0x8FCB0562L , 0x9C9BF696L , 0x6EF07595L ,
366+ 0x417B1DBCL , 0xB3109EBFL , 0xA0406D4BL , 0x522BEE48L ,
367+ 0x86E18AA3L , 0x748A09A0L , 0x67DAFA54L , 0x95B17957L ,
368+ 0xCBA24573L , 0x39C9C670L , 0x2A993584L , 0xD8F2B687L ,
369+ 0x0C38D26CL , 0xFE53516FL , 0xED03A29BL , 0x1F682198L ,
370+ 0x5125DAD3L , 0xA34E59D0L , 0xB01EAA24L , 0x42752927L ,
371+ 0x96BF4DCCL , 0x64D4CECFL , 0x77843D3BL , 0x85EFBE38L ,
372+ 0xDBFC821CL , 0x2997011FL , 0x3AC7F2EBL , 0xC8AC71E8L ,
373+ 0x1C661503L , 0xEE0D9600L , 0xFD5D65F4L , 0x0F36E6F7L ,
374+ 0x61C69362L , 0x93AD1061L , 0x80FDE395L , 0x72966096L ,
375+ 0xA65C047DL , 0x5437877EL , 0x4767748AL , 0xB50CF789L ,
376+ 0xEB1FCBADL , 0x197448AEL , 0x0A24BB5AL , 0xF84F3859L ,
377+ 0x2C855CB2L , 0xDEEEDFB1L , 0xCDBE2C45L , 0x3FD5AF46L ,
378+ 0x7198540DL , 0x83F3D70EL , 0x90A324FAL , 0x62C8A7F9L ,
379+ 0xB602C312L , 0x44694011L , 0x5739B3E5L , 0xA55230E6L ,
380+ 0xFB410CC2L , 0x092A8FC1L , 0x1A7A7C35L , 0xE811FF36L ,
381+ 0x3CDB9BDDL , 0xCEB018DEL , 0xDDE0EB2AL , 0x2F8B6829L ,
382+ 0x82F63B78L , 0x709DB87BL , 0x63CD4B8FL , 0x91A6C88CL ,
383+ 0x456CAC67L , 0xB7072F64L , 0xA457DC90L , 0x563C5F93L ,
384+ 0x082F63B7L , 0xFA44E0B4L , 0xE9141340L , 0x1B7F9043L ,
385+ 0xCFB5F4A8L , 0x3DDE77ABL , 0x2E8E845FL , 0xDCE5075CL ,
386+ 0x92A8FC17L , 0x60C37F14L , 0x73938CE0L , 0x81F80FE3L ,
387+ 0x55326B08L , 0xA759E80BL , 0xB4091BFFL , 0x466298FCL ,
388+ 0x1871A4D8L , 0xEA1A27DBL , 0xF94AD42FL , 0x0B21572CL ,
389+ 0xDFEB33C7L , 0x2D80B0C4L , 0x3ED04330L , 0xCCBBC033L ,
390+ 0xA24BB5A6L , 0x502036A5L , 0x4370C551L , 0xB11B4652L ,
391+ 0x65D122B9L , 0x97BAA1BAL , 0x84EA524EL , 0x7681D14DL ,
392+ 0x2892ED69L , 0xDAF96E6AL , 0xC9A99D9EL , 0x3BC21E9DL ,
393+ 0xEF087A76L , 0x1D63F975L , 0x0E330A81L , 0xFC588982L ,
394+ 0xB21572C9L , 0x407EF1CAL , 0x532E023EL , 0xA145813DL ,
395+ 0x758FE5D6L , 0x87E466D5L , 0x94B49521L , 0x66DF1622L ,
396+ 0x38CC2A06L , 0xCAA7A905L , 0xD9F75AF1L , 0x2B9CD9F2L ,
397+ 0xFF56BD19L , 0x0D3D3E1AL , 0x1E6DCDEEL , 0xEC064EEDL ,
398+ 0xC38D26C4L , 0x31E6A5C7L , 0x22B65633L , 0xD0DDD530L ,
399+ 0x0417B1DBL , 0xF67C32D8L , 0xE52CC12CL , 0x1747422FL ,
400+ 0x49547E0BL , 0xBB3FFD08L , 0xA86F0EFCL , 0x5A048DFFL ,
401+ 0x8ECEE914L , 0x7CA56A17L , 0x6FF599E3L , 0x9D9E1AE0L ,
402+ 0xD3D3E1ABL , 0x21B862A8L , 0x32E8915CL , 0xC083125FL ,
403+ 0x144976B4L , 0xE622F5B7L , 0xF5720643L , 0x07198540L ,
404+ 0x590AB964L , 0xAB613A67L , 0xB831C993L , 0x4A5A4A90L ,
405+ 0x9E902E7BL , 0x6CFBAD78L , 0x7FAB5E8CL , 0x8DC0DD8FL ,
406+ 0xE330A81AL , 0x115B2B19L , 0x020BD8EDL , 0xF0605BEEL ,
407+ 0x24AA3F05L , 0xD6C1BC06L , 0xC5914FF2L , 0x37FACCF1L ,
408+ 0x69E9F0D5L , 0x9B8273D6L , 0x88D28022L , 0x7AB90321L ,
409+ 0xAE7367CAL , 0x5C18E4C9L , 0x4F48173DL , 0xBD23943EL ,
410+ 0xF36E6F75L , 0x0105EC76L , 0x12551F82L , 0xE03E9C81L ,
411+ 0x34F4F86AL , 0xC69F7B69L , 0xD5CF889DL , 0x27A40B9EL ,
412+ 0x79B737BAL , 0x8BDCB4B9L , 0x988C474DL , 0x6AE7C44EL ,
413+ 0xBE2DA0A5L , 0x4C4623A6L , 0x5F16D052L , 0xAD7D5351L
414+ };
415+
416+ static uint32_t
417+ crc32c (const unsigned char * data , size_t len )
418+ {
419+ uint32_t crc = 0xffffffff ;
420+
421+ while (len -- )
422+ crc = crc32c_table [(crc ^ * data ++ ) & 0xff ] ^ (crc >> 8 );
423+
424+ return crc ^ 0xffffffff ;
425+ }
426+
427+ static uint32_t
428+ compute_id_prefix (const unsigned char * id , const unsigned char * ip ,
429+ size_t ip_len )
430+ {
431+ unsigned char buf [8 ];
432+
433+ if (ip_len == 6 ) {
434+ buf [0 ] = (ip [0 ] & 0x3 ) | (id [19 ] & 0x7 ) << 5 ;
435+ buf [1 ] = ip [1 ] & 0xf ;
436+ buf [2 ] = ip [2 ] & 0x3f ;
437+ buf [3 ] = ip [3 ] & 0xff ;
438+ return crc32c (buf , 4 );
439+ } else if (ip_len == 18 ) {
440+ buf [0 ] = (ip [0 ] & 0x1 ) | (id [19 ] & 0x7 ) << 5 ;
441+ buf [1 ] = ip [1 ] & 0x3 ;
442+ buf [2 ] = ip [2 ] & 0x7 ;
443+ buf [3 ] = ip [3 ] & 0xf ;
444+ buf [4 ] = ip [4 ] & 0x1f ;
445+ buf [5 ] = ip [5 ] & 0x3f ;
446+ buf [6 ] = ip [6 ] & 0x7f ;
447+ buf [7 ] = ip [7 ] & 0xff ;
448+ return crc32c (buf , 8 );
449+ }
450+
451+ return 0 ;
452+ }
453+
344454FILE * dht_debug = NULL ;
345455
346456#ifdef __GNUC__
@@ -2077,6 +2187,26 @@ dht_periodic(const void *buf, size_t buflen,
20772187
20782188 switch (message ) {
20792189 case REPLY :
2190+ if (m .ip_len == 6 || m .ip_len == 18 ) {
2191+ if (!ext_ip_votes ) {
2192+ memcpy (ext_ip , m .ip , m .ip_len );
2193+ ext_ip_len = m .ip_len ;
2194+ ext_ip_votes ++ ;
2195+ } else if (ext_ip_len == m .ip_len &&
2196+ !memcmp (ext_ip , m .ip , m .ip_len )) {
2197+ if (ext_ip_votes == 10 ) {
2198+ uint32_t prefix = compute_id_prefix (myid , ext_ip ,
2199+ ext_ip_len );
2200+ myid [0 ] = prefix >> 24 ;
2201+ myid [1 ] = (prefix >> 16 ) & 0xff ;
2202+ myid [2 ] = ((prefix >> 8 ) & 0xf8 ) | (myid [2 ] & 0x7 );
2203+
2204+ ext_ip_votes = 0 ;
2205+ } else
2206+ ext_ip_votes ++ ;
2207+ } else
2208+ ext_ip_votes -- ;
2209+ }
20802210 if (m .tid_len != 4 ) {
20812211 debugf ("Broken node truncates transaction ids: " );
20822212 debug_printable (buf , buflen );
@@ -2532,7 +2662,21 @@ send_pong(const struct sockaddr *sa, int salen,
25322662{
25332663 char buf [512 ];
25342664 int i = 0 , rc ;
2535- rc = snprintf (buf + i , 512 - i , "d1:rd2:id20:" ); INC (i , rc , 512 );
2665+ rc = snprintf (buf + i , 512 - i , "d2:ip" ); INC (i , rc , 512 );
2666+ if (sa -> sa_family == AF_INET ) {
2667+ struct sockaddr_in * sin = (struct sockaddr_in * )sa ;
2668+ rc = snprintf (buf + i , 512 - i , "6:" ); INC (i , rc , 512 );
2669+ COPY (buf , i , & sin -> sin_addr , 4 , 512 );
2670+ COPY (buf , i , & sin -> sin_port , 2 , 512 );
2671+ } else if (sa -> sa_family == AF_INET6 ) {
2672+ struct sockaddr_in6 * sin6 = (struct sockaddr_in6 * )sa ;
2673+ rc = snprintf (buf + i , 512 - i , "18:" ); INC (i , rc , 512 );
2674+ COPY (buf , i , & sin6 -> sin6_addr , 16 , 512 );
2675+ COPY (buf , i , & sin6 -> sin6_port , 2 , 512 );
2676+ } else {
2677+ abort ();
2678+ }
2679+ rc = snprintf (buf + i , 512 - i , "1:rd2:id20:" ); INC (i , rc , 512 );
25362680 COPY (buf , i , myid , 20 , 512 );
25372681 rc = snprintf (buf + i , 512 - i , "e1:t%d:" , tid_len ); INC (i , rc , 512 );
25382682 COPY (buf , i , tid , tid_len , 512 );
@@ -2585,7 +2729,21 @@ send_nodes_peers(const struct sockaddr *sa, int salen,
25852729 char buf [2048 ];
25862730 int i = 0 , rc , j0 , j , k , len ;
25872731
2588- rc = snprintf (buf + i , 2048 - i , "d1:rd2:id20:" ); INC (i , rc , 2048 );
2732+ rc = snprintf (buf + i , 2048 - i , "d2:ip" ); INC (i , rc , 2048 );
2733+ if (sa -> sa_family == AF_INET ) {
2734+ struct sockaddr_in * sin = (struct sockaddr_in * )sa ;
2735+ rc = snprintf (buf + i , 2048 - i , "6:" ); INC (i , rc , 2048 );
2736+ COPY (buf , i , & sin -> sin_addr , 4 , 2048 );
2737+ COPY (buf , i , & sin -> sin_port , 2 , 2048 );
2738+ } else if (sa -> sa_family == AF_INET6 ) {
2739+ struct sockaddr_in6 * sin6 = (struct sockaddr_in6 * )sa ;
2740+ rc = snprintf (buf + i , 2048 - i , "18:" ); INC (i , rc , 2048 );
2741+ COPY (buf , i , & sin6 -> sin6_addr , 16 , 2048 );
2742+ COPY (buf , i , & sin6 -> sin6_port , 2 , 2048 );
2743+ } else {
2744+ abort ();
2745+ }
2746+ rc = snprintf (buf + i , 2048 - i , "1:rd2:id20:" ); INC (i , rc , 2048 );
25892747 COPY (buf , i , myid , 20 , 2048 );
25902748 if (nodes_len > 0 ) {
25912749 rc = snprintf (buf + i , 2048 - i , "5:nodes%d:" , nodes_len );
@@ -2815,7 +2973,21 @@ send_peer_announced(const struct sockaddr *sa, int salen,
28152973 char buf [512 ];
28162974 int i = 0 , rc ;
28172975
2818- rc = snprintf (buf + i , 512 - i , "d1:rd2:id20:" ); INC (i , rc , 512 );
2976+ rc = snprintf (buf + i , 512 - i , "d2:ip" ); INC (i , rc , 512 );
2977+ if (sa -> sa_family == AF_INET ) {
2978+ struct sockaddr_in * sin = (struct sockaddr_in * )sa ;
2979+ rc = snprintf (buf + i , 512 - i , "6:" ); INC (i , rc , 512 );
2980+ COPY (buf , i , & sin -> sin_addr , 4 , 512 );
2981+ COPY (buf , i , & sin -> sin_port , 2 , 512 );
2982+ } else if (sa -> sa_family == AF_INET6 ) {
2983+ struct sockaddr_in6 * sin6 = (struct sockaddr_in6 * )sa ;
2984+ rc = snprintf (buf + i , 512 - i , "18:" ); INC (i , rc , 512 );
2985+ COPY (buf , i , & sin6 -> sin6_addr , 16 , 512 );
2986+ COPY (buf , i , & sin6 -> sin6_port , 2 , 512 );
2987+ } else {
2988+ abort ();
2989+ }
2990+ rc = snprintf (buf + i , 512 - i , "1:rd2:id20:" ); INC (i , rc , 512 );
28192991 COPY (buf , i , myid , 20 , 512 );
28202992 rc = snprintf (buf + i , 512 - i , "e1:t%d:" , tid_len );
28212993 INC (i , rc , 512 );
@@ -3042,6 +3214,18 @@ parse_message(const unsigned char *buf, int buflen,
30423214 debugf ("eek... unexpected end for want.\n" );
30433215 }
30443216
3217+ p = dht_memmem (buf , buflen , "2:ip" , 4 );
3218+ if (p ) {
3219+ long l ;
3220+ char * q ;
3221+ l = strtol ((char * )p + 4 , & q , 10 );
3222+ if (q && * q == ':' && l > 0 && l <= 18 ) {
3223+ CHECK (q + 1 , l );
3224+ memcpy (m -> ip , q + 1 , l );
3225+ m -> ip_len = l ;
3226+ }
3227+ }
3228+
30453229#undef CHECK
30463230
30473231 if (dht_memmem (buf , buflen , "1:y1:r" , 6 ))
0 commit comments