/*
 * Copyright (C) 2015 Michael Brown <mbrown@fensystems.co.uk>.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 2 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 * 02110-1301, USA.
 *
 * You can also choose to distribute this program under the terms of
 * the Unmodified Binary Distribution Licence (as given in the file
 * COPYING.UBDL), provided that you have satisfied its requirements.
 */

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );

#include <errno.h>
#include <assert.h>
#include <ipxe/uaccess.h>
#include <ipxe/sha256.h>
#include <ipxe/sha512.h>
#include <ipxe/hmac.h>
#include <ipxe/base16.h>
#include <ipxe/pccrc.h>

/** @file
 *
 * Peer Content Caching and Retrieval: Content Identification [MS-PCCRC]
 *
 */

/******************************************************************************
 *
 * Utility functions
 *
 ******************************************************************************
 */

/**
 * Transcribe hash value (for debugging)
 *
 * @v info		Content information
 * @v hash		Hash value
 * @ret string		Hash value string
 */
static inline const char *
peerdist_info_hash_ntoa ( const struct peerdist_info *info, const void *hash ) {
	static char buf[ ( 2 * PEERDIST_DIGEST_MAX_SIZE ) + 1 /* NUL */ ];
	size_t digestsize = info->digestsize;

	/* Sanity check */
	assert ( info != NULL );
	assert ( digestsize != 0 );
	assert ( base16_encoded_len ( digestsize ) < sizeof ( buf ) );

	/* Transcribe hash value */
	base16_encode ( hash, digestsize, buf, sizeof ( buf ) );
	return buf;
}

/**
 * Get raw data
 *
 * @v info		Content information
 * @v data		Data buffer
 * @v offset		Starting offset
 * @v len		Length
 * @ret rc		Return status code
 */
static int peerdist_info_get ( const struct peerdist_info *info, void *data,
			       size_t offset, size_t len ) {

	/* Sanity check */
	if ( ( offset > info->raw.len ) ||
	     ( len > ( info->raw.len - offset ) ) ) {
		DBGC ( info, "PCCRC %p data underrun at [%zx,%zx) of %zx\n",
		       info, offset, ( offset + len ), info->raw.len );
		return -ERANGE;
	}

	/* Copy data */
	copy_from_user ( data, info->raw.data, offset, len );

	return 0;
}

/**
 * Populate segment hashes
 *
 * @v segment		Content information segment to fill in
 * @v hash		Segment hash of data
 * @v secret		Segment secret
 */
static void peerdist_info_segment_hash ( struct peerdist_info_segment *segment,
					 const void *hash, const void *secret ){
	const struct peerdist_info *info = segment->info;
	struct digest_algorithm *digest = info->digest;
	uint8_t ctx[ hmac_ctxsize ( digest ) ];
	size_t digestsize = info->digestsize;
	static const uint16_t magic[] = PEERDIST_SEGMENT_ID_MAGIC;

	/* Sanity check */
	assert ( digestsize <= sizeof ( segment->hash ) );
	assert ( digestsize <= sizeof ( segment->secret ) );
	assert ( digestsize <= sizeof ( segment->id ) );

	/* Get segment hash of data */
	memcpy ( segment->hash, hash, digestsize );

	/* Get segment secret */
	memcpy ( segment->secret, secret, digestsize );

	/* Calculate segment identifier */
	hmac_init ( digest, ctx, segment->secret, digestsize );
	hmac_update ( digest, ctx, segment->hash, digestsize );
	hmac_update ( digest, ctx, magic, sizeof ( magic ) );
	hmac_final ( digest, ctx, segment->id );
}

/******************************************************************************
 *
 * Content Information version 1
 *
 ******************************************************************************
 */

/**
 * Get number of blocks within a block description
 *
 * @v info		Content information
 * @v offset		Block description offset
 * @ret blocks		Number of blocks, or negative error
 */
static int peerdist_info_v1_blocks ( const struct peerdist_info *info,
				     size_t offset ) {
	struct peerdist_info_v1_block raw;
	unsigned int blocks;
	int rc;

	/* Get block description header */
	if ( ( rc = peerdist_info_get ( info, &raw, offset,
					sizeof ( raw ) ) ) != 0 )
		return rc;

	/* Calculate number of blocks */
	blocks = le32_to_cpu ( raw.blocks );

	return blocks;
}

