Beispiel #1
0
 public void run() {
   byte[] last = null;
   while (!Thread.currentThread().isInterrupted()) {
     byte[] data = recv();
     if (!Util.equals(
         data,
         last)) { // prevent re-processing the same received packet again and again... in real
                  // life the transmission doesn't "hang around" but this simulation does not
                  // have a mechanism for "clearing the air" yet.
       last = data;
       // detect frame type
       FrameType frameType = FrameType.nullOrValueOf(Util.first(data, FrameType.LENGTH));
       if (frameType == null) {
         log("Received invalid frame data: " + Hex.encodeHexString(data));
       } else if (frameType.equals(FrameType.BEACON)) { // if( frame instanceof BeaconFrame ) {
         BeaconFrame beaconFrame = new BeaconFrame(data); // (BeaconFrame)frame;
         NodeInfo nodeInfo = nodes.get(beaconFrame.sourceNodeAddress);
         if (nodeInfo == null) {
           nodeInfo = new NodeInfo();
           nodeInfo.address = beaconFrame.sourceNodeAddress;
           nodes.put(beaconFrame.sourceNodeAddress, nodeInfo);
         }
         nodeInfo.lastBeaconAt = System.currentTimeMillis();
         nodes.put(beaconFrame.sourceNodeAddress, nodeInfo);
         beaconReply(beaconFrame);
         for (Connection c : ports.values()) {
           if (c.authentication() == null) {
             portAdviceReply(beaconFrame, c.portAdvice());
           } else {
             portAdviceReply(beaconFrame, c.endorsedPortAdvice());
           }
         }
       } else if (frameType.equals(
           FrameType.PORT_ADVICE)) { // else if( frame instanceof PortAdviceFrame ) {
         PortAdviceFrame portAdviceFrame = new PortAdviceFrame(data); // (PortAdviceFrame)frame;
         // once we have a port advice, we do not let anyone redefine it. node must be reset in
         // order to accept new definitions.
         if (!ports.containsKey(portAdviceFrame.portAddress())) {
           // only add the port advice if we support its protocols
           if (encodings.contains(portAdviceFrame.encoding)) {
             ports.put(portAdviceFrame.portAddress(), new Connection(link, portAdviceFrame));
           }
         }
       } else if (frameType.equals(FrameType.ENDORSED_PORT_ADVICE)) {
         EndorsedPortAdviceFrame endorsedPortAdviceFrame = new EndorsedPortAdviceFrame(data);
         /*
         // if it's authenticated port advice, then we overwrite existing advice for that port;  for example this can be used to change secrets
         Connection c = ports.get(endorsedPortAdviceFrame.portAddress());
         if( c != null ) {
             c.recv(data);
             // XXX TODO hmm, so how do we find out from the connection if the frame was authentic - because we need to know before we do ports.put(...)
         }
         */
         // for now we use the same rule as non-authenticated port advice, which is only to
         // create a new port if we don't already have it
         if (!ports.containsKey(endorsedPortAdviceFrame.portAddress())) {
           // only add the port advice if we support its protocols
           if (encodings.contains(endorsedPortAdviceFrame.encoding)
               && authentications.contains(endorsedPortAdviceFrame.authentication)) {
             ports.put(
                 endorsedPortAdviceFrame.portAddress(),
                 new Connection(link, endorsedPortAdviceFrame));
           }
         }
       } else if (frameType.equals(FrameType.DATA)) {
         Connection c = ports.get(DataFrame.extractPortAddress(data));
         if (c != null) {
           c.recv(
               data); // pass the frame to appropriate connection - it will handle handshakes,
                      // data, etc.
         }
       } else if (frameType.equals(FrameType.ENDORSED_DATA)) {
         Connection c = ports.get(EndorsedDataFrame.extractPortAddress(data));
         if (c != null) {
           c.recv(
               data); // pass the frame to appropriate connection - it will handle handshakes,
                      // data, etc.
         }
       }
     }
     Util.sleep(1, TimeUnit.MILLISECONDS);
   }
 }