/* $Id$ */ package org.noreply.fancydress.type3; import java.io.*; import java.util.zip.*; import org.noreply.fancydress.crypto.*; import org.noreply.fancydress.directory.*; import org.noreply.fancydress.misc.Util; import org.noreply.fancydress.type3.routing.*; public class Payload { byte[][] payloads; RoutingDestination[] route; public Payload(RoutingDestination route, String body) { try { PipedOutputStream poMessage = new PipedOutputStream(); PipedInputStream piMessage = new PipedInputStream( poMessage ); Deflater compresser = new Deflater(Deflater.BEST_COMPRESSION); DeflaterOutputStream compresserStream = new DeflaterOutputStream(poMessage, compresser); /* FIXME, do a more clever and robust way of reading/writing */ byte[] message = Util.toOctets(body); compresserStream.write(message, 0, message.length); compresserStream.close(); byte[] compressed = new byte[message.length]; // UGH int read = piMessage.read(compressed,0,compressed.length); compressed = Util.slice(compressed, 0, read); byte[] padding = CryptoPrimitives.rand( 28*1024 - compressed.length - 22); byte[] payload = new byte[28*1024]; int pos = 0; int firstWord = compressed.length; payload[pos] = (byte) ( (firstWord >> 8) & 0xff); pos++; payload[pos] = (byte) ( firstWord & 0xff); pos++; System.arraycopy(CryptoPrimitives.hash(compressed, padding), 0, payload, pos, CryptoPrimitives.HASH_LEN); pos += CryptoPrimitives.HASH_LEN; System.arraycopy(compressed, 0, payload, pos, compressed.length); pos += compressed.length; System.arraycopy(padding, 0, payload, pos, padding.length); pos += padding.length; if (pos != 28*1024) throw new Error("did not fill in 28k bytes"); payloads = new byte[1][]; payloads[0] = payload; } catch (Exception e) { throw new Error(e); }; this.route = new RoutingDestination[1]; this.route[0] = route; // Return a singleton payload containing: // Flag 0 | Int(15,LEN(M_C)) | Hash(M_C | PADDING) | M_C | PADDING } public int numPackets() { return payloads.length; } public byte[] getPayload(int i) { return payloads[i]; } public RoutingDestination getRoute(int i) { return route[i]; } public Server[] filterExithops(Server[] s) { return s; } }