/**
 * Locate block description
 *
 * @v info		Content information
 * @v index		Segment index
 * @ret offset		Block description offset, or negative error
 */
static ssize_t peerdist_info_v1_block_offset ( const struct peerdist_info *info,
					       unsigned int index ) {
	size_t digestsize = info->digestsize;
	unsigned int i;
	size_t offset;
	int blocks;
	int rc;

	/* Sanity check */
	assert ( index < info->segments );

	/* Calculate offset of first block description */
	offset = ( sizeof ( struct peerdist_info_v1 ) +
		   ( info->segments *
		     sizeof ( peerdist_info_v1_segment_t ( digestsize ) ) ) );

	/* Iterate over block descriptions until we find this segment */
	for ( i = 0 ; i < index ; i++ ) {

		/* Get number of blocks */
		blocks = peerdist_info_v1_blocks ( info, offset );
		if ( blocks < 0 ) {
			rc = blocks;
			DBGC ( info, "PCCRC %p segment %d could not get number "
			       "of blocks: %s\n", info, i, strerror ( rc ) );
			return rc;
		}

		/* Move to next block description */
		offset += sizeof ( peerdist_info_v1_block_t ( digestsize,
							      blocks ) );
	}

	return offset;
}

/**
 * Populate content information
 *
 * @v info		Content information to fill in
 * @ret rc		Return status code
 */
static int peerdist_info_v1 ( struct peerdist_info *info ) {
	struct peerdist_info_v1 raw;
	struct peerdist_info_segment first;
	struct peerdist_info_segment last;
	size_t first_skip;
	size_t last_skip;
	size_t last_read;
	int rc;

	/* Get raw header */
	if ( ( rc = peerdist_info_get ( info, &raw, 0, sizeof ( raw ) ) ) != 0){
		DBGC ( info, "PCCRC %p could not get V1 content information: "
		       "%s\n", info, strerror ( rc ) );
		return rc;
	}
	assert ( raw.version.raw == cpu_to_le16 ( PEERDIST_INFO_V1 ) );

	/* Determine hash algorithm */
	switch ( raw.hash ) {
	case cpu_to_le32 ( PEERDIST_INFO_V1_HASH_SHA256 ) :
		info->digest = &sha256_algorithm;
		break;
	case cpu_to_le32 ( PEERDIST_INFO_V1_HASH_SHA384 ) :
		info->digest = &sha384_algorithm;
		break;
	case cpu_to_le32 ( PEERDIST_INFO_V1_HASH_SHA512 ) :
		info->digest = &sha512_algorithm;
		break;
	default:
		DBGC ( info, "PCCRC %p unsupported hash algorithm %#08x\n",
		       info, le32_to_cpu ( raw.hash ) );
		return -ENOTSUP;
	}
	info->digestsize = info->digest->digestsize;
	assert ( info->digest != NULL );
	DBGC2 ( info, "PCCRC %p using %s[%zd]\n",
		info, info->digest->name, ( info->digestsize * 8 ) );

	/* Calculate number of segments */
	info->segments = le32_to_cpu ( raw.segments );

	/* Get first segment */
	if ( ( rc = peerdist_info_segment ( info, &first, 0 ) ) != 0 )
		return rc;

	/* Calculate range start offset */
	info->range.start = first.range.start;

	/* Calculate trimmed range start offset */
	first_skip = le32_to_cpu ( raw.first );
	info->trim.start = ( first.range.start + first_skip );

	/* Get last segment */
	if ( ( rc = peerdist_info_segment ( info, &last,
					    ( info->segments - 1 ) ) ) != 0 )
		return rc;

	/* Calculate range end offset */
	info->range.end = last.range.end;

	/* Calculate trimmed range end offset */
	if ( raw.last ) {
		/* Explicit length to include from last segment is given */
		last_read = le32_to_cpu ( raw.last );
		last_skip = ( last.index ? 0 : first_skip );
		info->trim.end = ( last.range.start + last_skip + last_read );
	} else {
		/* No explicit length given: range extends to end of segment */
		info->trim.end = last.range.end;
	}

	return 0;
}

