Пример #1
0
 /**
  * Decodes the payload from a Netty buffer in a big switch
  *
  * @param content The content type
  * @param buffer The buffer to read from
  * @param message The message to store the results
  * @throws IndexOutOfBoundsException If a buffer is read beyond its limits
  * @throws NoSuchAlgorithmException
  * @throws SignatureException
  * @throws InvalidKeyException
  * @throws InvalidKeySpecException
  * @throws InvalidKeySpecException
  * @throws IOException
  * @throws DecoderException
  * @throws ASN1Exception
  * @throws UnsupportedEncodingException If UTF-8 is not there
  */
 public static boolean decodePayload(
     final Content content, final ChannelBuffer buffer, final Message message)
     throws InvalidKeyException, SignatureException, NoSuchAlgorithmException,
         InvalidKeySpecException, IOException, DecoderException {
   final int len;
   byte[] me;
   switch (content) {
     case KEY:
       if (buffer.readableBytes() < 20) return false;
       message.setKey0(readID(buffer));
       return true;
     case KEY_KEY:
       if (buffer.readableBytes() < 40) return false;
       message.setKeyKey0(readID(buffer), readID(buffer));
       return true;
     case MAP_KEY_DATA:
       if (buffer.readableBytes() < 4) return false;
       int size = buffer.readInt();
       Map<Number160, Data> result = new HashMap<Number160, Data>(size);
       for (int i = 0; i < size; i++) {
         if (buffer.readableBytes() < 20) return false;
         Number160 key = readID(buffer);
         final Data data = decodeData(new ChannelDecoder(buffer), message.getSender());
         if (data == null) return false;
         if (message.isRequest()) {
           if (data.isProtectedEntry() && message.getPublicKey() == null)
             throw new DecoderException(
                 "You indicated that you want to protect the data, but you did not provide or provided too late a public key.");
           data.setPublicKey(message.getPublicKey());
         }
         result.put(key, data);
       }
       message.setDataMap0(result);
       return true;
     case MAP_KEY_KEY:
       if (buffer.readableBytes() < 4) return false;
       len = buffer.readInt();
       if (buffer.readableBytes() < ((20 + 20) * len)) return false;
       final Map<Number160, Number160> keyMap = new HashMap<Number160, Number160>();
       for (int i = 0; i < len; i++) {
         final Number160 key1 = readID(buffer);
         final Number160 key2 = readID(buffer);
         keyMap.put(key1, key2);
       }
       message.setKeyMap0(keyMap);
       return true;
     case SET_KEYS:
       // can be 31bit long ~ 2GB
       if (buffer.readableBytes() < 4) return false;
       len = buffer.readInt();
       if (buffer.readableBytes() < (20 * len)) return false;
       final Collection<Number160> tmp = new ArrayList<Number160>(len);
       for (int i = 0; i < len; i++) {
         Number160 key = readID(buffer);
         tmp.add(key);
       }
       message.setKeys0(tmp);
       return true;
     case SET_NEIGHBORS:
       if (buffer.readableBytes() < 1) return false;
       len = buffer.readUnsignedByte();
       if (buffer.readableBytes() < (len * PeerAddress.SIZE_IPv4)) return false;
       final Collection<PeerAddress> neighbors = new ArrayList<PeerAddress>(len);
       for (int i = 0; i < len; i++) {
         PeerAddress peerAddress = readPeerAddress(buffer);
         if (peerAddress == null) return false;
         neighbors.add(peerAddress);
       }
       message.setNeighbors0(neighbors);
       return true;
     case SET_TRACKER_DATA:
       if (buffer.readableBytes() < 1) return false;
       len = buffer.readUnsignedByte();
       if (buffer.readableBytes() < (len * (PeerAddress.SIZE_IPv4 + 1))) return false;
       final Collection<TrackerData> trackerDatas = new ArrayList<TrackerData>(len);
       for (int i = 0; i < len; i++) {
         PeerAddress peerAddress = readPeerAddress(buffer);
         if (peerAddress == null) return false;
         byte[] attachment = null;
         int offset = 0;
         int length = 0;
         if (buffer.readableBytes() < 1) return false;
         byte miniHeader = buffer.readByte();
         if (miniHeader != 0) {
           if (buffer.readableBytes() < 4) return false;
           length = buffer.readInt();
           if (buffer.readableBytes() < length) return false;
           attachment = new byte[length];
           buffer.readBytes(attachment);
         }
         trackerDatas.add(
             new TrackerData(peerAddress, message.getSender(), attachment, offset, length));
       }
       message.setTrackerData0(trackerDatas);
       return true;
     case CHANNEL_BUFFER:
       if (buffer.readableBytes() < 4) return false;
       len = buffer.readInt();
       if (buffer.readableBytes() < len) return false;
       // you can only use slice if no execution handler is in place,
       // otherwise, you will overwrite stuff
       final ChannelBuffer tmpBuffer = buffer.slice(buffer.readerIndex(), len);
       buffer.skipBytes(len);
       message.setPayload0(tmpBuffer);
       return true;
     case LONG:
       if (buffer.readableBytes() < 8) return false;
       message.setLong0(buffer.readLong());
       return true;
     case INTEGER:
       if (buffer.readableBytes() < 4) return false;
       message.setInteger0(buffer.readInt());
       return true;
     case PUBLIC_KEY:
     case PUBLIC_KEY_SIGNATURE:
       if (buffer.readableBytes() < 2) return false;
       len = buffer.readUnsignedShort();
       me = new byte[len];
       if (buffer.readableBytes() < len) return false;
       message.setPublicKey0(decodePublicKey(new ChannelDecoder(buffer), me));
       if (content == Content.PUBLIC_KEY_SIGNATURE) {
         message.setHintSign(true);
       }
       return true;
     case EMPTY:
     case RESERVED1:
     case RESERVED2:
     case RESERVED3:
     default:
       return true;
   }
 }