NSIS                                                           C. Werner
Internet-Draft                                                               X. Fu
Internet-Draft                                                 C. Werner
Expires: May 2, 2005 January 18, 2006                               Univ. Goettingen
                                                           H. Tschofenig
                                                               T. Tsenov
                                                                 Siemens
                                                                 C. Aoun
                                                                  Nortel
                                                           November 2004

                       NSLP
                                                         N. Steinleitner
                                                        Univ. Goettingen
                                                           July 17, 2005

                       NAT/FW NSLP State Machine
            draft-werner-nsis-natfw-nslp-statemachine-00.txt
            draft-werner-nsis-natfw-nslp-statemachine-01.txt

Status of this Memo

   This document is an Internet-Draft and is subject to all provisions
   of section 3 of RFC 3667.

   By submitting this Internet-Draft, each author represents that any
   applicable patent or other IPR claims of which he or she is aware
   have been or will be disclosed, and any of which he or she become becomes
   aware will be disclosed, in accordance with
   RFC 3668. Section 6 of BCP 79.

   Internet-Drafts are working documents of the Internet Engineering
   Task Force (IETF), its areas, and its working groups.  Note that
   other groups may also distribute working documents as
   Internet-Drafts. Internet-
   Drafts.

   Internet-Drafts are draft documents valid for a maximum of six months
   and may be updated, replaced, or obsoleted by other documents at any
   time.  It is inappropriate to use Internet-Drafts as reference
   material or to cite them other than as "work in progress."

   The list of current Internet-Drafts can be accessed at
   http://www.ietf.org/ietf/1id-abstracts.txt.

   The list of Internet-Draft Shadow Directories can be accessed at
   http://www.ietf.org/shadow.html.

   This Internet-Draft will expire on May 2, 2005. January 18, 2006.

Copyright Notice

   Copyright (C) The Internet Society (2004). (2005).

Abstract

   This document describes the state machines for the NSIS Signaling
   Layer Protocol for Network Address Translation/Firewall signaling
   (NAT/FW NSLP).  A set of state machines for NAT/FW NSLP entities at
   different locations of a signaling path are presented in order to
   illustrate how NAT/FW NSLP may be implemented.

Table of Contents

   1.   Introduction . . . . . . . . . . . . . . . . . . . . . . . . .   3
   2.   Terminology  . . . . . . . . . . . . . . . . . . . . . . . . .  4   3
   3.   Notational conventions used in state diagrams  . . . . . . . .  5   3
   4.   State Machine Symbols  . . . . . . . . . . . . . . . . . . . .  8   6
   5.   Common Rules . . . . . . . . . . . . . . . . . . . . . . . . .  9   7
     5.1  Common Procedures  . . . . . . . . . . . . . . . . . . . .  9   7
     5.2  Common Variables . . . . . . . . . . . . . . . . . . . . . 11   9
     5.3  Constants  . . . . . . . . . . . . . . . . . . . . . . . . 12  10
   6.   State machine for the NAT/FW NI  . . . . . . . . . . . . . . . 13  10
   7.   State machines for the NAT/FW NF . . . . . . . . . . . . . . . 16  14
     7.1  State machine for NAT/FW Firewall NF . . . . . . . . . . . 16  15
     7.2  State machine for NAT/FW NAT NF  . . . . . . . . . . . . . 18  22
   8.   State machine for the NAT/FW NR  . . . . . . . . . . . . . . . 24  29
   9.   Security Considerations  . . . . . . . . . . . . . . . . . . . 27  33
   10.  Open Issues  . . . . . . . . . . . . . . . . . . . . . . . . 28  34
   11.  Acknowledgments  . . . . . . . . . . . . . . . . . . . . . . 29  34
   12.  References . . . . . . . . . . . . . . . . . . . . . . . . . 30  34
     12.1   Normative References . . . . . . . . . . . . . . . . . . . . 30  34
     12.2   Informative References . . . . . . . . . . . . . . . . . . . 30  34
        Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . 30  35
        Intellectual Property and Copyright Statements . . . . . . . . 32  37

1.  Introduction

   This document describes the state machines for NAT/FW NSLP [1],
   trying to show how NAT/FW NSLP can be implemented to support its
   deployment.  The state machines described in this document are
   illustrative of how the NAT/FW NSLP protocol defined in [1] may be
   implemented for the first NAT/FW NSLP node in the signaling path,
   intermediate NAT/FW NSLP nodes with Firewall and/or NAT
   functionality, and the last NAT/FW NSLP node in the signaling path.
   Where there are differences [1] are authoritative.  The state
   machines are informative only.  Implementations may achieve the same
   results using different methods.

   The messages used in the NAT/FW NSLP protocol can be summarized as
   follows:

      Requesting message       Responding message
      ------------------------+---------------------------
      CREATE                  |RESPONSE
      REA                     |RESPONSE
      QUERY                   |RESPONSE
      RESPONSE                |NONE
      NOTIFY                  |NONE
      TRIGGER                 |CREATE
      ------------------------+---------------------------

   We describe a set of state machines for different roles of entities
   running NAT/FW NSLP to illustrate how NAT/FW NSLP may be implemented.

2.  Terminology

   The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
   "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this
   document are to be interpreted as described in [2].

3.  Notational conventions used in state diagrams

   The following state transition tables are completed mostly based on
   the conventions specified in [3].  The complete text is described
   below.

   State transition tables are used to represent the operation of the
   protocol by a number of cooperating state machines each comprising a
   group of connected, mutually exclusive states.  Only one state of
   each machine can be active at any given time.

   All permissible transitions from a given state to other states and
   associated actions performed when the transitions occur are
   represented by using triplets of (exit condition, exit action, exit
   state).  All conditions are expressions that evaluate to TRUE or
   FALSE; if a condition evaluates to TRUE, then the condition is met.
   A state "ANY" is a wildcard state that matches the current state in
   each state machine.  The exit conditions of a wildcard state are
   evaluated after all other exit conditions of specific to the current
   state are met.

   On exit from a state, the procedures defined for the state and the
   exit condition are executed exactly once, in the order that they
   appear on the page.  (Note that the procedures defined in [4]  are
   executed on entry to a state, which is one major difference from this
   document.)  Each procedure is deemed to be atomic; i.e., execution of
   a procedure completes before the next sequential procedure starts to
   execute.  No procedures execute outside of a state block.  The
   procedures in only one state block execute at a time, even if the
   conditions for execution of state blocks in different state machines
   are satisfied, and all procedures in an executing state block
   complete execution before the transition to and execution of any
   other state block occurs, i.e., the execution of any state block
   appears to be atomic with respect to the execution of any other state
   block and the transition condition to that state from the previous
   state is TRUE when execution commences.  The order of execution of
   state blocks in different state machines is undefined except as
   constrained by their transition conditions.  A variable that is set
   to a particular value in a state block retains this value until a
   subsequent state block executes a procedure that modifies the value.

   On completion of the transition from the previous state to the
   current state, all exit conditions for the current state (including
   exit conditions defined for the wildcard state) are evaluated
   continuously until one of the conditions is met.

   Any event variable is set to TRUE when the corresponding event occurs
   and set to FALSE immediately after completion of the action
   associated with the current state and the event.

   The interpretation of the special symbols and operators is reused
   from [4] and the state diagrams are based on the conventions
   specified in [5], Section 8.2.1.

   The complete text is reproduced here:

      State diagrams are used to represent the operation of the protocol
      by a number of cooperating state machines each comprising a group
      of connected, mutually exclusive states.  Only one state of each
      machine can be active at any given time.

      All permissible transitions between states are represented by
      arrows, the arrowhead denoting the direction of the possible
      transition.  Labels attached to arrows denote the condition(s)
      that must be met in order for the transition to take place.  All
      conditions are expressions that evaluate to TRUE or FALSE; if a
      condition evaluates to TRUE, then the condition is met.  The label
      UCT denotes an unconditional transition (i.e., UCT always
      evaluates to TRUE).  A transition that is global in nature (i.e.,
      a transition that occurs from any of the possible states if the
      condition attached to the arrow is met) is denoted by an open
      arrow; i.e., no specific state is identified as the origin of the
      transition.  When the condition associated with a global
      transition is met, it supersedes all other exit conditions
      including UCT.  The special global condition BEGIN supersedes all
      other global conditions, and once asserted remains asserted until
      all state blocks have executed to the point that variable
      assignments and other consequences of their execution remain
      unchanged.

      On entry to a state, the procedures defined for the state (if any)
      are executed exactly once, in the order that they appear on the
      page.  Each action is deemed to be atomic; i.e., execution of a
      procedure completes before the next sequential procedure starts to
      execute.  No procedures execute outside of a state block.  The
      procedures in only one state block execute at a time, even if the
      conditions for execution of state blocks in different state
      machines are satisfied, and all procedures in an executing state
      block complete execution before the transition to and execution of
      any other state block occurs, i.e., the execution of any state
      block appears to be atomic with respect to the execution of any
      other state block and the transition condition to that state from
      the previous state is TRUE when execution commences.  The order of
      execution of state blocks in different state machines is undefined
      except as constrained by their transition conditions.  A variable
      that is set to a particular value in a state block retains this
      value until a subsequent state block executes a procedure that
      modifies the value.

      On completion of all of the procedures within a state, all exit
      conditions for the state (including all conditions associated with
      global transitions) are evaluated continuously until one of the
      conditions is met.  The label ELSE denotes a transition that
      occurs if none of the other conditions for transitions from the
      state are met (i.e., ELSE evaluates to TRUE if all other possible
      exit conditions from the state evaluate to FALSE).  Where two or
      more exit conditions with the same level of precedence become TRUE
      simultaneously, the choice as to which exit condition causes the
      state transition to take place is arbitrary.

   In addition to the above notation, there are a couple of
   clarifications specific to this document.  First, all boolean
   variables are initialized to FALSE before the state machine execution
   begins.  Second, the following notational shorthand is specific to
   this document:

   <variable> = <expression1> | <expression2> | ...
      Execution of a statement of this form will result in <variable>
      having a value of exactly one of the expressions.  The logic for
      which of those expressions gets executed is outside of the state
      machine and could be environmental, configurable, or based on
      another state machine such as that of the method.