/**
 * Populate content information segment
 *
 * @v segment		Content information segment to fill in
 * @ret rc		Return status code
 */
static int peerdist_info_v1_segment ( struct peerdist_info_segment *segment ) {
	const struct peerdist_info *info = segment->info;
	size_t digestsize = info->digestsize;
	peerdist_info_v1_segment_t ( digestsize ) raw;
	ssize_t raw_offset;
	int blocks;
	int rc;

	/* Sanity checks */
	assert ( segment->index < info->segments );

	/* Get raw description */
	raw_offset = ( sizeof ( struct peerdist_info_v1 ) +
		       ( segment->index * sizeof ( raw ) ) );
	if ( ( rc = peerdist_info_get ( info, &raw, raw_offset,
					sizeof ( raw ) ) ) != 0 ) {
		DBGC ( info, "PCCRC %p segment %d could not get segment "
		       "description: %s\n", info, segment->index,
		       strerror ( rc ) );
		return rc;
	}

	/* Calculate start offset of this segment */
	segment->range.start = le64_to_cpu ( raw.segment.offset );

	/* Calculate end offset of this segment */
	segment->range.end = ( segment->range.start +
			       le32_to_cpu ( raw.segment.len ) );

	/* Calculate block size of this segment */
	segment->blksize = le32_to_cpu ( raw.segment.blksize );

	/* Locate block description for this segment */
	raw_offset = peerdist_info_v1_block_offset ( info, segment->index );
	if ( raw_offset < 0 ) {
		rc = raw_offset;
		return rc;
	}

	/* Get number of blocks */
	blocks = peerdist_info_v1_blocks ( info, raw_offset );
	if ( blocks < 0 ) {
		rc = blocks;
		DBGC ( info, "PCCRC %p segment %d could not get number of "
		       "blocks: %s\n", info, segment->index, strerror ( rc ) );
		return rc;
	}
	segment->blocks = blocks;

	/* Calculate segment hashes */
	peerdist_info_segment_hash ( segment, raw.hash, raw.secret );

	return 0;
}

/**
 * Populate content information block
 *
 * @v block		Content information block to fill in
 * @ret rc		Return status code
 */
static int peerdist_info_v1_block ( struct peerdist_info_block *block ) {
	const struct peerdist_info_segment *segment = block->segment;
	const struct peerdist_info *info = segment->info;
	size_t digestsize = info->digestsize;
	peerdist_info_v1_block_t ( digestsize, segment->blocks ) raw;
	ssize_t raw_offset;
	int rc;

	/* Sanity checks */
	assert ( block->index < segment->blocks );

	/* Calculate start offset of this block */
	block->range.start = ( segment->range.start +
			       ( block->index * segment->blksize ) );

	/* Calculate end offset of this block */
	block->range.end = ( block->range.start + segment->blksize );
	if ( block->range.end > segment->range.end )
		block->range.end = segment->range.end;

	/* Locate block description */
	raw_offset = peerdist_info_v1_block_offset ( info, segment->index );
	if ( raw_offset < 0 ) {
		rc = raw_offset;
		return rc;
	}

	/* Get block hash */
	raw_offset += offsetof ( typeof ( raw ), hash[block->index] );
	if ( ( rc = peerdist_info_get ( info, block->hash, raw_offset,
					digestsize ) ) != 0 ) {
		DBGC ( info, "PCCRC %p segment %d block %d could not get "
		       "hash: %s\n", info, segment->index, block->index,
		       strerror ( rc ) );
		return rc;
	}

	return 0;
}

/** Content information version 1 operations */
static struct peerdist_info_operations peerdist_info_v1_operations = {
	.info = peerdist_info_v1,
	.segment = peerdist_info_v1_segment,
	.block = peerdist_info_v1_block,
};

/******************************************************************************
 *
 * Content Information version 2
 *
 ******************************************************************************
 */

/** A segment cursor */
struct peerdist_info_v2_cursor {
	/** Raw data offset */
	size_t offset;
	/** Number of segments remaining within this chunk */
	unsigned int remaining;
	/** Accumulated segment length */
	size_t len;
};

/**
 * Initialise segment cursor
 *
 * @v cursor		Segment cursor
 */
