Exemplo n.º 1
0
 /**
  * Returns the ip (given in BIG-endian) format of buf[offset]...buf[offset+3] as standard
  * dotted-decimal, e.g., 192.168.0.1
  *
  * <p>
  *
  * @param ip the IP address to convert
  * @param offset the offset into the IP array to convert
  * @return the IP address as a dotted-quad string
  */
 public static final String ip2string(byte[] ip, int offset) {
   // xxx.xxx.xxx.xxx => 15 chars
   StringBuffer sbuf = new StringBuffer(16);
   sbuf.append(ByteOrder.ubyte2int(ip[offset]));
   sbuf.append('.');
   sbuf.append(ByteOrder.ubyte2int(ip[offset + 1]));
   sbuf.append('.');
   sbuf.append(ByteOrder.ubyte2int(ip[offset + 2]));
   sbuf.append('.');
   sbuf.append(ByteOrder.ubyte2int(ip[offset + 3]));
   return sbuf.toString();
 }
Exemplo n.º 2
0
  /**
   * Make a new PatchTableMessage object by parsing data a remote computer sent us.
   *
   * <p>Creates a new PATCH variant with data read from the network. The first byte is guaranteed to
   * be PATCH_VARIANT.
   *
   * <p>Throws BadPacketException the remaining values in payload are not well-formed, e.g., because
   * it's the wrong length, the sequence size is less than the sequence number, etc.
   *
   * @param guid The message GUID we read from the header
   * @param ttl The TTL we read from the message header
   * @param hops The hops count we read from the message header
   * @param payload The payload of the message after that, like fNSCBpatchdatapatchdatapatchdata
   */
  protected PatchTableMessage(byte[] guid, byte ttl, byte hops, byte[] payload)
      throws BadPacketException {

    // Save the GUID, TTL, hops and length in the Message and RouteTableMessage cores of this new
    // PatchTableMessage
    super(
        guid,
        ttl,
        hops,
        payload.length,
        RouteTableMessage.PATCH_VARIANT); // 0x01 identifies this as a PatchTableMessage

    /*
     * TODO: maybe we shouldn't enforce this
     * if (payload.length < 5) throw new BadPacketException("Extra arguments in reset message.");
     */

    /*
     * The payload of a patch message looks like this:
     *
     * fNSCBpatchdatapatchdata...
     */

    // Make sure the first payload byte, f, is 0x01, identifying this as a patch message
    Assert.that(payload[0] == PATCH_VARIANT);

    // Read the sequence number and sequence size, N and S, a distance of 1 and 2 bytes into the
    // payload data
    this.sequenceNumber = (short) ByteOrder.ubyte2int(payload[1]);
    this.sequenceSize = (short) ByteOrder.ubyte2int(payload[2]);
    if (sequenceNumber < 1 || sequenceSize < 1 || sequenceNumber > sequenceSize)
      throw new BadPacketException("Bad sequence/size: " + sequenceNumber + "/" + sequenceSize);

    // Find out if the patch data is compressed by reading C 3 bytes into the payload data
    this.compressor = payload[3];
    if (!(compressor == COMPRESSOR_NONE || compressor == COMPRESSOR_DEFLATE))
      throw new BadPacketException("Bad compressor: " + compressor);

    // Find out if the patch data was halved or not by reading B 4 bytes into the payload data
    this.entryBits = payload[4];
    if (entryBits < 0) throw new BadPacketException("Negative entryBits: " + entryBits);

    // Clip out the chunk of probably compressed and halved patch data this patch message carries
    // after that
    this.data =
        new byte
            [payload.length
                - 5]; // It's the whole paylaod not including the first 4 fNSCB bytes we read
    System.arraycopy(payload, 5, data, 0, data.length); // Copy it from 5 bytes in to the end
  }
Exemplo n.º 3
0
  /**
   * 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
  }
Exemplo n.º 4
0
 /** Packs a Collection of IpPorts into a byte array. */
 public static byte[] packIpPorts(Collection ipPorts) {
   byte[] data = new byte[ipPorts.size() * 6];
   int offset = 0;
   for (Iterator i = ipPorts.iterator(); i.hasNext(); ) {
     IpPort next = (IpPort) i.next();
     byte[] addr = next.getInetAddress().getAddress();
     int port = next.getPort();
     System.arraycopy(addr, 0, data, offset, 4);
     offset += 4;
     ByteOrder.short2leb((short) port, data, offset);
     offset += 2;
   }
   return data;
 }
Exemplo n.º 5
0
  /**
   * Get the port number this push packet tells the firewalled computer to push open a connection
   * to. This is the port number of the computer that wants the file and sent this packet.
   *
   * @return The downloading computer's port number
   */
  public int getPort() {

    // Read the port number from the 2 bytes after the IP address
    return ByteOrder.ushort2int(ByteOrder.leb2short(payload, 24));
  }
Exemplo n.º 6
0
  /**
   * Get the file ID index of the file the firewalled computer is sharing, and will push out. The
   * firewalled computer returned a query hit with this file ID. The downloading computer writes
   * this ID in this push packet to tell the firewalled computer which one to push out.
   *
   * @return The shared file ID
   */
  public long getIndex() {

    // Return the 4 byte file id 16 bytes into the payload
    return ByteOrder.uint2long(ByteOrder.leb2int(payload, 16));
  }