The 'LF' GGEP Extension ========================== Name: LF (Large File) Where: Query Hit Status: Draft Date: 2004-11-04 Format: Variable-Length Integer COBS-Encoding: If neccessary Deflate: No 1. OVERVIEW Due to the wide use of broadband internet connections and increasing amount of huge content, the transfer of files larger than 4 GiB is no longer utopic. The standard Gnutella protocol is limited to 32-bit integers to express filesizes. This limit can easily be removed by a GGEP extension. 2. USAGE In general, the value of the LF extension overrides the value in the legacy filesize field of the query hit. The extension should only be used if necessary. To prevent problems with older clients, using the extension should be considered if the filesize exceeds 2^31-1 bytes. If the LF extension is used, the legacy filesize should be set to ~0 i.e., all bits set. This may be used to detect clients that are not aware of this extension and assume a different filesize. In order to take advantage of the LF extension, all related routines (e.g., HTTP parsers) must be able to parse and emit at least 64-bit values and detect too large values that cannot be handled by them. 3. SPECIFICATION There is no need to indicate support for this feature at any stage. This extension is defined as follows: Due to the location of the LF extension, there must be no NUL bytes in the the GGEP data. Therefore, the payload must be COBS encoded if it contains any NUL bytes. The ordering of the bytes is little-endian. To save space, the value is encoded as a Variable-Length Integer. The byte length is equal to the GGEP payload size. Trailing zeros must be discarded. If the last byte is a NUL character, the encoding is invalid. Thus, zero is not a valid filesize in the context of the GGEP LF extension. 4. EXAMPLE CODE This example implementation in C uses 64-bit integers, allowing filesizes up to (2 ^ 64) - 1 bytes. The maximum length of the GGEP payload data is therefore 8 bytes. The decoder is strict i.e., trailing zeros are disallowed. A filesize of zero bytes, is considered invalid. On failure, both functions return 0. uint64_t decode_lf(uint8_t *data, int length) { uint64_t filesize, b; int i, j; if (length < 1 || length > 8) return 0; j = i = filesize = 0; do { b = data[i]; filesize |= b << j; j += 8; } while (++i < length); if (0 == b) return 0; return filesize; } int encode_lf(uint64_t filesize, uint8_t *data) { uint8_t *p = data; if (0 == filesize) return 0; do { *p++ = filesize; } while (0 != (filesize >>= 8)); return p - data; }