static inline void
peerdist_info_v2_cursor_init ( struct peerdist_info_v2_cursor *cursor ) {

	/* Initialise cursor */
	cursor->offset = ( sizeof ( struct peerdist_info_v2 ) +
			   sizeof ( struct peerdist_info_v2_chunk ) );
	cursor->remaining = 0;
	cursor->len = 0;
}

/**
 * Update segment cursor to next segment description
 *
 * @v info		Content information
 * @v offset		Current offset
 * @v remaining		Number of segments remaining within this chunk
 * @ret rc		Return status code
 */
static int
peerdist_info_v2_cursor_next ( const struct peerdist_info *info,
			       struct peerdist_info_v2_cursor *cursor ) {
	size_t digestsize = info->digestsize;
	peerdist_info_v2_segment_t ( digestsize ) raw;
	struct peerdist_info_v2_chunk chunk;
	int rc;

	/* Get chunk description if applicable */
	if ( ! cursor->remaining ) {

		/* Get chunk description */
		if ( ( rc = peerdist_info_get ( info, &chunk,
						( cursor->offset -
						  sizeof ( chunk ) ),
						sizeof ( chunk ) ) ) != 0 )
			return rc;

		/* Update number of segments remaining */
		cursor->remaining = ( be32_to_cpu ( chunk.len ) /
				      sizeof ( raw ) );
	}

	/* Get segment description header */
	if ( ( rc = peerdist_info_get ( info, &raw.segment, cursor->offset,
					sizeof ( raw.segment ) ) ) != 0 )
		return rc;

	/* Update cursor */
	cursor->offset += sizeof ( raw );
	cursor->remaining--;
	if ( ! cursor->remaining )
		cursor->offset += sizeof ( chunk );
	cursor->len += be32_to_cpu ( raw.segment.len );

	return 0;
}

/**
 * Get number of segments and total length
 *
 * @v info		Content information
 * @v len		Length to fill in
 * @ret rc		Number of segments, or negative error
 */
static int peerdist_info_v2_segments ( const struct peerdist_info *info,
				       size_t *len ) {
	struct peerdist_info_v2_cursor cursor;
	unsigned int segments;
	int rc;

	/* Iterate over all segments */
	for ( peerdist_info_v2_cursor_init ( &cursor ), segments = 0 ;
	      cursor.offset < info->raw.len ; segments++ ) {

		/* Update segment cursor */
		if ( ( rc = peerdist_info_v2_cursor_next ( info,
							   &cursor ) ) != 0 ) {
			DBGC ( info, "PCCRC %p segment %d could not update "
			       "segment cursor: %s\n",
			       info, segments, strerror ( rc ) );
			return rc;
		}
	}

	/* Record accumulated length */
	*len = cursor.len;

	return segments;
}

/**
 * Populate content information
 *
 * @v info		Content information to fill in
 * @ret rc		Return status code
 */
static int peerdist_info_v2 ( struct peerdist_info *info ) {
	struct peerdist_info_v2 raw;
	size_t len = 0;
	int segments;
	int rc;

	/* Get raw header */
	if ( ( rc = peerdist_info_get ( info, &raw, 0, sizeof ( raw ) ) ) != 0){
		DBGC ( info, "PCCRC %p could not get V2 content information: "
		       "%s\n", info, strerror ( rc ) );
		return rc;
	}
	assert ( raw.version.raw == cpu_to_le16 ( PEERDIST_INFO_V2 ) );

	/* Determine hash algorithm */
	switch ( raw.hash ) {
	case PEERDIST_INFO_V2_HASH_SHA512_TRUNC :
		info->digest = &sha512_algorithm;
		info->digestsize = ( 256 / 8 );
		break;
	default:
		DBGC ( info, "PCCRC %p unsupported hash algorithm %#02x\n",
		       info, raw.hash );
		return -ENOTSUP;
	}
	assert ( info->digest != NULL );
	DBGC2 ( info, "PCCRC %p using %s[%zd]\n",
		info, info->digest->name, ( info->digestsize * 8 ) );

	/* Calculate number of segments and total length */
	segments = peerdist_info_v2_segments ( info, &len );
	if ( segments < 0 ) {
		rc = segments;
		DBGC ( info, "PCCRC %p could not get segment count and length: "
		       "%s\n", info, strerror ( rc ) );
		return rc;
	}
	info->segments = segments;

	/* Calculate range start offset */
	info->range.start = be64_to_cpu ( raw.offset );

	/* Calculate trimmed range start offset */
	info->trim.start = ( info->range.start + be32_to_cpu ( raw.first ) );

	/* Calculate range end offset */
	info->range.end = ( info->range.start + len );

	/* Calculate trimmed range end offset */
	info->trim.end = ( raw.len ? be64_to_cpu ( raw.len ) :
			   info->range.end );

	return 0;
}

