+ private MapRegisterCacheValue refreshEntry(final MapRegisterCacheKey cacheKey) {
+ MapRegisterCacheValue mapRegisterCacheValue = lispSbPlugin.getMapRegisterCache().refreshEntry(cacheKey);
+ if (mapRegisterCacheValue != null) {
+ mapRegisterCacheValue = refreshAuthKeyIfNecessary(mapRegisterCacheValue);
+ lispSbPlugin.getMapRegisterCache().addEntry(cacheKey, mapRegisterCacheValue);
+ return mapRegisterCacheValue;
+ }
+ return null;
+ }
+
+ private MapRegisterCacheValue refreshAuthKeyIfNecessary(MapRegisterCacheValue mapRegisterCacheValue) {
+ final Map<EidLispAddressKey, EidLispAddress> eids = mapRegisterCacheValue.getMapRegisterCacheMetadata()
+ .getEidLispAddress();
+
+ if (lispSbPlugin.getAuthenticationKeyDataListener().authKeysForEidsUnchanged(
+ eids, lispSbPlugin.getMapRegisterCacheTimeout())) {
+ return mapRegisterCacheValue;
+ }
+
+ final MappingAuthkey mappingAuthkey = provideAuthenticateKey(eids);
+ final MapRegisterCacheValueBuilder newMapRegisterCacheValueBuilder = new MapRegisterCacheValueBuilder(
+ mapRegisterCacheValue);
+ final MapRegisterCacheMetadataBuilder newMapRegisterCacheMetadataBuilder =
+ new MapRegisterCacheMetadataBuilder(mapRegisterCacheValue.getMapRegisterCacheMetadata());
+
+ newMapRegisterCacheValueBuilder.setMappingAuthkey(mappingAuthkey);
+ newMapRegisterCacheValueBuilder.setMapRegisterCacheMetadata(newMapRegisterCacheMetadataBuilder.build());
+ return newMapRegisterCacheValueBuilder.build();
+ }
+
+ private MapRegisterCacheValue resolveCacheValue(Map.Entry<MapRegisterCacheKey, byte[]> entry) {
+ if (entry != null) {
+ final MapRegisterCacheValue mapRegisterCacheValue =
+ lispSbPlugin.getMapRegisterCache().getEntry(entry.getKey());
+ if (mapRegisterCacheValue != null) {
+ final long creationTime = mapRegisterCacheValue.getMapRegisterCacheMetadata().getTimestamp();
+ final long currentTime = System.currentTimeMillis();
+ if (currentTime - creationTime > lispSbPlugin.getMapRegisterCacheTimeout()) {
+ lispSbPlugin.getMapRegisterCache().removeEntry(entry.getKey());
+ return null;
+ } else if (Arrays.equals(mapRegisterCacheValue.getPacketData(), entry.getValue())) {
+ return mapRegisterCacheValue;
+ }
+ }
+ }
+ return null;
+ }
+
+ private static MappingKeepAlive createMappingKeepAlive(final MapRegisterCacheValue value) {
+ MappingKeepAliveBuilder mappingKeepAliveBuilder = new MappingKeepAliveBuilder();
+ mappingKeepAliveBuilder.setMapRegisterCacheMetadata(value.getMapRegisterCacheMetadata());
+ return mappingKeepAliveBuilder.build();
+ }
+
+ /**
+ * Returns null if not all of eids have the same value of authentication key.
+ */
+ private MappingAuthkey provideAuthenticateKey(final Map<EidLispAddressKey, EidLispAddress> eidLispAddresses) {
+ MappingAuthkey firstAuthKey = null;
+ if (eidLispAddresses == null) {
+ return null;
+ }
+ for (int i = 0; i < eidLispAddresses.size(); i++) {
+ final Eid eid = eidLispAddresses.get(new EidLispAddressKey(Integer.toString(i))).getEid();
+ if (i == 0) {
+ firstAuthKey = lispSbPlugin.getAkdb().getAuthenticationKey(eid);
+ } else {
+ final MappingAuthkey authKey = lispSbPlugin.getAkdb().getAuthenticationKey(eid);
+ if (!Objects.equals(firstAuthKey, authKey)) {
+ return null;
+ }
+ }
+ }
+ return firstAuthKey;
+
+ }
+
+ private void sendMapNotifyMsg(final ByteBuffer inBuffer, final InetAddress inetAddress, int portNumber,
+ MapRegisterCacheValue mapRegisterValue) {
+ if (mapRegisterValue.getMappingAuthkey().getKeyType() != null) {
+ ByteBuffer outBuffer = transformMapRegisterToMapNotify(inBuffer);
+ if (mapRegisterValue.getMappingAuthkey().getKeyType().toJava() != 0) {
+ outBuffer = calculateAndSetNewMAC(outBuffer, mapRegisterValue.getMappingAuthkey().getKeyString());
+ }
+ outBuffer.position(0);
+ lispSbPlugin.handleSerializedLispBuffer(inetAddress, outBuffer, MessageType.MapNotify, portNumber,
+ this.channel);
+ } else {
+ LOG.error("Map-Register Cache: authentication succeeded, but can't find auth key for sending Map-Notify");
+ }
+ }
+
+ /**
+ * Calculates new message authentication code (MAC) for notify message.
+ */
+ private static ByteBuffer calculateAndSetNewMAC(final ByteBuffer buffer, final String authKey) {
+ final byte[] authenticationData = LispAuthenticationUtil.createAuthenticationData(buffer, authKey);
+ buffer.position(ILispAuthentication.MAP_REGISTER_AND_NOTIFY_AUTHENTICATION_POSITION);
+ buffer.put(authenticationData);
+ return buffer;
+ }
+
+ private static ByteBuffer transformMapRegisterToMapNotify(final ByteBuffer buffer) {
+ buffer.position(0);
+ byte typeAndFlags = buffer.get(0);
+ // Shift the xTR-ID present and built for an RTR bits to their correct position
+ byte flags = (byte) (typeAndFlags << 2 & 0x0F);
+ // Set control message type to 4 (Map-Notify)
+ byte type = 0x40;
+ // Combine the nibbles
+ typeAndFlags = (byte) (type | flags);
+ byte[] byteReplacement = new byte[] {typeAndFlags, 0x00, 0x00};
+ buffer.put(byteReplacement);
+
+ return buffer;
+ }
+
+ private static Map<EidLispAddressKey, EidLispAddress> provideEidPrefixesFromMessage(final MapRegister mapRegister) {
+ Map<EidLispAddressKey, EidLispAddress> eidsResult = new LinkedHashMap<>();
+ int idx = 0;
+ for (MappingRecordItem mappingRecordItem : mapRegister.getMappingRecordItem()) {
+ final EidLispAddressBuilder eidLispAddressBuilder = new EidLispAddressBuilder();
+ final Eid eid = mappingRecordItem.getMappingRecord().getEid();
+ eidLispAddressBuilder.setEidLispAddressId(LispAddressStringifier.getString(eid));
+ eidLispAddressBuilder.setEid(eid);
+ eidsResult.put(new EidLispAddressKey(Integer.toString(idx)), eidLispAddressBuilder.build());
+ }
+ return eidsResult;
+ }
+
+ /**
+ * Checks whether authentication data is valid.
+ *
+ * <p>Methods pass through all records from map register message. For the EID of the first record it gets
+ * authentication key and does validation of authentication data again this authentication key. If it pass
+ * it just checks for remaining records (and its EID) whether they have the same authentication key stored in
+ * the authentication key database.
+ *
+ * @return Returns authentication key if all of EIDs have the same authentication key or null otherwise
+ */
+ private MappingAuthkey tryToAuthenticateMessage(final MapRegister mapRegister, final ByteBuffer byteBuffer) {
+ if (lispSbPlugin.getAkdb() == null) {
+ LOG.debug("Simple map cache wasn't instantieted and set.");
+ return null;
+ }
+
+ MappingAuthkey firstAuthKey = null;
+ final List<MappingRecordItem> mappingRecords = mapRegister.getMappingRecordItem();
+ for (int i = 0; i < mappingRecords.size(); i++) {
+ final MappingRecordItem recordItem = mappingRecords.get(i);
+ final MappingRecord mappingRecord = recordItem.getMappingRecord();
+ if (i == 0) {
+ firstAuthKey = lispSbPlugin.getAkdb().getAuthenticationKey(mappingRecord.getEid());
+ if (!LispAuthenticationUtil.validate(mapRegister, byteBuffer, mappingRecord.getEid(), firstAuthKey)) {
+ return null;
+ }
+ } else {
+ final Eid eid = mappingRecord.getEid();
+ final MappingAuthkey authKey = lispSbPlugin.getAkdb().getAuthenticationKey(eid);
+ if (!firstAuthKey.equals(authKey)) {
+ LOG.debug("Map register packet contained several eids. Authentication keys for first one and for "
+ + "{} are different.",LispAddressStringifier.getString(eid));
+ return null;
+ }
+ }
+ }
+ return firstAuthKey;
+ }
+
+ @SuppressWarnings("checkstyle:IllegalCatch")