From c02dd7f87e9ba574f06e5cc1eb36ebeb76b9f446 Mon Sep 17 00:00:00 2001
From: mrossign <mrossign@localhost>
Date: Thu, 08 Oct 2009 16:02:17 +0000
Subject: [PATCH] - Addition of ReplServerStartDSMsg now sent to a DS connecting to a RS  in handshake phase instead of a ReplServerStartMsg. ReplServerStartDSMsg  contains same thing as ReplServerStartMsg but also contains

---
 opendj-sdk/opends/src/server/org/opends/server/replication/protocol/ReplServerStartMsg.java |  127 +++++++++++++++++++++++++++++++++++-------
 1 files changed, 105 insertions(+), 22 deletions(-)

diff --git a/opendj-sdk/opends/src/server/org/opends/server/replication/protocol/ReplServerStartMsg.java b/opendj-sdk/opends/src/server/org/opends/server/replication/protocol/ReplServerStartMsg.java
index 7c83505..6fce977 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/replication/protocol/ReplServerStartMsg.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/replication/protocol/ReplServerStartMsg.java
@@ -50,6 +50,14 @@
   private boolean sslEncryption;
 
   /**
+   * NOTE: Starting from protocol V4, we introduce a dedicated PDU for answering
+   * to the DS ServerStartMsg. This is the ReplServerStartDSMsg. So the
+   * degradedStatusThreshold value being used only by a DS, it could be removed
+   * from the ReplServerStartMsg PDU. However for a smoothly transition to V4
+   * protocol, we prefer to let this variable also in this PDU but the one
+   * really used is in the ReplServerStartDSMsg PDU. This prevents from having
+   * only RSv3 able to connect to RSv4 as connection initiator.
+   *
    * Threshold value used by the RS to determine if a DS must be put in
    * degraded status because the number of pending changes for him has crossed
    * this value. This field is only used by a DS.
@@ -108,6 +116,15 @@
     allowedPduTypes[1] = MSG_TYPE_REPL_SERVER_START_V1;
     headerLength = decodeHeader(allowedPduTypes, in);
 
+    // Protocol version has been read as part of the header:
+    // decode the body according to the protocol version read in the header
+    switch(protocolVersion)
+    {
+      case ProtocolVersion.REPLICATION_PROTOCOL_V1:
+        decodeBody_V1(in, headerLength);
+        return;
+    }
+
     try
     {
       /* The ReplServerStartMsg payload is stored in the form :
@@ -154,22 +171,85 @@
       sslEncryption = Boolean.valueOf(new String(in, pos, length, "UTF-8"));
       pos += length +1;
 
-      // For easiness (no additional method), simply compare PDU type to
-      // know if we have to read new parameters of V2
-      if (in[0] == MSG_TYPE_REPL_SERVER_START)
-      {
-        /**
-         * read the degraded status threshold
-         */
-        length = getNextLength(in, pos);
-        degradedStatusThreshold =
-          Integer.valueOf(new String(in, pos, length, "UTF-8"));
-        pos += length + 1;
-      }
+      /**
+       * read the degraded status threshold
+       */
+      length = getNextLength(in, pos);
+      degradedStatusThreshold =
+        Integer.valueOf(new String(in, pos, length, "UTF-8"));
+      pos += length + 1;
 
       // Read the ServerState
       // Caution: ServerState MUST be the last field. Because ServerState can
