Merge "BUG-612 : defensive parser for LSPA"
authorRobert Varga <rovarga@cisco.com>
Thu, 26 Jun 2014 14:17:18 +0000 (14:17 +0000)
committerGerrit Code Review <gerrit@opendaylight.org>
Thu, 26 Jun 2014 14:17:18 +0000 (14:17 +0000)
pcep/ietf-stateful07/src/main/java/org/opendaylight/protocol/pcep/ietf/initiated00/CInitiated00PCInitiateMessageParser.java
pcep/ietf-stateful07/src/main/java/org/opendaylight/protocol/pcep/ietf/stateful07/Stateful07PCReportMessageParser.java
pcep/ietf-stateful07/src/main/java/org/opendaylight/protocol/pcep/ietf/stateful07/Stateful07PCUpdateRequestMessageParser.java
pcep/ietf-stateful07/src/test/java/org/opendaylight/protocol/pcep/ietf/PCEPValidatorTest.java
pcep/impl/src/main/java/org/opendaylight/protocol/pcep/impl/message/PCEPReplyMessageParser.java

index 34ddac08486ef83596c80832657b6ac96dcff12e..41aac5860112ffff9ad7784ffdd6a648882a7e6b 100644 (file)
@@ -9,12 +9,9 @@ package org.opendaylight.protocol.pcep.ietf.initiated00;
 
 import com.google.common.base.Preconditions;
 import com.google.common.collect.Lists;
-
 import io.netty.buffer.ByteBuf;
 import io.netty.buffer.Unpooled;
-
 import java.util.List;
-
 import org.opendaylight.protocol.pcep.spi.AbstractMessageParser;
 import org.opendaylight.protocol.pcep.spi.MessageUtil;
 import org.opendaylight.protocol.pcep.spi.ObjectRegistry;
@@ -41,7 +38,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.typ
 /**
  * Parser for {@link Pcinitiate}
  */
