/// <summary> /// Create a new Interest with the given name and interest lifetime and "none" /// for other values. /// </summary> /// /// <param name="name">The name for the interest.</param> /// <param name="interestLifetimeMilliseconds"></param> public Interest(Name name, double interestLifetimeMilliseconds) { this.name_ = new ChangeCounter(new Name()); this.minSuffixComponents_ = -1; this.maxSuffixComponents_ = -1; this.keyLocator_ = new ChangeCounter( new KeyLocator()); this.exclude_ = new ChangeCounter(new Exclude()); this.childSelector_ = -1; this.mustBeFresh_ = true; this.interestLifetimeMilliseconds_ = -1; this.nonce_ = new Blob(); this.getNonceChangeCount_ = 0; this.lpPacket_ = null; this.linkWireEncoding_ = new Blob(); this.linkWireEncodingFormat_ = null; this.link_ = new ChangeCounter(null); this.selectedDelegationIndex_ = -1; this.defaultWireEncoding_ = new SignedBlob(); this.getDefaultWireEncodingChangeCount_ = 0; this.changeCount_ = 0; if (name != null) name_.set(new Name(name)); interestLifetimeMilliseconds_ = interestLifetimeMilliseconds; }
/// <summary> /// Get the first header field in lpPacket which is an IncomingFaceId. This is /// an internal method which the application normally would not use. /// </summary> /// /// <param name="lpPacket">The LpPacket with the header fields to search.</param> /// <returns>The first IncomingFaceId header field, or null if not found.</returns> public static IncomingFaceId getFirstHeader(LpPacket lpPacket) { for (int i = 0; i < lpPacket.countHeaderFields(); ++i) { Object field = lpPacket.getHeaderField(i); if (field is IncomingFaceId) return (IncomingFaceId) field; } return null; }
/// <summary> /// Get the first header field in lpPacket which is a NetworkNack. This is /// an internal method which the application normally would not use. /// </summary> /// /// <param name="lpPacket">The LpPacket with the header fields to search.</param> /// <returns>The first NetworkNack header field, or null if not found.</returns> public static NetworkNack getFirstHeader(LpPacket lpPacket) { for (int i = 0; i < lpPacket.countHeaderFields(); ++i) { Object field = lpPacket.getHeaderField(i); if (field is NetworkNack) return (NetworkNack) field; } return null; }
/// <summary> /// Get the first header field in lpPacket which is a CongestionMark. This is /// an internal method which the application normally would not use. /// </summary> /// /// <param name="lpPacket">The LpPacket with the header fields to search.</param> /// <returns>The first CongestionMark header field, or null if not found.</returns> static public CongestionMark getFirstHeader(LpPacket lpPacket) { for (int i = 0; i < lpPacket.countHeaderFields(); ++i) { Object field = lpPacket.getHeaderField(i); if (field is CongestionMark) { return((CongestionMark)field); } } return(null); }
/// <summary> /// Create a new Data object with default values and where the signature is a /// blank Sha256WithRsaSignature. /// </summary> /// public Data() { this.signature_ = new ChangeCounter( new Sha256WithRsaSignature()); this.name_ = new ChangeCounter(new Name()); this.metaInfo_ = new ChangeCounter(new MetaInfo()); this.content_ = new Blob(); this.lpPacket_ = null; this.defaultWireEncoding_ = new SignedBlob(); this.defaultFullName_ = new Name(); this.getDefaultWireEncodingChangeCount_ = 0; this.changeCount_ = 0; }
/// <summary> /// Get the first header field in lpPacket which is an IncomingFaceId. This is /// an internal method which the application normally would not use. /// </summary> /// /// <param name="lpPacket">The LpPacket with the header fields to search.</param> /// <returns>The first IncomingFaceId header field, or null if not found.</returns> static public IncomingFaceId getFirstHeader(LpPacket lpPacket) { for (int i = 0; i < lpPacket.countHeaderFields(); ++i) { Object field = lpPacket.getHeaderField(i); if (field is IncomingFaceId) { return((IncomingFaceId)field); } } return(null); }
/// <summary> /// Create a deep copy of the given data object, including a clone of the /// signature object. /// </summary> /// /// <param name="data">The data object to copy.</param> public Data(Data data) { this.signature_ = new ChangeCounter( new Sha256WithRsaSignature()); this.name_ = new ChangeCounter(new Name()); this.metaInfo_ = new ChangeCounter(new MetaInfo()); this.content_ = new Blob(); this.lpPacket_ = null; this.defaultWireEncoding_ = new SignedBlob(); this.defaultFullName_ = new Name(); this.getDefaultWireEncodingChangeCount_ = 0; this.changeCount_ = 0; try { signature_ .set((data.signature_ == null) ? (net.named_data.jndn.util.ChangeCountable) (new Sha256WithRsaSignature()) : (net.named_data.jndn.util.ChangeCountable) ((Signature) data.getSignature().Clone())); } catch (Exception e) { // We don't expect this to happen, so just treat it as if we got a null pointer. throw new NullReferenceException( "Data.setSignature: unexpected exception in clone(): " + e.Message); } name_.set(new Name(data.getName())); metaInfo_.set(new MetaInfo(data.getMetaInfo())); content_ = data.content_; setDefaultWireEncoding(data.defaultWireEncoding_, null); }
/// <summary> /// An internal library method to set the LpPacket for an incoming packet. The /// application should not call this. /// </summary> /// /// <param name="lpPacket">The LpPacket. This does not make a copy.</param> /// <returns>This Data so that you can chain calls to update values.</returns> /// @note This is an experimental feature. This API may change in the future. internal Data setLpPacket(LpPacket lpPacket) { lpPacket_ = lpPacket; // Don't update changeCount_ since this doesn't affect the wire encoding. return this; }
/// <summary> /// Create a new interest as a deep copy of the given interest. /// </summary> /// /// <param name="interest">The interest to copy.</param> public Interest(Interest interest) { this.name_ = new ChangeCounter(new Name()); this.minSuffixComponents_ = -1; this.maxSuffixComponents_ = -1; this.keyLocator_ = new ChangeCounter( new KeyLocator()); this.exclude_ = new ChangeCounter(new Exclude()); this.childSelector_ = -1; this.mustBeFresh_ = true; this.interestLifetimeMilliseconds_ = -1; this.nonce_ = new Blob(); this.getNonceChangeCount_ = 0; this.lpPacket_ = null; this.linkWireEncoding_ = new Blob(); this.linkWireEncodingFormat_ = null; this.link_ = new ChangeCounter(null); this.selectedDelegationIndex_ = -1; this.defaultWireEncoding_ = new SignedBlob(); this.getDefaultWireEncodingChangeCount_ = 0; this.changeCount_ = 0; name_.set(new Name(interest.getName())); minSuffixComponents_ = interest.minSuffixComponents_; maxSuffixComponents_ = interest.maxSuffixComponents_; keyLocator_.set(new KeyLocator(interest.getKeyLocator())); exclude_.set(new Exclude(interest.getExclude())); childSelector_ = interest.childSelector_; mustBeFresh_ = interest.mustBeFresh_; interestLifetimeMilliseconds_ = interest.interestLifetimeMilliseconds_; nonce_ = interest.getNonce(); linkWireEncoding_ = interest.linkWireEncoding_; linkWireEncodingFormat_ = interest.linkWireEncodingFormat_; if (interest.link_.get() != null) link_.set(new Link((Link) interest.link_.get())); selectedDelegationIndex_ = interest.selectedDelegationIndex_; setDefaultWireEncoding(interest.getDefaultWireEncoding(), interest.defaultWireEncodingFormat_); }
/// <summary> /// Decode input as an NDN-TLV LpPacket and set the fields of the lpPacket object. /// </summary> /// /// <param name="lpPacket">The LpPacket object whose fields are updated.</param> /// <param name="input"></param> /// <param name="copy">unchanged while the Blob values are used.</param> /// <exception cref="EncodingException">For invalid encoding.</exception> public override void decodeLpPacket(LpPacket lpPacket, ByteBuffer input, bool copy) { lpPacket.clear(); TlvDecoder decoder = new TlvDecoder(input); int endOffset = decoder.readNestedTlvsStart(net.named_data.jndn.encoding.tlv.Tlv.LpPacket_LpPacket); while (decoder.getOffset() < endOffset) { // Imitate TlvDecoder.readTypeAndLength. int fieldType = decoder.readVarNumber(); int fieldLength = decoder.readVarNumber(); int fieldEndOffset = decoder.getOffset() + fieldLength; if (fieldEndOffset > input.limit()) throw new EncodingException( "TLV length exceeds the buffer length"); if (fieldType == net.named_data.jndn.encoding.tlv.Tlv.LpPacket_Fragment) { // Set the fragment to the bytes of the TLV value. lpPacket.setFragmentWireEncoding(new Blob(decoder.getSlice( decoder.getOffset(), fieldEndOffset), copy)); decoder.seek(fieldEndOffset); // The fragment is supposed to be the last field. break; } else if (fieldType == net.named_data.jndn.encoding.tlv.Tlv.LpPacket_Nack) { NetworkNack networkNack = new NetworkNack(); int code = (int) decoder.readOptionalNonNegativeIntegerTlv( net.named_data.jndn.encoding.tlv.Tlv.LpPacket_NackReason, fieldEndOffset); // The enum numeric values are the same as this wire format, so use as is. if (code < 0 || code == net.named_data.jndn.NetworkNack.Reason.NONE.getNumericType()) // This includes an omitted NackReason. networkNack.setReason(net.named_data.jndn.NetworkNack.Reason.NONE); else if (code == net.named_data.jndn.NetworkNack.Reason.CONGESTION.getNumericType()) networkNack.setReason(net.named_data.jndn.NetworkNack.Reason.CONGESTION); else if (code == net.named_data.jndn.NetworkNack.Reason.DUPLICATE.getNumericType()) networkNack.setReason(net.named_data.jndn.NetworkNack.Reason.DUPLICATE); else if (code == net.named_data.jndn.NetworkNack.Reason.NO_ROUTE.getNumericType()) networkNack.setReason(net.named_data.jndn.NetworkNack.Reason.NO_ROUTE); else { // Unrecognized reason. networkNack.setReason(net.named_data.jndn.NetworkNack.Reason.OTHER_CODE); networkNack.setOtherReasonCode(code); } lpPacket.addHeaderField(networkNack); } else if (fieldType == net.named_data.jndn.encoding.tlv.Tlv.LpPacket_IncomingFaceId) { IncomingFaceId incomingFaceId = new IncomingFaceId(); incomingFaceId.setFaceId(decoder .readNonNegativeInteger(fieldLength)); lpPacket.addHeaderField(incomingFaceId); } else { // Unrecognized field type. The conditions for ignoring are here: // http://redmine.named-data.net/projects/nfd/wiki/NDNLPv2 bool canIgnore = (fieldType >= net.named_data.jndn.encoding.tlv.Tlv.LpPacket_IGNORE_MIN && fieldType <= net.named_data.jndn.encoding.tlv.Tlv.LpPacket_IGNORE_MAX && (fieldType & 0x01) == 1); if (!canIgnore) throw new EncodingException( "Did not get the expected TLV type"); // Ignore. decoder.seek(fieldEndOffset); } decoder.finishNestedTlvs(fieldEndOffset); } decoder.finishNestedTlvs(endOffset); }
public void onReceivedElement(ByteBuffer element) { LpPacket lpPacket = null; if (element.get(0) == net.named_data.jndn.encoding.tlv.Tlv.LpPacket_LpPacket) { // Decode the LpPacket and replace element with the fragment. lpPacket = new LpPacket(); // Set copy false so that the fragment is a slice which will be copied below. // The header fields are all integers and don't need to be copied. net.named_data.jndn.encoding.TlvWireFormat.get().decodeLpPacket(lpPacket, element, false); element = lpPacket.getFragmentWireEncoding().buf(); } // First, decode as Interest or Data. Interest interest = null; Data data = null; if (element.get(0) == net.named_data.jndn.encoding.tlv.Tlv.Interest || element.get(0) == net.named_data.jndn.encoding.tlv.Tlv.Data) { TlvDecoder decoder = new TlvDecoder(element); if (decoder.peekType(net.named_data.jndn.encoding.tlv.Tlv.Interest, element.remaining())) { interest = new Interest(); interest.wireDecode(element, net.named_data.jndn.encoding.TlvWireFormat.get()); if (lpPacket != null) interest.setLpPacket(lpPacket); } else if (decoder.peekType(net.named_data.jndn.encoding.tlv.Tlv.Data, element.remaining())) { data = new Data(); data.wireDecode(element, net.named_data.jndn.encoding.TlvWireFormat.get()); if (lpPacket != null) data.setLpPacket(lpPacket); } } if (lpPacket != null) { // We have decoded the fragment, so remove the wire encoding to save memory. lpPacket.setFragmentWireEncoding(new Blob()); NetworkNack networkNack = net.named_data.jndn.NetworkNack.getFirstHeader(lpPacket); if (networkNack != null) { if (interest == null) // We got a Nack but not for an Interest, so drop the packet. return; ArrayList<PendingInterestTable.Entry> pitEntries = new ArrayList<PendingInterestTable.Entry>(); pendingInterestTable_.extractEntriesForNackInterest(interest, pitEntries); for (int i = 0; i < pitEntries.Count; ++i) { PendingInterestTable.Entry pendingInterest = pitEntries[i]; try { pendingInterest.getOnNetworkNack().onNetworkNack( pendingInterest.getInterest(), networkNack); } catch (Exception ex) { logger_.log(ILOG.J2CsMapping.Util.Logging.Level.SEVERE, "Error in onNack", ex); } } // We have processed the network Nack packet. return; } } // Now process as Interest or Data. if (interest != null) { // Quickly lock and get all interest filter callbacks which match. ArrayList matchedFilters = new ArrayList(); interestFilterTable_.getMatchedFilters(interest, matchedFilters); // The lock on interestFilterTable_ is released, so call the callbacks. for (int i_0 = 0; i_0 < matchedFilters.Count; ++i_0) { InterestFilterTable.Entry entry = (InterestFilterTable.Entry) matchedFilters[i_0]; try { entry.getOnInterest().onInterest( entry.getFilter().getPrefix(), interest, entry.getFace(), entry.getInterestFilterId(), entry.getFilter()); } catch (Exception ex_1) { logger_.log(ILOG.J2CsMapping.Util.Logging.Level.SEVERE, "Error in onInterest", ex_1); } } } else if (data != null) { ArrayList<PendingInterestTable.Entry> pitEntries_2 = new ArrayList<PendingInterestTable.Entry>(); pendingInterestTable_.extractEntriesForExpressedInterest(data, pitEntries_2); for (int i_3 = 0; i_3 < pitEntries_2.Count; ++i_3) { PendingInterestTable.Entry pendingInterest_4 = pitEntries_2[i_3]; try { pendingInterest_4.getOnData().onData( pendingInterest_4.getInterest(), data); } catch (Exception ex_5) { logger_.log(ILOG.J2CsMapping.Util.Logging.Level.SEVERE, "Error in onData", ex_5); } } } }
/// <summary> /// Decode input as an LpPacket and set the fields of the lpPacket object. Copy /// from the input when making new Blob values. Your derived class should /// override. /// </summary> /// /// <param name="lpPacket">The LpPacket object whose fields are updated.</param> /// <param name="input"></param> /// <exception cref="EncodingException">For invalid encoding.</exception> /// <exception cref="System.NotSupportedException">for unimplemented if the derivedclass does not override.</exception> public void decodeLpPacket(LpPacket lpPacket, ByteBuffer input) { decodeLpPacket(lpPacket, input, true); }
/// <summary> /// Decode input as an LpPacket and set the fields of the lpPacket object. Your /// derived class should override. /// </summary> /// /// <param name="lpPacket">The LpPacket object whose fields are updated.</param> /// <param name="input"></param> /// <param name="copy">unchanged while the Blob values are used.</param> /// <exception cref="EncodingException">For invalid encoding.</exception> /// <exception cref="System.NotSupportedException">for unimplemented if the derivedclass does not override.</exception> public virtual void decodeLpPacket(LpPacket lpPacket, ByteBuffer input, bool copy) { throw new NotSupportedException( "decodeLpPacket is not implemented"); }