示例#1
0
/*=r=*************************************************************************/
boolean cfdp_close_external_file_xfer (TRANSACTION trans)
{
  MACHINE             *machine_ptr;
  /*------------------------------------------------------------*/

  /*----------------*/
  /* Validate input */
  /*----------------*/

  machine_ptr = machine_list__get_this_trans (trans);

  if (machine_ptr == NULL)
    /* Given transaction is not known to us. */
    return (0);

  else if (!machine_ptr->is_external_xfer_open)
    /* We can't close something that isn't open */
    return (0);

  /*----------------------------*/
  /* Input is valid, take action */
  /*----------------------------*/

  machine_ptr->publik.external_file_xfer = NO;
  machine_ptr->should_external_xfer_be_closed = YES;
  return (1);
}
示例#2
0
/*=r=*************************************************************************/
boolean cfdp_open_external_file_xfer (TRANSACTION trans)
{
  MACHINE             *machine_ptr;
  /*------------------------------------------------------------*/

  /*----------------*/
  /* Validate input */
  /*----------------*/

  machine_ptr = machine_list__get_this_trans (trans);

  if (machine_ptr == NULL)
    /* Given transaction is not known to us. */
    return (0);

  else if ((machine_ptr->publik.role != CLASS_1_SENDER) &&
           (machine_ptr->publik.role != CLASS_2_SENDER))
    /* We can't disable Filedata output if we are not the Sender */
    return (0);

  /*----------------------------*/
  /* Input is valid, take action */
  /*----------------------------*/

  machine_ptr->publik.external_file_xfer = YES;
  machine_ptr->is_external_xfer_open = YES;
  return (1);
}
示例#3
0
/*=r=*************************************************************************/
boolean cfdp_set_file_checksum (TRANSACTION trans, u_int_4 checksum)
{
  MACHINE             *machine_ptr;
   /*------------------------------------------------------------*/

  /*----------------*/
  /* Validate input */
  /*----------------*/

  machine_ptr = machine_list__get_this_trans (trans);

  if (machine_ptr == NULL)
    /* Given transaction is not known to us. */
    return (0);

  /*----------------------------*/
  /* Input is valid, take action */
  /*----------------------------*/

  machine_ptr->publik.file_checksum_as_calculated = checksum;
  return (1);
}
示例#4
0
/*=r=************************************************************************/
boolean cfdp_give_pdu (PDU pdu)
     /* NOTE:  The CFDP protocol requires a transaction's Inactivity-timer 
      *   to be started (or restarted) each time a PDU is received.  
      *   That action is taken here rather than in 25 different places in 
      *   all the state table modules.
      */
{
  HDR             hdr;
  MACHINE        *m;
  ROLE            my_role;
  _PDU_TYPE_      pdu_type;
  boolean         successful;
  /*------------------------------------------------------------*/
  
  REPORT_VERSION_ONCE;

  /*------------------*/
  /* Validate the pdu */
  /*------------------*/

  if (!pdu__is_this_pdu_acceptable (&pdu))
    return (0);

  pdu_type = pdu__what_type (&pdu);
  if (pdu_type == _DONT_KNOW_)
    /* PDUs such as 'Keepalive' are simply ignored */
    {
      d_msg__ ("cfdp_engine: ignored incoming PDU of unknown type.\n");
      return (1);
    }
  hdr = pdu__hdr_struct_from_pdu (&pdu);
  my_role = pdu__receiver_role_from_pdu_hdr (hdr);
  /* If we are the sender of the file, there are some pdu-types that our
   * partner should never send (for example, EOF).  If we are the receiver
   * of the file, there are other pdu-types that our partner should never
   * send (for example, Ack-EOF).
   */
  if (!m__is_pdu_sane (pdu_type, my_role))
    return (0);

  /* Perhaps put out some debug messages */
  if (cfdp_is_message_class_enabled (CFDP_MSG_DEBUG_PDU))
    {
      pdu__display_raw_pdu (pdu);
      pdu__display_disassembled_pdu (pdu);
    }

  /* Validation was successful; assume the response will also be successful
   * unless/until proven otherwise.
   */
  successful = YES;   

  /*----------------------------------------------------------------*/
  /* If an existing state machine is assigned to this transaction,  */
  /* pass the PDU to that state machine.                            */
  /*----------------------------------------------------------------*/

  if ((m = machine_list__get_this_trans (hdr.trans)) != NULL)
    {
      /* Conceptually, re-starting the inactivity-timer belongs in each
       * of the state tables, but it's done here for practical purposes
       * (it would be duplicated in 20+ places otherwise).
       */
      if (!m->publik.frozen && !m->publik.suspended)
        m->inactivity_timer = timer__start (mib__inactivity_timeout(NULL));
      m__give_pdu_to_trans (m, &pdu);
    }

  /*----------------------------------------------------------------*/
  /* If the incoming PDU is a MD/FD/EOF for a Receiver, then create */
  /* a new state machine and pass the PDU to that state machine.    */
  /*----------------------------------------------------------------*/

  else if (((pdu_type == _MD_) || (pdu_type == _FD_) || (pdu_type == _EOF_)) &&
           ((my_role == R_1) || (my_role == R_2)))
    {

      if ((m = m__start_new_receiver_machine (hdr)) != NULL)
        m__give_pdu_to_trans (m, &pdu);
      else
        successful = NO;
    }

  /*--------------------------------------------------------------------*/
  /* If the incoming PDU is a Finished PDU for a Class 2 Sender, then   */
  /* create a new state machine and pass the PDU to that state machine. */
  /*--------------------------------------------------------------------*/

  else if ((pdu_type == _FIN_) && (my_role == S_2))
    {
      if ((m = m__restart_old_sender_machine (hdr)) != NULL)
        m__give_pdu_to_trans (m, &pdu);
      else
        successful = NO;
    }

  /*----------------------------*/
  /* Any other PDUs are ignored */
  /*----------------------------*/

  else
    d_msg__ ("cfdp_engine: ignored an incoming PDU (trans %s).\n\n",
             cfdp_trans_as_string (hdr.trans));
  
  return (successful);
}
示例#5
0
/*=r=************************************************************************/
boolean cfdp_give_request (const char *request_string)
{
  CFDP_FILE            *fp;
  MACHINE              *m;
  REQUEST               request;
  boolean               successful = YES;
  /*------------------------------------------------------------*/

  REPORT_VERSION_ONCE;

  /*---------------------------------*/
  /* Validate the given User Request */
  /*---------------------------------*/

  if (request_string == NULL)
    {
      e_msg__ ("cfdp_engine: cfdp_give_request: given a null-pointer.\n");
      successful = NO;
    }

  else if (!utils__request_from_string (request_string, &request))
    /* The string does not represent a valid request */
    {
      e_msg__ ("cfdp_engine: request is invalid (%s).\n", request_string);
      successful = NO;
    }

  else if ((request.type == REQ_PUT) &&
           (cfdp_are_these_ids_equal (request.info.put.dest_id, 
                                      mib__get_my_id())))
    /* This Put Request is invalid */
    {
      e_msg__ ("cfdp_engine: Won't allow you to send a file to yourself!\n");
      successful = NO;
    }
  
  /* If the User Request is an "empty" one, just ignore it */
  else if (request.type == REQ_NONE)
    /* No action needed */
    d_msg__ ("cfdp_engine: ignoring an empty User Request.\n");
  

  /*---------------------------------------------------------
   * If the User Request is a Put Request, then create a new 
   * state machine, and pass the Put Request to that machine
   *---------------------------------------------------------*/
  
  else if (request.type == REQ_PUT)
    {
      /* Optimization:  If the source-file doesn't exist, catch it now */
      fp = fopen_callback (request.info.put.source_file_name, "rb");
      if (fp == NULL)
        /* The source-file doesn't exist; no point in trying to transfer it */
        {
          e_msg__ ("cfdp_engine: can't transfer non-existent file (%s).\n",
                   request.info.put.source_file_name);
          successful = NO;
        }
      else
        {
          /* It does exist; close it and let the state machine re-open it */
          fclose_callback (fp);
          /* Start a new state machine */
          if ((m = m__start_new_sender_machine (request)) != NULL)
            /* Fire the state table event associated with a Put Request */
            m__state_table (m, RECEIVED_PUT_REQUEST, NULL, &request);
          else
            successful = NO;
        }
    }
  
  
  /*------------------------------------------------------------------
   * If the User Request applies to *all* transactions, then pass it
   * to all active state machines
   *------------------------------------------------------------------*/
  
  else if (request.type == REQ_REPORT)
    /* Report all active transactions */
    m__give_request_to_all_trans (request.type);
  
  else if (request.type == REQ_FREEZE)
    /* Freeze all active transactions, and any future ones too */
    {
      m__give_request_to_all_trans (request.type);
      misc__freeze_all_partners ();
    }
  
  else if (request.type == REQ_THAW)
    /* Thaw all active transactions, and any future ones too */
    {
      m__give_request_to_all_trans (request.type);
      misc__thaw_all_partners ();
    }
  
  else if (request.type == REQ_ABANDON_ALL_TRANSACTIONS)
    m__give_request_to_all_trans (REQ_ABANDON);
  
  else if (request.type == REQ_CANCEL_ALL_TRANSACTIONS)
    m__give_request_to_all_trans (REQ_CANCEL);
  
  else if (request.type == REQ_SUSPEND_ALL_TRANSACTIONS)
    m__give_request_to_all_trans (REQ_SUSPEND);
  
  else if (request.type == REQ_RESUME_ALL_TRANSACTIONS)
    m__give_request_to_all_trans (REQ_RESUME);
  
  
  /*-----------------------------------------------------------------
   * If the User Request applies to one transaction, then attempt to
   * find an active state machine assigned to that transaction, and
   * pass the Request to that state machine.
   *-----------------------------------------------------------------*/
  
  else if ((request.type == REQ_ABANDON) ||
           (request.type == REQ_CANCEL) ||
           (request.type == REQ_SUSPEND) ||
           (request.type == REQ_RESUME))
    {
      if ((m = machine_list__get_this_trans (request.info.trans)) !=  NULL)
        /* Success (a machine is assigned to this transaction) */
        m__give_request_to_one_trans (m, request.type);
      else
        /* No state machine assigned */
        {
          e_msg__ ("cfdp_engine: ignoring User-Request that references "
                   "unknown transaction (%s).\n",
                   cfdp_trans_as_string (request.info.trans));
          successful = NO;
        }
    }
  
  
  else
    {
      w_msg__ ("cfdp_engine: ignoring unrecognized User-Request (%s).\n",
               request_string);
      successful = NO;
    }
  
  return (successful);
}