int parse_packet( const char str[] ) { const char *beg; int port = 0; /* Find port (required) */ beg = parse_packet_param( str, "Port: "); if( beg == NULL ) { return 0; } /* Read port */ if( sscanf( beg, "%d\r\n", &port ) != 1 && port > 0 && port < 65536 ) { return 0; } /* Find infohash (optional) */ beg = parse_packet_param( str, "Infohash: " ); if( beg != NULL ) { /* Read infohash for own request */ if( (strstr(beg, "\r\n") - beg) == SHA1_HEX_LENGTH && str_isHex( beg, SHA1_HEX_LENGTH ) && memcmp( beg, LPD_DEFAULT_INFOHASH, SHA1_HEX_LENGTH ) != 0 ) { memcpy( g_infohash, beg, SHA1_HEX_LENGTH ); } } return port; }
/* * Lookup the address of the node that has the given id. * The port refers to the kad instance. */ int kad_lookup_node( const char query[], IP *addr_return ) { UCHAR id[SHA1_BIN_LENGTH]; struct search *sr; int i, rc; if( strlen( query ) != SHA1_HEX_LENGTH || !str_isHex( query, SHA1_HEX_LENGTH ) ) { return -1; } bytes_from_hex( id, query, SHA1_HEX_LENGTH ); dht_lock(); rc = 1; sr = searches; while( sr ) { if( sr->af == gconf->af && id_equal( sr->id, id ) ) { for( i = 0; i < sr->numnodes; ++i ) { if( id_equal( sr->nodes[i].id, id ) ) { memcpy( addr_return, &sr->nodes[i].ss, sizeof(IP) ); rc = 0; goto done; } } break; } sr = sr->next; } done:; dht_unlock(); return rc; }
/* * Compute the id of a string using the sha1 digest. * In case of a 20 Byte hex string, the id converted directly. */ void id_compute( UCHAR id[], const char str[] ) { SHA1_CTX ctx; size_t size; size = strlen( str ); if( size == SHA1_HEX_LENGTH && str_isHex( str, SHA1_HEX_LENGTH ) ) { /* Treat hostname as hex string */ bytes_from_hex( id, str, SHA1_HEX_LENGTH ); } else { SHA1_Init( &ctx ); SHA1_Update( &ctx, (const UCHAR *) str, size); SHA1_Final( &ctx, id ); } }