/** * Make a new PushRequest object to represent a push packet we read from the network. This is the * packet parser. * * @param guid The GUID that uniquely identifies this Gnutella message * @param ttl The message TTL, the number of times it will travel across the Internet * @param hops The number of times this Gnutella message has traveled across the Internet * @param payload The 26 byte payload * @param network The Internet protocol that brought us this message, like 1 N_TCP or 2 N_UDP * @return A new PushRequest object with that information */ public PushRequest(byte[] guid, byte ttl, byte hops, byte[] payload, int network) throws BadPacketException { // Call the Message constructor to save information from the packet header in the Message // members this PushRequest inherits super(guid, Message.F_PUSH, ttl, hops, payload.length, network); // Make sure the payload is at least 26 bytes if (payload.length < STANDARD_PAYLOAD_SIZE) { ReceivedErrorStat.PUSH_INVALID_PAYLOAD.incrementStat(); throw new BadPacketException("Payload too small: " + payload.length); } // Save the payload data this.payload = payload; // Make sure the port number isn't 0 if (!NetworkUtils.isValidPort(getPort())) { ReceivedErrorStat.PUSH_INVALID_PORT.incrementStat(); throw new BadPacketException("invalid port"); } // Make sure the IP address doesn't start 0 or 255 String ip = NetworkUtils.ip2string(payload, 20); if (!NetworkUtils.isValidAddress(ip)) { ReceivedErrorStat.PUSH_INVALID_ADDRESS.incrementStat(); throw new BadPacketException("invalid address: " + ip); } }
/** * Creates a new Endpoint instance * * @param hostBytes IP address of the host (MSB first) * @param port The port number for the host */ public Endpoint(byte[] hostBytes, int port) { if (!NetworkUtils.isValidPort(port)) throw new IllegalArgumentException("invalid port: " + port); if (!NetworkUtils.isValidAddress(hostBytes)) throw new IllegalArgumentException("invalid address"); this.port = port; this.hostname = NetworkUtils.ip2string(hostBytes); }
/** * Express this PushRequest object as text. * * @return A String like "PushRequest({guid=00FF00FF00FF00FF00FF00FF00FF00FF, ttl=1, hops=1, * priority=1} 1.2.3.4:5)" */ public String toString() { // Compose and return the text return "PushRequest(" + super.toString() + " " + NetworkUtils.ip2string(getIP()) + ":" + getPort() + ")"; }
/** * Make a new PushRequest object for us to send with the given information. This is the packet * maker. * * @param guid For the header, the message GUID that will mark this packet unique * @param ttl For the header, the TTL * @param clientGUID For the payload, the client ID GUID of the firewalled computer that has the * file and will push open the connection * @param index For the payload, the ID number the firewalled computer has assigned the file the * downloading computer wants * @param ip For the payload, the downloading computer's IP address the firewalled computer will * push open a connection to * @param port For the payload, the downloading computer's port number the firewalled computer * will push open a connection to * @param network The Internet protocol this push packet will travel on, like 1 N_TCP or 2 N_UDP, * this is not a part of the packet that's sent * @return A new PushRequest object with that information */ public PushRequest( byte[] guid, byte ttl, byte[] clientGUID, long index, byte[] ip, int port, int network) { // Call the Message constructor to save packet header information super( guid, // The message GUID Message.F_PUSH, // 0x40, this is a push message ttl, // The number of times this push will be able to travel between ultrapeers (byte) 0, // This push message hasn't traveled any hops yet STANDARD_PAYLOAD_SIZE, // The payload length will be 26 bytes network); // The Internet protocol we'll use to send, the Message object keeps this // information but it is not part of the packet that's sent // Make sure the GUID is 16 bytes, the file id fits in 4 bytes, the IP is 4 bytes, the IP // address doesn't start 0 or 255, and the port number fits in 2 bytes if (clientGUID.length != 16) throw new IllegalArgumentException("invalid guid length: " + clientGUID.length); else if ((index & 0xFFFFFFFF00000000l) != 0) throw new IllegalArgumentException("invalid index: " + index); else if (ip.length != 4) throw new IllegalArgumentException("invalid ip length: " + ip.length); else if (!NetworkUtils.isValidAddress(ip)) throw new IllegalArgumentException("invalid ip " + NetworkUtils.ip2string(ip)); else if (!NetworkUtils.isValidPort(port)) throw new IllegalArgumentException("invalid port: " + port); /* * The 26 byte pong payload has this structure: * * [client ID GUID] At 0, 16 bytes The client ID GUID of the computer that will get this packet and push open a new connection * FILE At 16, 4 bytes The number the pushing computer has given the file the wanting computer wants * IPIPPP At 20, 6 bytes The IP address and port number of the wanting computer */ // Compose the 26 byte push payload payload = new byte[STANDARD_PAYLOAD_SIZE]; // Make a byte array that can hold 26 bytes System.arraycopy(clientGUID, 0, payload, 0, 16); // Copy the client ID GUID into the first 16 ByteOrder.int2leb((int) index, payload, 16); // 16 bytes into the array, copy the 4 byte file id payload[20] = ip[0]; // 20 bytes into the array, copy the 4 bytes of the IP address payload[21] = ip[1]; payload[22] = ip[2]; payload[23] = ip[3]; ByteOrder.short2leb( (short) port, payload, 24); // 24 bytes into the array, place the 2 byte port number }
/** Returns an InetAddress representing the given IP address. */ public static InetAddress getByAddress(byte[] addr) throws UnknownHostException { String addrString = NetworkUtils.ip2string(addr); return InetAddress.getByName(addrString); }