package com.limegroup.gnutella.util; import com.limegroup.gnutella.GUID; import com.limegroup.gnutella.messages.GGEP; import com.limegroup.gnutella.messages.PingReply; /** * Utility class for creating common message types for tests. */ public class MessageTestUtils { /** * Cached constant for the vendor GGEP extension. */ private static final byte[] CACHED_VENDOR = new byte[5]; /** * Should never be instantiated. */ private MessageTestUtils() {} /** * Creates a new <tt>PingReply</tt> instance with the GGEP extension * advertising free ultrapeer and leaf slots. The generated pong will * have a random "unique" IP address that is statistically unlikely to * collide with other addresses returned by this method. * * @return a new <tt>PingReply</tt> for testing with the GGEP extension * advertising free ultrapeer and leaf slots */ public static PingReply createPongWithFreeLeafSlots() { GGEP ggep = newGGEP(20, true, true, true, false); byte a = (byte)(40 + (Math.random()*80)); byte b = (byte)(40 + (Math.random()*80)); byte c = (byte)(40 + (Math.random()*80)); byte d = (byte)(40 + (Math.random()*80)); PingReply pr = PingReply.create(GUID.makeGuid(), (byte)1, 6346, new byte[]{a,b,c,d}, 10, 10, true, ggep); return pr; } /** * Creates a new <tt>PingReply</tt> instance with the GGEP extension * advertising free ultrapeer and leaf slots. The generated pong will * have a random "unique" IP address that is statistically unlikely to * collide with other addresses returned by this method. * * @return a new <tt>PingReply</tt> for testing with the GGEP extension * advertising free ultrapeer and leaf slots */ public static PingReply createPongWithUltrapeerSlots() { GGEP ggep = newGGEP(20, true, true, false, true); byte a = (byte)(40 + (Math.random()*80)); byte b = (byte)(40 + (Math.random()*80)); byte c = (byte)(40 + (Math.random()*80)); byte d = (byte)(40 + (Math.random()*80)); PingReply pr = PingReply.create(GUID.makeGuid(), (byte)1, 6346, new byte[]{a,b,c,d}, 10, 10, true, ggep); return pr; } /** * Returns the GGEP payload bytes to encode the given uptime. */ private static GGEP newGGEP(int dailyUptime, boolean isUltrapeer, boolean isGUESSCapable, boolean freeLeaf, boolean freeUP) { GGEP ggep = new GGEP(true); if (dailyUptime >= 0) ggep.put(GGEP.GGEP_HEADER_DAILY_AVERAGE_UPTIME, dailyUptime); if (isGUESSCapable && isUltrapeer) { // indicate guess support byte[] vNum = { convertToGUESSFormat(CommonUtils.getGUESSMajorVersionNumber(), CommonUtils.getGUESSMinorVersionNumber())}; ggep.put(GGEP.GGEP_HEADER_UNICAST_SUPPORT, vNum); } if (isUltrapeer) { // indicate UP support addUltrapeerExtension(ggep, freeLeaf, freeUP); } // all pongs should have vendor info ggep.put(GGEP.GGEP_HEADER_VENDOR_INFO, CACHED_VENDOR); return ggep; } /** * Adds the ultrapeer GGEP extension to the pong. This has the version of * the Ultrapeer protocol that we support as well as the number of free * leaf and Ultrapeer slots available. * * @param ggep the <tt>GGEP</tt> instance to add the extension to */ private static void addUltrapeerExtension(GGEP ggep, boolean freeLeaf, boolean freeUP) { byte[] payload = new byte[3]; // put version payload[0] = convertToGUESSFormat(CommonUtils.getUPMajorVersionNumber(), CommonUtils.getUPMinorVersionNumber() ); if(freeLeaf) { payload[1] = (byte)10; } else { payload[1] = (byte)0; } if(freeUP) { payload[2] = (byte)10; } else { payload[2] = (byte)0; } // add it ggep.put(GGEP.GGEP_HEADER_UP_SUPPORT, payload); } /** * puts major as the high order bits, minor as the low order bits. * * @exception IllegalArgumentException thrown if major/minor is greater * than 15 or less than 0. */ private static byte convertToGUESSFormat(int major, int minor) throws IllegalArgumentException { if ((major < 0) || (minor < 0) || (major > 15) || (minor > 15)) throw new IllegalArgumentException(); // set major int retInt = major; retInt = retInt << 4; // set minor retInt |= minor; return (byte) retInt; } }