FCP FEC Proposal rev. 1.0
[EMAIL PROTECTED] 20020912

I. INTRODUCTION:

This proposal presents a set of new FCP commands that can be used to
encode and decode files using forward error correction (FEC).

FEC is a way of encoding packetized data files with extra error
recovery information which can be used to reconstruct lost packets.
In this document I will refer to the packets containing data as "data
blocks" and those containing error recovery information as "check
blocks".

One of the objectives of this design is to separate FEC encoding and
decoding from inserting and retrieving the data and check blocks
to/from Freenet.  By separating encoding and decoding from insertion
and retrieval I sidestep the problem of having to hold FCP connections
open while waiting for large amounts of data to be fetched from /
inserted into Freenet.

For a given maximum block size, some FEC algorithms can only
practically handle files up to a certain maximum size.  The design
uses segmentation to handle this case.  Large files are divided into
smaller segments and FEC is only done on a per segment basis.  This
compromise provides a least limited redundancy for large files.

II. Assumptions
This proposal doesn't specify any particular FEC algorithm.  
However the following assumptions are implicit in the design:
 
A. For a given segment with k data blocks and n - k check blocks, it
must be possible to decode all k data blocks from any k of n data or
check blocks.

B. Encoder and decoder implementations must be completely specified by
an implementation name and a file length.  No other parameters can be
required to instantiate the encoder or decoder.

C. Within a segment all data blocks must be the same size and all
check blocks must be the same size.  The check block and data block
sizes are not required to be the same however.  Smaller trailing
blocks must be zero padded to the required length.

D. The encoder may ask for extra trailing data blocks.  These extra
blocks must contain zeros.

II. Proposed FCP FEC commands

convention: All numbers are hexadecimal

A. Helper messages, SegmentHeader and BlockMap

A SegmentHeader message contains all the information necessary to FEC
encode or decode a segment of a file.  SegmentHeaders may contain FEC
implementation specific fields.  They are guaranteed to contain the
documented fields given in the example SegmentHeader
message below:

SegmentHeader
FECAlgorithm=OnionFEC_a_1_2   // The FEC implementation name
FileLength=170000             // Total file length
Offset=0                      // Offset from the start of the file
BlockCount=6                  // Number of data blocks
BlockSize=40000               // Data block size
CheckBlockCount=3             // Number of check blocks
CheckBlockSize=3              // Check block size
Segments=1                    // Total number of segments
SegmentNum=0                  // Index of the current segment
BlocksRequired=6              // Blocks required to decode this segment
EndMessage

Client code should not rely on any undocumented fields.

BlockMap messages are used to list the CHKs of the data and check
blocks for a segment.

Here's an example:

BlockMap
Block.0=freenet:CHK@p2ISvZPkCwbY62xciJb~KrsOCTsSAwI,jGonMeCCz1GCHde5bc1t~w
Block.1=freenet:CHK@1z8CubDNzLEfNfuTYM4NVJAUxU4SAwI,5cxWki4YzWyKP0s3g9~Vow
Block.2=freenet:CHK@~VW7XskmHcJMFlmG6l2c7jkTOnkSAwI,Il2ztTbQImZvVlsnuDq-8Q
Block.3=freenet:CHK@A-qK8GWofXd9JOxb4fHfVMHAUawSAwI,2D5~Mm~MjAfup3edGXy6Eg
Block.4=freenet:CHK@r-FhUu444LxUIUGi5BMuEVGM4nQSAwI,J7HpLvPscLyW3Sc6Nq2S5g
Check.0=freenet:CHK@rLdCwOXO7PAv6BDpm21ThdIwmnkSAwI,4ZX2inJ7gg0EectTxPYRSg
Check.1=freenet:CHK@EjEg1UHWsAfHHMQmRbxe2ToY0RQSAwI,xjJCPsCxpnw9lyNI2VBRGA
EndMessage

B. FECSegmentFile
The FECSegmentFile message is used to generate the segment headers
necessary to encode a file of a given length with a specified FEC
algorithm.  

FECSegmentFile
AlgoName=OnionFEC_a_1_2
FileLength=ABC123
EndMessage

If this command is successful one or more SegmentHeader messages are sent in 
order
of ascending SegmentNumber.

The client can detect when the last segment has been sent by checking the 
SegmentNumber
and Segments field of each received SegmentHeader.

On failure a Failed message is sent.

C. FECEncodeSegment
The FECEncodeSegment message is used to create check blocks for a
segment of a file.  The RequestedList field contains a comma delimited
list of the requested check blocks. If the list is empty or omitted completely
all the check blocks are sent.

The SegmentHeader for the requested segment must sent as data in the
trailing field of the FECEncodeSegment message, preceding the raw
segment data to encode.