-public final class CInitiated00PCInitiateMessageParser extends AbstractMessageParser {
+public class CInitiated00PCInitiateMessageParser extends AbstractMessageParser {
 
     public static final int TYPE = 12;
 
@@ -55,32 +52,36 @@ public final class CInitiated00PCInitiateMessageParser extends AbstractMessagePa
         final org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.crabbe.initiated.rev131126.pcinitiate.message.PcinitiateMessage init = ((Pcinitiate) message).getPcinitiateMessage();
         ByteBuf buffer = Unpooled.buffer();
         for (final Requests req : init.getRequests()) {
-            serializeObject(req.getSrp(), buffer);
-            serializeObject(req.getLsp(), buffer);
-            if (req.getEndpointsObj() != null) {
-                serializeObject(req.getEndpointsObj(), buffer);
-            }
-            if (req.getEro() != null) {
-                serializeObject(req.getEro(), buffer);
-            }
-            if (req.getLspa() != null) {
-                serializeObject(req.getLspa(), buffer);
-            }
-            if (req.getBandwidth() != null) {
-                serializeObject(req.getBandwidth(), buffer);
-            }
-            if (req.getMetrics() != null && !req.getMetrics().isEmpty()) {
-                for (final Metrics m : req.getMetrics()) {
-                    serializeObject(m.getMetric(), buffer);
-                }
-            }
-            if (req.getIro() != null) {
-                serializeObject(req.getIro(), buffer);
-            }
+            serializeRequest(req, buffer);
         }
         MessageUtil.formatMessage(TYPE, buffer, out);
     }
 
+    protected void serializeRequest(final Requests req, final ByteBuf buffer) {
+        serializeObject(req.getSrp(), buffer);
+        serializeObject(req.getLsp(), buffer);
+        if (req.getEndpointsObj() != null) {
+            serializeObject(req.getEndpointsObj(), buffer);
+        }
+        if (req.getEro() != null) {
+            serializeObject(req.getEro(), buffer);
+        }
+        if (req.getLspa() != null) {
+            serializeObject(req.getLspa(), buffer);
+        }
+        if (req.getBandwidth() != null) {
+            serializeObject(req.getBandwidth(), buffer);
+        }
+        if (req.getMetrics() != null && !req.getMetrics().isEmpty()) {
+            for (final Metrics m : req.getMetrics()) {
+                serializeObject(m.getMetric(), buffer);
+            }
+        }
+        if (req.getIro() != null) {
+            serializeObject(req.getIro(), buffer);
+        }
+    }
+
     @Override
     protected Message validate(final List<Object> objects, final List<Message> errors) throws PCEPDeserializerException {
         if (objects == null) {
@@ -100,7 +101,7 @@ public final class CInitiated00PCInitiateMessageParser extends AbstractMessagePa
         return new PcinitiateBuilder().setPcinitiateMessage(builder.build()).build();
     }
 
-    private Requests getValidRequest(final List<Object> objects) {
+    protected Requests getValidRequest(final List<Object> objects) {
         final RequestsBuilder builder = new RequestsBuilder();
         builder.setSrp((Srp) objects.get(0));
         objects.remove(0);
index 9e47f20610f9f9e9da0e29dcd8ed549ae9f6be1f..6849dee2c1eb7f07bd98c1338e6d9cfa05152d10 100644 (file)
@@ -9,12 +9,9 @@ package org.opendaylight.protocol.pcep.ietf.stateful07;
 
 import com.google.common.base.Preconditions;
 import com.google.common.collect.Lists;
-
 import io.netty.buffer.ByteBuf;
 import io.netty.buffer.Unpooled;
-
 import java.util.List;
-
 import org.opendaylight.protocol.pcep.spi.AbstractMessageParser;
 import org.opendaylight.protocol.pcep.spi.MessageUtil;
 import org.opendaylight.protocol.pcep.spi.ObjectRegistry;
@@ -43,7 +40,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.typ
 /**
  * Parser for {@link Pcrpt}
  */
-public final class Stateful07PCReportMessageParser extends AbstractMessageParser {
+public class Stateful07PCReportMessageParser extends AbstractMessageParser {
 
     public static final int TYPE = 10;
 
@@ -58,33 +55,37 @@ public final class Stateful07PCReportMessageParser extends AbstractMessageParser
         final List<Reports> reports = msg.getPcrptMessage().getReports();
         ByteBuf buffer = Unpooled.buffer();
         for (final Reports report : reports) {
-            if (report.getSrp() != null) {
-                serializeObject(report.getSrp(), buffer);
+            serializeReport(report, buffer);
+        }
+        MessageUtil.formatMessage(TYPE, buffer, out);
+    }
+
+    protected void serializeReport(final Reports report, final ByteBuf buffer) {
+        if (report.getSrp() != null) {
+            serializeObject(report.getSrp(), buffer);
+        }
+        serializeObject(report.getLsp(), buffer);
+        final Path p = report.getPath();
+        if (p != null) {
+            serializeObject(p.getEro(), buffer);
+            if (p.getLspa() != null) {
+                serializeObject(p.getLspa(), buffer);
             }
-            serializeObject(report.getLsp(), buffer);
-            final Path p = report.getPath();
-            if (p != null) {
-                serializeObject(p.getEro(), buffer);
-                if (p.getLspa() != null) {
-                    serializeObject(p.getLspa(), buffer);
-                }
-                if (p.getBandwidth() != null) {
-                    serializeObject(p.getBandwidth(), buffer);
-                }
-                if (p.getMetrics() != null && !p.getMetrics().isEmpty()) {
-                    for (final Metrics m : p.getMetrics()) {
-                        serializeObject(m.getMetric(), buffer);
-                    }
-                }
-                if (p.getIro() != null) {
-                    serializeObject(p.getIro(), buffer);
-                }
-                if (p.getRro() != null) {
-                    serializeObject(p.getRro(), buffer);
+            if (p.getBandwidth() != null) {
+                serializeObject(p.getBandwidth(), buffer);
+            }
+            if (p.getMetrics() != null && !p.getMetrics().isEmpty()) {
+                for (final Metrics m : p.getMetrics()) {
+                    serializeObject(m.getMetric(), buffer);
                 }
             }
+            if (p.getIro() != null) {
+                serializeObject(p.getIro(), buffer);
+            }
+            if (p.getRro() != null) {
+                serializeObject(p.getRro(), buffer);
+            }
         }
-        MessageUtil.formatMessage(TYPE, buffer, out);
     }
 
     @Override
@@ -100,14 +101,15 @@ public final class Stateful07PCReportMessageParser extends AbstractMessageParser
 
         while (!objects.isEmpty()) {
             final Reports report = getValidReports(objects, errors);
-            if (reports != null) {
+            if (report != null) {
                 reports.add(report);
             }
         }
         return new PcrptBuilder().setPcrptMessage(new PcrptMessageBuilder().setReports(reports).build()).build();
     }
 
-    private Reports getValidReports(final List<Object> objects, final List<Message> errors) {
+    protected Reports getValidReports(final List<Object> objects, final List<Message> errors) {
+        boolean isValid = true;
         final ReportsBuilder builder = new ReportsBuilder();
         if (objects.get(0) instanceof Srp) {
             builder.setSrp((Srp) objects.get(0));
@@ -118,14 +120,24 @@ public final class Stateful07PCReportMessageParser extends AbstractMessageParser
             objects.remove(0);
         } else {
             errors.add(createErrorMsg(PCEPErrors.LSP_MISSING));
-            return null;
+            isValid = false;
         }
         if (!objects.isEmpty()) {
             final PathBuilder pBuilder = new PathBuilder();
+            if (objects.get(0) instanceof Ero) {
+                pBuilder.setEro((Ero) objects.get(0));
+                objects.remove(0);
+            } else {
+                errors.add(createErrorMsg(PCEPErrors.ERO_MISSING));
+                isValid = false;
+            }
             parsePath(objects, pBuilder);
             builder.setPath(pBuilder.build());
         }
-        return builder.build();
+        if(isValid) {
+            return builder.build();
+        }
+        return null;
     }
 
     private void parsePath(final List<Object> objects, final PathBuilder builder) {
@@ -136,12 +148,6 @@ public final class Stateful07PCReportMessageParser extends AbstractMessageParser
             obj = objects.get(0);
             switch (state) {
             case Init:
-                state = State.EroIn;
-                if (obj instanceof Ero) {
-                    builder.setEro((Ero) obj);
-                    break;
-                }
-            case EroIn:
                 state = State.LspaIn;
                 if (obj instanceof Lspa) {
                     builder.setLspa((Lspa) obj);
@@ -188,6 +194,6 @@ public final class Stateful07PCReportMessageParser extends AbstractMessageParser
     }
 
     private enum State {
-        Init, EroIn, LspaIn, BandwidthIn, MetricIn, IroIn, RroIn, End
+        Init, LspaIn, BandwidthIn, MetricIn, IroIn, RroIn, End
     }
 }
index 2fb4c4bdd646b1554a89ed83764588b6da2f41d4..b4e4b7ec696536b5d50e08b025bf71cab7afc1a5 100644 (file)
@@ -9,12 +9,9 @@ package org.opendaylight.protocol.pcep.ietf.stateful07;
 
 import com.google.common.base.Preconditions;
 import com.google.common.collect.Lists;
-
 import io.netty.buffer.ByteBuf;
 import io.netty.buffer.Unpooled;
-
 import java.util.List;
-
 import org.opendaylight.protocol.pcep.spi.AbstractMessageParser;
 import org.opendaylight.protocol.pcep.spi.MessageUtil;
 import org.opendaylight.protocol.pcep.spi.ObjectRegistry;
@@ -42,7 +39,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.typ
 /**
  * Parser for {@link Pcupd}
  */
-public final class Stateful07PCUpdateRequestMessageParser extends AbstractMessageParser {
+public class Stateful07PCUpdateRequestMessageParser extends AbstractMessageParser {
 
     public static final int TYPE = 11;
 
@@ -57,28 +54,32 @@ public final class Stateful07PCUpdateRequestMessageParser extends AbstractMessag
         final List<Updates> updates = msg.getPcupdMessage().getUpdates();
         ByteBuf buffer = Unpooled.buffer();
         for (final Updates update : updates) {
-            serializeObject(update.getSrp(), buffer);
-            serializeObject(update.getLsp(), buffer);
-            final Path p = update.getPath();
-            if (p != null) {
-                serializeObject(p.getEro(), buffer);
-                if (p.getLspa() != null) {
-                    serializeObject(p.getLspa(), buffer);
-                }
-                if (p.getBandwidth() != null) {
-                    serializeObject(p.getBandwidth(), buffer);
-                }
-                if (p.getMetrics() != null && !p.getMetrics().isEmpty()) {
-                    for (final Metrics m : p.getMetrics()) {
-                        serializeObject(m.getMetric(), buffer);
-                    }
-                }
-                if (p.getIro() != null) {
-                    serializeObject(p.getIro(), buffer);
+            serializeUpdate(update, buffer);
+        }
+        MessageUtil.formatMessage(TYPE, buffer, out);
+    }
+
+    protected void serializeUpdate(final Updates update, final ByteBuf buffer) {
+        serializeObject(update.getSrp(), buffer);
+        serializeObject(update.getLsp(), buffer);
+        final Path p = update.getPath();
+        if (p != null) {
+            serializeObject(p.getEro(), buffer);
+            if (p.getLspa() != null) {
+                serializeObject(p.getLspa(), buffer);
+            }
+            if (p.getBandwidth() != null) {
+                serializeObject(p.getBandwidth(), buffer);
+            }
+            if (p.getMetrics() != null && !p.getMetrics().isEmpty()) {
+                for (final Metrics m : p.getMetrics()) {
+                    serializeObject(m.getMetric(), buffer);
                 }
             }
+            if (p.getIro() != null) {
+                serializeObject(p.getIro(), buffer);
+            }
         }
-        MessageUtil.formatMessage(TYPE, buffer, out);
     }
 
     @Override
@@ -93,9 +94,9 @@ public final class Stateful07PCUpdateRequestMessageParser extends AbstractMessag
         final List<Updates> updateRequests = Lists.newArrayList();
 
         while (!objects.isEmpty()) {
-            final Updates update = getValidUpdates(objects, errors);
-            if (update != null) {
-                updateRequests.add(update);
+            final Updates upd = getValidUpdates(objects, errors);
+            if(upd != null) {
+                updateRequests.add(upd);
             }
         }
         if (!objects.isEmpty()) {
@@ -104,21 +105,22 @@ public final class Stateful07PCUpdateRequestMessageParser extends AbstractMessag
         return new PcupdBuilder().setPcupdMessage(new PcupdMessageBuilder().setUpdates(updateRequests).build()).build();
     }
 
-    private Updates getValidUpdates(final List<Object> objects, final List<Message> errors) {
+    protected Updates getValidUpdates(final List<Object> objects, final List<Message> errors) {
+        boolean isValid = true;
         final UpdatesBuilder builder = new UpdatesBuilder();
         if (objects.get(0) instanceof Srp) {
             builder.setSrp((Srp) objects.get(0));
             objects.remove(0);
         } else {
             errors.add(createErrorMsg(PCEPErrors.SRP_MISSING));
-            return null;
+            isValid = false;
         }
         if (objects.get(0) instanceof Lsp) {
             builder.setLsp((Lsp) objects.get(0));
             objects.remove(0);
         } else {
             errors.add(createErrorMsg(PCEPErrors.LSP_MISSING));
-            return null;
+            isValid = false;
         }
         if (!objects.isEmpty()) {
             final PathBuilder pBuilder = new PathBuilder();
@@ -127,12 +129,15 @@ public final class Stateful07PCUpdateRequestMessageParser extends AbstractMessag
                 objects.remove(0);
             } else {
                 errors.add(createErrorMsg(PCEPErrors.ERO_MISSING));
-                return null;
+                isValid = false;
             }
             parsePath(objects, pBuilder);
             builder.setPath(pBuilder.build());
         }
-        return builder.build();
+        if(isValid) {
+            return builder.build();
+        }
+        return null;
     }
 
     private void parsePath(final List<Object> objects, final PathBuilder pBuilder) {
index aa2bd05023632df73d7f7a2bed8572449ddfdb12..7aaa095735c0a5c1cb5cef6c00e9c1cb7cca0d3f 100644 (file)
@@ -9,16 +9,14 @@ package org.opendaylight.protocol.pcep.ietf;
 
 import static org.junit.Assert.assertArrayEquals;
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
 
 import com.google.common.collect.Lists;
-
 import io.netty.buffer.ByteBuf;
 import io.netty.buffer.Unpooled;
-
 import java.io.IOException;
 import java.util.Collections;
 import java.util.List;
-
 import org.junit.Before;
 import org.junit.Test;
 import org.opendaylight.protocol.pcep.ietf.initiated00.CInitiated00PCInitiateMessageParser;
@@ -404,4 +402,34 @@ public class PCEPValidatorTest {
             assertArrayEquals(result.array(), buf.array());
         }
     }
+
+    @Test
+    public void testMissingLspObjectErrorInPcRptMsg() throws PCEPDeserializerException {
+        final byte[] statefulMsg= {
+            0x20,0x0B,0x00,0x1C,
+            /* srp-object */
+            0x21,0x10,0x00,0x0C,
+            0x00,0x00,0x00,0x001,
+            0x00,0x00,0x00,0x01,
+            /* lsp-object is missing*/
+            /* sr-ero-object */
+            0x07,0x10,0x00,0x0C,
+            /* ipv4 prefix subobject */
+            (byte) 0x81,0x08,(byte) 0xFF,(byte) 0xFF,
+            (byte) 0xFF,(byte) 0xFF,0x16,0x00};
+
+        final Stateful07PCReportMessageParser parser = new Stateful07PCReportMessageParser(this.ctx.getObjectHandlerRegistry());
+
+        final PcerrMessageBuilder errMsgBuilder = new PcerrMessageBuilder();
+        errMsgBuilder.setErrors(Lists.newArrayList(new ErrorsBuilder().setErrorObject(
+                new ErrorObjectBuilder().setType((short) 6).setValue((short) 8).build()).build()));
+        final PcerrBuilder builder = new PcerrBuilder();
+        builder.setPcerrMessage(errMsgBuilder.build());
+
+        ByteBuf buf = Unpooled.wrappedBuffer(statefulMsg);
+        final List<Message> errors = Lists.<Message>newArrayList();
+        parser.parseMessage(buf.slice(4, buf.readableBytes() - 4), errors);
+        assertFalse(errors.isEmpty());
+        assertEquals(builder.build(), errors.get(0));
+    }
 }
index 332920c33cef6fe1df8170ed243387ed483b6c27..509179209401724cff379af5f96fa6fe72a06099 100644 (file)
@@ -9,12 +9,9 @@ package org.opendaylight.protocol.pcep.impl.message;
 
 import com.google.common.base.Preconditions;
 import com.google.common.collect.Lists;
-
 import io.netty.buffer.ByteBuf;
 import io.netty.buffer.Unpooled;
-
 import java.util.List;
-
 import org.opendaylight.protocol.pcep.spi.AbstractMessageParser;
 import org.opendaylight.protocol.pcep.spi.MessageUtil;
 import org.opendaylight.protocol.pcep.spi.ObjectRegistry;
@@ -69,51 +66,55 @@ public class PCEPReplyMessageParser extends AbstractMessageParser {
             if (reply.getRp() == null) {
                 throw new IllegalArgumentException("Reply must contain RP object.");
             }
-            serializeObject(reply.getRp(), buffer);
-            if (reply.getResult() != null) {
-                if (reply.getResult() instanceof FailureCase) {
-                    final FailureCase f = ((FailureCase) reply.getResult());
-                    serializeObject(f.getNoPath(), buffer);
-                    if (f.getLspa() != null) {
-                        serializeObject(f.getLspa(), buffer);
+            serializeReply(reply, buffer);
+        }
+        MessageUtil.formatMessage(TYPE, buffer, out);
+    }
+
+    protected void serializeReply(final Replies reply, final ByteBuf buffer) {
+        serializeObject(reply.getRp(), buffer);
+        if (reply.getResult() != null) {
+            if (reply.getResult() instanceof FailureCase) {
+                final FailureCase f = ((FailureCase) reply.getResult());
+                serializeObject(f.getNoPath(), buffer);
+                if (f.getLspa() != null) {
+                    serializeObject(f.getLspa(), buffer);
+                }
+                if (f.getBandwidth() != null) {
+                    serializeObject(f.getBandwidth(), buffer);
+                }
+                if (f.getMetrics() != null && !f.getMetrics().isEmpty()) {
+                    for (final Metrics m : f.getMetrics()) {
+                        serializeObject(m.getMetric(), buffer);
+                    }
+                }
+                if (f.getIro() != null) {
+                    serializeObject(f.getIro(), buffer);
+                }
+            } else {
+                final SuccessCase s = (SuccessCase) reply.getResult();
+                for (final Paths p : s.getSuccess().getPaths()) {
+                    serializeObject(p.getEro(), buffer);
+                    if (p.getLspa() != null) {
+                        serializeObject(p.getLspa(), buffer);
+                    }
+                    if (p.getOf() != null) {
+                        serializeObject(p.getOf(), buffer);
                     }
-                    if (f.getBandwidth() != null) {
-                        serializeObject(f.getBandwidth(), buffer);
+                    if (p.getBandwidth() != null) {
+                        serializeObject(p.getBandwidth(), buffer);
                     }
-                    if (f.getMetrics() != null && !f.getMetrics().isEmpty()) {
-                        for (final Metrics m : f.getMetrics()) {
+                    if (p.getMetrics() != null && !p.getMetrics().isEmpty()) {
+                        for (final Metrics m : p.getMetrics()) {
                             serializeObject(m.getMetric(), buffer);
                         }
                     }
-                    if (f.getIro() != null) {
-                        serializeObject(f.getIro(), buffer);
-                    }
-                } else {
-                    final SuccessCase s = (SuccessCase) reply.getResult();
-                    for (final Paths p : s.getSuccess().getPaths()) {
-                        serializeObject(p.getEro(), buffer);
-                        if (p.getLspa() != null) {
-                            serializeObject(p.getLspa(), buffer);
-                        }
-                        if (p.getOf() != null) {
-                            serializeObject(p.getOf(), buffer);
-                        }
-                        if (p.getBandwidth() != null) {
-                            serializeObject(p.getBandwidth(), buffer);
-                        }
-                        if (p.getMetrics() != null && !p.getMetrics().isEmpty()) {
-                            for (final Metrics m : p.getMetrics()) {
-                                serializeObject(m.getMetric(), buffer);
-                            }
-                        }
-                        if (p.getIro() != null) {
-                            serializeObject(p.getIro(), buffer);
-                        }
+                    if (p.getIro() != null) {
+                        serializeObject(p.getIro(), buffer);
                     }
                 }
             }
         }
-        MessageUtil.formatMessage(TYPE, buffer, out);
     }
 
     @Override