support mask=0 TELSDN-369: #close
[lispflowmapping.git] / mappingservice / implementation / src / main / java / org / opendaylight / lispflowmapping / implementation / lisp / MapServer.java
1 /*
2  * Copyright (c) 2013 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.implementation.lisp;
10
11 import java.util.ArrayList;
12 import java.util.List;
13 import java.util.Map;
14
15 import org.opendaylight.lispflowmapping.implementation.authentication.LispAuthenticationUtil;
16 import org.opendaylight.lispflowmapping.interfaces.dao.ILispDAO;
17 import org.opendaylight.lispflowmapping.interfaces.dao.IMappingServiceKey;
18 import org.opendaylight.lispflowmapping.interfaces.dao.MappingEntry;
19 import org.opendaylight.lispflowmapping.interfaces.dao.MappingServiceKeyUtil;
20 import org.opendaylight.lispflowmapping.interfaces.dao.MappingServiceRLOC;
21 import org.opendaylight.lispflowmapping.interfaces.dao.MappingServiceValue;
22 import org.opendaylight.lispflowmapping.interfaces.lisp.IMapServer;
23 import org.opendaylight.lispflowmapping.type.lisp.EidToLocatorRecord;
24 import org.opendaylight.lispflowmapping.type.lisp.LocatorRecord;
25 import org.opendaylight.lispflowmapping.type.lisp.MapNotify;
26 import org.opendaylight.lispflowmapping.type.lisp.MapRegister;
27 import org.opendaylight.lispflowmapping.type.lisp.address.IMaskable;
28 import org.opendaylight.lispflowmapping.type.lisp.address.LispAddress;
29 import org.slf4j.Logger;
30 import org.slf4j.LoggerFactory;
31
32 public class MapServer implements IMapServer {
33     private ILispDAO dao;
34     private volatile boolean shouldAuthenticate;
35     private volatile boolean shouldIterateMask;
36     protected static final Logger logger = LoggerFactory.getLogger(MapServer.class);
37
38     public MapServer(ILispDAO dao) {
39         this(dao, true);
40     }
41
42     public MapServer(ILispDAO dao, boolean authenticate) {
43         this(dao, authenticate, true);
44     }
45
46     public MapServer(ILispDAO dao, boolean authenticate, boolean iterateAuthenticationMask) {
47         this.dao = dao;
48         this.shouldAuthenticate = authenticate;
49         this.shouldIterateMask = iterateAuthenticationMask;
50     }
51
52     public MapNotify handleMapRegister(MapRegister mapRegister) {
53         if (dao == null) {
54             logger.warn("handleMapRegister called while dao is uninitialized");
55             return null;
56         }
57         String password = null;
58         for (EidToLocatorRecord eidRecord : mapRegister.getEidToLocatorRecords()) {
59
60             if (shouldAuthenticate) {
61                 password = getPassword(eidRecord.getPrefix(), eidRecord.getMaskLength());
62                 if (!LispAuthenticationUtil.validate(mapRegister, password)) {
63                     logger.debug("Authentication failed");
64                     return null;
65                 }
66             }
67             MappingServiceValue value = new MappingServiceValue();
68             MappingEntry<MappingServiceValue> entry = new MappingEntry<MappingServiceValue>("value", value);
69             List<MappingServiceRLOC> rlocs = new ArrayList<MappingServiceRLOC>();
70             for (LocatorRecord locatorRecord : eidRecord.getLocators()) {
71                 rlocs.add(new MappingServiceRLOC(locatorRecord, eidRecord.getRecordTtl()));
72             }
73             value.setRlocs(rlocs);
74             IMappingServiceKey key = MappingServiceKeyUtil.generateMappingServiceKey(eidRecord.getPrefix(), eidRecord.getMaskLength());
75             dao.put(key, entry);
76
77         }
78         MapNotify mapNotify = null;
79         if (mapRegister.isWantMapNotify()) {
80             logger.trace("MapRegister wants MapNotify");
81             mapNotify = new MapNotify();
82             mapNotify.setFromMapRegister(mapRegister);
83             if (shouldAuthenticate) {
84                 mapNotify.setAuthenticationData(LispAuthenticationUtil.createAuthenticationData(mapNotify, password));
85             }
86         }
87         return mapNotify;
88     }
89
90     private String getPassword(LispAddress prefix, int maskLength) {
91         if (prefix instanceof IMaskable) {
92             prefix = ((IMaskable) prefix).clone();
93         }
94         while (maskLength >= 0) {
95             IMappingServiceKey key = MappingServiceKeyUtil.generateMappingServiceKey(prefix, maskLength);
96             Map<String, ?> daoMap = dao.get(key);
97             if (daoMap != null) {
98                 MappingServiceValue value = (MappingServiceValue) daoMap.get("value");
99                 if (value != null && value.getKey() != null) {
100                     return value.getKey();
101                 } else if (shouldIterateMask()) {
102                     maskLength -= 1;
103                 } else {
104                     return null;
105                 }
106             } else {
107                 maskLength -= 1;
108
109             }
110         }
111         return null;
112     }
113
114     public String getAuthenticationKey(LispAddress address, int maskLen) {
115         return getPassword(address, maskLen);
116     }
117
118     public boolean removeAuthenticationKey(LispAddress address, int maskLen) {
119         IMappingServiceKey key = MappingServiceKeyUtil.generateMappingServiceKey(address, maskLen);
120         Map<String, ?> daoMap = dao.get(key);
121         if (daoMap != null) {
122             MappingServiceValue value = (MappingServiceValue) daoMap.get("value");
123             if (value != null) {
124                 value.setKey(null);
125                 if (value.isEmpty()) {
126                     dao.remove(key);
127                 } else {
128                     dao.put(key, new MappingEntry<MappingServiceValue>("value", value));
129                 }
130                 return true;
131             } else {
132                 return false;
133             }
134         } else {
135             return false;
136         }
137     }
138
139     public boolean addAuthenticationKey(LispAddress address, int maskLen, String key) {
140         IMappingServiceKey mappingServiceKey = MappingServiceKeyUtil.generateMappingServiceKey(address, maskLen);
141         Map<String, ?> daoMap = dao.get(mappingServiceKey);
142         MappingServiceValue value = null;
143         if (daoMap != null) {
144             value = (MappingServiceValue) daoMap.get("value");
145             if (value == null) {
146                 value = new MappingServiceValue();
147             }
148         } else {
149             value = new MappingServiceValue();
150         }
151         value.setKey(key);
152         MappingEntry<MappingServiceValue> entry = new MappingEntry<MappingServiceValue>("value", value);
153         dao.put(mappingServiceKey, entry);
154         return true;
155     }
156
157     public boolean shouldAuthenticate() {
158         return shouldAuthenticate;
159     }
160
161     public boolean shouldIterateMask() {
162         return shouldIterateMask;
163     }
164
165     public void setShouldIterateMask(boolean shouldIterateMask) {
166         this.shouldIterateMask = shouldIterateMask;
167     }
168
169     public void setShouldAuthenticate(boolean shouldAuthenticate) {
170         this.shouldAuthenticate = shouldAuthenticate;
171     }
172
173 }