Bug 8746: Multi-threading improvements
[lispflowmapping.git] / mappingservice / southbound / src / test / java / org / opendaylight / lispflowmapping / southbound / lisp / LispSouthboundServiceTest.java
1 /*
2  * Copyright (c) 2014 Contextream, Inc. and others.  All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8
9 package org.opendaylight.lispflowmapping.southbound.lisp;
10
11 import static io.netty.buffer.Unpooled.wrappedBuffer;
12 import static org.junit.Assert.assertEquals;
13 import static org.junit.Assert.assertFalse;
14 import static org.junit.Assert.assertTrue;
15 import static org.mockito.Mockito.mock;
16 import static org.opendaylight.lispflowmapping.southbound.lisp.MapRegisterCacheTestUtil.DATA1;
17 import static org.opendaylight.lispflowmapping.southbound.lisp.MapRegisterCacheTestUtil.DATA2;
18 import static org.opendaylight.lispflowmapping.southbound.lisp.MapRegisterCacheTestUtil.DATA3;
19 import static org.opendaylight.lispflowmapping.southbound.lisp.MapRegisterCacheTestUtil.KEY_ID;
20 import static org.opendaylight.lispflowmapping.southbound.lisp.MapRegisterCacheTestUtil.NONCE;
21 import static org.opendaylight.lispflowmapping.southbound.lisp.MapRegisterCacheTestUtil.SITE_ID;
22 import static org.opendaylight.lispflowmapping.southbound.lisp.MapRegisterCacheTestUtil.XTR_ID;
23 import static org.opendaylight.lispflowmapping.southbound.lisp.MapRegisterCacheTestUtil.joinArrays;
24
25 import io.netty.channel.socket.DatagramPacket;
26 import java.net.InetSocketAddress;
27 import java.net.UnknownHostException;
28 import java.nio.ByteBuffer;
29 import java.util.ArrayList;
30 import java.util.Arrays;
31 import java.util.List;
32 import junitx.framework.ArrayAssert;
33 import org.apache.commons.lang3.ArrayUtils;
34 import org.jmock.api.Invocation;
35 import org.junit.Before;
36 import org.junit.BeforeClass;
37 import org.junit.Ignore;
38 import org.junit.Test;
39 import org.mockito.AdditionalMatchers;
40 import org.mockito.InOrder;
41 import org.mockito.Matchers;
42 import org.mockito.Mockito;
43 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
44 import org.opendaylight.controller.md.sal.binding.api.NotificationPublishService;
45 import org.opendaylight.lispflowmapping.lisp.serializer.MapNotifySerializer;
46 import org.opendaylight.lispflowmapping.lisp.serializer.MapReplySerializer;
47 import org.opendaylight.lispflowmapping.lisp.type.LispMessage;
48 import org.opendaylight.lispflowmapping.lisp.util.ByteUtil;
49 import org.opendaylight.lispflowmapping.lisp.util.LispAddressUtil;
50 import org.opendaylight.lispflowmapping.lisp.util.MapNotifyBuilderHelper;
51 import org.opendaylight.lispflowmapping.lisp.util.MaskUtil;
52 import org.opendaylight.lispflowmapping.mapcache.AuthKeyDb;
53 import org.opendaylight.lispflowmapping.southbound.ConcurrentLispSouthboundStats;
54 import org.opendaylight.lispflowmapping.southbound.LispSouthboundPlugin;
55 import org.opendaylight.lispflowmapping.southbound.lisp.cache.MapRegisterCache;
56 import org.opendaylight.lispflowmapping.southbound.lisp.exception.LispMalformedPacketException;
57 import org.opendaylight.lispflowmapping.tools.junit.BaseTestCase;
58 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.iana.afn.safi.rev130704.AddressFamily;
59 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.lisp.address.types.rev151105.InstanceIdType;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.binary.address.types.rev160504.Ipv4BinaryAfi;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.binary.address.types.rev160504.Ipv4PrefixBinaryAfi;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.binary.address.types.rev160504.Ipv6PrefixBinaryAfi;
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.AddMapping;
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.MapRegister;
65 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.MapRequest;
66 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.MessageType;
67 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.RequestMapping;
68 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.eid.container.Eid;
69 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.eid.list.EidItem;
70 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.locatorrecords.LocatorRecord;
71 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.locatorrecords.LocatorRecordBuilder;
72 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.map.register.cache.key.container.MapRegisterCacheKey;
73 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.map.register.cache.key.container.MapRegisterCacheKeyBuilder;
74 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.map.register.cache.metadata.container.MapRegisterCacheMetadataBuilder;
75 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.map.register.cache.value.grouping.MapRegisterCacheValue;
76 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.map.register.cache.value.grouping.MapRegisterCacheValueBuilder;
77 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.mapnotifymessage.MapNotifyBuilder;
78 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.mapping.authkey.container.MappingAuthkeyBuilder;
79 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.mapping.record.container.MappingRecord;
80 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.mapping.record.container.MappingRecord.Action;
81 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.mapping.record.container.MappingRecordBuilder;
82 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.mapping.record.list.MappingRecordItem;
83 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.mapping.record.list.MappingRecordItemBuilder;
84 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.mapreplymessage.MapReplyBuilder;
85 import org.opendaylight.yangtools.yang.binding.Notification;
86
87 public class LispSouthboundServiceTest extends BaseTestCase {
88
89     private LispSouthboundHandler testedLispService;
90     private NotificationPublishService nps;
91     private byte[] mapRequestPacket;
92     private byte[] mapRegisterPacket;
93     private ValueSaverAction<Notification> lispNotificationSaver;
94     // private ValueSaverAction<MapRegister> mapRegisterSaver;
95     // private ValueSaverAction<MapRequest> mapRequestSaver;
96     private MapNotifyBuilder mapNotifyBuilder;
97     private MapReplyBuilder mapReplyBuilder;
98     private MappingRecordBuilder mappingRecordBuilder;
99     private MapRegisterCache mapRegisterCache;
100     private LispSouthboundPlugin mockLispSouthboundPlugin;
101     private ConcurrentLispSouthboundStats lispSouthboundStats;
102     private static final long CACHE_RECORD_TIMEOUT = 90000;
103
104     private static AuthKeyDb akdb;
105     private static AuthenticationKeyDataListener akdl;
106
107     private interface MapReplyIpv4SingleLocatorPos {
108         int RECORD_COUNT = 3;
109         int NONCE = 4;
110         int LOCATOR_COUNT = 16;
111         int EID_MASK_LEN = 17;
112         int AFI_TYPE = 22;
113         int EID_PREFIX = 24;
114         int LOC_AFI = 34;
115         int LOCATOR_RBIT = 33;
116         int LOCATOR = 36;
117     }
118
119     private interface MapReplyIpv4SecondLocatorPos {
120         int FIRST_LOCATOR_IPV4_LENGTH = 12;
121         int LOC_AFI = MapReplyIpv4SingleLocatorPos.LOC_AFI + FIRST_LOCATOR_IPV4_LENGTH;
122         int LOCATOR_RBIT = MapReplyIpv4SingleLocatorPos.LOCATOR_RBIT + FIRST_LOCATOR_IPV4_LENGTH;
123         int LOCATOR = MapReplyIpv4SingleLocatorPos.LOCATOR + FIRST_LOCATOR_IPV4_LENGTH;
124     }
125
126     @BeforeClass
127     public static void initTests() {
128         akdb = Mockito.mock(AuthKeyDb.class);
129         Mockito.when(akdb.getAuthenticationKey(Matchers.eq(LispAddressUtil.asIpv4PrefixBinaryEid("10.10.10.10/8"))))
130                 .thenReturn(new MappingAuthkeyBuilder().setKeyType(1).setKeyString("password").build());
131         Mockito.when(akdb.getAuthenticationKey(Matchers.eq(LispAddressUtil.asIpv6PrefixBinaryEid(
132                 "2610:d0:ffff:192:0:0:0:1/128"))))
133                 .thenReturn(new MappingAuthkeyBuilder().setKeyType(1).setKeyString("password").build());
134         Mockito.when(akdb.getAuthenticationKey(Matchers.eq(LispAddressUtil.asIpv4PrefixBinaryEid("153.16.254.1/32"))))
135                 .thenReturn(new MappingAuthkeyBuilder().setKeyType(1).setKeyString("password").build());
136         Mockito.when(akdb.getAuthenticationKey(Matchers.eq(LispAddressUtil.asIpv4PrefixBinaryEid("125.124.123.122/8",
137                 new InstanceIdType(21L)))))
138                 .thenReturn(new MappingAuthkeyBuilder().setKeyType(1).setKeyString("password").build());
139         Mockito.when(akdb.getAuthenticationKey(Matchers.eq(LispAddressUtil.asMacEid("0a:0b:0c:0d:0e:0f"))))
140                 .thenReturn(new MappingAuthkeyBuilder().setKeyType(1).setKeyString("password").build());
141         Mockito.when(akdb.getAuthenticationKey(Matchers.eq(LispAddressUtil.asIpv6PrefixBinaryEid(
142                 "f0f:f0f:f0f:f0f:f0f:f0f:f0f:f0f/8"))))
143                 .thenReturn(new MappingAuthkeyBuilder().setKeyType(1).setKeyString("password").build());
144         Mockito.when(akdb.getAuthenticationKey(Matchers.eq(LispAddressUtil.asIpv4PrefixBinaryEid("172.1.1.2/32"))))
145                 .thenReturn(new MappingAuthkeyBuilder().setKeyType(1).setKeyString("password").build());
146
147         akdl = Mockito.mock(AuthenticationKeyDataListener.class);
148         Mockito.when(akdl.authKeysForEidsUnchanged(Mockito.anyList(), Mockito.anyLong())).thenReturn(true);
149     }
150
151     @Override
152     @Before
153     public void before() throws Exception {
154         super.before();
155         // mapResolver = context.mock(IMapResolver.class);
156         // mapServer = context.mock(IMapServer.class);
157         mockLispSouthboundPlugin = mock(LispSouthboundPlugin.class);
158         Mockito.when(mockLispSouthboundPlugin.isMapRegisterCacheEnabled()).thenReturn(true);
159         testedLispService = new LispSouthboundHandler(mockLispSouthboundPlugin);
160         testedLispService.setMapRegisterCacheTimeout(90000);
161         mapRegisterCache = new MapRegisterCache();
162         testedLispService.setMapRegisterCache(mapRegisterCache);
163         testedLispService.setDataBroker(Mockito.mock(DataBroker.class));
164         testedLispService.setAuthKeyDb(akdb);
165         testedLispService.setAuthenticationKeyDataListener(akdl);
166         nps = context.mock(NotificationPublishService.class);
167         testedLispService.setNotificationProvider(nps);
168         lispSouthboundStats = new ConcurrentLispSouthboundStats();
169         testedLispService.setStats(lispSouthboundStats);
170         lispNotificationSaver = new ValueSaverAction<Notification>();
171         // mapRegisterSaver = new ValueSaverAction<MapRegister>();
172         // mapRequestSaver = new ValueSaverAction<MapRequest>();
173         // SRC: 127.0.0.1:58560 to 127.0.0.1:4342
174         // LISP(Type = 8 - Encapsulated)
175         // IP: 192.168.136.10 -> 1.2.3.4
176         // UDP: 56756
177         // LISP(Type = 1 Map-Request
178         // Record Count: 1
179         // ITR-RLOC count: 0
180         // Source EID AFI: 0
181         // Source EID not present
182         // Nonce: 0x3d8d2acd39c8d608
183         // ITR-RLOC AFI=1 Address=192.168.136.10
184         // Record 1: 1.2.3.4/32
185         mapRequestPacket = extractWSUdpByteArray(new String(
186                   "0000   00 00 00 00 00 00 00 00 00 00 00 00 08 00 45 00 "
187                 + "0010   00 58 00 00 40 00 40 11 3c 93 7f 00 00 01 7f 00 "
188                 + "0020   00 01 e4 c0 10 f6 00 44 fe 57 80 00 00 00 45 00 "
189                 + "0030   00 38 d4 31 00 00 ff 11 56 f3 c0 a8 88 0a 01 02 "
190                 + "0040   03 04 dd b4 10 f6 00 24 ef 3a 10 00 00 01 3d 8d "
191                 + "0050   2a cd 39 c8 d6 08 00 01 01 02 03 04 00 01 c0 a8 88 0a 00 20 "
192                 + "0060   00 01 01 02 03 04"));
193         mapReplyBuilder = new MapReplyBuilder();
194         mapReplyBuilder.setMappingRecordItem(new ArrayList<MappingRecordItem>());
195         mapReplyBuilder.setNonce((long) 0);
196         mapReplyBuilder.setEchoNonceEnabled(false);
197         mapReplyBuilder.setProbe(true);
198         mapReplyBuilder.setSecurityEnabled(true);
199         mappingRecordBuilder = new MappingRecordBuilder();
200         String ip = "0.0.0.0";
201         mappingRecordBuilder.setEid(LispAddressUtil.asIpv4PrefixEid(ip + "/0"));
202         mappingRecordBuilder.setLocatorRecord(new ArrayList<LocatorRecord>());
203         mappingRecordBuilder.setRecordTtl(10);
204         mappingRecordBuilder.setMapVersion((short) 0);
205         mappingRecordBuilder.setAction(Action.NativelyForward);
206         mappingRecordBuilder.setAuthoritative(false);
207         // eidToLocatorBuilder.setPrefix(new LispIpv4Address(0));
208         // mapReply.addEidToLocator(eidToLocatorBuilder);
209
210         // IP: 192.168.136.10 -> 128.223.156.35
211         // UDP: 49289 -> 4342
212         // LISP(Type = 3 Map-Register, P=1, M=1
213         // Record Counter: 1
214         // Nonce: 0
215         // Key ID: 0x0001
216         // AuthDataLength: 20 Data:
217         // e8:f5:0b:c5:c5:f2:b0:21:27:a8:21:41:04:f3:46:5a:a5:68:89:ec
218         // EID prefix: 153.16.254.1/32 (EID=0x9910FE01), TTL: 10, Authoritative,
219         // No-Action
220         // Local RLOC: 192.168.136.10 (RLOC=0xC0A8880A), Reachable,
221         // Priority/Weight: 1/100, Multicast Priority/Weight:
222         // 255/0
223         //
224
225         mapRegisterPacket = extractWSUdpByteArray(new String(
226                   "0000   00 50 56 ee d1 4f 00 0c 29 7a ce 79 08 00 45 00 "
227                 + "0010   00 5c 00 00 40 00 40 11 d4 db c0 a8 88 0a 80 df "
228                 + "0020   9c 23 d6 40 10 f6 00 48 59 a4 38 00 01 01 00 00 "
229                 + "0030   00 00 00 00 00 00 00 01 00 14 0e a4 c6 d8 a4 06 "
230                 + "0040   71 7c 33 a4 5c 4a 83 1c de 74 53 03 0c ad 00 00 "
231                 + "0050   00 0a 01 20 10 00 00 00 00 01 99 10 fe 01 01 64 "
232                 + "0060   ff 00 00 05 00 01 c0 a8 88 0a"));
233         mapNotifyBuilder = new MapNotifyBuilder();
234         mapNotifyBuilder.setAuthenticationData(new byte[0]);
235     }
236
237     @Test
238     @Ignore
239     public void todos() throws Exception {
240
241         // TODO: MapRequest: usage of Map-Reply-Record in MapRequest packet.
242         // TODO: Non-Encapsulated packets
243     }
244
245     @Test(expected = LispMalformedPacketException.class)
246     public void mapRegister__IllegalPacket() throws Exception {
247         mapRegisterPacket = extractWSUdpByteArray(new String(
248                   "0000   00 0c 29 7a ce 8d 00 0c 29 e4 ef 70 08 00 45 00 "
249                 + "0010   00 68 00 00 40 00 40 11 26 15 0a 01 00 6e 0a 01 "
250                 + "0020   00 01 10 f6 10 f6 00 54 03 3b 38 00 01 01 00 00 "));
251
252         handleMapRegisterPacket(mapRegisterPacket);
253     }
254
255     @Test(expected = LispMalformedPacketException.class)
256     public void mapRequest__IllegalPacket() throws Exception {
257         mapRequestPacket = extractWSUdpByteArray(new String(
258                   "0000   00 00 00 00 00 00 00 00 00 00 00 00 08 00 45 00 "
259                 + "0010   00 58 00 00 40 00 40 11 3c 93 7f 00 00 01 7f 00 "
260                 + "0020   00 01 e4 c0 10 f6 00 44 fe 57 80 00 00 00 45 00 "
261                 + "0030   00 38 d4 31 00 00 ff 11 56 f3 c0 a8 88 0a 01 02 "
262                 + "0040   03 04 dd b4 10 f6 00 24 ef 3a 10 00 00 01 3d 8d "));
263         handleMapRequestPacket(mapRequestPacket);
264     }
265
266     @Test(expected = LispMalformedPacketException.class)
267     public void mapRequest__IllegalEncapsulatedPacket() throws Exception {
268         mapRequestPacket = extractWSUdpByteArray(new String(
269                   "0000   00 00 00 00 00 00 00 00 00 00 00 00 08 00 45 00 "
270                 + "0010   00 58 00 00 40 00 40 11 3c 93 7f 00 00 01 7f 00 "
271                 + "0020   00 01 e4 c0 10 f6 00 44 fe 57 80 00 00 00 45 00 "));
272         handleMapRequestPacket(mapRequestPacket);
273     }
274
275     private MapRegister lastMapRegister() {
276         assertTrue(lispNotificationSaver.lastValue instanceof AddMapping);
277         AddMapping lastValue = (AddMapping) lispNotificationSaver.lastValue;
278         return lastValue.getMapRegister();
279     }
280
281     private MapRequest lastMapRequest() {
282         RequestMapping lastValue = (RequestMapping) lispNotificationSaver.lastValue;
283         return lastValue.getMapRequest();
284     }
285
286     @Test
287     public void mapRegister__TwoRlocs() throws Exception {
288         // P Bit & M Bit set
289         // EID prefix: 172.1.1.2/32, TTL: 10, Authoritative, No-Action
290         // Local RLOC: 10.1.0.110, Reachable, Priority/Weight: 1/100, Multicast
291         // Priority/Weight: 255/0
292         // Local RLOC: 192.168.136.51, Reachable, Priority/Weight: 6/100,
293         // Multicast Priority/Weight: 255/0
294         mapRegisterPacket = extractWSUdpByteArray(new String(
295                   "0000   00 0c 29 7a ce 8d 00 0c 29 e4 ef 70 08 00 45 00 "
296                 + "0010   00 68 00 00 40 00 40 11 26 15 0a 01 00 6e 0a 01 "
297                 + "0020   00 01 10 f6 10 f6 00 54 03 3b 38 00 01 01 00 00 "
298                 + "0030   00 00 00 00 00 00 00 01 00 14 ae d8 7b d4 9c 59 "
299                 + "0040   e9 35 75 6e f1 29 27 a3 45 20 96 06 c2 e1 00 00 "
300                 + "0050   00 0a 02 20 10 00 00 00 00 01 ac 01 01 02 01 64 "
301                 + "0060   ff 00 00 05 00 01 0a 01 00 6e 06 64 ff 00 00 05 "
302                 + "0070   00 01 c0 a8 88 33"));
303
304         oneOf(nps).putNotification(with(lispNotificationSaver));
305
306         handleMapRegisterPacket(mapRegisterPacket);
307
308         List<MappingRecordItem> eidRecords = lastMapRegister().getMappingRecordItem();
309         assertEquals(1, eidRecords.size());
310         MappingRecord eidRecord = eidRecords.get(0).getMappingRecord();
311         assertEquals(2, eidRecord.getLocatorRecord().size());
312         assertEquals(LispAddressUtil.asIpv4Rloc("10.1.0.110"), eidRecord.getLocatorRecord().get(0).getRloc());
313         assertEquals(LispAddressUtil.asIpv4Rloc("192.168.136.51"), eidRecord.getLocatorRecord().get(1).getRloc());
314     }
315
316     @Test
317     public void mapRegister__Ipv6Rloc() throws Exception {
318         // P bit (Proxy-Map-Reply): Set
319         // M bit (Want-Map-Notify): Set
320         // Record Counter: 1
321         // Nonce: 0
322         // Key ID: 1
323         // AuthLength: 20
324         // Authentication Data: 5bc4d44a57e2a55d577a6f89779c004f5da713fb
325         // EID prefix: 2610:d0:ffff:192::1/128, TTL: 10, Authoritative,
326         // No-Action
327         // Local RLOC: 10.0.58.156, Reachable, Priority/Weight: 1/100, Multicast
328         // Priority/Weight: 255/0
329
330         mapRegisterPacket = extractWSUdpByteArray(new String(
331                   "0000   00 0c 29 34 3e 1b 00 0c 29 f6 d6 0d 08 00 45 00 "
332                 + "0010   00 68 00 00 40 00 40 11 ea c3 0a 00 3a 9c 0a 00 "
333                 + "0020   01 26 10 f6 10 f6 00 54 f5 9a 38 00 03 01 00 00 "
334                 + "0030   00 00 00 00 00 00 00 01 00 14 22 97 ff 61 ec d8 "
335                 + "0040   0f 91 c6 c4 01 ef 7f bb 77 58 39 5c 92 23 00 00 "
336                 + "0050   00 0a 01 80 10 00 00 00 00 02 26 10 00 d0 ff ff "
337                 + "0060   01 92 00 00 00 00 00 00 00 01 01 64 ff 00 00 05 "
338                 + "0070   00 01 0a 00 3a 9c"));
339
340         oneOf(nps).putNotification(with(lispNotificationSaver));
341
342         handleMapRegisterPacket(mapRegisterPacket);
343
344         MappingRecord eidToLocatorRecord = lastMapRegister().getMappingRecordItem().get(0).getMappingRecord();
345         assertEquals(LispAddressUtil.asIpv6PrefixBinaryEid("2610:d0:ffff:192:0:0:0:1/128"),
346                 eidToLocatorRecord.getEid());
347         assertEquals(Ipv6PrefixBinaryAfi.class, eidToLocatorRecord.getEid().getAddressType());
348
349         assertEquals(LispAddressUtil.asIpv4Rloc("10.0.58.156"), eidToLocatorRecord.getLocatorRecord().get(0).getRloc());
350     }
351
352     @Test
353     public void mapRegister__VerifyBasicFields() throws Exception {
354         oneOf(nps).putNotification(with(lispNotificationSaver));
355         handleMapRegisterPacket(mapRegisterPacket);
356
357         MappingRecord eidToLocator = lastMapRegister().getMappingRecordItem().get(0).getMappingRecord();
358         assertEquals(LispAddressUtil.asIpv4PrefixBinaryEid("153.16.254.1/32"), eidToLocator.getEid());
359
360         assertEquals(1, eidToLocator.getLocatorRecord().size());
361         assertEquals(LispAddressUtil.asIpv4Rloc("192.168.136.10"), eidToLocator.getLocatorRecord().get(0).getRloc());
362     }
363
364     @Test
365     @Ignore
366     public void mapRegister__NoResponseFromMapServerShouldReturnNullPacket() throws Exception {
367         oneOf(nps).putNotification(with(lispNotificationSaver));
368         mapNotifyBuilder = null;
369
370         assertNull(handleMapRegisterPacket(mapRegisterPacket));
371     }
372
373     @Test
374     public void mapRegister__NonSetMBit() throws Exception {
375         byte[] registerWithNonSetMBit = extractWSUdpByteArray(new String(
376                   "0000   00 50 56 ee d1 4f 00 0c 29 7a ce 79 08 00 45 00 "
377                 + "0010   00 5c 00 00 40 00 40 11 d4 db c0 a8 88 0a 80 df "
378                 + "0020   9c 23 d6 40 10 f6 00 48 59 a4 38 00 00 01 00 00 "
379                 + "0030   00 00 00 00 00 00 00 01 00 14 79 d1 44 66 19 99 "
380                 + "0040   83 63 a7 79 6e f0 40 97 54 26 3a 44 b4 eb 00 00 "
381                 + "0050   00 0a 01 20 10 00 00 00 00 01 99 10 fe 01 01 64 "
382                 + "0060   ff 00 00 05 00 01 c0 a8 88 0a"));
383         stubMapRegister(true);
384
385         handleMapRegisterPacket(registerWithNonSetMBit);
386
387         assertFalse(lastMapRegister().isWantMapNotify());
388     }
389
390     @Test
391     public void mapRegister__NonSetMBitWithNonZeroReservedBits() throws Exception {
392         byte[] registerWithNonSetMBit = extractWSUdpByteArray(new String(
393                   "0000   00 50 56 ee d1 4f 00 0c 29 7a ce 79 08 00 45 00 "
394                 + "0010   00 5c 00 00 40 00 40 11 d4 db c0 a8 88 0a 80 df "
395                 + "0020   9c 23 d6 40 10 f6 00 48 59 a4 38 00 02 01 00 00 "
396                 + "0030   00 00 00 00 00 00 00 01 00 14 c0 c7 c5 2f 57 f6 "
397                 + "0040   e7 20 25 3d e8 b2 07 e2 63 de 62 2b 7a 20 00 00 "
398                 + "0050   00 0a 01 20 10 00 00 00 00 01 99 10 fe 01 01 64 "
399                 + "0060   ff 00 00 05 00 01 c0 a8 88 0a"));
400         stubMapRegister(true);
401
402         handleMapRegisterPacket(registerWithNonSetMBit);
403         assertFalse(lastMapRegister().isWantMapNotify());
404     }
405
406     @Test
407     public void mapRegister__SetMBitWithNonZeroReservedBits() throws Exception {
408         byte[] registerWithNonSetMBit = extractWSUdpByteArray(new String(
409                   "0000   00 50 56 ee d1 4f 00 0c 29 7a ce 79 08 00 45 00 "
410                 + "0010   00 5c 00 00 40 00 40 11 d4 db c0 a8 88 0a 80 df "
411                 + "0020   9c 23 d6 40 10 f6 00 48 59 a4 38 00 03 01 00 00 "
412                 + "0030   00 00 00 00 00 00 00 01 00 14 a2 72 40 7b 1a ae "
413                 + "0040   4e 6b e2 e5 e1 01 40 8a c9 e1 d1 80 cb 72 00 00 "
414                 + "0050   00 0a 01 20 10 00 00 00 00 01 99 10 fe 01 01 64 "
415                 + "0060   ff 00 00 05 00 01 c0 a8 88 0a"));
416         stubMapRegister(true);
417
418         handleMapRegisterPacket(registerWithNonSetMBit);
419         assertTrue(lastMapRegister().isWantMapNotify());
420     }
421
422     /**
423      * Tests whether handling of map-register message will generate mapping-keep-alive notification.
424      */
425     @Test
426     public void mapRegister_isMappingKeepAliveAndMapNotifyGenerated() throws InterruptedException,
427             UnknownHostException {
428         byte[] eidPrefixAfi = new byte[] {
429             0x00, 0x01                  //eid-prefix-afi
430         };
431
432         byte[] eidPrefix = new byte[] {
433             0x0a, 0x0a, 0x0a, 0x0a     //ipv4 address
434         };
435
436         NotificationPublishService notifServiceMock = MapRegisterCacheTestUtil.resetMockForNotificationProvider(
437                 testedLispService);
438
439         //send stream of byte -> map register message
440         final MapRegisterCacheKey cacheKey = MapRegisterCacheTestUtil.createMapRegisterCacheKey(eidPrefix);
441         MapRegisterCacheTestUtil.beforeMapRegisterInvocationValidation(cacheKey, mapRegisterCache);
442         mapRegisterInvocationForCacheTest(eidPrefixAfi, eidPrefix);
443         MapRegisterCacheTestUtil.afterMapRegisterInvocationValidation(notifServiceMock,
444                 cacheKey, mapRegisterCache, eidPrefixAfi, eidPrefix);
445
446         //sending the same byte stream -> map register second time
447         notifServiceMock = MapRegisterCacheTestUtil.resetMockForNotificationProvider(testedLispService);
448         mapRegisterInvocationForCacheTest(eidPrefixAfi, eidPrefix);
449
450         //mapping-keep-alive message should be generated
451         MapRegisterCacheTestUtil.afterSecondMapRegisterInvocationValidation(notifServiceMock,
452                 mockLispSouthboundPlugin, eidPrefixAfi, eidPrefix);
453     }
454
455     void mapRegisterInvocationForCacheTest(byte[] eidPrefixAfi, byte[] eidPrefix) {
456         mapRegisterInvocationForCacheTest(eidPrefixAfi, eidPrefix, MapRegisterCacheTestUtil.AUTH_DATA);
457     }
458
459     void mapRegisterInvocationForCacheTest(byte[] eidPrefixAfi, byte[] eidPrefix, byte[] authenticationData) {
460         final byte[] mapRegisterMessage = MapRegisterCacheTestUtil.joinArrays(DATA1, NONCE, KEY_ID,
461                 authenticationData, DATA2, eidPrefixAfi, eidPrefix, DATA3, XTR_ID, SITE_ID);
462         handlePacket(mapRegisterMessage);
463     }
464
465     /**
466      * It tests whether map register message is stored to local cache with Ipv4 EidPrefix.
467      */
468     @Test
469     public void mapRegister_cacheWithEidPrefixIpv4Test() throws InterruptedException {
470         byte[] eidPrefixAfi = new byte[] {
471             0x00, 0x01                  //eid-prefix-afi
472         };
473
474         byte[] eidPrefix = new byte[] {
475             0x0a, 0x0a, 0x0a, 0x0a     //ipv4 address
476         };
477
478         cacheTest(eidPrefixAfi, eidPrefix, MapRegisterCacheTestUtil.AUTH_DATA);
479     }
480
481     /**
482      * It tests whether map register message is stored to local cache with Ipv6 EidPrefix.
483      */
484     @Test
485     public void mapRegister_cacheWithEidPrefixIpv6Test() throws InterruptedException {
486         byte[] eidPrefixAfi = new byte[] {
487             0x00, 0x02                  //eid-prefix-afi
488         };
489
490         byte[] eidPrefix = new byte[] {
491             0x0f, 0x0f, 0x0f, 0x0f,     //ipv6 address
492             0x0f, 0x0f, 0x0f, 0x0f,     //ipv6 address
493             0x0f, 0x0f, 0x0f, 0x0f,     //ipv6 address
494             0x0f, 0x0f, 0x0f, 0x0f      //ipv6 address
495         };
496
497         byte[] authenticationData = new byte[]{
498             0x00, 0x14,
499             0x41,(byte)0x83,0x13,0x7C,
500             0x48,(byte)0xEE,0x75,(byte)0x9A,
501             0x4,(byte)0x8C,0x46,(byte)0xA6,
502             0x1B,0x13,(byte)0xC8,0x4D,
503             (byte)0xA1,0x17,0x53,(byte)0xC3
504         };
505
506         cacheTest(eidPrefixAfi, eidPrefix, authenticationData);
507     }
508
509     /**
510      * It tests whether map register message is stored to local cache with Mac 48bits EidPrefix.
511      */
512     @Test
513     public void mapRegister_cacheWithEidPrefixMac48Test() throws InterruptedException {
514         byte[] eidPrefixAfi = new byte[] {
515             0x40, 0x05                  //eid-prefix-afi
516         };
517
518         byte[] eidPrefix = new byte[] {
519             0x0a, 0x0b, 0x0c, 0x0d,     //mac address
520             0x0e, 0x0f                 //mac address
521         };
522         byte[] authenticationData = new byte[]{
523             0x00, 0x14,
524             (byte)0xB2,(byte)0x8E,0x6,(byte)0x9D,
525             0x61,(byte)0xD8,0xC,0x24,
526             (byte)0x80,0x61,0x5A,0x20,
527             0xD,0x50,0x5E,(byte)0xAE,
528             0x47,(byte)0xF7,(byte)0x86,0x36
529         };
530         cacheTest(eidPrefixAfi, eidPrefix, authenticationData);
531     }
532
533     /**
534      * It tests whether map register message is stored to local cache with Lcaf EidPrefix (inside Ipv4).
535      */
536     @Test
537     public void mapRegister_cacheWithEidPrefixLcafTest() throws InterruptedException {
538         byte[] eidPrefixAfi = new byte[] {
539             0x40, 0x03                  //eid-prefix-afi
540         };
541
542         //following lcaf prefixed variables are defined according to https://tools.ietf
543         // .org/html/draft-ietf-lisp-lcaf-12#section-4.1
544         byte[] lcafRsvd1 = new byte[]{0x00};
545         byte[] lcafFlags = new byte[]{0x00};
546         byte[] lcafType = new byte[]{0x02};
547         byte[] lcafIIDMaskLength = new byte[]{0x20};
548         byte[] lcafLength = new byte[] {0x00, 0x0a};
549         byte[] lcafInstanceId = new byte[]{0x00, 0x00, 0x00, 0x15};
550         byte[] lcafAfi = new byte[] {0x00, 0x01};
551         byte[] lcafAddress = new byte[] {0x7d, 0x7c, 0x7b, 0x7a};
552
553         byte[] eidPrefix = joinArrays(lcafRsvd1, lcafFlags, lcafType, lcafIIDMaskLength, lcafLength, lcafInstanceId,
554                 lcafAfi, lcafAddress);
555
556         byte[] authenticationData = new byte[]{
557             0x00, 0x14,                 //authentication data length
558             0x68, 0x1d, (byte) 0x9e, 0x6e,    //auth data
559             0x5e, 0x32, (byte) 0x88, 0x1a,    //auth data
560             (byte) 0xae, 0x6b, (byte) 0xe3, 0x40,    //auth data
561             0x30, (byte) 0x0b, (byte) 0xb6, (byte) 0xa0,    //auth data
562             0x71, (byte) 0xf4, (byte) 0x8c, 0x5f    //auth data
563         };
564
565
566         cacheTest(eidPrefixAfi, eidPrefix, authenticationData);
567     }
568
569     /**
570      * It tests whether map register message is stored to local cache.
571      */
572     public void cacheTest(byte[] eidPrefixAfi, byte[] eidPrefix, byte[] authenticationData) throws
573             InterruptedException {
574         final MapRegisterCacheKey mapRegisterCacheKey = MapRegisterCacheTestUtil.createMapRegisterCacheKey(eidPrefix);
575
576         final NotificationPublishService mockedNotificationProvider = mock(NotificationPublishService.class);
577         testedLispService.setNotificationProvider(mockedNotificationProvider);
578
579         MapRegisterCacheTestUtil.beforeMapRegisterInvocationValidation(mapRegisterCacheKey, mapRegisterCache);
580         mapRegisterInvocationForCacheTest(eidPrefixAfi, eidPrefix, authenticationData);
581         MapRegisterCacheTestUtil.afterMapRegisterInvocationValidation(mockedNotificationProvider,
582                 mapRegisterCacheKey, mapRegisterCache, eidPrefixAfi, eidPrefix);
583     }
584
585
586     /*
587         Checks whether old record from cache will expire and is replaced with new record.
588
589         add to empty cache record with timestamp older then 90 second - one object
590         add the same entry through calling of handleMapRegister
591         check that removeEntry() and addEntry() (or refreshEntry() was called on mocked object for mapRegisterCache
592     */
593     @Test
594     public void mapRegister_cacheRecordExpirationTest() throws InterruptedException {
595         //tests handling of map register message when next message comes:
596
597         //after cache entry timeout
598         cacheRecordExpirationTest(true);
599
600         //before cache entry timout
601         cacheRecordExpirationTest(false);
602     }
603
604     private void cacheRecordExpirationTest(boolean cacheRecordTimeouted) throws InterruptedException {
605         mapRegisterCache = Mockito.mock(MapRegisterCache.class);
606         testedLispService.setMapRegisterCache(mapRegisterCache);
607         testedLispService.setNotificationProvider(Mockito.mock(NotificationPublishService.class));
608
609         final byte[] eidPrefixAfi = new byte[] {0x00, 0x01};
610         final byte[] eidPrefix = new byte[] {0x0a, 0x0a, 0x0a, 0x0a};
611
612         MapRegisterCacheKeyBuilder cacheKeyBld = new MapRegisterCacheKeyBuilder();
613         cacheKeyBld.setXtrId(XTR_ID);
614         cacheKeyBld.setEidPrefix(eidPrefix);
615         cacheKeyBld.setSiteId(SITE_ID);
616
617         MapRegisterCacheMetadataBuilder cacheMetadataBld = new MapRegisterCacheMetadataBuilder();
618         cacheMetadataBld.setTimestamp(System.currentTimeMillis() - (cacheRecordTimeouted ? CACHE_RECORD_TIMEOUT : 0L));
619         cacheMetadataBld.setWantMapNotify(false);
620
621         MapRegisterCacheValueBuilder cacheValueBld = new MapRegisterCacheValueBuilder();
622         cacheValueBld.setMapRegisterCacheMetadata(cacheMetadataBld.build());
623         cacheValueBld.setPacketData(MapRegisterCacheTestUtil.joinArrays(DATA1, KEY_ID, DATA2, eidPrefixAfi,
624                 eidPrefix, DATA3, XTR_ID, SITE_ID));
625
626
627         final MapRegisterCacheKey cacheKey = cacheKeyBld.build();
628         final MapRegisterCacheValue cacheValue = cacheValueBld.build();
629
630         Mockito.when(mapRegisterCache.getEntry(Mockito.eq(cacheKey))).thenReturn(cacheRecordTimeouted ? null :
631                 cacheValue);
632         Mockito.when(mapRegisterCache.refreshEntry(Mockito.eq(cacheKey))).thenReturn(cacheValue);
633
634         mapRegisterInvocationForCacheTest(eidPrefixAfi, eidPrefix);
635
636         InOrder inOrder = Mockito.inOrder(mapRegisterCache);
637         inOrder.verify(mapRegisterCache).getEntry(Mockito.eq(cacheKey));
638
639         if (cacheRecordTimeouted) {
640             inOrder.verify(mapRegisterCache).addEntry(Mockito.eq(cacheKey), AdditionalMatchers.not(Mockito.eq(
641                     cacheValue)));
642         } else {
643             inOrder.verify(mapRegisterCache).refreshEntry(Mockito.eq(cacheKey));
644         }
645     }
646
647     @Test
648     @Ignore
649     public void mapRegisterAndNotify__ValidExtraDataParsedSuccessfully() throws Exception {
650         byte[] extraDataPacket = new byte[mapRegisterPacket.length + 3];
651         extraDataPacket[mapRegisterPacket.length] = 0x9;
652         System.arraycopy(mapRegisterPacket, 0, extraDataPacket, 0, mapRegisterPacket.length);
653         stubMapRegister(true);
654
655         DatagramPacket dp = new DatagramPacket(wrappedBuffer(extraDataPacket), new InetSocketAddress(0),
656                 new InetSocketAddress(0));
657         testedLispService.handlePacket(dp);
658         // Check map register fields.
659         // XXX: test
660         // byte[] notifyResult = testedLispService.handlePacket(dp).getData();
661         byte[] notifyResult = lastMapNotifyPacket().content().array();
662         assertEquals(mapRegisterPacket.length, notifyResult.length);
663
664     }
665
666     private DatagramPacket lastMapReplyPacket() {
667         ByteBuffer serialize = MapReplySerializer.getInstance().serialize(mapReplyBuilder.build());
668         return new DatagramPacket(wrappedBuffer(serialize), new InetSocketAddress(0), new InetSocketAddress(0));
669     }
670
671     private DatagramPacket lastMapNotifyPacket() {
672         if (mapNotifyBuilder.getMappingRecordItem() == null) {
673             mapNotifyBuilder.setMappingRecordItem(new ArrayList<MappingRecordItem>());
674         }
675         mapNotifyBuilder.getMappingRecordItem().add(new MappingRecordItemBuilder().setMappingRecord(
676                 mappingRecordBuilder.build()).build());
677         mapNotifyBuilder.setNonce((long) 0);
678         mapNotifyBuilder.setKeyId((short) 0);
679         mapNotifyBuilder.setAuthenticationData(new byte[0]);
680         ByteBuffer serialize = MapNotifySerializer.getInstance().serialize(mapNotifyBuilder.build());
681         return new DatagramPacket(wrappedBuffer(serialize), new InetSocketAddress(0), new InetSocketAddress(0));
682     }
683
684     @Test
685     @Ignore
686     public void mapNotify__VerifyBasicFields() throws Exception {
687         byte registerType = mapRegisterPacket[0];
688         assertEquals(MessageType.MapRegister.getIntValue(), registerType >> 4);
689
690         stubMapRegister(true);
691
692         byte[] result = handleMapRegisterAsByteArray(mapRegisterPacket);
693
694         assertEquals(mapRegisterPacket.length, result.length);
695
696         byte expectedType = (byte) (MessageType.MapNotify.getIntValue() << 4);
697         assertHexEquals(expectedType, result[0]);
698         assertHexEquals((byte) 0x00, result[1]);
699         assertHexEquals((byte) 0x00, result[2]);
700
701         byte[] registerWithoutTypeWithoutAuthenticationData = ArrayUtils.addAll(
702                 Arrays.copyOfRange(mapRegisterPacket, 3, 16),
703                 Arrays.copyOfRange(mapRegisterPacket, 36, mapRegisterPacket.length));
704         byte[] notifyWithoutTypeWithOutAuthenticationData = ArrayUtils.addAll(Arrays.copyOfRange(result, 3, 16),
705                 Arrays.copyOfRange(result, 36, result.length));
706         ArrayAssert.assertEquals(registerWithoutTypeWithoutAuthenticationData,
707                 notifyWithoutTypeWithOutAuthenticationData);
708     }
709
710     @Ignore
711     @Test
712     public void mapNotify__VerifyPort() throws Exception {
713         stubMapRegister(true);
714
715         DatagramPacket notifyPacket = handleMapRegisterPacket(mapRegisterPacket);
716         assertEquals(LispMessage.PORT_NUM, notifyPacket.recipient().getPort());
717     }
718
719     @Test
720     public void mapRequest__VerifyBasicFields() throws Exception {
721         oneOf(nps).putNotification(with(lispNotificationSaver));
722         handleMapRequestAsByteArray(mapRequestPacket);
723         List<EidItem> eids = lastMapRequest().getEidItem();
724         assertEquals(1, eids.size());
725         Eid lispAddress = eids.get(0).getEid();
726         assertEquals(Ipv4PrefixBinaryAfi.class, lispAddress.getAddressType());
727         assertEquals(LispAddressUtil.asIpv4PrefixBinaryEid("1.2.3.4/32"), lispAddress);
728         assertEquals(0x3d8d2acd39c8d608L, lastMapRequest().getNonce().longValue());
729     }
730
731     @Test
732     public void mapRequest__Ipv6Eid() throws Exception {
733         // Internet Protocol Version 6, Src: 2610:d0:ffff:192::1
734         // (2610:d0:ffff:192::1), Dst: 2610:d0:ffff:192::2
735         // (2610:d0:ffff:192::2)
736         // MBIT: SET
737         // EID AFI: 2
738         // Source EID: 2610:d0:ffff:192::1 (2610:d0:ffff:192::1)
739         // ITR-RLOC 1: 10.0.58.156
740         // Record 1: 2610:d0:ffff:192::2/128
741         // Map-Reply Record: EID prefix: 2610:d0:ffff:192::1/128, TTL: 10,
742         // Authoritative, No-Action
743
744         mapRequestPacket = extractWSUdpByteArray(new String(
745                   "0000   00 0c 29 34 3e 1b 00 0c 29 f6 d6 0d 08 00 45 00 "
746                 + "0010   00 b0 00 00 40 00 40 11 ea 7b 0a 00 3a 9c 0a 00 "
747                 + "0020   01 26 10 f6 10 f6 00 9c 9b 19 80 00 00 00 60 00 "
748                 + "0030   00 00 00 68 11 ff 26 10 00 d0 ff ff 01 92 00 00 "
749                 + "0040   00 00 00 00 00 01 26 10 00 d0 ff ff 01 92 00 00 "
750                 + "0050   00 00 00 00 00 02 10 f6 10 f6 00 68 94 8b 10 00 "
751                 + "0060   00 01 ff f5 bf 5d 7b 75 93 e6 00 02 26 10 00 d0 "
752                 + "0070   ff ff 01 92 00 00 00 00 00 00 00 01 00 01 0a 00 "
753                 + "0080   3a 9c 00 80 00 02 26 10 00 d0 ff ff 01 92 00 00 "
754                 + "0090   00 00 00 00 00 02 00 00 00 0a 01 80 10 00 00 00 "
755                 + "00a0   00 02 26 10 00 d0 ff ff 01 92 00 00 00 00 00 00 "
756                 + "00b0   00 01 01 64 ff 00 00 05 00 01 0a 00 3a 9c"));
757
758         oneOf(nps).putNotification(with(lispNotificationSaver));
759         // ret(mapReply);
760
761         handleMapRequestAsByteArray(mapRequestPacket);
762         assertEquals(LispAddressUtil.asIpv6Eid("2610:d0:ffff:192:0:0:0:1"), lastMapRequest().getSourceEid().getEid());
763         assertEquals(LispAddressUtil.asIpv6PrefixBinaryEid("2610:d0:ffff:192:0:0:0:2/128"),
764                 lastMapRequest().getEidItem().get(0).getEid());
765     }
766
767     @Ignore
768     @Test
769     public void mapRequest__UsesIpv6EncapsulatedUdpPort() throws Exception {
770         // Internet Protocol Version 6, Src: 2610:d0:ffff:192::1
771         // (2610:d0:ffff:192::1), Dst: 2610:d0:ffff:192::2
772         // (2610:d0:ffff:192::2)
773         // encapsulated UDP source port: 4342
774
775         mapRequestPacket = extractWSUdpByteArray(new String(
776                   "0000   00 0c 29 34 3e 1b 00 0c 29 f6 d6 0d 08 00 45 00 "
777                 + "0010   00 b0 00 00 40 00 40 11 ea 7b 0a 00 3a 9c 0a 00 "
778                 + "0020   01 26 10 f6 10 f6 00 9c 9b 19 80 00 00 00 60 00 "
779                 + "0030   00 00 00 68 11 ff 26 10 00 d0 ff ff 01 92 00 00 "
780                 + "0040   00 00 00 00 00 01 26 10 00 d0 ff ff 01 92 00 00 "
781                 + "0050   00 00 00 00 00 02 10 f6 10 f6 00 68 94 8b 14 00 "
782                 + "0060   00 01 ff f5 bf 5d 7b 75 93 e6 00 02 26 10 00 d0 "
783                 + "0070   ff ff 01 92 00 00 00 00 00 00 00 01 00 01 0a 00 "
784                 + "0080   3a 9c 00 80 00 02 26 10 00 d0 ff ff 01 92 00 00 "
785                 + "0090   00 00 00 00 00 02 00 00 00 0a 01 80 10 00 00 00 "
786                 + "00a0   00 02 26 10 00 d0 ff ff 01 92 00 00 00 00 00 00 "
787                 + "00b0   00 01 01 64 ff 00 00 05 00 01 0a 00 3a 9c"));
788         oneOf(nps).putNotification(with(lispNotificationSaver));
789         // ret(mapReply);
790
791         DatagramPacket replyPacket = handleMapRequestPacket(mapRequestPacket);
792         assertEquals(4342, replyPacket.recipient().getPort());
793     }
794
795     @Test
796     public void mapRequest__WithSourceEid() throws Exception {
797         // encapsulated LISP packet
798         // Source EID = 153.16.254.1
799
800         mapRequestPacket = extractWSUdpByteArray(new String(
801                   "0000   00 0c 29 7a ce 83 00 15 17 c6 4a c9 08 00 45 00 "
802                 + "0010   00 78 00 00 40 00 3e 11 ec b1 0a 00 01 26 0a 00 "
803                 + "0020   3a 9e 10 f6 10 f6 00 64 c3 a5 80 00 00 00 45 00 "
804                 + "0030   00 58 d4 31 00 00 ff 11 31 89 99 10 fe 01 0a 00 "
805                 + "0040   14 c8 10 f6 10 f6 00 44 84 ee 10 00 00 01 ba f9 "
806                 + "0050   ff 53 27 36 38 3a 00 01 99 10 fe 01 00 01 0a 00 "
807                 + "0060   01 26 00 20 00 01 0a 00 14 c8 00 00 00 0a 01 20 "
808                 + "0070   10 00 00 00 00 01 99 10 fe 01 01 64 ff 00 00 05 "
809                 + "0080   00 01 0a 00 01 26"));
810
811         oneOf(nps).putNotification(with(lispNotificationSaver));
812         // ret(mapReply);
813
814         handleMapRequestAsByteArray(mapRequestPacket);
815         assertEquals(Ipv4BinaryAfi.class, lastMapRequest().getSourceEid().getEid().getAddressType());
816
817     }
818
819     @Test
820     @Ignore
821     public void mapReply__VerifyBasicIPv4Fields() throws Exception {
822         mappingRecordBuilder.setEid(LispAddressUtil.asIpv4PrefixEid("10.0.20.200/32"));
823         mapReplyBuilder.setNonce(0x3d8d2acd39c8d608L);
824
825         stubHandleRequest();
826
827         byte[] result = handleMapRequestAsByteArray(mapRequestPacket);
828
829         assertEquals(28, result.length);
830
831         byte expectedLispMessageType = 2;
832         assertEquals(expectedLispMessageType, (byte) (result[LispMessage.Pos.TYPE] >> 4));
833         assertEquals(0x3d8d2acd39c8d608L, ByteUtil.getLong(result, MapReplyIpv4SingleLocatorPos.NONCE));
834
835         byte expectedRecordCount = (byte) 1;
836         assertEquals(expectedRecordCount, result[MapReplyIpv4SingleLocatorPos.RECORD_COUNT]);
837
838         assertEquals(MaskUtil.getMaskForAddress(mappingRecordBuilder.getEid().getAddress()),
839                 result[MapReplyIpv4SingleLocatorPos.EID_MASK_LEN]);
840         assertEquals(AddressFamily.IpV4.getIntValue(), ByteUtil.getInt(result, MapReplyIpv4SingleLocatorPos.AFI_TYPE));
841         assertEquals(0x0a0014c8, ByteUtil.getInt(result, MapReplyIpv4SingleLocatorPos.EID_PREFIX));
842     }
843
844     @Test
845     @Ignore
846     public void mapReply__VerifyBasicIPv6() throws Exception {
847         mappingRecordBuilder.setEid(LispAddressUtil.asIpv6PrefixEid("0:0:0:0:0:0:0:1/128"));
848
849         stubHandleRequest();
850
851         byte[] result = handleMapRequestAsByteArray(mapRequestPacket);
852
853         assertEquals(40, result.length);
854
855         byte expectedRecordCount = (byte) 1;
856         assertEquals(expectedRecordCount, result[MapReplyIpv4SingleLocatorPos.RECORD_COUNT]);
857
858         assertEquals(MaskUtil.getMaskForAddress(mappingRecordBuilder.getEid().getAddress()),
859                 result[MapReplyIpv4SingleLocatorPos.EID_MASK_LEN]);
860         assertEquals(AddressFamily.IpV6.getIntValue(), ByteUtil.getInt(result, MapReplyIpv4SingleLocatorPos.AFI_TYPE));
861         byte[] expectedIpv6 = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 };
862
863         ArrayAssert.assertEquals(expectedIpv6, Arrays.copyOfRange(result, 24, 40));
864     }
865
866     @Test
867     @Ignore
868     public void mapReply__VerifyIPv6EidAndLocator() throws Exception {
869         mappingRecordBuilder.setEid(LispAddressUtil.asIpv6PrefixEid("0:0:0:0:0:0:0:1/128"));
870         mappingRecordBuilder.getLocatorRecord().add(
871                 new LocatorRecordBuilder().setRloc(LispAddressUtil.asIpv6Rloc("0:0:0:0:0:0:0:2")).build());
872
873         stubHandleRequest();
874
875         byte[] result = handleMapRequestAsByteArray(mapRequestPacket);
876
877         assertEquals(64, result.length);
878
879         byte[] expectedIpv6Eid = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 };
880         ArrayAssert.assertEquals(expectedIpv6Eid, Arrays.copyOfRange(result, 24, 40));
881
882         byte[] expectedIpv6Rloc = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2 };
883         ArrayAssert.assertEquals(expectedIpv6Rloc, Arrays.copyOfRange(result, 48, 64));
884     }
885
886     @Ignore
887     @Test
888     public void mapReply__UseEncapsulatedUdpPort() throws Exception {
889         stubHandleRequest();
890
891         assertEquals(LispMessage.PORT_NUM, handleMapRequestPacket(mapRequestPacket).recipient().getPort());
892     }
893
894     @Test
895     @Ignore
896     public void mapReply__WithNonRoutableSingleLocator() throws Exception {
897         mappingRecordBuilder.setEid(LispAddressUtil.asIpv4PrefixEid("10.0.20.200/32"));
898         mappingRecordBuilder.getLocatorRecord().add(
899                 new LocatorRecordBuilder().setRouted(false).setRloc(LispAddressUtil.asIpv4Rloc("4.3.2.1")).build());
900         stubHandleRequest();
901
902         byte[] result = handleMapRequestAsByteArray(mapRequestPacket);
903         assertEquals(0x00, result[MapReplyIpv4SingleLocatorPos.LOCATOR_RBIT] & 0x01);
904     }
905
906     @Test
907     @Ignore
908     public void mapReply__WithSingleLocator() throws Exception {
909         mappingRecordBuilder.setEid(LispAddressUtil.asIpv4PrefixEid("10.0.20.200/32"));
910         mappingRecordBuilder.getLocatorRecord().add(
911                 new LocatorRecordBuilder().setRouted(true).setRloc(LispAddressUtil.asIpv4Rloc("4.3.2.1")).build());
912         stubHandleRequest();
913
914         byte[] result = handleMapRequestAsByteArray(mapRequestPacket);
915         assertEquals(40, result.length);
916
917         byte expectedLocCount = 1;
918         assertEquals(expectedLocCount, result[MapReplyIpv4SingleLocatorPos.LOCATOR_COUNT]);
919
920         assertEquals(AddressFamily.IpV4.getIntValue(), ByteUtil.getInt(result, MapReplyIpv4SingleLocatorPos.LOC_AFI));
921
922         assertEquals(0x04030201, ByteUtil.getInt(result, MapReplyIpv4SingleLocatorPos.LOCATOR));
923         assertEquals(0x01, result[MapReplyIpv4SingleLocatorPos.LOCATOR_RBIT] & 0x01);
924     }
925
926     @Test
927     @Ignore
928     public void mapReply__WithMultipleLocator() throws Exception {
929         mappingRecordBuilder.getLocatorRecord().add(
930                 new LocatorRecordBuilder().setRouted(true).setRloc(LispAddressUtil.asIpv4Rloc("4.3.2.1")).build());
931         mappingRecordBuilder.getLocatorRecord().add(
932                 new LocatorRecordBuilder().setRouted(true).setRloc(LispAddressUtil.asIpv6Rloc("0:0:0:0:0:0:0:1"))
933                 .build());
934         stubHandleRequest();
935
936         byte[] result = handleMapRequestAsByteArray(mapRequestPacket);
937         assertEquals(64, result.length);
938
939         assertEquals(2, result[MapReplyIpv4SingleLocatorPos.LOCATOR_COUNT]);
940
941         assertEquals(AddressFamily.IpV4.getIntValue(), ByteUtil.getInt(result, MapReplyIpv4SingleLocatorPos.LOC_AFI));
942         assertEquals(0x04030201, ByteUtil.getInt(result, MapReplyIpv4SingleLocatorPos.LOCATOR));
943         assertEquals(0x01, result[MapReplyIpv4SingleLocatorPos.LOCATOR_RBIT] & 0x01);
944
945         assertEquals(AddressFamily.IpV6.getIntValue(), ByteUtil.getInt(result, MapReplyIpv4SecondLocatorPos.LOC_AFI));
946
947         byte[] expectedIpv6Rloc = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 };
948         ArrayAssert.assertEquals(expectedIpv6Rloc, Arrays.copyOfRange(result, MapReplyIpv4SecondLocatorPos.LOCATOR,
949                 MapReplyIpv4SecondLocatorPos.LOCATOR + 16));
950
951         assertEquals(0x01, result[MapReplyIpv4SecondLocatorPos.LOCATOR_RBIT] & 0x01);
952     }
953
954     @Test
955     public void handleUnknownLispMessage() throws Exception {
956         // IP: 192.168.136.10 -> 128.223.156.35
957         // UDP: 49289 -> 4342
958         // LISP(Type = 14 UNKNOWN!!!, P=1, M=1
959
960         byte[] unknownTypePacket = extractWSUdpByteArray(new String(
961                   "0000   00 50 56 ee d1 4f 00 0c 29 7a ce 79 08 00 45 00 "
962                 + "0010   00 5c 00 00 40 00 40 11 d4 db c0 a8 88 0a 80 df "
963                 + "0020   9c 23 d6 40 10 f6 00 48 59 a4 F8 00 01 01 00 00 "
964                 + "0030   00 00 00 00 00 00 00 01 00 14 e8 f5 0b c5 c5 f2 "
965                 + "0040   b0 21 27 a8 21 41 04 f3 46 5a a5 68 89 ec 00 00 "
966                 + "0050   00 0a 01 20 10 00 00 00 00 01 99 10 fe 01 01 64 "
967                 + "0060   ff 00 00 05 00 01 c0 a8 88 0a"));
968         assertNull(handlePacket(unknownTypePacket));
969     }
970
971     @Test
972     public void mapRequest__MultipleItrRlocs() throws Exception {
973         // this is what LISPmob sends when configured multiple RLOCs for single
974         // EID.
975         // ITR-RLOC 1: 10.1.0.111
976         // ITR-RLOC 2: 192.168.136.51
977         //
978         mapRequestPacket = extractWSUdpByteArray(new String(
979                   "0000   00 0c 29 7a ce 8d 00 0c 29 e4 ef 70 08 00 45 00 "
980                 + "0010   00 8a 00 00 40 00 40 11 25 f2 0a 01 00 6f 0a 01 "
981                 + "0020   00 01 10 f6 10 f6 00 76 06 1f 80 00 00 00 45 00 "
982                 + "0030   00 6a d4 31 00 00 ff 11 2a 3e ac 01 01 02 08 08 "
983                 + "0040   08 08 10 f6 10 f6 00 56 63 14 10 00 01 01 79 67 "
984                 + "0050   ff 75 a0 61 66 19 00 01 ac 01 01 02 00 01 0a 01 "
985                 + "0060   00 6f 00 01 c0 a8 88 33 00 20 00 01 08 08 08 08 "
986                 + "0070   00 00 00 0a 02 20 10 00 00 00 00 01 ac 01 01 02 "
987                 + "0080   01 64 ff 00 00 05 00 01 0a 01 00 6f 06 64 ff 00 "
988                 + "0090   00 05 00 01 c0 a8 88 33"));
989
990         oneOf(nps).putNotification(with(lispNotificationSaver));
991         handleMapRequestAsByteArray(mapRequestPacket);
992
993     }
994
995     private void stubMapRegister(final boolean setNotifyFromRegister) {
996         try {
997             allowing(nps).putNotification(with(lispNotificationSaver));
998         } catch (InterruptedException e) {
999             LOG.debug("Interrupted", e);
1000         }
1001         will(new SimpleAction() {
1002
1003             @Override
1004             public Object invoke(Invocation invocation) throws Throwable {
1005                 if (setNotifyFromRegister) {
1006                     MapNotifyBuilderHelper.setFromMapRegister(mapNotifyBuilder, lastMapRegister());
1007                 }
1008                 return null;
1009             }
1010         });
1011     }
1012
1013     private void stubHandleRequest() {
1014         try {
1015             allowing(nps).putNotification(wany(Notification.class));
1016         } catch (InterruptedException e) {
1017             LOG.debug("Interrupted", e);
1018         }
1019     }
1020
1021     private byte[] handleMapRequestAsByteArray(byte[] inPacket) {
1022         handleMapRequestPacket(inPacket);
1023         return lastMapReplyPacket().content().array();
1024     }
1025
1026     private byte[] handleMapRegisterAsByteArray(byte[] inPacket) {
1027         handleMapRegisterPacket(inPacket);
1028         return lastMapNotifyPacket().content().array();
1029     }
1030
1031     private DatagramPacket handleMapRequestPacket(byte[] inPacket) {
1032         DatagramPacket dp = new DatagramPacket(wrappedBuffer(inPacket), new InetSocketAddress(0),
1033                 new InetSocketAddress(0));
1034         // Unless we explicitly set the source port, it will be -1, which breaks some tests
1035         // This is till not the real port number, but it's better
1036         //dp.setPort(LispMessage.PORT_NUM);
1037         testedLispService.handlePacket(dp);
1038         return lastMapReplyPacket();
1039     }
1040
1041     private DatagramPacket handleMapRegisterPacket(byte[] inPacket) {
1042         DatagramPacket dp = new DatagramPacket(wrappedBuffer(inPacket), new InetSocketAddress(0),
1043                 new InetSocketAddress(0));
1044         // Unless we explicitly set the source port, it will be -1, which breaks some tests
1045         // This is till not the real port number, but it's better
1046         //dp.setPort(LispMessage.PORT_NUM);
1047         testedLispService.handlePacket(dp);
1048         if (mapNotifyBuilder == null) {
1049             return null;
1050         } else {
1051             return lastMapNotifyPacket();
1052         }
1053     }
1054
1055     private DatagramPacket handlePacket(byte[] inPacket) {
1056         // TODO get from mock
1057         testedLispService.handlePacket(new DatagramPacket(wrappedBuffer(inPacket), new InetSocketAddress(0),
1058                 new InetSocketAddress(0)));
1059         return null;
1060     }
1061
1062     private byte[] extractWSUdpByteArray(String wiresharkHex) {
1063         final int headerLen = 42;
1064         byte[] res = new byte[1000];
1065         String[] split = wiresharkHex.split(" ");
1066         int counter = 0;
1067         for (String cur : split) {
1068             cur = cur.trim();
1069             if (cur.length() == 2) {
1070                 ++counter;
1071                 if (counter > headerLen) {
1072                     res[counter - headerLen - 1] = (byte) Integer.parseInt(cur, 16);
1073                 }
1074
1075             }
1076         }
1077         return Arrays.copyOf(res, counter - headerLen);
1078     }
1079
1080     @Test(expected = LispMalformedPacketException.class)
1081     public void mapRequest__NoIpItrRloc() throws Exception {
1082         mapRequestPacket = hexToByteBuffer("10 00 " //
1083                 + "02 " // This means 3 ITR - RLOCs
1084                 + "01 3d 8d 2a cd 39 c8 d6 08 00 00 " //
1085                 + "40 05 c0 a8 88 0a 01 02 " // MAC (ITR-RLOC #1 of 3)
1086                 + "40 05 00 00 00 00 00 00 " // MAC (ITR-RLOC #2 of 3)
1087                 + "40 05 11 22 34 56 78 90 " // MAC (ITR-RLOC #3 of 3)
1088                 + "00 20 00 01 01 02 03 04").array();
1089         handleMapRequestPacket(mapRequestPacket);
1090     }
1091
1092     // @Ignore
1093     // @Test
1094     // public void mapRequest__IPITRRLOCIsSecond() throws Exception {
1095     // mapRequestPacket = hexToByteBuffer("10 00 " //
1096     // + "01 " // This means 3 ITR - RLOCs
1097     // + "01 3d 8d 2a cd 39 c8 d6 08 00 00 " //
1098     // + "40 05 c0 a8 88 0a 01 02 " // MAC (ITR-RLOC #1 of 2)
1099     // + "00 01 01 02 03 04 " // IP (ITR-RLOC #2 of 2)
1100     // + "00 20 00 01 01 02 03 04").array();
1101     // oneOf(nps).putNotification(with(lispNotificationSaver));
1102     // // ret(mapReply);
1103     // DatagramPacket packet = handleMapRequestPacket(mapRequestPacket);
1104     // assertEquals(2, lastMapRequest().getItrRlocs().size());
1105     // assertEquals((new LispIpv4Address("1.2.3.4")).getAddress(),
1106     // packet.getAddress());
1107     // }
1108     //
1109     // @Ignore
1110     // @Test
1111     // public void mapRequest__MULTIPLEIPITRRLOCs() throws Exception {
1112     // mapRequestPacket = hexToByteBuffer("10 00 " //
1113     // + "01 " // This means 3 ITR - RLOCs
1114     // + "01 3d 8d 2a cd 39 c8 d6 08 00 00 " //
1115     // + "00 01 01 02 03 04 " // IP (ITR-RLOC #1 of 2)
1116     // + "00 01 c0 a8 88 0a " // MAC (ITR-RLOC #2 of 2)
1117     // + "00 20 00 01 01 02 03 04").array();
1118     // oneOf(nps).putNotification(with(lispNotificationSaver));
1119     // // ret(mapReply);
1120     // DatagramPacket packet = handleMapRequestPacket(mapRequestPacket);
1121     // assertEquals(2, lastMapRequest().getItrRloc().size());
1122     // assertEquals((new LispIpv4Address("1.2.3.4")).getAddress(),
1123     // packet.getAddress());
1124     // }
1125
1126 }