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