/**
 * Populate content information segment
 *
 * @v segment		Content information segment to fill in
 * @ret rc		Return status code
 */
static int peerdist_info_v2_segment ( struct peerdist_info_segment *segment ) {
	const struct peerdist_info *info = segment->info;
	size_t digestsize = info->digestsize;
	peerdist_info_v2_segment_t ( digestsize ) raw;
	struct peerdist_info_v2_cursor cursor;
	unsigned int index;
	size_t len;
	int rc;

	/* Sanity checks */
	assert ( segment->index < info->segments );

	/* Iterate over all segments before the target segment */
	for ( peerdist_info_v2_cursor_init ( &cursor ), index = 0 ;
	      index < segment->index ; index++ ) {

		/* Update segment cursor */
		if ( ( rc = peerdist_info_v2_cursor_next ( info,
							   &cursor ) ) != 0 ) {
			DBGC ( info, "PCCRC %p segment %d could not update "
			       "segment cursor: %s\n",
			       info, index, strerror ( rc ) );
			return rc;
		}
	}

	/* Get raw description */
	if ( ( rc = peerdist_info_get ( info, &raw, cursor.offset,
					sizeof ( raw ) ) ) != 0 ) {
		DBGC ( info, "PCCRC %p segment %d could not get segment "
		       "description: %s\n",
		       info, segment->index, strerror ( rc ) );
		return rc;
	}

	/* Calculate start offset of this segment */
	segment->range.start = ( info->range.start + cursor.len );

	/* Calculate end offset of this segment */
	len = be32_to_cpu ( raw.segment.len );
	segment->range.end = ( segment->range.start + len );

	/* Model as a segment containing a single block */
	segment->blocks = 1;
	segment->blksize = len;

	/* Calculate segment hashes */
	peerdist_info_segment_hash ( segment, raw.hash, raw.secret );

	return 0;
}

/**
 * Populate content information block
 *
 * @v block		Content information block to fill in
 * @ret rc		Return status code
 */
static int peerdist_info_v2_block ( struct peerdist_info_block *block ) {
	const struct peerdist_info_segment *segment = block->segment;
	const struct peerdist_info *info = segment->info;
	size_t digestsize = info->digestsize;

	/* Sanity checks */
	assert ( block->index < segment->blocks );

	/* Model as a block covering the whole segment */
	memcpy ( &block->range, &segment->range, sizeof ( block->range ) );
	memcpy ( block->hash, segment->hash, digestsize );

	return 0;
}

/** Content information version 2 operations */
static struct peerdist_info_operations peerdist_info_v2_operations = {
	.block = peerdist_info_v2_block,
	.segment = peerdist_info_v2_segment,
	.info = peerdist_info_v2,
};

/******************************************************************************
 *
 * Content Information
 *
 ******************************************************************************
 */

/**
 * Populate content information
 *
 * @v data		Raw data
 * @v len		Length of raw data
 * @v info		Content information to fill in
 * @ret rc		Return status code
 */