FECEncodeSegment
[RequestedList=0,A,F]
DataLength=<SegmentHeader length> + <segment length>
Data

< SegmentHeader >
< raw data >

If the encode request is successful, the server sends a BlocksEncoded
confirmation message, followed by DataChunk messages for the encoded
blocks.  Check blocks are sent in order of ascending index.

e.g:

BlocksEncoded
BlockCount=3
BlockSize=40000
EndMessage

DataChunk 
...
(3 * 40000 = 0xC0000 worth of DataChunk messages)
...

If the requests fails a Failed message is sent.


Note: 
The total segment size 
(SegmentHeader.BlockSize * SegmentHeader.BlockCount) can exceed the
length of the data present in the last segment.  In this case partial 
blocks should be zero padded and extra zero filled blocks should
be sent if requested.

D. FECDecodeSegment 
The FECDecodeSegment message is used to decode missing data blocks for
a segment of a file.  The RequestedList field contains a comma
delimited list of the requested data blocks.  Similarly, BlockList and
CheckList contain the indices of the data blocks and check blocks that
are being sent to decode from.  All index lists must be in ascending
order.

The SegmentHeader for the segment must sent as data in the trailing
field of the FECDecodeSegment message preceding the blocks to
decode from.

FECDecodeSegment
BlockList=0,2,3,5,6
CheckList=9,c
RequestedList=1,4
DataLength=<SegmentHeader length> + <total length of data and check blocks>
Data
< SegmentHeader >
< raw data blocks in order of index >
< raw check blocks in order of index >

If the decode request is successful, the server sends a BlocksDecoded
confirmation message, followed by DataChunk messages for the decoded
blocks.  The decoded data blocks are sent in order of ascending index.

e.g:

BlocksDecoded
BlockCount=2
BlockSize=40000
DataLength
EndMessage

DataChunk 
...
(2 * 40000 = 0x80000 worth of DataChunk messages)
...

If the requests fails a Failed message is sent.

E. FECSegmentSplitFile

The FECSegmentSplitFile command generates a list of SegmentHeaders and
BlockMaps from SplitFile metadata. The SplitFile metadata should
be sent as data in its trailing field.

e.g.:
FECSegmentSplitFile
DataLength=<SplitFile metadata length>
Data
<SplitFile metadata>

If successful the FCP server sends back one or more pairs of 
SegmentHeader and BlockMap messages in order of ascending segment number.

The client can tell how many pairs are coming by inspecting the Segments
field in the first SegmentHeader.

On failure a Failed message is sent.

F. FECMakeMetadata
The FECMakeMetadata command creates a metadata for a SplitFile from
a list of SegmentHeader BlockMap pairs sent as data in it's trailing field.
The list must be in order of ascending segment number.

FECMakeMetadata
Description=file
MimeType=text/plain
DataLength=<total length of all SegmentHeaders and BlockMaps>
Data
<SegmentHeader, BlockMap pairs>


III. Usage cases
Here's a brief description of how these messages are used to
encode and decode files.

A. Encoding
The client code sends a FECSegmentFile with the file's length and
saves the returned SegmentHeaders.

For each segment, it calls FECEncodeSegment with the segment's data
blocks and saves the returned check blocks.

It then inserts the data and check blocks into Freenet using the
existing ClientPut command, and saves the resulting CHK URIs.

After the data blocks and check blocks for all segments have been
inserted, the client code sends a FECMakeMetadata command with the
SegmentHeaders and BlockMaps listing the inserted blocks.  It saves
the SplitFile metadata and inserts it into Freenet.

Done.

A. Decoding

The client code sends a FECSegmentSplitFile with the SplitFile metadata
and saves the SegmentHeader,BlockMap pairs.

For each segment, it uses the CHK lists int the BlockMap to 
downloads the minimum number of data and check blocks
as given by SegmentHeader.BlocksRequired. It then calls FECDecodeSegment to 
decode the missing data blocks.

Finally, it concatinates the data blocks together, possibly ignoring trailing 
padding blocks.

Done.

III. Changes to SplitFile metadata format.

0) Deprecate the BlockSize field, since check blocks are not necessarily the
same size as data blocks and blocks may be different sizes across segments.

1) Add an AlgoName field. This is the name for the decoder and encoder 
implementation,
that can be used to decode or re-encode the file.  This replaces decoder.name 
and decoder.encoder
in the previous implementation.

2) Remove the decoder FieldSet.

* SplitFile.Graph is currently not being used and is not implemented.









_______________________________________________
devl mailing list
[EMAIL PROTECTED]
http://hawk.freenetproject.org/cgi-bin/mailman/listinfo/devl

Reply via email to