Commit 0354bd8f authored by Yann Garcia's avatar Yann Garcia
Browse files

Bug fixed in sctp_offline_layer

parent b7ef8f8a
Loading
Loading
Loading
Loading
+33 −10
Original line number Diff line number Diff line
@@ -84,12 +84,17 @@ void sctp_offline_layer::receive_data(OCTETSTRING &p_data, params &p_params) {
  OCTETSTRING chunk = OCTETSTRING(p_data.lengthof() - 12, 12 + static_cast<const uint8_t*>(p_data));
  loggers::get_instance().log_msg("sctp_offline_layer::receive_data: chunk: ", chunk);
  
  do {
    OCTETSTRING payload(0, nullptr);
  process_chunk(chunk, p_params, payload);
    OCTETSTRING next_chunk(0, nullptr);
    process_chunk(chunk, p_params, payload, next_chunk);
    if (payload.lengthof() == 0) {
    loggers::get_instance().log("sctp_offline_layer::receive_data: SCTP chunk, skip it");
      loggers::get_instance().log("sctp_offline_layer::receive_data: Empty payload, skip it");
      return;
    }
    receive_to_all_layers(payload, p_params);
    chunk = next_chunk;
  } while (chunk.lengthof() > 0);

  // Update params
  // CHARSTRING s = oct2str(dst);
@@ -99,13 +104,13 @@ void sctp_offline_layer::receive_data(OCTETSTRING &p_data, params &p_params) {
  // s = oct2str(protocol);
  // p_params.insert(std::pair<std::string, std::string>(params::ip_proto, std::string(static_cast<const char *>(s))));
  // Pass the packet to the upper layers
  receive_to_all_layers(payload, p_params);
}

void sctp_offline_layer::process_chunk(const OCTETSTRING& p_chunk, params &p_params, OCTETSTRING& p_payload) {
void sctp_offline_layer::process_chunk(const OCTETSTRING& p_chunk, params &p_params, OCTETSTRING& p_payload, OCTETSTRING& p_next_chunk) {
  loggers::get_instance().log_msg(">>> sctp_offline_layer::process_chunk: ", p_chunk);

  const uint8_t* p = static_cast<const uint8_t*>(p_chunk); // Chunk type
  loggers::get_instance().log("sctp_offline_layer::process_chunk: Chunk type: %02x", static_cast<const uint8_t>(*p));
  switch (static_cast<const uint8_t>(*p)) {
    case 0x00: { // DATA chunk
        p += 2; // Skip Chunk type + Chunk flag
@@ -113,6 +118,9 @@ void sctp_offline_layer::process_chunk(const OCTETSTRING& p_chunk, params &p_par
        uint16_t l = (*p << 8 | *(p + 1)) & 0xffff;
        loggers::get_instance().log("sctp_offline_layer::process_chunk: l: %d", l);
        p += 2;
        // Calculate the padding
        uint8_t padding_length = sctp_padding_length(l);
        loggers::get_instance().log("sctp_offline_layer::process_chunk: padding_length: %d", padding_length);

        p += 4; // Skip Transmission sequence number

@@ -129,7 +137,21 @@ void sctp_offline_layer::process_chunk(const OCTETSTRING& p_chunk, params &p_par
        loggers::get_instance().log("sctp_offline_layer::process_chunk: protocol: %d", protocol);
        p += 4;
        loggers::get_instance().log("sctp_offline_layer::process_chunk: pointer offset: %d", (uint32_t)(p - static_cast<const uint8_t*>(p_chunk)));
        p_payload = OCTETSTRING(p_chunk.lengthof() - (uint32_t)(p - static_cast<const uint8_t*>(p_chunk)), p);
        p_payload = OCTETSTRING(l - (uint32_t)(p - static_cast<const uint8_t*>(p_chunk)), p);
        loggers::get_instance().log_msg("sctp_offline_layer::process_chunk: p_payload: ", p_payload);
        p += p_payload.lengthof() + padding_length;
        if (p_chunk.lengthof() > (uint32_t)(p - static_cast<const uint8_t*>(p_chunk))) {
          // Extract the next chunk
          p_next_chunk = OCTETSTRING(p_chunk.lengthof() - (uint32_t)(p - static_cast<const uint8_t*>(p_chunk)), p);
          if (p_next_chunk.lengthof() == 0) { // Padding only, skip it
            loggers::get_instance().log("sctp_offline_layer::process_chunk: Skip padding");
            p_next_chunk = OCTETSTRING(0, nullptr);
          } else {  
            loggers::get_instance().log_msg("sctp_offline_layer::process_chunk: Next chunk: ", p_next_chunk);
          }
        } else {
          p_next_chunk = OCTETSTRING(0, nullptr);
        }
      }
      break;
    case 0x01: // INIT chunk
@@ -146,7 +168,8 @@ void sctp_offline_layer::process_chunk(const OCTETSTRING& p_chunk, params &p_par
        if (p_chunk.lengthof() > l) {
          // Extract and process the next chunk
          OCTETSTRING chunk(p_chunk.lengthof() - l, p + l);
          process_chunk(chunk, p_params, p_payload);
          OCTETSTRING next_chunk(0, nullptr);
          process_chunk(chunk, p_params, p_payload, next_chunk);
        }
      }
      break;
+9 −3
Original line number Diff line number Diff line
@@ -27,6 +27,8 @@ class sctp_offline_layer : public layer {

  std::string _time_key;

  const uint8_t _sctp_chunk_alignment = 4;

  static void *run(void *p_this);

public:
@@ -65,12 +67,16 @@ public: //! \publicsection
private: //! \privatesection
  /*!
   * \fn void process_chunk(const OCTETSTRING& p_chunk, OCTETSTRING& p_payload);
   * \brief Process SCTP chunk and extrat the payload if the chunck is of DATA type
   * \brief Process SCTP chunk and extrat the payload if the chunk is of DATA type
   * \param[in] p_data The bytes formated data received
   * \param[inout] p_params Some lower layers parameters values when data was received
   * \param[out] p_payload The payload if the chunck is of DATA type, unchanged otherwise
   * \param[out] p_payload The payload if the chunk is of DATA type, unchanged otherwise
   */
  void process_chunk(const OCTETSTRING& p_chunk, params &p_params, OCTETSTRING& p_payload);
  void process_chunk(const OCTETSTRING& p_chunk, params &p_params, OCTETSTRING& p_payload, OCTETSTRING& p_next_chunk);

  inline uint8_t sctp_padding_length(uint16_t chunk_length) {
    return (_sctp_chunk_alignment - (chunk_length % _sctp_chunk_alignment)) % _sctp_chunk_alignment;
  }

  void Handle_Fd_Event_Readable(int fd);
};