int peerdist_info ( userptr_t data, size_t len, struct peerdist_info *info ) {
	union peerdist_info_version version;
	int rc;

	/* Initialise structure */
	memset ( info, 0, sizeof ( *info ) );
	info->raw.data = data;
	info->raw.len = len;

	/* Get version */
	if ( ( rc = peerdist_info_get ( info, &version, 0,
					sizeof ( version ) ) ) != 0 ) {
		DBGC ( info, "PCCRC %p could not get version: %s\n",
		       info, strerror ( rc ) );
		return rc;
	}
	DBGC2 ( info, "PCCRC %p version %d.%d\n",
		info, version.major, version.minor );

	/* Determine version */
	switch ( version.raw ) {
	case cpu_to_le16 ( PEERDIST_INFO_V1 ) :
		info->op = &peerdist_info_v1_operations;
		break;
	case cpu_to_le16 ( PEERDIST_INFO_V2 ) :
		info->op = &peerdist_info_v2_operations;
		break;
	default:
		DBGC ( info, "PCCRC %p unsupported version %d.%d\n",
		       info, version.major, version.minor );
		return -ENOTSUP;
	}
	assert ( info->op != NULL );
	assert ( info->op->info != NULL );

	/* Populate content information */
	if ( ( rc = info->op->info ( info ) ) != 0 )
		return rc;

	DBGC2 ( info, "PCCRC %p range [%08zx,%08zx) covers [%08zx,%08zx) with "
		"%d segments\n", info, info->range.start, info->range.end,
		info->trim.start, info->trim.end, info->segments );
	return 0;
}

/**
 * Populate content information segment
 *
 * @v info		Content information
 * @v segment		Content information segment to fill in
 * @v index		Segment index
 * @ret rc		Return status code
 */
int peerdist_info_segment ( const struct peerdist_info *info,
			    struct peerdist_info_segment *segment,
			    unsigned int index ) {
	int rc;

	/* Sanity checks */
	assert ( info != NULL );
	assert ( info->op != NULL );
	assert ( info->op->segment != NULL );
	if ( index >= info->segments ) {
		DBGC ( info, "PCCRC %p segment %d of [0,%d) out of range\n",
		       info, index, info->segments );
		return -ERANGE;
	}

	/* Initialise structure */
	memset ( segment, 0, sizeof ( *segment ) );
	segment->info = info;
	segment->index = index;

	/* Populate content information segment */
	if ( ( rc = info->op->segment ( segment ) ) != 0 )
		return rc;

	DBGC2 ( info, "PCCRC %p segment %d range [%08zx,%08zx) with %d "
		"blocks\n", info, segment->index, segment->range.start,
		segment->range.end, segment->blocks );
	DBGC2 ( info, "PCCRC %p segment %d digest %s\n", info, segment->index,
		peerdist_info_hash_ntoa ( info, segment->hash ) );
	DBGC2 ( info, "PCCRC %p segment %d secret %s\n", info, segment->index,
		peerdist_info_hash_ntoa ( info, segment->secret ) );
	DBGC2 ( info, "PCCRC %p segment %d identf %s\n", info, segment->index,
		peerdist_info_hash_ntoa ( info, segment->id ) );
	return 0;
}

/**
 * Populate content information block
 *
 * @v segment		Content information segment
 * @v block		Content information block to fill in
 * @v index		Block index
 * @ret rc		Return status code
 */
int peerdist_info_block ( const struct peerdist_info_segment *segment,
			  struct peerdist_info_block *block,
			  unsigned int index ) {
	const struct peerdist_info *info = segment->info;
	size_t start;
	size_t end;
	int rc;

	/* Sanity checks */
	assert ( segment != NULL );
	assert ( info != NULL );
	assert ( info->op != NULL );
	assert ( info->op->block != NULL );
	if ( index >= segment->blocks ) {
		DBGC ( info, "PCCRC %p segment %d block %d of [0,%d) out of "
		       "range\n", info, segment->index, index, segment->blocks);
		return -ERANGE;
	}

	/* Initialise structure */
	memset ( block, 0, sizeof ( *block ) );
	block->segment = segment;
	block->index = index;

	/* Populate content information block */
	if ( ( rc = info->op->block ( block ) ) != 0 )
		return rc;

	/* Calculate trimmed range */
	start = block->range.start;
	if ( start < info->trim.start )
		start = info->trim.start;
	end = block->range.end;
	if ( end > info->trim.end )
		end = info->trim.end;
	if ( end < start )
		end = start;
	block->trim.start = start;
	block->trim.end = end;

	DBGC2 ( info, "PCCRC %p segment %d block %d hash %s\n",
		info, segment->index, block->index,
		peerdist_info_hash_ntoa ( info, block->hash ) );
	DBGC2 ( info, "PCCRC %p segment %d block %d range [%08zx,%08zx) covers "
		"[%08zx,%08zx)\n", info, segment->index, block->index,
		block->range.start, block->range.end, block->trim.start,
		block->trim.end );
	return 0;
}
