X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;ds=sidebyside;f=mappingservice%2Fsouthbound%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Flispflowmapping%2Fsouthbound%2Flisp%2FLispSouthboundHandler.java;h=535ab72631d62720faf91ca21d19bee00169a192;hb=06ed700110eb5a30c885a894fadd19aea4df85b3;hp=0d7bd8ff3af3a02a63a7effe286aa2bc8297dc2e;hpb=bb53240896a70377005d772ba440cf5bbf519f2b;p=lispflowmapping.git diff --git a/mappingservice/southbound/src/main/java/org/opendaylight/lispflowmapping/southbound/lisp/LispSouthboundHandler.java b/mappingservice/southbound/src/main/java/org/opendaylight/lispflowmapping/southbound/lisp/LispSouthboundHandler.java index 0d7bd8ff3..535ab7263 100644 --- a/mappingservice/southbound/src/main/java/org/opendaylight/lispflowmapping/southbound/lisp/LispSouthboundHandler.java +++ b/mappingservice/southbound/src/main/java/org/opendaylight/lispflowmapping/southbound/lisp/LispSouthboundHandler.java @@ -8,61 +8,83 @@ package org.opendaylight.lispflowmapping.southbound.lisp; +import static org.opendaylight.yangtools.yang.common.UintConversions.fromJava; + import io.netty.buffer.ByteBufUtil; +import io.netty.channel.Channel; import io.netty.channel.ChannelHandler; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.SimpleChannelInboundHandler; import io.netty.channel.socket.DatagramPacket; - import java.net.InetAddress; import java.nio.ByteBuffer; - -import org.opendaylight.controller.md.sal.binding.api.NotificationPublishService; -import org.opendaylight.lispflowmapping.southbound.LispSouthboundPlugin; -import org.opendaylight.lispflowmapping.southbound.LispSouthboundStats; -import org.opendaylight.lispflowmapping.southbound.util.LispNotificationHelper; -import org.opendaylight.lispflowmapping.lisp.type.LispMessage; -import org.opendaylight.lispflowmapping.lisp.util.ByteUtil; -import org.opendaylight.lispflowmapping.lisp.util.MapRequestUtil; +import java.util.Arrays; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import org.opendaylight.lispflowmapping.config.ConfigIni; +import org.opendaylight.lispflowmapping.lisp.authentication.ILispAuthentication; +import org.opendaylight.lispflowmapping.lisp.authentication.LispAuthenticationUtil; import org.opendaylight.lispflowmapping.lisp.serializer.MapNotifySerializer; import org.opendaylight.lispflowmapping.lisp.serializer.MapRegisterSerializer; import org.opendaylight.lispflowmapping.lisp.serializer.MapReplySerializer; import org.opendaylight.lispflowmapping.lisp.serializer.MapRequestSerializer; +import org.opendaylight.lispflowmapping.lisp.type.LispMessage; +import org.opendaylight.lispflowmapping.lisp.util.ByteUtil; +import org.opendaylight.lispflowmapping.lisp.util.LispAddressStringifier; +import org.opendaylight.lispflowmapping.lisp.util.MapRequestUtil; +import org.opendaylight.lispflowmapping.southbound.ConcurrentLispSouthboundStats; +import org.opendaylight.lispflowmapping.southbound.LispSouthboundPlugin; +import org.opendaylight.lispflowmapping.southbound.lisp.cache.MapRegisterPartialDeserializer; import org.opendaylight.lispflowmapping.southbound.lisp.exception.LispMalformedPacketException; import org.opendaylight.lispflowmapping.southbound.lisp.network.PacketHeader; +import org.opendaylight.lispflowmapping.southbound.util.LispNotificationHelper; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.PortNumber; import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.AddMappingBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.GotMapNotifyBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.GotMapReplyBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.MessageType; import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.MapNotify; import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.MapRegister; -import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.MapRequest; import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.MapReply; +import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.MapRequest; +import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.MappingKeepAlive; +import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.MappingKeepAliveBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.MessageType; import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.RequestMappingBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.eid.container.Eid; +import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.map.register.cache.key.container.MapRegisterCacheKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.map.register.cache.metadata.container.MapRegisterCacheMetadata; +import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.map.register.cache.metadata.container.MapRegisterCacheMetadataBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.map.register.cache.metadata.container.map.register.cache.metadata.EidLispAddress; +import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.map.register.cache.metadata.container.map.register.cache.metadata.EidLispAddressBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.map.register.cache.metadata.container.map.register.cache.metadata.EidLispAddressKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.map.register.cache.value.grouping.MapRegisterCacheValue; +import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.map.register.cache.value.grouping.MapRegisterCacheValueBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.mapping._record.container.MappingRecord; +import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.mapping._record.list.MappingRecordItem; +import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.mapping.authkey.container.MappingAuthkey; import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.transport.address.TransportAddressBuilder; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.PortNumber; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @ChannelHandler.Sharable -public class LispSouthboundHandler extends SimpleChannelInboundHandler implements ILispSouthboundService { - private NotificationPublishService notificationPublishService; +public class LispSouthboundHandler extends SimpleChannelInboundHandler + implements ILispSouthboundService, AutoCloseable { protected static final Logger LOG = LoggerFactory.getLogger(LispSouthboundHandler.class); + //TODO: think whether this field can be accessed through mappingservice or some other configuration parameter + private final boolean authenticationEnabled = ConfigIni.getInstance().isAuthEnabled(); private final LispSouthboundPlugin lispSbPlugin; - private LispSouthboundStats lispSbStats = null; + private final boolean isReadFromChannelEnabled = true; + + private Channel channel; public LispSouthboundHandler(LispSouthboundPlugin lispSbPlugin) { this.lispSbPlugin = lispSbPlugin; - if (lispSbPlugin != null) { - this.lispSbStats = lispSbPlugin.getStats(); - } - } - - public void setNotificationProvider(NotificationPublishService nps) { - this.notificationPublishService = nps; } + @Override public void handlePacket(DatagramPacket msg) { ByteBuffer inBuffer = msg.content().nioBuffer(); int type = ByteUtil.getUnsignedByte(inBuffer, LispMessage.Pos.TYPE) >> 4; @@ -73,7 +95,7 @@ public class LispSouthboundHandler extends SimpleChannelInboundHandler> 4); + int ipType = inBuffer.get() >> 4; if (ipType == 4) { inBuffer.position(inBuffer.position() + PacketHeader.Length.IPV4 - 1); } else if (ipType == 6) { inBuffer.position(inBuffer.position() + PacketHeader.Length.IPV6_NO_EXT - 1); } else { - throw new LispMalformedPacketException("Couldn't deserialize Map-Request: inner packet has unknown IP version: " + ipType); + throw new LispMalformedPacketException( + "Couldn't deserialize Map-Request: inner packet has unknown IP version: " + ipType); } int encapsulatedSourcePort = inBuffer.getShort() & 0xFFFF; inBuffer.position(inBuffer.position() + PacketHeader.Length.UDP - 2); return encapsulatedSourcePort; } catch (RuntimeException re) { - throw new LispMalformedPacketException("Couldn't deserialize Map-Request (len=" + inBuffer.capacity() + ")", re); + throw new LispMalformedPacketException("Couldn't deserialize Map-Request (len=" + + inBuffer.capacity() + ")", re); } } + @SuppressWarnings("checkstyle:IllegalCatch") private void handleMapRegister(ByteBuffer inBuffer, InetAddress sourceAddress, int port) { try { - MapRegister mapRegister = MapRegisterSerializer.getInstance().deserialize(inBuffer, sourceAddress); - AddMappingBuilder addMappingBuilder = new AddMappingBuilder(); - addMappingBuilder.setMapRegister(LispNotificationHelper.convertMapRegister(mapRegister)); - TransportAddressBuilder transportAddressBuilder = new TransportAddressBuilder(); - transportAddressBuilder.setIpAddress(LispNotificationHelper.getIpAddressFromInetAddress(sourceAddress)); - transportAddressBuilder.setPort(new PortNumber(port)); - addMappingBuilder.setTransportAddress(transportAddressBuilder.build()); - if (notificationPublishService != null) { - notificationPublishService.putNotification(addMappingBuilder.build()); - LOG.trace("MapRegister was published!"); + Map.Entry artificialEntry = null; + MapRegisterCacheKey cacheKey = null; + MapRegisterCacheValue cacheValue = null; + if (lispSbPlugin.isMapRegisterCacheEnabled()) { + artificialEntry = MapRegisterPartialDeserializer.deserializePartially(inBuffer, sourceAddress); + cacheKey = artificialEntry == null ? null : artificialEntry.getKey(); + cacheValue = resolveCacheValue(artificialEntry); + } + if (cacheValue != null) { + lispSbPlugin.getStats().incrementCacheHits(); + MapRegisterCacheMetadata mapRegisterMeta = cacheValue.getMapRegisterCacheMetadata(); + LOG.debug("Map register message site-ID: {} xTR-ID: {} from cache.", mapRegisterMeta.getSiteId(), + mapRegisterMeta.getXtrId()); + cacheValue = refreshEntry(cacheKey); + if (cacheValue != null) { + lispSbPlugin.sendNotificationIfPossible(createMappingKeepAlive(cacheValue)); + if (cacheValue.getMapRegisterCacheMetadata().getWantMapNotify()) { + sendMapNotifyMsg(inBuffer, sourceAddress, port, cacheValue); + } + } } else { - LOG.warn("Notification Provider is null!"); + lispSbPlugin.getStats().incrementCacheMisses(); + MapRegister mapRegister = MapRegisterSerializer.getInstance().deserialize(inBuffer, sourceAddress); + + MappingAuthkey mappingAuthkey = null; + if (authenticationEnabled) { + mappingAuthkey = tryToAuthenticateMessage(mapRegister, inBuffer); + if (mappingAuthkey == null) { + return; + } + } + + AddMappingBuilder addMappingBuilder = new AddMappingBuilder(); + addMappingBuilder.setMapRegister(LispNotificationHelper.convertMapRegister(mapRegister)); + TransportAddressBuilder transportAddressBuilder = new TransportAddressBuilder(); + transportAddressBuilder.setIpAddress(LispNotificationHelper.getIpAddressBinaryFromInetAddress( + sourceAddress)); + transportAddressBuilder.setPort(new PortNumber(fromJava(port))); + addMappingBuilder.setTransportAddress(transportAddressBuilder.build()); + lispSbPlugin.sendNotificationIfPossible(addMappingBuilder.build()); + if (artificialEntry != null) { + final MapRegisterCacheMetadataBuilder cacheMetadataBldNew = new + MapRegisterCacheMetadataBuilder(); + cacheMetadataBldNew.setEidLispAddress(provideEidPrefixesFromMessage(mapRegister)); + cacheMetadataBldNew.setXtrId(mapRegister.getXtrId()); + cacheMetadataBldNew.setSiteId(mapRegister.getSiteId()); + cacheMetadataBldNew.setWantMapNotify(mapRegister.getWantMapNotify()); + cacheMetadataBldNew.setMergeEnabled(mapRegister.getMergeEnabled()); + cacheMetadataBldNew.setTimestamp(System.currentTimeMillis()); + + final MapRegisterCacheValueBuilder cacheValueBldNew = new MapRegisterCacheValueBuilder(); + cacheValueBldNew.setPacketData(artificialEntry.getValue()); + cacheValueBldNew.setMappingAuthkey(mappingAuthkey); + cacheValueBldNew.setMapRegisterCacheMetadata(cacheMetadataBldNew.build()); + + lispSbPlugin.getMapRegisterCache().addEntry(cacheKey, cacheValueBldNew.build()); + } } } catch (RuntimeException re) { - throw new LispMalformedPacketException("Couldn't deserialize Map-Register (len=" + inBuffer.capacity() + ")", re); + throw new LispMalformedPacketException("Couldn't deserialize Map-Register (len=" + + inBuffer.capacity() + ")", re); } catch (InterruptedException e) { LOG.warn("Notification publication interrupted!"); } } + 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 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 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 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 provideEidPrefixesFromMessage(final MapRegister mapRegister) { + Map 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. + * + *

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 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") private void handleMapNotify(ByteBuffer inBuffer, InetAddress sourceAddress, int port) { try { MapNotify mapNotify = MapNotifySerializer.getInstance().deserialize(inBuffer); GotMapNotifyBuilder gotMapNotifyBuilder = new GotMapNotifyBuilder(); gotMapNotifyBuilder.setMapNotify(LispNotificationHelper.convertMapNotify(mapNotify)); TransportAddressBuilder transportAddressBuilder = new TransportAddressBuilder(); - transportAddressBuilder.setIpAddress(LispNotificationHelper.getIpAddressFromInetAddress(sourceAddress)); - transportAddressBuilder.setPort(new PortNumber(port)); + transportAddressBuilder.setIpAddress(LispNotificationHelper + .getIpAddressBinaryFromInetAddress(sourceAddress)); + transportAddressBuilder.setPort(new PortNumber(fromJava(port))); gotMapNotifyBuilder.setTransportAddress(transportAddressBuilder.build()); - if (notificationPublishService != null) { - notificationPublishService.putNotification(gotMapNotifyBuilder.build()); - LOG.trace("MapNotify was published!"); - } else { - LOG.warn("Notification Provider is null!"); - } + lispSbPlugin.sendNotificationIfPossible(gotMapNotifyBuilder.build()); } catch (RuntimeException re) { - throw new LispMalformedPacketException("Couldn't deserialize Map-Notify (len=" + inBuffer.capacity() + ")", re); + throw new LispMalformedPacketException("Couldn't deserialize Map-Notify (len=" + + inBuffer.capacity() + ")", re); } catch (InterruptedException e) { LOG.warn("Notification publication interrupted!"); } } + @SuppressWarnings("checkstyle:IllegalCatch") private void handleMapReply(ByteBuffer inBuffer, InetAddress sourceAddress, int port) { try { MapReply mapReply = MapReplySerializer.getInstance().deserialize(inBuffer); GotMapReplyBuilder gotMapReplyBuilder = new GotMapReplyBuilder(); gotMapReplyBuilder.setMapReply(LispNotificationHelper.convertMapReply(mapReply)); TransportAddressBuilder transportAddressBuilder = new TransportAddressBuilder(); - transportAddressBuilder.setIpAddress(LispNotificationHelper.getIpAddressFromInetAddress(sourceAddress)); - transportAddressBuilder.setPort(new PortNumber(port)); + transportAddressBuilder.setIpAddress(LispNotificationHelper + .getIpAddressBinaryFromInetAddress(sourceAddress)); + transportAddressBuilder.setPort(new PortNumber(fromJava(port))); gotMapReplyBuilder.setTransportAddress(transportAddressBuilder.build()); - if (notificationPublishService != null) { - notificationPublishService.putNotification(gotMapReplyBuilder.build()); - LOG.trace("MapReply was published!"); - } else { - LOG.warn("Notification Provider is null!"); - } + lispSbPlugin.sendNotificationIfPossible(gotMapReplyBuilder.build()); } catch (RuntimeException re) { - throw new LispMalformedPacketException("Couldn't deserialize Map-Reply (len=" + inBuffer.capacity() + ")", re); + throw new LispMalformedPacketException("Couldn't deserialize Map-Reply (len=" + + inBuffer.capacity() + ")", re); } catch (InterruptedException e) { LOG.warn("Notification publication interrupted!"); } } private void handleStats(int type) { - if (lispSbStats != null) { - if (type <= LispSouthboundStats.MAX_LISP_TYPES) { - lispSbStats.incrementRx(type); + if (lispSbPlugin.getStats() != null) { + if (type <= ConcurrentLispSouthboundStats.MAX_LISP_TYPES) { + lispSbPlugin.getStats().incrementRx(type); } else { - lispSbStats.incrementRxUnknown(); + lispSbPlugin.getStats().incrementRxUnknown(); } } } @Override protected void channelRead0(ChannelHandlerContext ctx, DatagramPacket msg) throws Exception { - if (LOG.isTraceEnabled()) { - LOG.trace("Received UDP packet from {}:{} with content:\n{}", msg.sender().getHostString(), - msg.sender().getPort(), ByteBufUtil.prettyHexDump(msg.content())); + if (isReadFromChannelEnabled) { + if (LOG.isTraceEnabled()) { + LOG.trace("Received UDP packet from {}:{} with content:\n{}", msg.sender().getHostString(), + msg.sender().getPort(), ByteBufUtil.prettyHexDump(msg.content())); + } + this.channel = ctx.channel(); + handlePacket(msg); } - handlePacket(msg); } @Override @@ -237,4 +477,8 @@ public class LispSouthboundHandler extends SimpleChannelInboundHandler