4.  State Machine Symbols

   ( ) Used to force the precedence of operators in Boolean expressions
      and to delimit the argument(s) of actions within state boxes.
   ;  Used as a terminating delimiter for actions within state boxes.
      Where a state box contains multiple actions, the order of
      execution follows the normal language conventions for reading
      text.
   =  Assignment action.  The value of the expression to the right of
      the operator is assigned to the variable to the left of the
      operator.  Where this operator is used to define multiple
      assignments, e.g., a = b = X the action causes the value of the
      expression following the right-most assignment operator to be
      assigned to all of the variables that appear to the left of the
      right-most assignment operator.
   !  Logical NOT operator.
   && Logical AND operator.
   || Logical OR operator.
   if...then... Conditional action.  If the Boolean expression following
      the if evaluates to TRUE, then the action following the then is
      executed.
   \{ statement 1, ... statement N \} Compound statement.  Braces are
      used to group statements that are executed together as if they
      were a single statement.
   != Inequality.  Evaluates to TRUE if the expression to the left of
      the operator is not equal in value to the expression to the right.
   == Equality.  Evaluates to TRUE if the expression to the left of the
      operator is equal in value to the expression to the right.
   >  Greater than.  Evaluates to TRUE if the value of the expression to
      the left of the operator is greater than the value of the
      expression to the right.

   <= Less than or equal to.  Evaluates to TRUE if the value of the
      expression to the left of the operator is either less than or
      equal to the value of the expression to the right.
   ++ Increment the preceding integer operator by 1.

5.  Common Rules

   Throughout the document we use terms defined in the [1], such as NI,
   NF, NR, NI+, NR+, CREATE, QUERY, or RESPONSE.

5.1  Common Procedures

   tx_CREATE(): Transmit a CREATE message
   tx_CREATE(LIFETIME=0): Transmit CREATE message with lifetime object
      explicitly set to 0 for session deletion
   tx_RESP(code,type): Transmit RESPONSE message with specified code
      (SUCCESS or ERROR) and result type (related to a specific request
      type message: CREATE, REA or QUERY).  A code or result type may be
      omitted, typically when forwarding received RESPONSE messages.
   tx_QUERY(): Transmit QUERY message.
   tx_NOTIFY(): Transmit NOTIFY message.
   rx_RESP(code, type): Evaluates to TRUE if a RESPONSE message has been
      received with the specified code (SUCCESS or ERROR) and result
      type (related to a specific request type message: CREATE, REA or
      QUERY).  If the code or type is omitted, any received RESPONSE
      message which is only matching the given code or type will
      evaluate this procedure to TRUE.
   rx_NOTIFY(): Evaluates to TRUE if a NOTIFY message has been received.
   rx_QUERY(): Evaluates to TRUE if a QUERY message has been received
   rx_CREATE(): Evaluates to TRUE if a CREATE message has been received.
   CHECK_AA(): Checks Authorization and Authentication of the received
      message.  Evaluates to TRUE if the check is successful, otherwise
      it evaluates to FALSE.  This check is performed on all received
      messages hence it will only be shown within the state machine when
      the check has failed.  This CHECK_AA also MAY include a local
      policy check for the received message.
   CHECK_NoNR(): Checks if the message can reach its targeted
      destination, i.e. the NR if it exists at the targeted host.
   CHECK_SCOPE(): Checks if the message has reached the network
      boundaries defined by the SCOPE object.
   Process Event(): Processes a NOTIFY messages and adapts the behaviour
      of this node to the new condition.
   Process Query(): Processes the received QUERY message and prepares
      the appropriate RESPONSE message.

   Binding.create(): Creates a public/private network translation
      binding on a NAT device for the requesting entity.
   Binding.clear(): Deletes a previously created a public/private
      network translation binding on a NAT device for the requesting
      entity.
   Session.create(): Installs all session related states, variables,
      bindings, policies.
   Session.update(): Updates all session related states, variables,
      bindings, policies based on received CREATE or TRIGGER if
      applicable.
   Session.clear(): Removes all session related states, variables,
      bindings, policies.
   PckFilter.create(): Installs a packet filter for the new session.
   PckFilter.update(): Updates the packet filter for changes in the
      session rules.
   PckFilter.clear(): Removes a previously set packet filter.
   Start.STATE_TIMER(identifier): This procedure starts a timer with a
      certain timespan, which is up to the specific implementation.  The
      parameter 'identifier' identifies this timer uniquely.  Any
      subsequent Start_STATE_TIMER(x), Stop_STATE_TIMER(x),
      TIMEOUT_STATE(x) refer to the same timer labeled x.  This timer is
      required to time the lifetime of state, which means that when it
      times out, it indicates the current machine state should be left
      or its validation has expired.  This procedure starts the timer
      'identifier'.  If a timer with the same 'identifier' has
      already	been started and not yet stopped, the timer is now stopped
      and restarted.  After the timer has timed out, the procedure
      TIMEOUT_STATE(identifier) evaluates to TRUE.  The timer does not
      restart automatically, but must be started again with a
      Start_STATE_TIMER(identifier).  Notice that there is no difference
      to the Start_REFRESH_TIMER(identifier) procedure which has exactly
      the same functionality.  The different procedure names are only
      supplied to underline the purpose of this specific timer.
   Stop.STATE_TIMER(identifier): This procedure stops the timer labeled
      'identifier'.  If it has already been stopped, this procedure has
      no effect.  If the timer has already timed out, this procedure
      removes the timeout-state from the timer 'identifier', so
      subsequent calls to TIMEOUT_STATE(identifier) evaluate to FALSE.
      A timeout cannot occur until the timer 'identifier' has been
      (re-)started.
   TIMEOUT.STATE(identifier): This procedure evaluates to TRUE if the
      timer 'identifier' has timed out and indicates a state lifetime
      expiration.  Subsequent TIMEOUT_STATE(identifier) calls also
      evaluate to TRUE until the timer 'identifier' has been
      (re-)started.  This procedure cannot evaluate to TRUE if the timer
      has been stopped.

   Start.REFRESH_TIMER(identifier): This procedure starts a timer with a
      certain timespan, which is up to the specific implementation.  The
      parameter 'identifier' identifies this timer uniquely.  Any
      subsequent Start_REFRESH_TIMER(x), Stop_REFRESH_TIMER(x),
      TIMEOUT_REFRESH(x) refer to the same timer labeled x.  This timer
      times a refresh interval, which means that when it times out, it
      indicates a state refresh message is due to be sent.  This
      procedure starts the timer 'identifier'.  If a timer with the same
      'identifier' has already	been started and not yet stopped, the
      timer is now stopped and restarted.  After the timer has timed
      out, the procedure TIMEOUT_REFRESH(identifier) evaluates to TRUE.
      The timer does not restart automatically, but must be started
      again with a Start_REFRESH_TIMER(identifier).  Notice that there
      is no difference to the Start_STATE_TIMER(identifier) procedure
      which has exactly the same functionality.  The different procedure
      names are only supplied to underline the purpose of this specific
      timer.
   Stop.REFRESH_TIMER(identifier): This procedure stops the timer
      labeled 'identifier'.  If it has already been stopped, this
      procedure has no effect.  If the timer has already timed out, this
      procedure removes the timeout-state from the timer 'identifier',
      so subsequent calls to TIMEOUT_REFRESH(identifier) evaluate to
      FALSE.  A timeout cannot occur until the timer 'identifier' has
      been (re-)started.
   TIMEOUT.REFRESH(identifier): This procedure evaluates to TRUE if the
      timer 'identifier' has timed out and indicates a refresh interval
      expiration.  Subsequent TIMEOUT_REFRESH(identifier) calls also
      evaluate to TRUE until the timer 'identifier' has been
      (re-)started.  This procedure cannot evaluate to TRUE if the timer
      has been stopped.
   tg_QUERY: External trigger to send a QUERY message (typically
      triggered by the application).
   tg_CREATE: External trigger to send a CREATE message (typically
      triggered by the application).
   tg_NOTIFY: External trigger to notify the entity of a new event to be
      processed (typically triggered by the application)
   tg_TRIGGER: External trigger to send a TRIGGER message to a NF
      (typically triggered by the application)
   tg_TEARDOWN: External trigger to delete a previously created session
      (typically triggered by the application)
   tg_REA: External trigger to send a REA message towards an
      opportunistic address (typically triggered by the application)