-      // contain null character (string termination of sererid string ..) it
+      // contain null character (string termination of serverid string ..) it
+      // cannot be decoded using getNextLength() like the other fields. The
+      // only way is to rely on the end of the input buffer : and that forces
+      // the ServerState to be the last. This should be changed and we want to
+      // have more than one ServerState field.
+      serverState = new ServerState(in, pos, in.length - 1);
+    } catch (UnsupportedEncodingException e)
+    {
+      throw new DataFormatException("UTF-8 is not supported by this jvm.");
+    }
+  }
+
+  /**
+   * Decodes the body of a just received ReplServerStartMsg. The body is in the
+   * passed array, and starts at the provided location. This is for a PDU
+   * encoded in V1 protocol version.
+   * @param in A byte array containing the body for the ReplServerStartMsg
+   * @param pos The position in the array where the decoding should start
+   * @throws DataFormatException If the in does not contain a properly
+   *                             encoded ReplServerStartMsg.
+   */
+  public void decodeBody_V1(byte[] in, int pos) throws DataFormatException
+  {
+    try
+    {
+      /* The ReplServerStartMsg payload is stored in the form :
+       * <baseDn><serverId><serverURL><windowSize><sslEncryption>
+       * <serverState>
+       */
+
+      /* read the dn
+       * first calculate the length then construct the string
+       */
+      int length = getNextLength(in, pos);
+      baseDn = new String(in, pos, length, "UTF-8");
+      pos += length +1;
+
+      /*
+       * read the ServerId
+       */
+      length = getNextLength(in, pos);
+      String serverIdString = new String(in, pos, length, "UTF-8");
+      serverId = Integer.valueOf(serverIdString);
+      pos += length +1;
+
+      /*
+       * read the ServerURL
+       */
+      length = getNextLength(in, pos);
+      serverURL = new String(in, pos, length, "UTF-8");
+      pos += length +1;
+
+      /*
+       * read the window size
+       */
+      length = getNextLength(in, pos);
+      windowSize = Integer.valueOf(new String(in, pos, length, "UTF-8"));
+      pos += length +1;
+
+      /*
+       * read the sslEncryption setting
+       */
+      length = getNextLength(in, pos);
+      sslEncryption = Boolean.valueOf(new String(in, pos, length, "UTF-8"));
+      pos += length +1;
+
+      // Read the ServerState
+      // Caution: ServerState MUST be the last field. Because ServerState can
+      // contain null character (string termination of serverid string ..) it
       // cannot be decoded using getNextLength() like the other fields. The
       // only way is to rely on the end of the input buffer : and that forces
       // the ServerState to be the last. This should be changed and we want to
@@ -235,8 +315,12 @@
   public byte[] getBytes(short protocolVersion)
      throws UnsupportedEncodingException
   {
-    if  (protocolVersion == ProtocolVersion.REPLICATION_PROTOCOL_V1)
-      return getBytes_V1();
+    // If an older version requested, encode in the requested way
+    switch(protocolVersion)
+    {
+      case ProtocolVersion.REPLICATION_PROTOCOL_V1:
+        return getBytes_V1();
+    }
 
     /* The ReplServerStartMsg is stored in the form :
      * <operation type><baseDn><serverId><serverURL><windowSize><sslEncryption>
@@ -254,12 +338,12 @@
       String.valueOf(degradedStatusThreshold).getBytes("UTF-8");
 
     int length = byteDn.length + 1 + byteServerId.length + 1 +
-    byteServerUrl.length + 1 + byteWindowSize.length + 1 +
-    byteSSLEncryption.length + 1 +
-    byteDegradedStatusThreshold.length + 1 +
-    byteServerState.length + 1;
+      byteServerUrl.length + 1 + byteWindowSize.length + 1 +
+      byteSSLEncryption.length + 1 +
+      byteDegradedStatusThreshold.length + 1 +
+      byteServerState.length + 1;
 
-    /* encode the header in a byte[] large enough to also contain the mods */
+    /* encode the header in a byte[] large enough */
     byte resultByteArray[] =
       encodeHeader(MSG_TYPE_REPL_SERVER_START, length, protocolVersion);
 
@@ -377,7 +461,7 @@
                    byteSSLEncryption.length + 1 +
                    byteServerState.length + 1;
 
-      /* encode the header in a byte[] large enough to also contain the mods */
+      /* encode the header in a byte[] large enough */
       byte resultByteArray[] = encodeHeader_V1(MSG_TYPE_REPL_SERVER_START_V1,
         length);
       int pos = headerLength;
@@ -407,5 +491,4 @@
       return null;
     }
   }
-
 }

--
Gitblit v1.10.0