public PortAddress createPort( PortName name, Encoding enc, LengthMultiplier m, Authentication auth, DataEndorser endorser) { PortAddress portAddress; // get a new random port address that is not in use (that we know of) do { portAddress = new PortAddress(); } while (ports.containsKey(portAddress)); EndorsedPortAdviceFrame portAdviceFrame = new EndorsedPortAdviceFrame(); portAdviceFrame.encoding = enc; portAdviceFrame.lengthMultiplier = m; portAdviceFrame.portAddress = portAddress; portAdviceFrame.portName = name; portAdviceFrame.authentication = auth; try { byte[] endorsement = endorser.endorse(portAdviceFrame.document()); portAdviceFrame.endorsement = new ByteArray(endorsement); portAdviceFrame.endorsementLength = new EndorsementLength(endorsement.length); } catch (IOException e) { log("cannot create endorsed port: " + e.toString()); } Connection c = new Connection( this, portAdviceFrame); // port advice frame is public, our configuration is private (secret // keys, etc) // c.open(); // mus tbe done by caller with Configuration ports.put(portAddress, c); return portAddress; }
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); } }