5.2  Common Variables
   IS_EDGE: Boolean flag which evaluates to TRUE if the node is on the
      network edge, otherwise it evaluates to FALSE.
   IS_PUBLICSIDE: Boolean flag which evaluates to TRUE if the (CREATE-
      or REA-) message has been received on the public side of the
      network.
   CREATE(LIFETIME?): Gets the value of the LIFETIME object in the
      CREATE message.
   CREATE(TRIGGER?): Evaluates to TRUE if the received CREATE message
      indicates a CREATE trigger.
   CREATE(POLICY?): Gets the policy for the CREATE message.
   CREATE(SOURCE?): Retrieves the sender of the CREATE message.
   CREATE(NoNR?): Evaluates to TRUE if the CREATE message has an active
      NoNR-flag.
   CREATE(Scope?): Evaluates to TRUE if the CREATE message has an active
      Scope-flag.
   Retry_Counter(CREATE): Denotes the current number of retries of
      CREATE message which has been re-transmitted due to previous
      RESPONSE_ERROR message.  If the number of Retry_Counter(CREATE)
      equals the value of MAXRETRY(CREATE), the current session creation
      attempt is aborted and the application is being notified.
   Retry_Counter(QUERY): Denotes the current number of retries of QUERY
      message which has been re-transmitted due to previous
      RESPONSE_ERROR message.  If the number of Retry_Counter(QUERY)
      equals the value of MAXRETRY(QUERY), the current QUERY attempt is
      aborted and the application is being notified.
   Retry_Counter(REA): Denotes the current number of retries of REA
      message which has been re-transmitted due to previous
      RESPONSE_ERROR message.  If the number of Retry_Counter(REA)
      equals the value of MAXRETRY(REA), the current REA initiation
      attempt is aborted and the application is being notified.

5.3  Constants

   Max_Retry(CREATE): Contains the maximum number of retransmission
      attempts of a CREATE message after it is aborted and the
      application is being notified.
   Max_Retry(QUERY): Contains the maximum number of retransmission
      attempts of a QUERY message after it is aborted and the
      application is being notified.
   Max_Retry(REA): Contains the maximum number of retransmission
      attempts of a REA message after it is aborted and the application
      is being notified.

6.  State machine for the NAT/FW NI

   This section presents the state machines for the NSIS initator which
   is capable of NSLP NAT/FW signaling

      -------------------
   -----------
   State: Initialize
      ------------------- INITIALIZE
   -----------

   Condition                Action                    State
      ------------------------+-------------------------+------------      Note
   ------------------------+-------------------------+-----------+---
   UCT             |retry_Counter(Create)=0; |IDLE
                              |retry_Counter(Query)=0;                     |Initialize variables     |
      ------------------------+-------------------------+------------

      ------------------- IDLE      |*
   ------------------------+-------------------------+-----------+---

   NOTE:
      * - Application triggered for forking process

   -----------
   State: IDLE
      -------------------
   -----------

   Condition                Action                    State
      ------------------------+-------------------------+------------      Note
   ------------------------+-------------------------+-----------+---
   tg_CREATE               |Start.STATE_TIMER(Resp);               |tx_CREATE                |WAITRESP2- |
         (sid, sig, pubkey)|      (sid, sig, pubkey);|    SESSION|
                           |Start.STATE_TIMER        |PENDING
                              |retry_Counter(Create)=0;    |
                              |tx_CREATE;
                           |
      ------------------------+-------------------------+------------
      -------------------              (Response);|           |
                           |                         |           |
   (tg_CREATE (sid))       |tx_CREATE (sid);         |WAITRESP1- |
                           |Start.STATE_TIMER        |    SESSION|
                           |              (Response);|PENDING    |
   ------------------------+-------------------------+-----------+---
   -----------
   State: WAITRESP-SESSION PENDING
      -------------------
   -----------

   Condition                Action                    State
      ------------------------+-------------------------+------------
      rx_RESP(SUCCESS,Create) |Stop.STATE_TIMER(Resp);  |ESTABLISHED
                              |Session.create();        |
                              |Start.REFRESH_TIMER(Cre);|
                              |retry_Counter(Create)=0; |      Note
   ------------------------+-------------------------+-----------+---
   TIMEOUT.STATE(Response) |Stop.STATE_TIMER         |WAITRESP-  |
                           |
      TIMEOUT.STATE(Resp)     |Stop.STATE_TIMER(Resp);              (Response);|    SESSION|
                           |retry_counter(Create)++; |PENDING
                              |retry_Counter(Create)++;    |
                           |if (retry_Counter(Create)|
                              |<=Max_Retry(Create)) (retry_counter(Create)|           |
                           |     <=Max_Retry(Create))|           |
                           |{Start_STATE_TIMER       |           |
                           |               (Response)|           |
                              |{Start.STATE_TIMER(Resp);|
                           |tx_CREATE;}              |           |
                           |
      (Retry_Counter(Create)                         |           |
   (rx_RESPONSE(SUCCESS,   |Stop.STATE_TIMER         |SESSION    |
                   Create))|              (Response);|ESTABLISHED|
                           |Session.create();        |           |
                           |Start.REFRESH_TIMER      |           |
                           |                (Create);|           |
                           |retry_counter(Create)=0; |           |
                           |                         |           |
   (Retry_Counter(Create)> |Send info to appl.;      |IDLE
      > Appl.;      | IDLE      |
      Max_Retry(Create)) |||Stop.STATE_TIMER         |           |
   (tg_TEARDOWN) || |Stop.STATE_TIMER(Resp);        |
      tg_TEARDOWN              (Response);|           |
   (rx_RESPONSE(ERROR,     |                         |           |
                   Create))|                         |           |
   ------------------------+-------------------------+-----------+

   -----------
   State: WAITRESP1-SESSION PENDING
   -----------

   Condition                Action                    State      Note
   ------------------------+-------------------------+-----------+---
   (TIMEOUT.STATE(Response)|Send info to Appl.;      |IDLE       |
   || (rx_RESPONSE(ERROR,  |                         |
      rx_RESP(ERROR,Create)           |
                   Create))|                         |
      ------------------------+-------------------------+------------

      -------------------           |
                           |                         |           |
   (rx_RESPONSE(SUCCESS,   |Tx_Create(sid, sig,      |WAITPKRESP-|
                   Create))|                 pubkey);|    SESSION|
                           |Start.STATE_TIMER        |PENDING    |
                           |              (Response);|           |
   ------------------------+-------------------------+-----------+---
   -----------
   State: WAITRESP2-SESSION PENDING
   -----------

   Condition                Action                    State      Note
   ------------------------+-------------------------+-----------+---
   (tr(RESPONSE(sid))      |tx_CREATE (sid);         |WAITRESP-  |
                           |Start.STATE_TIMER        |    SESSION|
                           |              (Response);|PENDING    |
                           |retry_counter(Create)=0; |           |
   ------------------------+-------------------------+-----------+---

   -----------
   State: WAITPKRESP-SESSION PENDING
   -----------

   Condition                Action                    State      Note
   ------------------------+-------------------------+-----------+---
   (tr(RESPONSE(sid))      |tx_CREATE (sid);         |WAITRESP-  |
                           |Start.STATE_TIMER        |    SESSION|
                           |              (Response);|PENDING    |
                           |retry_counter(Create)=0; |           |
   ------------------------+-------------------------+-----------+---

   -----------
   State: SESSION ESTABLISHED
      -------------------
   -----------

   Condition                Action                    State
      ------------------------+-------------------------+------------
      rx_RESP(SUCCESS,Query)  |Stop.STATE_TIMER(Query); |ESTABLISHED
      && CHECK_AA             |Send      Note
   ------------------------+-------------------------+-----------+---
   (rx_RESPONSE            |Stop.STATE_TIMER(QDRQ);  |SESSION    |
           (SUCCESS, QDRQ))|Send info to appl.;      |ESTABLISHED|
   && (CHECK_AA)           |                         |           |
      tg_QUERY                |tx_QUERY;                |ESTABLISHED
                              |Start.STATE_TIMER(Query);|
                              |retry_Counter(Query)=0;
                           |                         |           |
      rx_RESP(SUCCESS,Create) |Start.REFRESH_TIMER(Cre);|ESTABLISHED
                              |Stop.STATE_TIMER(Resp);
                           |
                              |retry_counter(Create)=0;                         |
   (rx_RESPONSE            |Stop.STATE_TIMER(QDRQ);  |SESSION    |
              (ERROR, QDRQ)|retry_counter(QDRQ)++;   |ESTABLISHED|
   || TIMEOUT_STATE(QDRQ)) |If (retry_counter(QDRQ)< |
      TIMEOUT.REFRESH(Cre)    |Start.STATE_TIMER(Resp); |ESTABLISHED           |
                           |          Max_Retry(QDRQ)|           |
                           |{Start.STATE_TIMER(QDRQ);|           |
                           |                tx_QDRQ;}|           |
                           |else{send info to appl.;}|           |
                           |                         |           |
   (tg_QDRQ)               |tx_QDRQ;                 |SESSION    |
                           |Start.STATE_TIMER(QDRQ); |ESTABLISHED|
                           |retry_counter(QDRQ)=0;   |           |
                           |                         |           |
   TIMEOUT.REFRESH(Create) |Start.STATE_TIMER        |SESSION    |
                           |              (Response);|ESTABLISHED|
                           |tx_CREATE;               |           |
                           |
      TIMEOUT.STATE(Resp)     |Stop.STATE_TIMER(Resp);  |ESTABLISHED
                              |retry_Counter(Create)++;                         |
                              |if (retry_Counter(Create)|           | <= Max_Retry(Create)) {
   TIMEOUT.STATE(Response) |Stop.STATE_TIMER         |SESSION    |
                           |              (Response);|ESTABLISHED|
                           |retry_counter(Create)++; |           |
                           |If (retry_counter(Create)|           |
                           |     <=Max_Retry(Create))|           |
                           |{Start.STATE_TIMER       |           |
                           |
                              |Start.STATE_TIMER(Resp);              (Response);|           |
                           |tx_CREATE;}              |           |
                           |
      rx_NOTIFY && CHECK_AA                         |           |
   (rx_RESPONSE(SUCCESS,   |Start.REFRESH_TIMER      |SESSION    |
                   Create))|                (Create);|ESTABLISHED|
                           |Stop.STATE_TIMER         |           |
                           |              (Response);|           |
                           |retry_counter(Create)=0; |           |
                           |                         |           |
   (rx_NOTIFY)&&(CHECK_AA) |Process Event();         |ESTABLISHED         |SESSION    |
                           |
      rx_RESP(ERROR,Query) || |Stop.STATE_TIMER(Query); |ESTABLISHED
      TIMEOUT.STATE(Query)    |retry_Counter(Query)++;                         |ESTABLISHED|
                           |
                              |if (retry_Counter(Query)                         |           | <= Max_Retry(Query)) {
   (tg_TEARDOWN)           |tx_CREATE(LIFETIME=0);   |IDLE       |
                              |Start.STATE_TIMER(Query);|
                              |tx_QUERY;} else {
                           |Session.clear();         |
                              |send info to appl.}           |
                           |Stop.REFRESH_TIMER       |           |
                           |                (Create);|           |
                           |Stop.STATE_TIMER(        |           |
                           |               Response);|           |
                           |                         |
      (retry_Counter(Create)           |
   (retry_counter(Create)> |Send info to appl.; Appl.;      |IDLE
      > Max_Rety(Create)) ||  |Session.clear();       |
      rx_RESP(ERROR,Create)   |Stop.REFRESH_TIMER(Cre);
     Max_Retries(Create) |||Session.clear();         |           |
   rx_RESPONSE(ERROR,      |Stop.REFRESH_TIMER       |
      tg_TEARDOWN             |tx_CREATE(LIFETIME=0);   |IDLE
                              |Session.clear();         |
                              |Stop.REFRESH_TIMER(Cre);           |
                              |Stop.STATE_TIMER(Resp);
                   Create))|                (Create);|           |
      ------------------------+-------------------------+------------
   ------------------------+-------------------------+-----------+

7.  State machines for the NAT/FW NF

   This section describes the state machines for intermediate nodes
   within the signaling path capable of processing NAT/FW NSLP messages.
   These nodes typically implement firewall and/or network address
   translation (NAT) functionality.  To keep it simple, the state
   machines are separated in two independent state machines for nodes
   with firewall and nodes with NAT functionality.

7.1  State machine for NAT/FW Firewall NF

      -------------------
      State: Initialize
      -------------------

      Condition                Action                    State
      ------------------------+-------------------------+------------
              UCT             | -                       |IDLE
      ------------------------+-------------------------+------------

   -------------------
   State: IDLE
   -------------------

      Condition                Action                    State
   ------------------------+-------------------------+------------
      rx_REA
   (rx_REA) && !(CHECK_AA)   |tx_RESP(ERROR,Rea); (!IS_EDGE)  |tx_REA;                  |IDLE
                           |                         |
      rx_RESP(Rea)            |tx_RESP(Rea);
   (rx_CREATE) &&          |tx_RESPONSE(ERROR,       |IDLE
   !(CHECK_AA)             |Create)                  |
                           |
      rx_REA                         |
   (rx_RESPONSE (,Rea))    |tx_RESPONSE (,Rea)       |IDLE
                           |                         |
   (rx_REA) && IS_EDGE       |tx_RESP(ERROR,Rea);  (*) (IS_EDGE)   |tx_RESPONSE(ERROR, Rea)  |IDLE
                           | "No NAT here"           |
      rx_REA
                           |                         |
   (rx_UCREATE) && !(IS_EDGE)    |tx_REA;         |tx_RESPONSE(ERROR,       |IDLE
   !(CHECK_AA)             |UCREATE);                |
                           |                         |
      rx_CREATE
   ((rx_CREATE(sid)) && CHECK_AA   |Start.STATE_TIMER(Resp);    |Start.STATE_TIMER        |WAITRESP1-
   (CHECK_AA)  &&          |(Response);              |SESSION/
   (!IS_PUBLICSIDE))       |tx_CREATE;               |USESSION
                           |                         |PENDING
                           |                         |
   (rx_UCREATE) &&         |tx_RESPONSE(SUCCESS,     |WAITRESP-
   (CHECK_AA)              |UCREATE);                |SESSION/US
                           |tx_CREATE;               |ESSION
                           |Retry_Counter(Create)=0; |PENDING
                           |Start.STATE_TIMER(Respons|
                           |e);                      |
                           |                         |
      rx_CREATE
   (rx_CREATE) && !(CHECK_AA)|tx_RESP(ERROR,Create);   |IDLE          |tx_RESPONSE(SUCCESS,     |NoNR/Scope-
   (CHECK_AA)              |Create),                 |WaitResponse
   && ((CREATE(NoNR?) &&   |tx_CREATE;               |
   CHECK_NoNR) ||          | Start.STATE_TIMER(Respon|
   CREATE(Scope?) &&       |se)                      |
   CHECK_Scope))           |                         |
   ------------------------+-------------------------+------------
      * REA Error message "No NAT here"
   -------------------
   State: PENDING NoNR/Scope-WaitResponse
   -------------------

      Condition                Action                    State
   ------------------------+-------------------------+------------
      rx_RESP(SUCCESS,Create) |Stop_STATE_TIMER(Resp);  |ESTABLISHED
                              |Session.create();
   (retry_Counter(Create)> |Send info to Appl.;      |IDLE
   Max_Retry(Create)) ||   |Stop.STATE_TIMER(Response|
   (tg_TEARDOWN))          |);                       |
                           |                         |
   rx_RESPONSE(SUCCESS,    |Stop.STATE_TIMER(Response|NoNR/Scope
   Create)                 |);                       |Sessions
                           |Session.create();        |Established
                           |PckFilter.create();      |
                              |Start.STATE_TIMER(Cre);
                           |Start.STATE_TIMER(Create)|
                           |;                        |
                           |Start.REFRESH_TIMER(Creat|
                           |eB);                     |
                           |retry_counter(Create)=0; |
                           |Retry_counter(CreateB)=0;|
   ------------------------+-------------------------+------------

   ------------------------------
   State: NoNR/ScopeSessions Established
   ------------------------------

      Condition                Action                    State
   ------------------------+-------------------------+------------
   (rx_CREATE) &&          |tx_RESPONSE_SUCCESS(Creat|NoNR/Scope
   (CHECK_AA) &&           |e);                      |Sessions
    [CHECK_LP] &&          |Start_STATE_TIMER(Create)|Established
   (CREATE(LIFETIME?)>0)   |;                        |
                           |                         |
   (tg_NOTIFY)             |tx_NOTIFY                |NoNR/Scope
                           |                         |Sessions
                           |                         |Established
                           |                         |
   (rx_CREATE) &&          |tx_RESPONSE(ERROR,       |NoNR/Scope
   !(CHECK_AA))            |Create);                 |Sessions
                           |                         |Established
                           |                         |
      rx_RESP(ERROR,Create)   |Stop.STATE_TIMER(Resp);
   (rx_RESPONSE(ERROR,     |Stop.STATE_TIMER(Response|NoNR/Scope
   Create) ||              |);                       |Sessions
    TIMOUT.STATE(Response))|retry_counter(Create)++; |Established
                           | if                      |
                           |(retry_counter(Create)<=M|
                           |ax_Retry(Create))        |
                           |{Start.STATE_TIMER(Respon|
                           |se);                     |
                           |tx_CREATE;}              |
                           |                         |
   (rx_QDRQ) &&  (CHECK_AA)|Process QDRQ();          |NoNR/Scope
                           | tx_RESPONSE (,QDRQ)     |Sessions
                           |                         |Established
                           |                         |
   (TIMEOUT.REFRESH(CreateB|retry_counter(CreateB)++;|NoNR/Scope
   ))                      |If                       |Sessions
                           |(retry_counter(CreateB)<=|Established
                           |Max_retries)             |
                           |{tx_CREATE;              |
                           |Start.TIMER_STATE(Respons|
                           |eB);}                    |
                           |                         |
   (tg_TEARDOWN) ||        |Session.clear();         |IDLE
   ((rx_CREATE)  &&        |PckFilter.clear();       |
   (CREATE(LIFETIME?)==0)) |Stop.STATE_TIMER(Create);|
   || TIMEOUT.STATE(Resp)                      | Stop.REFRESH_TIMER(Creat|
   TIMEOUT_STATE(Create) |||eB);                     |
   (retry_counter(CreateB)>|tx_CREATE(LIFETIME=0);   |
   Max_Retries(CreateB)) |||                         |
   ||                      |                         |
   (retry_counter(Create)> |                         |
   Max_Retries(Create))    |                         |
   ------------------------+-------------------------+------------
      -------------------

   ------------------------------
   State: ESTABLISHED
      ------------------- WAITRESP1-SESSION/USESSION PENDING
   ------------------------------

      Condition                Action                    State
   ------------------------+-------------------------+------------
      rx_CREATE
   ((rx_RESPONSE(success)) |Session.create();        |WAITPKRESP-
   && !(CHECK_AA)|tx_RESP(ERROR,Create);   |ESTABLISHED (CHECK_AA)           |Start.STATE_TIMER        |SESSION/
                           |(Response);              |USESSION
                           |tx_RESPONSE; Scheme = 1  |PENDING
                           |                         |
   (TIMEOUT.STATE(Response)|                         |IDLE
   ------------------------+-------------------------+------------
   -----------------------------------
   State: WAITPKRESP-SESSION/USESSION PENDING
   -----------------------------------

      Condition                Action                    State
   ------------------------+-------------------------+------------
   ((rx_RESPONSE(success)) |pubkey.create();         |WAITRESP-
   && (CHECK_AA)           |Start.STATE_TIMER        |SESSION/
                           |(Response);              |USESSION
                           |tx_RESPONSE;             |PENDING
                           |                         |
      rx_TRIGGER
   (TIMEOUT.STATE(Response)|Session.remove()         |IDLE
   && CHECK_AA  |tx_TRIGGER;              |ESTABLISHED (scheme ==2)         |                         |
   ------------------------+-------------------------+------------
   ----------------------------------------
   State: WAITRESP-SESSION/USESSION PENDING
   ----------------------------------------

      Condition                Action                    State
   ------------------------+-------------------------+------------
   (TIMEOUT.STATE(Response)|Retry_counter(CREATE)++; |WAITRESP-
                           |If                       |SESSION/
                           |(retry_counter(CREATE)<=M|USESSION
                           |ax_Retries(CREATE))      |PENDING
                           |{Start.STATE_TIMER(Respon|
                           |se); tx_CREATE}          |
                           |                         |
   (rx_RESPONSE(SUCCESS,   |Stop.STATE_TIMER(Response|SESSION
   CREATE) from NR)        |);                       |ESTA-
   && !IS_EDGE (CHECK_AA)           |Session.create();        |BLISHED
                           |PckFilter.create();      |
                           |Start.REFRESH_TIMER(Creat|
                           |e);                      |
                           |tx_RESPONSE(SUCCESS,     |
                           |Create);                 |
      rx_RESP(SUCCESS,Create) |Start.STATE_TIMER(Cre);  |ESTABLISHED
                              |tx_RESP(SUCCESS,Create);
                           |                         |
   (TIMEOUT.STATE(Response)|Pubkey.remove()          |WAITPKRESP
                           |                         |-SESSION/
                           |                         |USESSION
                           |                         |PENDING
                           |                         |
   (rx_RESPONSE(ERROR,     |Stop.STATE_TIMER(Response|IDLE
   Create) ||              |);                       |
    if(Retry_counter)>Max_R|Send info to appl.       |
   etries(CREATE)          |                         |
                           |
      rx_QUERY                         |
   (rx_RESPONSE(SUCCESS,   |Stop.STATE_TIMER(Response|SESSION
   Create) from NI)        |);                       |ESTA-
   && CHECK_AA    |Process Query(); (CHECK_AA)           |Session.create();        |BLISHED
                           |PckFilter.create();      |
                           |Start.STATE_TIMER(Create)|
                           |;                        |
                           |tx_RESPONSE(SUCCESS,     |
                           |Create);                 |
   ------------------------+-------------------------+----------

   --------------------------
   State: SESSION ESTABLISHED
   --------------------------

      Condition                Action                    State

   ------------------------+-------------------------+------------
   (rx_RESPONSE (,QDRQ)) &&|tx_RESPONSE(.QDRQ)       |SESSION
    (CHECK_AA)             |                         |ESTABLISHED
                              |tx_QUERY;
                           |                         |
   (tg_NOTIFY)             |tx_NOTIFY                |SESSION
                           |
      rx_CREATE && CHECK_AA   |tx_CREATE;                         |ESTABLISHED
                           |                         |
   (rx_NOTIFY) && CREATE(LIFETIME?)>0          |Process Event(),         |SESSION
   (CHECK_AA)              |tx_NOTIFY                |ESTABLISHED
                           |                         |
   (rx_CREATE) &&          |tx_RESPONSE(ERROR,       |SESSION
    !(CHECK_AA)            |Create);                 |ESTABLISHED
                           |                         |
      rx_RESP(,Query)
   (rx_TRIGGER) &&         |tx_TRIGGER               |SESSION
   (Check_AA)  &&      |tx_RESP(,Query);          |                         |ESTABLISHED
      CHECK_AA
   (!IS_EDGE)              |                         |
                           |                         |
      tg_NOTIFY               |tx_NOTIFY;
   (rx_RESPONSE(SUCCESS,   |Start.STATE_TIMER(Create)|SESSION
   Create))                |; tx_RESPONSE(SUCCESS,   |ESTABLISHED
                           |Create);                 |
                           |Stop.STATE_TIMER(Response|
                           |);                       |
                           |retry_counter(Create)=0; |
                           |                         |
      rx_NOTIFY
   (rx_QDRQ) && CHECK_AA   |Process Event();  (CHECK_AA)|Process QDRQ(); tx_QDRQ  |SESSION
                           |                         |ESTABLISHED
                              |tx_NOTIFY;
                           |                         |
   TIMEOUT.STATE(Response) |Stop.STATE_TIMER(Response|SESSION
                           |);                       |ESTABLISHED
                           |retry_counter(Create)++; |
      TIMEOUT.STATE(Cre) ||   |Session.clear();         |IDLE
      tg_TEARDOWN             |PckFilter.clear();
                           |If                       |
                           |(retry_counter(Create)<=M|
                           |ax_Retries(Create))      |
                           |{Start.STATE_TIMER(Respon|
                           |se); tx_CREATE;}         |
                           |                         |
   (TIMEOUT.REFRESH        |Start.STATE_TIMER(Respons|SESSION
   (Create))               |e);                      |ESTABLISHED
                           |tx_CREATE;               |
                           |                         |
      rx_CREATE
   (rx_CREATE) && CHECK_AA   |tx_CREATE(LIFETIME=0);   |IDLE          |tx_CREATE                |SESSION
   (CHECK_AA) && CREATE(LIFETIME?)==0           |                         |ESTABLISHED
   (CREATE(LIFETIME?)>0)   |                         |
                           |                         |
   (TIMEOUT.STATE (Create) |Stop.REFRESH_TIMER(Create|IDLE
   || (tg_TEARDOWN) ||     |);                       |
   (retry_counter(Create)> |Session.clear();         |
   Max_Retries(Create) ||  |PckFilter.clear();       |
                              |Stop.STATE_TIMER(Cre);
   rx_RESPONSE(ERROR,      |Send info to Appl.;      |
   Create))                |                         |
   ------------------------+-------------------------+------------

7.2  State machine for NAT/FW NAT NF

   -------------------
   State: Initialize
   -------------------

      Condition                Action                    State
   ------------------------+-------------------------+------------
                 UCT             |Retry_Counter(Create)=0;       |                         |IDLE
   ------------------------+-------------------------+------------
   -------------------
   State: IDLE
   -------------------

      Condition                Action                    State
   ------------------------+-------------------------+------------
      rx_CREATE
   rx_REA && (CHECK_AA)    |tx_RESPONSE(ERROR, REA)  |IDLE
     &&            |tx_RESP(ERROR,Rea);  (*1)|IDLE
      IS_PUBLICSIDE (IS_PUBLICSIDE)    |  "No reservation made"  |
                           |                         |
   rx_REA&& (IS_PUBLICSIDE)|tx_RESPONSE(ERROR, REA)  |IDLE
                           |  "Rea on public side"   |
                           |                         |
   rx_REA && CHECK_AA (CHECK_AA)    |Binding_create();        |REA
     &&   |tx_RESP(ERROR,Rea);  (*2)|IDLE (I _EDGE) && IS_PUBLICSIDE       |  Start.STATE_TIMER(Rea);|
     (!IS_ UBLICSIDE)      |  Start.REFRESH_TIMER(Create);
                           |  tx_RESPONSE(SUCCESS, Rea);
                           |
      rx_REA && CHECK_AA                         |
                           |  Start.STATE_TIMER(Response);
                           |  tx_CREATE              |
                           |                         |
                           |                         |
   rx_UCREATE &&   |Binding.create();        |NonEDGE REA
      !IS_EDGE                |tx_REA; (CHECK_AA)|tx_RESPONSE(SUCCESS,UCREA|WAITRESP-
                           |TE);tx_CREATE;           | SESSION/
                           |  Retry_counter(Create)=0| USESSION
                           |  Start.STATE_TIMER(Respo| PENDING
                           |
                              |Start_STATE_TIMER(Rea);  nse)                   |
                           |                         |
   rx_REA && CHECK_AA &&   |Binding.create();        |REA
      IS_EDGE (CHECK_AA)    |Binding_create();        |Non-edge
     &&(!IS_EDGE) &&              |Start.STATE_TIMER(Rea);       |
      !IS_PUBLICSIDE          |tx_RESP(SUCCESS,Rea);  PckFilter.create();    |
                              |retry_Counter(Create)=0; NAT Binding
     (!IS_PUBLICSIDE)      |
                              |Start.STATE_TIMER(Resp);  Start.STATE_TIMER(Rea);|
                           |
                              |tx_CREATE;  tx_REA;                |
                           |                         |
      rx_CREATE
   (rx_CREATE(sid)         |Start.STATE_TIMER(Respons|WAITRESP-
   && CHECK_AA   |Binding.create();        |PENDING (CHECK_AA)           |e); tx_CREATE(); scheme=1| SESESION
   && !IS_PUBLICSIDE       |Start.STATE_TIMER(Resp); (!US_PUBLICSIDE))    |                         |
                           |                         |
   (rx_CREATE(sid,sig,     |Start.STATE_TIMER(Respons|WAITRESP-
   pubkey)) && (CHECK_AA)  |e); tx_CREATE(); scheme=2| SESSION/
   && (!US_PUBLICSIDE))    |                         | USESSION
                           |
                              |tx_CREATE;                         | PENDING
   ------------------------+-------------------------+------------
      *1 Error message is "No reservation made"
      *2 Error message is "REA received on public side"
   -------------------
   State: NonEDGE REA
   -------------------

      Condition                Action                    State
   ------------------------+-------------------------+------------
      rx_RESP(,Query) &&      |tx_RESP(,Query);         |NonEDGE REA
      CHECK_AA
   TIMEOUT.STATE(Create)   |Start.STATE_TIMER(Rea);  |REA
                           |  Start.STATE_TIMER(Respo|
                           |  nse); tx_CREATE;       |
                           |  Retry_Counter(Create)=0|
                           |
      rx_QUERY                         |
   rx_QDRQ && CHECK_AA    |Process Query();         |NonEDGE REA
                              |tx_QUERY; (CHECK_AA)   |tx_RESPONSE(QDRQ)        |
                           |                         |
      tx_TRIGGER && CHECK_AA  |PckFilter.update();      |NonEDGE REA
                              |Start.STATE_TIMER(Rea);
   rg_Notify               |tx_Notify                |
                              |tx_TRIGGER;
                           |                         |
   TIMEOUT.STATE(Response) |Stop.STATE_TIMER(Response)|REA
                           | Retry_Counter(Create)++;|
                           | If(Retry_Counter(Create)|
                           | <=Max_Retry(Create)) {  |
                           | tx_CREATE;              |
                           | Start.STATE_TIMER(Respon|
                           |
      rx_CREATE se); }                  |
                           |                         |
   rx_RESPONSE(from NI) && CHECK_AA   |Stop.STATE_TIMER(Rea);   |PENDING
                              |Start.STATE_TIMER(Resp); |Start.STATE_TIMER(Respons|WAITRESP-
    (CHECK_AA)             |
                              |tx_CREATE; e); Stop.REFRESH_TIMER  | REA+NI-
                           | (Create); tx_CREATE;    | SESSION
                           |                         | PENDING
                           |                         |
   rx_RESPONSE(SUCCESS,    |Stop.STATE_TIMER(Response);|REA
    Create)                |Start.REFRESH_TIMER(Create)|
                           |                         |
   TIMEOUT.STATE(Rea) ||      |Binding.clear();         |IDLE
      rx_RESPONSE(ERROR,Rea)  |PckFilter.clear();       |
   ------------------------+-------------------------+------------
   -------------------
   State: REA WAITRESP-REA+NI-SESSION PENDING
   -------------------

      Condition                Action                    State
   ------------------------+-------------------------+------------
      TIMEOUT.STATE(Rea) ||   |Binding.clear();         |IDLE
      rx_RESP(ERROR,Create)
   rx_RESPONSE(ERROR,      |                         |
                              |                         |
      rx_RESP(SUCCESS,Create) |Stop.STATE_TIMER(Resp);                         |REA
     Create)||TIMEOUT.STATE|                         |
    (Response)             |
      rx_CREATE &&            |Start.STATE_TIMER(Resp); |NI-PENDING
      CREATE(SOURCE?)==NI &&  |tx_CREATE;                         |
      CHECK_AA
                           |                         |
   rx_RESPONSE(SUCCESS,    |Stop.STATE_TIMER         |
    Create)                |
      TIMEOUT.STATE(Resp)     |Stop.STATE_TIMER(Resp);  |REA
                              |retry_Counter(Create)++; (Response);             |
                              |if (retry_Counter(Create)|
                           | <= Max_Retry(Create)) { Session.clear();        |
                              |tx_CREATE;
                           |
                              |Start.STATE_TIMER(Resp);}| Session.create();       |
                           |
      rx_TRIGGER && CHECK_AA  |Start.STATE_TIMER(Rea);  |REA
                              |Start.STATE_TIMER(Resp); PckFilter.create();     |
                              |retry_Counter(Create)=0;
                           |
                              |PckFilter.update(); Start_STATE_TIMER       |
                              |tx_CREATE;
                           |  (Create);              |
                           |
      tg_NOTIFY               |tx_NOTIFY;               |REA tx_REPONSE(SUCCESS,     |
                           |
      rx_QUERY && CHECK_AA    |tx_RESPONSE(,Query);     |REA   Create);              |
   ------------------------+-------------------------+------------

      -------------------
   State: WAITRESP1-SESSION/USESSION PENDING
   -------------------

      Condition                Action                    State
   ------------------------+-------------------------+------------
      rx_RESP(SUCCESS,Create) |Stop.STATE_TIMER(Resp);  |ESTABLISHED
                              |Start.STATE_TIMER(Cre);
    TIMEOUT.STATE(Response)|                         |IDLE
                           |                         |
   ((rx_RESPONSE(success)) |Session.create();        |WAITPKRESP-
   && (CHECK_AA)           |Start.STATE_TIMER        |SESSION/
                           |(Response);              |USESSION
                           |tx_RESPONSE; Scheme = 1  |PENDING
   ------------------------+-------------------------+------------
   --------------------------
   State: WAITPKRESP-SESSION/USESSION PENDING
   --------------------------

      Condition                Action                    State
   ------------------------+-------------------------+------------
   (TIMEOUT.STATE(Response)|Session.remove()         |IDLE
   && (scheme ==2))        |
                              |PckFilter.create();                         |
                              |tx_RESP(SUCCESS,Create);
                           |                         |
   ((rx_RESPONSE(success)) |pubkey.create();         |WAITRESP-
   && (CHECK_AA)           |Start.STATE_TIMER        |SESSION/
                           |(Response);              |USESSION
                           |tx_RESPONSE;             |PENDING
                           |                         |
      rx_RESP(ERROR,Create)   |Binding.remove();        |IDLE
      || TIMEOUT.STATE(Resp)
   (TIMEOUT.STATE(Response)| Session.remove()        |WAITRESP1-
   && (scheme ==1)         |                         |SESSION/
                           |                         |USESSION
                           |                         |PENDING
   ------------------------+-------------------------+------------

      -------------------

   --------------------------
   State: NI-PENDING
      ------------------- WAITRESP-SESSION/USESSION PENDING
   --------------------------
      Condition                Action                    State
   ------------------------+-------------------------+------------
      rx_RESP(SUCCESS,Create) |Stop.STATE_TIMER(Resp);  |ESTABLISHED
                              |Session.clear();
   (rx_RESPONSE(ERROR,     |Stop.STATE_TIMER(Response|IDLE
   Create) ||              |);                       |
                              |Session.create();
                           |
                              |PckFilter.create();                         |
                              |Start.STATE_TIMER(Cre);
   (TIMEOUT.STATE(Response)|Pubkey.remove()          |WAITPKRESP-
                           |
                              |tx_RESP(SUCCESS,Create);                         |SESSION/
                           |                         |USESSION
                           |                         |PENDING
                           |
      rx_RESP(ERROR,Create)                         | -                       |REA
      || TIMEOUT.STATE(Resp)
   (rx_RESPONSE(SUCCESS,   |Stop.STATE_TIMER(Response|SESSION
   CREATE) from NR)        |);                       |ESTA-
   && (CHECK_AA)           |Session.create();        |BLISHED
                           |PckFilter.create();      |
                           |Start.REFRESH_TIMER(Creat|
                           |e);                      |
                           |tx_RESPONSE(SUCCESS,     |
                           |Create);                 |
   ------------------------+-------------------------+------------
      -------------------
   --------------------------
   State: ESTABLISHED
      ------------------- Non-edge NAT Binding
   --------------------------

      Condition                Action                    State
   ------------------------+-------------------------+------------
      rx_CREATE && !(CHECK_AA)|tx_RESP(ERROR,Create);   |ESTABLISHED
   (TIMEOUT.STATE (Rea) || |Binding.clear();         |IDLE
     rx_RESPONSE(ERROR,    |PckFilter.clear();       |
     Rea))                 |                         |
                           |                         |
   (rx_RESPONSE (,QDRQ)) &&|tx_RESPONSE(,QDRQ);      |Non-edge
   (CHECK_AA)              |                         |NAT Binding
                           |
      rx_QUERY                         |
   (rx_QDRQ) && CHECK_AA (CHECK_AA) |Process Query();         |ESTABLISHED
                              |tx_QUERY; QDRQ();  tx_QDRQ;|Non-edge
                           |                         |NAT Binding
                           |                         |
   (rx_TRIGGER) &&         |PckFilter.update();      |Non-edge
   (CHECK_AA)              |Start.STATE_TIMER(Rea);  |NAT Binding
                           |tx_TRIGGER;              |
                           |                         |
      TIMEOUT.STATE(Cre)
   (rx_CREATE) &&          |Stop.STATE_TIMER(Rea);   |WAITRESP-
   (CHECK_AA)              |Start.STATE_TIMER        |SESSION/
                           |(Response);              |USESSION
                           |tx_CREATE;               |PENDING
   ------------------------+-------------------------+------------

   --------------------------
   State: SESSION ESTABLISHED
   --------------------------

      Condition                Action                    State
   ------------------------+-------------------------+------------
   (TIMEOUT.STATE (Create) |Stop.REFRESH_TIMER(Create|IDLE
   || (tg_TEARDOWN) ||     |);                       |
   (retry_counter(Create)> |Session.clear();         |IDLE
      tg_TEARDOWN             |send         |
   Max_Retries(Create) ||  |PckFilter.clear();       |
   rx_RESPONSE(ERROR,      |Send info to appl.; Appl.;      |
   Create))                |                         |
                           |                         |
      rx_CREATE
   ((rx_CREATE) && CHECK_AA         |tx_CREATE(LIFETIME=0);   |IDLE
   (CHECK_AA) && CREATE(LIFETIME?)==0           |Session.clear();         |
                              |PckFilter.clear();
   (CREATE(LIFETIME)==0))  |PckFilter.clear();?Stop.S|
                           |TATE_TIMER(Create);      |
                           |Stop.REFRESH_TIMER(Create|
                           |);                       |
                           |Stop.STATE_TIMER(Response|
                           |);                       |
                           |
      rx_TRIGGER                         |
   (rx_TRIGGER) && !IS_EDGE         |PckFilter.update();      |ESTABLISHED      |SESSION
    (!IS_EDGE) && CHECK_AA          |tx_TRIGGER;              |ESTABLISHED
   (CHECK_AA)              |                         |
                           |                         |
      rx_RESP(,Query)
   (rx_QDRQ) &&      |tx_RESP(,Query);  (CHECK_AA)|Process QDRQ();  tx_QDRQ;|SESSION
                           |                         |ESTABLISHED
      CHECK_AA
                           |                         |
   (tg_NOTIFY)             |tx_NOTIFY;               |SESSION
                           |                         |ESTABLISHED
                           |                         |
      rx_NOTIFY
   (rx_CREATE) && CHECK_AA   |Process Event();          |tx_RESPONSE(ERROR,       |SESSION
   !(CHECK_AA)             |Create);                 |ESTABLISHED
                              |tx_NOTIFY;
                           |                         |
   rx_RESPONSE(ERROR,      |tx_RESPONSE(ERROR,       |SESSION
   Create)                 |Create);                 |ESTABLISHED
                           |
      tg_NOTIFY               |tx_NOTIFY;                         |
   (rx_RESPONSE(SUCCESS,   |Start.STATE_TIMER(Create)|SESSION
   Create))                |; tx_RESPONSE(SUCCESS,   |ESTABLISHED
                           |Create);                 |
                           |Stop.STATE_TIMER(Response|
                           |);                       |
      rx_CREATE && CHECK_AA   |PckFilter.update();
                           |retry_counter(Create)=0; |
                           |                         |
   rx_RESPONSE(SUCCESS,    |Start.STATE_TIMER(Create)|SESSION
   Create)                 |; tx_RESPONSE(SUCCESS,   |ESTABLISHED
                           |Create);                 |
                           |                         |
   TIMEOUT.STATE(Response) |Stop.STATE_TIMER(Response|SESSION
                           |);                       |ESTABLISHED
                           |retry_counter(Create)++; |
                           |If                       |
                           |(retry_counter(Create)<=M|
                           |ax_Retries(Create))      |
                           |{Start.STATE_TIMER(Respon|
                           |se); tx_CREATE;}         |
                           |                         |
   rx_CREATE) && CREATE(LIFETIME?)>0  |tx_CREATE;           |PckFilter.update():      |SESSION
   CREATE(LIFETIME?)>0)  &&|tx_CREATE;               |ESTABLISHED
   CHECK_AA)               |                         |
                           |                         |
      rx_RESP(SUCCESS,Create) |Start.STATE_TIMER(Cre);
   (rx_NOTIFY) &&          |Process                  |SESSION
   (CHECK_AA)              |Event(); tx_NOTIFY;      |ESTABLISHED
                              |tx_RESP(SUCCESS,Create);
                           |                         |
   (rx_RESPONSE (QDRQ)) && |tx_RESPONSE (QDRQ);      |SESSION
   (CHECK_AA)              |
      rx_RESP(ERROR,Create)   |tx_RESP(ERROR,Create);                         |ESTABLISHED
   ------------------------+-------------------------+------------

8.  State machine for the NAT/FW NR

   This section presents the state machines for the NSIS responder which
   is capable of NSLP NAT/FW signaling

      -------------------

   -----------
   State: Initialize
      ------------------- INITIALIZE
   -----------

   Condition                Action                    State
      ------------------------+-------------------------+------------      Note
   ------------------------+-------------------------+-----------+---
   UCT (*)         |Retry_Counter(REA)=0;    |IDLE
      ------------------------+-------------------------+------------                     |Initialize variables     | IDLE      |*
   ------------------------+-------------------------+-----------+---

   NOTE:
      * Triggered by application when - Application triggered for forking process

      -------------------

   -----------
   State: IDLE
      -------------------
   -----------

   Condition                Action                    State
      ------------------------+-------------------------+------------
      rx_CREATE      Note
   ------------------------+-------------------------+-----------+---
   ((rx_CREATE(sid)) && CHECK_AA   |tx_RESP(SUCCESS,Create); |ESTABLISHED
                              |Start.STATE_TIMER(Cre);    |Start.STATE_TIMER        |WAITRESP1- |
                              |Session.start();
   (CHECK_AA)  &&          |
                              |PckFilter.create();              (Response);|  SESSION/ |
   (!IS_PUBLICSIDE))       |tx_CREATE;               |USESSION   |
                              |Send info to appl.
                           |                         |PENDING    |
                           |
      tg_REA                  |tx_REA;                         |           |
   (rx_CREATE)&&!(CHECK_AA)|tx_RESPONSE(ERROR,       |IDLE       |
                           |                 Create);|           |
                           |                         |           |
   (tg_UCREATE)            |(tx_UCREATE);            |WAITRESP - |
                           |retry_counter(UCREATE)=0;|   UCREATE/|
                           |Start.STATE_TIMER        |REA PENDING
                              |retry_Counter(REA)=0; PENDING|
                           |
                              |Start.STATE_Timer(Resp);              (Response);|           |
                           |                         |
      rx_CREATE && !(CHECK_AA)|tx_RESP(ERROR,Create);   |IDLE
      ------------------------+-------------------------+------------
      -------------------           |
   (tg_REA)                |tx_REA;                  |WAITRESP - |
                           |retry_counter(REA)=0;    |   UCREATE/|
                           |Start.STATE_TIMER        |REA PENDING|
                           |              (Response);|           |
   ------------------------+-------------------------+-----------+
   -----------
   State: REA WAITRESP -UCREATE/REA PENDING
      -------------------
   -----------

   Condition                Action                    State
      ------------------------+-------------------------+------------
      rx_RESP(SUCCESS,Rea)    |Stop.STATE_TIMER(Resp);  |TRIG PENDING
                              |Start.STATE_TIMER(Cre);      Note
   ------------------------+-------------------------+-----------+---
   (Retry_counter(REA)>    |Send info to Appl.;      | IDLE      |
       Max_Retries(REA)) |||                         |
      TIMEOUT.STATE(Resp)     |retry_Counter(REA)++;           |
   try_counter(UCREATE)>   |                         |           |
   Max_Retries(UCREATE)) |||                         |           |
   rx_RESPONSE             |                         |           |
       (ERROR, UCREATE)) |||                         |           |
   rx_RESPONSE(ERROR, Rea))|                         |           |
                           |                         |           |
   TIMEOUT.STATE(Response))|Retry_counter            |WAITRESP - |
                           |         (REA/UCREATE)++;|   UCREATE/|
                           |If (retry_counter        |REA PENDING
                              |if (retry_Counter(REA) PENDING|
                           |          (REA/UCREATE)<=|           | <= Max_Retry(REA)) {
                           |Max_Retry(REA/UCREATE))  |
                              |Start.STATE_TIMER(Resp);           |
                              |tx_REA;}
                           |{Start.STATE_TIMER       |           |
                           |
      (retry_Counter(REA) >   |Send info to appl.;      |IDLE
      Max_Retry(REA)) ||              (Response);|           |
                           |tx_REA/tx_UCREATE}       |
      rx_RESP(ERROR,Rea)           |
                           |
      ------------------------+-------------------------+------------

      -------------------                         |           |
   (rx_RESPONSE            |Stop.STATE_TIMER         |TRIGGERED  |
         (SUCCESS, REA)) |||              (Response);|CREATE/    |
   (rx_RESPONSE            |Start.STATE_TIMER        |    UCREATE|
        (SUCCESS, UCREATE))|                (CREATE);|PENDING    |
   ------------------------+-------------------------+-----------+
   -----------
   State: TRIG TRIGGERED CREATE/UCREATE PENDING
      -------------------
   -----------

   Condition                Action                    State
      ------------------------+-------------------------+------------
      TIMEOUT.STATE(Cre)      |Send      Note
   ------------------------+-------------------------+-----------+---
   (Retry_counter(Create)> | Send info to appl.;      |IDLE     | IDLE      |
        Max_Retries(Create)|                         |           |
                           |                         |           |
   (rx_CREATE)&& (CHECK_AA)|tx_RESPONSE              |SESSION    |
                           |       (SUCCESS, Create);|ESTABLISHED|
                           |Stop.STATE_TIMER(CREATE);|           |
      rx_CREATE && CHECK_AA   |tx_RESP(SUCCESS,Create); |ESTABLISHED
                           |Session.create();        |           |
                           |PckFilter.create();      |           |
                           |Send info Info to appl.; Appl.       |WAITRESP - |
                              |Start.STATE_TIMER(Cre);
                           |((Start.REFRESH_TIMER    |
                              |Start.REFRESH_TIMER(Trg);|
      ------------------------+-------------------------+------------
      -------------------     REATE/|
                           |               (UCreate);|REA PENDING|
                           |retry_counter            |           |
                           |           (UCreate)=0;))|           |
                           |                         |           |
   (TIMEOUT.STATE(CREATE)  |Retry_counter(CREATE)++; |TRIGGERED  |
                           |If (retry_counter(CREATE)|CREATE/    |
                           |   <=Max_Retries(CREATE))|    UCREATE|
                           |{Start.STATE_TIMER       |PENDING    |
                           |                (CREATE)}|           |
   ------------------------+-------------------------+-----------+

   -----------
   State:  SESSION ESTABLISHED
      -------------------
   -----------

   Condition                Action                    State
      ------------------------+-------------------------+------------
      (rx_CREATE      Note
   ------------------------+-------------------------+-----------+---
   (tg_NOTIFY)             |tx_NOTIFY;               |SESSION    |
                           |                         |ESTABLISHED|
                           |                         |           |
   (rx_NOTIFY) &&(CHECK_AA)|Process Event();         |SESSION    |
                           |                         |ESTABLISHED|
                           |                         |           |
   (rx_QDRQ) &&           |Session.session();       |IDLE
      CREATE(LIFETIME?)==0 (CHECK_AA) |Process QDRQ();          |SESSION    |
                           |tx_RESPONSE              |ESTABLISHED|
                           |         (SUCCESS,Query);|           |
                           |                         |           |
   (rx_RESPONSE            |Start.REFRESH_TIMER      |SESSION    |
         (SUCCESS,UCreate))|                (Create);|ESTABLISHED|
                           |Stop.STATE_TIMER         |           |
                           |              (Response);|           |
                           |retry_counter(UCreate)=0;|           |
                           |                         |           |
   (TIMEOUT.REFRESH        |Start.STATE_TIMER        |SESSION    |
                 (UCreate))|              (Response);|ESTABLISHED|
                           |tx_UCREATE;              |           |
                           |                         |           |
                           |                         |           |
   (rx_CREATE) && |PckFilter.clear();          |tx_RESPONSE(SUCCESS,     |SESSION    |
      CHECK_AA)
       (CREATE(LIFETIME)>0)|                 Create);|ESTABLISHED|
   && (CHECK_AA)           |Start.STATE_TIMER        |           |
                           |                (Create);|           |
                           |                         |           |
   TIMEOUT.STATE(Response) |Stop.STATE_TIMER         |SESSION    |
   || rx_RESPONSE(ERROR,   |              (Response);|ESTABLISHED|
                  UCreate))|retry_counter(UCreate)++;|           |
                           |If(retry_counter(UCreate)|           |
                           |  <=Max_Retries(UCreate))|           |
                           |{Start.STATE_TIMER       |           |
                           |              (Response);|           |
                           |tx_UCREATE;}             |           |
                           |                         |           |
   (rx_CREATE)&&!(CHECK_AA)|tx_RESPONSE(ERROR,       |SESSION    |
                           |                 Create);|ESTABLISHED|
                           |                         |           |
   (rx_CREATE) &&          |Session.clear();         | IDLE      |
      (CREATE(LIFETIME)==0)|PckFilter.clear();       |           |
   && (CHECK_AA)) ||       |Send info Info to appl.; Appl.;      |           |
   (TIMEOUT.STATE(Create)) |                         |
      TIMEOUT.STATE(Cre)           |
   ||(tg_TEARDOWN) ||      |                         |
      tg_TEARDOWN           |
   (retry_counter(UCreate)>|                         |           |
   Max_Retries(UCreate)    |
      TIMEOUT.REFRESH(Trg)    |tx_TRIGGER;              |ESTABLISHED
                              |Start.REFRESH_TIMER(Trg);|                         |           |
      rx_QUERY && CHECK_AA    |Process Query();         |ESTABLISHED
                              |tx_RESP(,Query);
   ------------------------+-------------------------+-----------+
   -----------
   State:  WAITPKRESP-SESSION/ USESSION PENDING
   -----------

   Condition                Action                    State      Note
   ------------------------+-------------------------+-----------+---
   (rx_CREATE) &&(CHECK_AA)|tx_RESPONSE(SUCCESS,     |SESSION    |
                           |                 Create);|ESTABLISHED|
                           |Start.STATE_TIMER        |           |
                           |                (Create);|           |
                           |Session.create();        |           |
                           |PckFilter.create();      |           |
                           |Send Info to Appl.       |           |
                           |                         |           |
   (TIMEOUT.STATE(Response)|Session.remove()         |WAITRESP1- |
      rx_CREATE &&            |if (CREATE(SOURCE?)!=NF){|ESTABLISHED
      CREATE(LIFETIME?)>0
            &&  |Stop.REFRESH_TIMER(Trg);}|
      CHECK_AA                |tx_RESP(SUCCESS,Create); (scheme ==1)|                         |   SESSION/|
                           |                         |USESSION   |
                           |                         |PENDING    |
                           |
                              |Start.STATE_TIMER(Cre);                         |           |
   (TIMEOUT.STATE(Response)|Session.remove()         |  IDLE     |
      rx_CREATE
            && !(CHECK_AA)|tx_RESP(ERROR,Create);   |ESTABLISHED (scheme ==2)|                         |           |
      rx_NOTIFY
   ------------------------+-------------------------+-----------+

   -----------
   State:  WAITRESP1-SESSION/ USESSION PENDING
   -----------

   Condition                Action                    State      Note
   ------------------------+-------------------------+-----------+---
   ((rx_RESPONSE(success)) |Session.create();        |WAITPKRESP-|
              && CHECK_AA   |Process Event();         |ESTABLISHED (CHECK_AA)|Start.STATE_TIMER        |   SESSION/|
                           |
      tg_NOTIFY               |tx_NOTIFY;               |ESTABLISHED
      ------------------------+-------------------------+------------              (Response);|USESSION   |
                           |tx_RESPONSE;  Scheme = 1;|PENDING    |
                           |                         |           |
   (TIMEOUT.STATE(Response)|                         |  IDLE     |
   ------------------------+-------------------------+-----------+

9.  Security Considerations

   This document does not raise new security considerations.  Any
   security concerns with the NAT/FW NSLP are likely reflected in
   security related NSIS work already (such as [1] or [6]).

   For the time being, the state machines described in this document do
   not consider the security aspect of NAT/FW NSLP protocol itself.  A
   future version of this document will add security relevant states and
   state transitions.

10.  Open Issues

   CREATE[NoNR]

   Since 00 version, we added session ownership and CREATE[Scope] message triggers are currently not
   implemented in UCREATE and some
   clarifications according to the state machines specification evolution.  Route
   change handling and all other Nonce object, as well as the open issues in [1]
   will be added in future versions of this document.

11.  Acknowledgments

   The authors would like to thank Tseno Tsenov Martin Stiemerling for his valuable
   comments and discussions.

12.  References

12.1  Normative References

   [1]  Stiemerling, M., "A NAT/Firewall "NAT/Firewall NSIS Signaling Layer Protocol
        (NSLP)", draft-ietf-nsis-nslp-natfw-04 draft-ietf-nsis-nslp-natfw-07 (work in progress),
        October 2004.
        July 2005.

   [2]  Bradner, S., "Key words for use in RFCs to Indicate Requirement
        Levels", RFC 2119, March 1997.

12.2  Informative References

   [3]  Ohba, Y.,  Fajardo, V., "State Machines for Protocol for Carrying
        Authentication for Network Access  (PANA)",
        draft-ohba-pana-statemachine-00
        draft-ietf-pana-statemachine-01 (work in progress), July 2004. 2005.

   [4]  Vollbrecht, J., Eronen, P., Petroni, N. N., and Y. Ohba, "State
        Machines for Extensible Authentication Protocol (EAP) Peer and
        Authenticator", draft-ietf-eap-statemachine-05 draft-ietf-eap-statemachine-06 (work in
        progress), September December 2004.

   [5]  Institute of Electrical and Electronics Engineers, "DRAFT
        Standard for Local and Metropolitan Area Networks: Port-Based
        Network Access Control (Revision)", IEEE 802-1X-REV/D9,
        January 2004.

   [6]  Tschofenig, H. and D. Kroeselberg, "Security Threats for NSIS",
        draft-ietf-nsis-threats-06 (work in progress), October 2004.
        RFC 4081, June 2005.

Authors' Addresses

   Constantin Werner
   University of Goettingen
   Telematics Group
   Lotzestr. 16-18
   Goettingen  37083
   Germany

   EMail:

   Email: werner@cs.uni-goettingen.de

   Xiaoming Fu
   University of Goettingen
   Telematics Group
   Lotzestr. 16-18
   Goettingen  37083
   Germany

   EMail:

   Email: fu@cs.uni-goettingen.de

   Hannes Tschofenig
   Siemens
   Otto-Hahn-Ring 6
   Munich, Bayern  81739
   Germany

   EMail:

   Email: Hannes.Tschofenig@siemens.com

   T. Tsenov
   Siemens
   Otto-Hahn-Ring 6
   Munich, Bayern  81739
   Germany

   Email: tseno.tsenov@mytum.de

   Cedric Aoun
   Nortel Networks/ENST Paris

   EMail:

   Email: cedric.aoun@nortelnetworks.com
   Niklas Steinleitner
   University of Goettingen
   Telematics Group
   Lotzestr. 16-18
   Goettingen  37083
   Germany

   Email: nsteinleitner@cs.uni-goettingen.de

Intellectual Property Statement

   The IETF takes no position regarding the validity or scope of any
   Intellectual Property Rights or other rights that might be claimed to
   pertain to the implementation or use of the technology described in
   this document or the extent to which any license under such rights
   might or might not be available; nor does it represent that it has
   made any independent effort to identify any such rights.  Information
   on the procedures with respect to rights in RFC documents can be
   found in BCP 78 and BCP 79.

   Copies of IPR disclosures made to the IETF Secretariat and any
   assurances of licenses to be made available, or the result of an
   attempt made to obtain a general license or permission for the use of
   such proprietary rights by implementers or users of this
   specification can be obtained from the IETF on-line IPR repository at
   http://www.ietf.org/ipr.

   The IETF invites any interested party to bring to its attention any
   copyrights, patents or patent applications, or other proprietary
   rights that may cover technology that may be required to implement
   this standard.  Please address the information to the IETF at
   ietf-ipr@ietf.org.

Disclaimer of Validity

   This document and the information contained herein are provided on an
   "AS IS" basis and THE CONTRIBUTOR, THE ORGANIZATION HE/SHE REPRESENTS
   OR IS SPONSORED BY (IF ANY), THE INTERNET SOCIETY AND THE INTERNET
   ENGINEERING TASK FORCE DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED,
   INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE
   INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED
   WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.

Copyright Statement

   Copyright (C) The Internet Society (2004). (2005).  This document is subject
   to the rights, licenses and restrictions contained in BCP 78, and
   except as set forth therein, the authors retain all their rights.

Acknowledgment

   Funding for the RFC Editor function is currently provided by the
   Internet Society.