<commit_before>#define CATCH_CONFIG_MAIN
#include <catch2/catch.hpp>

#include "types.hpp"

TEST_CASE("sizeof") {
  REQUIRE(sizeof(krbn::absolute_time_point) == 8);
  REQUIRE(sizeof(krbn::vendor_id) == 4);
  REQUIRE(sizeof(krbn::product_id) == 4);
  REQUIRE(sizeof(krbn::location_id) == 4);
}

TEST_CASE("absolute_time_point") {
  krbn::absolute_time_point t1(1000);
  krbn::absolute_time_point t2(2000);

  {
    auto d = t2 - t1;
    REQUIRE(d == krbn::absolute_time_duration(1000));
  }
  {
    auto d = t1 - t2;
    REQUIRE(d == krbn::absolute_time_duration(-1000));
  }
  {
    auto t = t1 + krbn::absolute_time_duration(100);
    REQUIRE(t == krbn::absolute_time_point(1100));
  }
  {
    auto t = t1 - krbn::absolute_time_duration(100);
    REQUIRE(t == krbn::absolute_time_point(900));
  }
  {
    auto t = t1;
    t += krbn::absolute_time_duration(100);
    REQUIRE(t == krbn::absolute_time_point(1100));
  }
  {
    auto t = t1;
    t -= krbn::absolute_time_duration(100);
    REQUIRE(t == krbn::absolute_time_point(900));
  }
}

TEST_CASE("operation_type") {
  krbn::operation_type_connect_console_user_server_struct s;
  std::vector<uint8_t> buffer(sizeof(s));
  memcpy(&(buffer[0]), &s, sizeof(s));
  REQUIRE(krbn::types::find_operation_type(buffer) == krbn::operation_type::connect_console_user_server);
}

TEST_CASE("grabbable_state") {
  {
    krbn::grabbable_state grabbable_state;
    REQUIRE(grabbable_state.get_device_id() == krbn::device_id(0));
    REQUIRE(grabbable_state.get_state() == krbn::grabbable_state::state::grabbable);
    REQUIRE(grabbable_state.get_ungrabbable_temporarily_reason() == krbn::grabbable_state::ungrabbable_temporarily_reason::none);
    REQUIRE(grabbable_state.get_time_stamp() == krbn::absolute_time_point(0));
  }
  {
    krbn::grabbable_state grabbable_state(krbn::device_id(1234),
                                          krbn::grabbable_state::state::ungrabbable_temporarily,
                                          krbn::grabbable_state::ungrabbable_temporarily_reason::key_repeating,
                                          krbn::absolute_time_point(1000));
    REQUIRE(grabbable_state.get_device_id() == krbn::device_id(1234));
    REQUIRE(grabbable_state.get_state() == krbn::grabbable_state::state::ungrabbable_temporarily);
    REQUIRE(grabbable_state.get_ungrabbable_temporarily_reason() == krbn::grabbable_state::ungrabbable_temporarily_reason::key_repeating);
    REQUIRE(grabbable_state.get_time_stamp() == krbn::absolute_time_point(1000));
  }
}

TEST_CASE("grabbable_state::equals_except_time_stamp") {
  {
    krbn::grabbable_state grabbable_state1(krbn::device_id(1234),
                                           krbn::grabbable_state::state::ungrabbable_temporarily,
                                           krbn::grabbable_state::ungrabbable_temporarily_reason::key_repeating,
                                           krbn::absolute_time_point(1000));
    krbn::grabbable_state grabbable_state2(krbn::device_id(1234),
                                           krbn::grabbable_state::state::ungrabbable_temporarily,
                                           krbn::grabbable_state::ungrabbable_temporarily_reason::key_repeating,
                                           krbn::absolute_time_point(2000));
    krbn::grabbable_state grabbable_state3(krbn::device_id(1234),
                                           krbn::grabbable_state::state::device_error,
                                           krbn::grabbable_state::ungrabbable_temporarily_reason::none,
                                           krbn::absolute_time_point(3000));
    REQUIRE(grabbable_state1 != grabbable_state2);
    REQUIRE(grabbable_state1.equals_except_time_stamp(grabbable_state2));
    REQUIRE(!grabbable_state1.equals_except_time_stamp(grabbable_state3));
  }
}

TEST_CASE("make_key_code") {
  REQUIRE(krbn::types::make_key_code("spacebar") == krbn::key_code::spacebar);
  REQUIRE(krbn::types::make_key_code("unknown") == std::nullopt);
  REQUIRE(krbn::types::make_key_code_name(krbn::key_code::spacebar) == std::string("spacebar"));
  REQUIRE(krbn::types::make_key_code_name(krbn::key_code::left_option) == std::string("left_alt"));

  {
    auto actual = krbn::types::make_key_code(krbn::hid_usage_page(kHIDPage_KeyboardOrKeypad),
                                             krbn::hid_usage(kHIDUsage_KeyboardTab));
    REQUIRE(*actual == krbn::key_code(kHIDUsage_KeyboardTab));
  }
  {
    auto actual = krbn::types::make_key_code(krbn::hid_usage_page(krbn::kHIDPage_AppleVendorTopCase),
                                             krbn::hid_usage(krbn::kHIDUsage_AV_TopCase_KeyboardFn));
    REQUIRE(*actual == krbn::key_code::fn);
  }
  {
    auto actual = krbn::types::make_key_code(krbn::hid_usage_page(krbn::kHIDPage_AppleVendorKeyboard),
                                             krbn::hid_usage(krbn::kHIDUsage_AppleVendorKeyboard_Function));
    REQUIRE(*actual == krbn::key_code::fn);
  }
  {
    auto actual = krbn::types::make_key_code(krbn::hid_usage_page(kHIDPage_Button),
                                             krbn::hid_usage(1));
    REQUIRE(actual == std::nullopt);
  }
}

TEST_CASE("make_key_code (modifier_flag)") {
  REQUIRE(krbn::types::make_key_code(krbn::modifier_flag::zero) == std::nullopt);
  REQUIRE(krbn::types::make_key_code(krbn::modifier_flag::caps_lock) == krbn::key_code::caps_lock);
  REQUIRE(krbn::types::make_key_code(krbn::modifier_flag::left_control) == krbn::key_code::left_control);
  REQUIRE(krbn::types::make_key_code(krbn::modifier_flag::left_shift) == krbn::key_code::left_shift);
  REQUIRE(krbn::types::make_key_code(krbn::modifier_flag::left_option) == krbn::key_code::left_option);
  REQUIRE(krbn::types::make_key_code(krbn::modifier_flag::left_command) == krbn::key_code::left_command);
  REQUIRE(krbn::types::make_key_code(krbn::modifier_flag::right_control) == krbn::key_code::right_control);
  REQUIRE(krbn::types::make_key_code(krbn::modifier_flag::right_shift) == krbn::key_code::right_shift);
  REQUIRE(krbn::types::make_key_code(krbn::modifier_flag::right_option) == krbn::key_code::right_option);
  REQUIRE(krbn::types::make_key_code(krbn::modifier_flag::right_command) == krbn::key_code::right_command);
  REQUIRE(krbn::types::make_key_code(krbn::modifier_flag::fn) == krbn::key_code::fn);
  REQUIRE(krbn::types::make_key_code(krbn::modifier_flag::end_) == std::nullopt);
}

TEST_CASE("make_modifier_flag") {
  REQUIRE(krbn::types::make_modifier_flag(krbn::key_code::caps_lock) == std::nullopt);
  REQUIRE(krbn::types::make_modifier_flag(krbn::key_code::left_control) == krbn::modifier_flag::left_control);
  REQUIRE(krbn::types::make_modifier_flag(krbn::key_code::left_shift) == krbn::modifier_flag::left_shift);
  REQUIRE(krbn::types::make_modifier_flag(krbn::key_code::left_option) == krbn::modifier_flag::left_option);
  REQUIRE(krbn::types::make_modifier_flag(krbn::key_code::left_command) == krbn::modifier_flag::left_command);
  REQUIRE(krbn::types::make_modifier_flag(krbn::key_code::right_control) == krbn::modifier_flag::right_control);
  REQUIRE(krbn::types::make_modifier_flag(krbn::key_code::right_shift) == krbn::modifier_flag::right_shift);
  REQUIRE(krbn::types::make_modifier_flag(krbn::key_code::right_option) == krbn::modifier_flag::right_option);
  REQUIRE(krbn::types::make_modifier_flag(krbn::key_code::right_command) == krbn::modifier_flag::right_command);
  REQUIRE(krbn::types::make_modifier_flag(krbn::key_code::fn) == krbn::modifier_flag::fn);

  REQUIRE(krbn::types::make_modifier_flag(krbn::hid_usage_page::keyboard_or_keypad, krbn::hid_usage(kHIDUsage_KeyboardA)) == std::nullopt);
  REQUIRE(krbn::types::make_modifier_flag(krbn::hid_usage_page::keyboard_or_keypad, krbn::hid_usage(kHIDUsage_KeyboardErrorRollOver)) == std::nullopt);
  REQUIRE(krbn::types::make_modifier_flag(krbn::hid_usage_page::keyboard_or_keypad, krbn::hid_usage(kHIDUsage_KeyboardLeftShift)) == krbn::modifier_flag::left_shift);
  REQUIRE(krbn::types::make_modifier_flag(krbn::hid_usage_page::button, krbn::hid_usage(1)) == std::nullopt);
}

TEST_CASE("make_consumer_key_code") {
  REQUIRE(krbn::types::make_consumer_key_code("mute") == krbn::consumer_key_code::mute);
  REQUIRE(!krbn::types::make_consumer_key_code("unknown"));

  REQUIRE(krbn::types::make_consumer_key_code_name(krbn::consumer_key_code::mute) == std::string("mute"));

  REQUIRE(krbn::types::make_consumer_key_code(krbn::hid_usage_page::consumer, krbn::hid_usage::csmr_mute) == krbn::consumer_key_code::mute);
  REQUIRE(!krbn::types::make_consumer_key_code(krbn::hid_usage_page::keyboard_or_keypad, krbn::hid_usage(kHIDUsage_KeyboardA)));

  REQUIRE(krbn::types::make_hid_usage_page(krbn::consumer_key_code::mute) == krbn::hid_usage_page::consumer);
  REQUIRE(krbn::types::make_hid_usage(krbn::consumer_key_code::mute) == krbn::hid_usage::csmr_mute);
}

TEST_CASE("make_pointing_button") {
  REQUIRE(krbn::types::make_pointing_button("button1") == krbn::pointing_button::button1);
  REQUIRE(!krbn::types::make_pointing_button("unknown"));

  REQUIRE(krbn::types::make_pointing_button_name(krbn::pointing_button::button1) == std::string("button1"));

  {
    auto actual = krbn::types::make_pointing_button(krbn::hid_usage_page(kHIDPage_Button),
                                                    krbn::hid_usage(1));
    REQUIRE(*actual == krbn::pointing_button::button1);
  }
  {
    auto actual = krbn::types::make_pointing_button(krbn::hid_usage_page(kHIDPage_KeyboardOrKeypad),
                                                    krbn::hid_usage(kHIDUsage_KeyboardTab));
    REQUIRE(actual == std::nullopt);
  }
}
<commit_msg>update tests<commit_after>#define CATCH_CONFIG_MAIN
#include <catch2/catch.hpp>

#include "types.hpp"

TEST_CASE("sizeof") {
  REQUIRE(sizeof(krbn::vendor_id) == 4);
  REQUIRE(sizeof(krbn::product_id) == 4);
  REQUIRE(sizeof(krbn::location_id) == 4);
}

TEST_CASE("operation_type") {
  krbn::operation_type_connect_console_user_server_struct s;
  std::vector<uint8_t> buffer(sizeof(s));
  memcpy(&(buffer[0]), &s, sizeof(s));
  REQUIRE(krbn::types::find_operation_type(buffer) == krbn::operation_type::connect_console_user_server);
}

TEST_CASE("grabbable_state") {
  {
    krbn::grabbable_state grabbable_state;
    REQUIRE(grabbable_state.get_device_id() == krbn::device_id(0));
    REQUIRE(grabbable_state.get_state() == krbn::grabbable_state::state::grabbable);
    REQUIRE(grabbable_state.get_ungrabbable_temporarily_reason() == krbn::grabbable_state::ungrabbable_temporarily_reason::none);
    REQUIRE(grabbable_state.get_time_stamp() == krbn::absolute_time_point(0));
  }
  {
    krbn::grabbable_state grabbable_state(krbn::device_id(1234),
                                          krbn::grabbable_state::state::ungrabbable_temporarily,
                                          krbn::grabbable_state::ungrabbable_temporarily_reason::key_repeating,
                                          krbn::absolute_time_point(1000));
    REQUIRE(grabbable_state.get_device_id() == krbn::device_id(1234));
    REQUIRE(grabbable_state.get_state() == krbn::grabbable_state::state::ungrabbable_temporarily);
    REQUIRE(grabbable_state.get_ungrabbable_temporarily_reason() == krbn::grabbable_state::ungrabbable_temporarily_reason::key_repeating);
    REQUIRE(grabbable_state.get_time_stamp() == krbn::absolute_time_point(1000));
  }
}

TEST_CASE("grabbable_state::equals_except_time_stamp") {
  {
    krbn::grabbable_state grabbable_state1(krbn::device_id(1234),
                                           krbn::grabbable_state::state::ungrabbable_temporarily,
                                           krbn::grabbable_state::ungrabbable_temporarily_reason::key_repeating,
                                           krbn::absolute_time_point(1000));
    krbn::grabbable_state grabbable_state2(krbn::device_id(1234),
                                           krbn::grabbable_state::state::ungrabbable_temporarily,
                                           krbn::grabbable_state::ungrabbable_temporarily_reason::key_repeating,
                                           krbn::absolute_time_point(2000));
    krbn::grabbable_state grabbable_state3(krbn::device_id(1234),
                                           krbn::grabbable_state::state::device_error,
                                           krbn::grabbable_state::ungrabbable_temporarily_reason::none,
                                           krbn::absolute_time_point(3000));
    REQUIRE(grabbable_state1 != grabbable_state2);
    REQUIRE(grabbable_state1.equals_except_time_stamp(grabbable_state2));
    REQUIRE(!grabbable_state1.equals_except_time_stamp(grabbable_state3));
  }
}

TEST_CASE("make_key_code") {
  REQUIRE(krbn::types::make_key_code("spacebar") == krbn::key_code::spacebar);
  REQUIRE(krbn::types::make_key_code("unknown") == std::nullopt);
  REQUIRE(krbn::types::make_key_code_name(krbn::key_code::spacebar) == std::string("spacebar"));
  REQUIRE(krbn::types::make_key_code_name(krbn::key_code::left_option) == std::string("left_alt"));

  {
    auto actual = krbn::types::make_key_code(krbn::hid_usage_page(kHIDPage_KeyboardOrKeypad),
                                             krbn::hid_usage(kHIDUsage_KeyboardTab));
    REQUIRE(*actual == krbn::key_code(kHIDUsage_KeyboardTab));
  }
  {
    auto actual = krbn::types::make_key_code(krbn::hid_usage_page(krbn::kHIDPage_AppleVendorTopCase),
                                             krbn::hid_usage(krbn::kHIDUsage_AV_TopCase_KeyboardFn));
    REQUIRE(*actual == krbn::key_code::fn);
  }
  {
    auto actual = krbn::types::make_key_code(krbn::hid_usage_page(krbn::kHIDPage_AppleVendorKeyboard),
                                             krbn::hid_usage(krbn::kHIDUsage_AppleVendorKeyboard_Function));
    REQUIRE(*actual == krbn::key_code::fn);
  }
  {
    auto actual = krbn::types::make_key_code(krbn::hid_usage_page(kHIDPage_Button),
                                             krbn::hid_usage(1));
    REQUIRE(actual == std::nullopt);
  }
}

TEST_CASE("make_key_code (modifier_flag)") {
  REQUIRE(krbn::types::make_key_code(krbn::modifier_flag::zero) == std::nullopt);
  REQUIRE(krbn::types::make_key_code(krbn::modifier_flag::caps_lock) == krbn::key_code::caps_lock);
  REQUIRE(krbn::types::make_key_code(krbn::modifier_flag::left_control) == krbn::key_code::left_control);
  REQUIRE(krbn::types::make_key_code(krbn::modifier_flag::left_shift) == krbn::key_code::left_shift);
  REQUIRE(krbn::types::make_key_code(krbn::modifier_flag::left_option) == krbn::key_code::left_option);
  REQUIRE(krbn::types::make_key_code(krbn::modifier_flag::left_command) == krbn::key_code::left_command);
  REQUIRE(krbn::types::make_key_code(krbn::modifier_flag::right_control) == krbn::key_code::right_control);
  REQUIRE(krbn::types::make_key_code(krbn::modifier_flag::right_shift) == krbn::key_code::right_shift);
  REQUIRE(krbn::types::make_key_code(krbn::modifier_flag::right_option) == krbn::key_code::right_option);
  REQUIRE(krbn::types::make_key_code(krbn::modifier_flag::right_command) == krbn::key_code::right_command);
  REQUIRE(krbn::types::make_key_code(krbn::modifier_flag::fn) == krbn::key_code::fn);
  REQUIRE(krbn::types::make_key_code(krbn::modifier_flag::end_) == std::nullopt);
}

TEST_CASE("make_modifier_flag") {
  REQUIRE(krbn::types::make_modifier_flag(krbn::key_code::caps_lock) == std::nullopt);
  REQUIRE(krbn::types::make_modifier_flag(krbn::key_code::left_control) == krbn::modifier_flag::left_control);
  REQUIRE(krbn::types::make_modifier_flag(krbn::key_code::left_shift) == krbn::modifier_flag::left_shift);
  REQUIRE(krbn::types::make_modifier_flag(krbn::key_code::left_option) == krbn::modifier_flag::left_option);
  REQUIRE(krbn::types::make_modifier_flag(krbn::key_code::left_command) == krbn::modifier_flag::left_command);
  REQUIRE(krbn::types::make_modifier_flag(krbn::key_code::right_control) == krbn::modifier_flag::right_control);
  REQUIRE(krbn::types::make_modifier_flag(krbn::key_code::right_shift) == krbn::modifier_flag::right_shift);
  REQUIRE(krbn::types::make_modifier_flag(krbn::key_code::right_option) == krbn::modifier_flag::right_option);
  REQUIRE(krbn::types::make_modifier_flag(krbn::key_code::right_command) == krbn::modifier_flag::right_command);
  REQUIRE(krbn::types::make_modifier_flag(krbn::key_code::fn) == krbn::modifier_flag::fn);

  REQUIRE(krbn::types::make_modifier_flag(krbn::hid_usage_page::keyboard_or_keypad, krbn::hid_usage(kHIDUsage_KeyboardA)) == std::nullopt);
  REQUIRE(krbn::types::make_modifier_flag(krbn::hid_usage_page::keyboard_or_keypad, krbn::hid_usage(kHIDUsage_KeyboardErrorRollOver)) == std::nullopt);
  REQUIRE(krbn::types::make_modifier_flag(krbn::hid_usage_page::keyboard_or_keypad, krbn::hid_usage(kHIDUsage_KeyboardLeftShift)) == krbn::modifier_flag::left_shift);
  REQUIRE(krbn::types::make_modifier_flag(krbn::hid_usage_page::button, krbn::hid_usage(1)) == std::nullopt);
}

TEST_CASE("make_consumer_key_code") {
  REQUIRE(krbn::types::make_consumer_key_code("mute") == krbn::consumer_key_code::mute);
  REQUIRE(!krbn::types::make_consumer_key_code("unknown"));

  REQUIRE(krbn::types::make_consumer_key_code_name(krbn::consumer_key_code::mute) == std::string("mute"));

  REQUIRE(krbn::types::make_consumer_key_code(krbn::hid_usage_page::consumer, krbn::hid_usage::csmr_mute) == krbn::consumer_key_code::mute);
  REQUIRE(!krbn::types::make_consumer_key_code(krbn::hid_usage_page::keyboard_or_keypad, krbn::hid_usage(kHIDUsage_KeyboardA)));

  REQUIRE(krbn::types::make_hid_usage_page(krbn::consumer_key_code::mute) == krbn::hid_usage_page::consumer);
  REQUIRE(krbn::types::make_hid_usage(krbn::consumer_key_code::mute) == krbn::hid_usage::csmr_mute);
}

TEST_CASE("make_pointing_button") {
  REQUIRE(krbn::types::make_pointing_button("button1") == krbn::pointing_button::button1);
  REQUIRE(!krbn::types::make_pointing_button("unknown"));

  REQUIRE(krbn::types::make_pointing_button_name(krbn::pointing_button::button1) == std::string("button1"));

  {
    auto actual = krbn::types::make_pointing_button(krbn::hid_usage_page(kHIDPage_Button),
                                                    krbn::hid_usage(1));
    REQUIRE(*actual == krbn::pointing_button::button1);
  }
  {
    auto actual = krbn::types::make_pointing_button(krbn::hid_usage_page(kHIDPage_KeyboardOrKeypad),
                                                    krbn::hid_usage(kHIDUsage_KeyboardTab));
    REQUIRE(actual == std::nullopt);
  }
}
<|endoftext|>


<commit_before>/** @file

  A brief file description

  @section license License

  Licensed to the Apache Software Foundation (ASF) under one
  or more contributor license agreements.  See the NOTICE file
  distributed with this work for additional information
  regarding copyright ownership.  The ASF licenses this file
  to you under the Apache License, Version 2.0 (the
  "License"); you may not use this file except in compliance
  with the License.  You may obtain a copy of the License at

      http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.
 */

/*************************** -*- Mod: C++ -*- ******************************
  SslConfig.cc
   Created On      : 07/20/2000

   Description:
   SSL Configurations
 ****************************************************************************/

#include "libts.h"
#include "I_Layout.h"

#include <string.h>
#include "P_Net.h"
#include <openssl/ssl.h>

int SslConfig::id = 0;
bool SslConfig::serverSSLTermination = 0;

SslConfig sslTerminationConfig;

#ifndef USE_CONFIG_PROCESSOR
SslConfigParams *SslConfig::ssl_config_params;
#endif

SslConfigParams::SslConfigParams()
{
  serverCertPath = serverCertPathOnly =
    serverCertChainPath =
    serverKeyPath = configFilePath =
    CACertFilename = CACertPath =
    clientCertPath = clientKeyPath =
    clientCACertFilename = clientCACertPath =
    cipherSuite =
    serverKeyPathOnly = NULL;

  clientCertLevel = client_verify_depth = verify_depth = clientVerify = 0;

  ssl_accept_port_number = 443;
  termMode = SSL_TERM_MODE_NONE;
  ssl_ctx_options = 0;
  ssl_session_cache = SSL_SESSION_CACHE_MODE_SERVER;
  ssl_session_cache_size = 1024*20;
}

SslConfigParams::~SslConfigParams()
{
  cleanup();
}

void
SslConfigParams::cleanup()
{
  if (serverCertPath) {
    ats_free(serverCertPath);
    serverCertPath = NULL;
  }
  if (serverCertChainPath) {
    ats_free(serverCertChainPath);
    serverCertChainPath = NULL;
  }
  if (serverKeyPath) {
    ats_free(serverKeyPath);
    serverKeyPath = NULL;
  }
  if (CACertFilename) {
    ats_free(CACertFilename);
    CACertFilename = NULL;
  }
  if (CACertPath) {
    ats_free(CACertPath);
    CACertPath = NULL;
  }
  if (clientCertPath) {
    ats_free(clientCertPath);
    clientCertPath = NULL;
  }
  if (clientKeyPath) {
    ats_free(clientKeyPath);
    clientKeyPath = NULL;
  }
  if (clientCACertFilename) {
    ats_free(clientCACertFilename);
    clientCACertFilename = NULL;
  }
  if (clientCACertPath) {
    ats_free(clientCACertPath);
    clientCACertPath = NULL;
  }
  if (configFilePath) {
    ats_free(configFilePath);
    configFilePath = NULL;
  }
  if (serverCertPathOnly) {
    ats_free(serverCertPathOnly);
    serverCertPathOnly = NULL;
  }
  if (serverKeyPathOnly) {
    ats_free(serverKeyPathOnly);
    serverKeyPathOnly = NULL;
  }
  if (cipherSuite) {
    ats_free(cipherSuite);
    cipherSuite = NULL;
  }

  clientCertLevel = client_verify_depth = verify_depth = clientVerify = 0;
  ssl_accept_port_number = -1;
  termMode = SSL_TERM_MODE_NONE;
}

// XXX: Add handling for Windows?
// If path is *not* absolute, consider it relative to PREFIX
// if it's empty, just take SYSCONFDIR, otherwise we can take it as-is
static void
set_paths_helper(const char *path, const char *filename, char **final_path, char **final_filename)
{
  if (final_path != NULL) {
    if (path && path[0] != '/') {
      *final_path = Layout::get()->relative_to(Layout::get()->prefix, path);
    } else if (!path || path[0] == '\0'){
      *final_path = ats_strdup(Layout::get()->sysconfdir);
    } else {
      *final_path = ats_strdup(path);
    }
  }
  if (filename) {
    *final_filename = ats_strdup(Layout::get()->relative_to(path, filename));
  } else {
    *final_filename = NULL;
  }

#ifdef _WIN32
  i = 0;
  while (final_path[i] != 0) {
    if (final_path[i] == '/')
      final_path[i] = '\\';
    i++;
  }

  i = 0;
  while (final_filename[i] != 0) {
    if (final_filename[i] == '/')
      final_filename[i] = '\\';
    i++;
  }
#endif
}
void
SslConfigParams::initialize()
{
  char serverCertFilename[PATH_NAME_MAX] = "";
  char serverCertRelativePath[PATH_NAME_MAX] = "";
  char *ssl_server_private_key_filename = NULL;
  char *ssl_server_private_key_path = NULL;
  char *CACertRelativePath = NULL;
  char *ssl_client_cert_filename = NULL;
  char *ssl_client_cert_path = NULL;
  char *ssl_client_private_key_filename = NULL;
  char *ssl_client_private_key_path = NULL;
  char *clientCACertRelativePath = NULL;
  char *multicert_config_file = NULL;

  int ssl_mode = SSL_TERM_MODE_NONE;
#ifdef _WIN32
  int i;
#endif

  cleanup();

  //+++++++++++++++++++++++++ Server part +++++++++++++++++++++++++++++++++
  verify_depth = 7;

  IOCORE_ReadConfigInteger(ssl_mode, "proxy.config.ssl.enabled");
  ssl_mode &= SSL_TERM_MODE_BOTH;
  termMode = (SSL_TERMINATION_MODE) ssl_mode;

  IOCORE_ReadConfigInt32(ssl_accept_port_number, "proxy.config.ssl.server_port");
  IOCORE_ReadConfigInt32(clientCertLevel, "proxy.config.ssl.client.certification_level");

  IOCORE_ReadConfigStringAlloc(cipherSuite, "proxy.config.ssl.server.cipher_suite");

  int options;
  IOCORE_ReadConfigInteger(options, "proxy.config.ssl.SSLv2");
  if (!options)
    ssl_ctx_options |= SSL_OP_NO_SSLv2;
  IOCORE_ReadConfigInteger(options, "proxy.config.ssl.SSLv3");
  if (!options)
    ssl_ctx_options |= SSL_OP_NO_SSLv3;
  IOCORE_ReadConfigInteger(options, "proxy.config.ssl.TLSv1");
  if (!options)
    ssl_ctx_options |= SSL_OP_NO_TLSv1;
#ifdef SSL_OP_CIPHER_SERVER_PREFERENCE
  IOCORE_ReadConfigInteger(options, "proxy.config.ssl.server.honor_cipher_order");
  if (!options)
    ssl_ctx_options |= SSL_OP_CIPHER_SERVER_PREFERENCE;
#endif
#ifdef SSL_OP_NO_COMPRESSION
  IOCORE_ReadConfigInteger(options, "proxy.config.ssl.compression");
  if (!options)
    ssl_ctx_options |= SSL_OP_NO_COMPRESSION;
#endif

  IOCORE_ReadConfigString(serverCertFilename, "proxy.config.ssl.server.cert.filename", PATH_NAME_MAX);
  IOCORE_ReadConfigString(serverCertRelativePath, "proxy.config.ssl.server.cert.path", PATH_NAME_MAX);
  set_paths_helper(serverCertRelativePath, serverCertFilename, &serverCertPathOnly, &serverCertPath);

  char *cert_chain = NULL;
  IOCORE_ReadConfigStringAlloc(cert_chain, "proxy.config.ssl.server.cert_chain.filename");
  set_paths_helper(serverCertRelativePath, cert_chain, &serverCertPathOnly, &serverCertChainPath);
  ats_free(cert_chain);

  IOCORE_ReadConfigStringAlloc(multicert_config_file, "proxy.config.ssl.server.multicert.filename");
  set_paths_helper(Layout::get()->sysconfdir, multicert_config_file, NULL, &configFilePath);
  ats_free(multicert_config_file);

  IOCORE_ReadConfigStringAlloc(ssl_server_private_key_filename, "proxy.config.ssl.server.private_key.filename");
  IOCORE_ReadConfigStringAlloc(ssl_server_private_key_path, "proxy.config.ssl.server.private_key.path");
  set_paths_helper(ssl_server_private_key_path, ssl_server_private_key_filename, &serverKeyPathOnly, &serverKeyPath);
  ats_free(ssl_server_private_key_filename);
  ats_free(ssl_server_private_key_path);

  IOCORE_ReadConfigStringAlloc(CACertFilename, "proxy.config.ssl.CA.cert.filename");
  IOCORE_ReadConfigStringAlloc(CACertRelativePath, "proxy.config.ssl.CA.cert.path");
  set_paths_helper(CACertRelativePath, CACertFilename, &CACertPath, &CACertFilename);
  ats_free(CACertRelativePath);

  // SSL session cache configurations
  IOCORE_ReadConfigInteger(ssl_session_cache, "proxy.config.ssl.session_cache");
  IOCORE_ReadConfigInteger(ssl_session_cache_size, "proxy.config.ssl.session_cache.size");

  // ++++++++++++++++++++++++ Client part ++++++++++++++++++++
  client_verify_depth = 7;
  IOCORE_ReadConfigInt32(clientVerify, "proxy.config.ssl.client.verify.server");

  ssl_client_cert_filename = NULL;
  ssl_client_cert_path = NULL;
  IOCORE_ReadConfigStringAlloc(ssl_client_cert_filename, "proxy.config.ssl.client.cert.filename");
  IOCORE_ReadConfigStringAlloc(ssl_client_cert_path, "proxy.config.ssl.client.cert.path");

  if (ssl_client_cert_path == NULL) {
    ssl_client_cert_path = ats_strdup(Layout::get()->sysconfdir);
  }
  if (ssl_client_cert_filename != NULL) {
    char *abs_path = Layout::get()->relative_to(Layout::get()->sysconfdir, ssl_client_cert_path);
    clientCertPath = Layout::get()->Layout::relative_to(abs_path, ssl_client_cert_filename);

#ifdef _WIN32
    i = 0;
    while (clientCertPath[i] != 0) {
      if (clientCertPath[i] == '/')
        clientCertPath[i] = '\\';
      i++;
    }
#endif
    ats_free(abs_path);
    ats_free(ssl_client_cert_filename);
  }
  ats_free(ssl_client_cert_path);

  ssl_client_cert_filename = NULL;
  ssl_client_cert_path = NULL;

  IOCORE_ReadConfigStringAlloc(ssl_client_private_key_filename, "proxy.config.ssl.client.private_key.filename");
  IOCORE_ReadConfigStringAlloc(ssl_client_private_key_path, "proxy.config.ssl.client.private_key.path");

  if (ssl_client_private_key_path == NULL) {
    ssl_client_private_key_path = ats_strdup(Layout::get()->sysconfdir);
  }

  if (ssl_client_private_key_filename != NULL) {
    char *abs_path = Layout::get()->relative_to(Layout::get()->sysconfdir, ssl_client_private_key_path);
    clientCertPath = Layout::get()->Layout::relative_to(abs_path, ssl_client_private_key_filename);

#ifdef _WIN32
    i = 0;
    while (clientKeyPath[i] != 0) {
      if (clientKeyPath[i] == '/')
        clientKeyPath[i] = '\\';
      i++;
    }
#endif
    ats_free(abs_path);
    ats_free(ssl_client_private_key_filename);
  }
  ats_free(ssl_client_private_key_path);

  ssl_client_private_key_path = NULL;

  IOCORE_ReadConfigStringAlloc(clientCACertFilename, "proxy.config.ssl.client.CA.cert.filename");
  if (clientCACertFilename && (*clientCACertFilename == 0)) {
    ats_free(clientCACertFilename);
    clientCACertFilename = NULL;
  }

  IOCORE_ReadConfigStringAlloc(clientCACertRelativePath, "proxy.config.ssl.client.CA.cert.path");

// Notice that we don't put the filename at the
// end of this path.  Its a quirk of the SSL lib interface.
  if (clientCACertRelativePath != NULL) {
    clientCACertPath = Layout::get()->relative_to(Layout::get()->sysconfdir, clientCACertRelativePath);
#ifdef _WIN32
    i = 0;
    while (clientCACertPath[i] != 0) {
      if (clientCACertPath[i] == '/')
        clientCACertPath[i] = '\\';
      i++;
    }
#endif
    ats_free(clientCACertRelativePath);
  }
}

void
SslConfig::startup()
{
  reconfigure();
}

void
SslConfig::reconfigure()
{
  SslConfigParams *params;
  params = NEW(new SslConfigParams);
  params->initialize();         // re-read configuration
#ifdef USE_CONFIG_PROCESSOR
  id = configProcessor.set(id, params);
#else
  ssl_config_params = params;
#endif
  serverSSLTermination = (params->termMode & SslConfigParams::SSL_TERM_MODE_SERVER) != 0;
}

SslConfigParams *
SslConfig::acquire()
{
#ifndef USE_CONFIG_PROCESSOR
  return ssl_config_params;
#else
  return ((SslConfigParams *) configProcessor.get(id));
#endif
}

void
SslConfig::release(SslConfigParams * params)
{
  (void) params;
#ifdef USE_CONFIG_PROCESSOR
  configProcessor.release(id, params);
#endif
}
<commit_msg>More cleanup re TS-944. All paths are now handled with set_paths_helper()<commit_after>/** @file

  A brief file description

  @section license License

  Licensed to the Apache Software Foundation (ASF) under one
  or more contributor license agreements.  See the NOTICE file
  distributed with this work for additional information
  regarding copyright ownership.  The ASF licenses this file
  to you under the Apache License, Version 2.0 (the
  "License"); you may not use this file except in compliance
  with the License.  You may obtain a copy of the License at

      http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.
 */

/*************************** -*- Mod: C++ -*- ******************************
  SslConfig.cc
   Created On      : 07/20/2000

   Description:
   SSL Configurations
 ****************************************************************************/

#include "libts.h"
#include "I_Layout.h"

#include <string.h>
#include "P_Net.h"
#include <openssl/ssl.h>

int SslConfig::id = 0;
bool SslConfig::serverSSLTermination = 0;

SslConfig sslTerminationConfig;

#ifndef USE_CONFIG_PROCESSOR
SslConfigParams *SslConfig::ssl_config_params;
#endif

SslConfigParams::SslConfigParams()
{
  serverCertPath = serverCertPathOnly =
    serverCertChainPath =
    serverKeyPath = configFilePath =
    CACertFilename = CACertPath =
    clientCertPath = clientKeyPath =
    clientCACertFilename = clientCACertPath =
    cipherSuite =
    serverKeyPathOnly = NULL;

  clientCertLevel = client_verify_depth = verify_depth = clientVerify = 0;

  ssl_accept_port_number = 443;
  termMode = SSL_TERM_MODE_NONE;
  ssl_ctx_options = 0;
  ssl_session_cache = SSL_SESSION_CACHE_MODE_SERVER;
  ssl_session_cache_size = 1024*20;
}

SslConfigParams::~SslConfigParams()
{
  cleanup();
}

void
SslConfigParams::cleanup()
{
  if (serverCertPath) {
    ats_free(serverCertPath);
    serverCertPath = NULL;
  }
  if (serverCertChainPath) {
    ats_free(serverCertChainPath);
    serverCertChainPath = NULL;
  }
  if (serverKeyPath) {
    ats_free(serverKeyPath);
    serverKeyPath = NULL;
  }
  if (CACertFilename) {
    ats_free(CACertFilename);
    CACertFilename = NULL;
  }
  if (CACertPath) {
    ats_free(CACertPath);
    CACertPath = NULL;
  }
  if (clientCertPath) {
    ats_free(clientCertPath);
    clientCertPath = NULL;
  }
  if (clientKeyPath) {
    ats_free(clientKeyPath);
    clientKeyPath = NULL;
  }
  if (clientCACertFilename) {
    ats_free(clientCACertFilename);
    clientCACertFilename = NULL;
  }
  if (clientCACertPath) {
    ats_free(clientCACertPath);
    clientCACertPath = NULL;
  }
  if (configFilePath) {
    ats_free(configFilePath);
    configFilePath = NULL;
  }
  if (serverCertPathOnly) {
    ats_free(serverCertPathOnly);
    serverCertPathOnly = NULL;
  }
  if (serverKeyPathOnly) {
    ats_free(serverKeyPathOnly);
    serverKeyPathOnly = NULL;
  }
  if (cipherSuite) {
    ats_free(cipherSuite);
    cipherSuite = NULL;
  }

  clientCertLevel = client_verify_depth = verify_depth = clientVerify = 0;
  ssl_accept_port_number = -1;
  termMode = SSL_TERM_MODE_NONE;
}

/**  set_paths_helper

 If path is *not* absolute, consider it relative to PREFIX
 if it's empty, just take SYSCONFDIR, otherwise we can take it as-is
 if final_path is NULL, it will not be updated.

 XXX: Add handling for Windows?
 */
static void
set_paths_helper(const char *path, const char *filename, char **final_path, char **final_filename)
{
  if (final_path != NULL) {
    if (path && path[0] != '/') {
      *final_path = Layout::get()->relative_to(Layout::get()->prefix, path);
    } else if (!path || path[0] == '\0'){
      *final_path = ats_strdup(Layout::get()->sysconfdir);
    } else {
      *final_path = ats_strdup(path);
    }
  }
  if (filename) {
    *final_filename = ats_strdup(Layout::get()->relative_to(path, filename));
  } else {
    *final_filename = NULL;
  }

#ifdef _WIN32
  i = 0;
  while (final_path[i] != 0) {
    if (final_path[i] == '/')
      final_path[i] = '\\';
    i++;
  }

  i = 0;
  while (final_filename[i] != 0) {
    if (final_filename[i] == '/')
      final_filename[i] = '\\';
    i++;
  }
#endif
}
void
SslConfigParams::initialize()
{
  char serverCertFilename[PATH_NAME_MAX] = "";
  char serverCertRelativePath[PATH_NAME_MAX] = "";
  char *ssl_server_private_key_filename = NULL;
  char *ssl_server_private_key_path = NULL;
  char *CACertRelativePath = NULL;
  char *ssl_client_cert_filename = NULL;
  char *ssl_client_cert_path = NULL;
  char *ssl_client_private_key_filename = NULL;
  char *ssl_client_private_key_path = NULL;
  char *clientCACertRelativePath = NULL;
  char *multicert_config_file = NULL;

  int ssl_mode = SSL_TERM_MODE_NONE;

  cleanup();

  //+++++++++++++++++++++++++ Server part +++++++++++++++++++++++++++++++++
  verify_depth = 7;

  IOCORE_ReadConfigInteger(ssl_mode, "proxy.config.ssl.enabled");
  ssl_mode &= SSL_TERM_MODE_BOTH;
  termMode = (SSL_TERMINATION_MODE) ssl_mode;

  IOCORE_ReadConfigInt32(ssl_accept_port_number, "proxy.config.ssl.server_port");
  IOCORE_ReadConfigInt32(clientCertLevel, "proxy.config.ssl.client.certification_level");

  IOCORE_ReadConfigStringAlloc(cipherSuite, "proxy.config.ssl.server.cipher_suite");

  int options;
  IOCORE_ReadConfigInteger(options, "proxy.config.ssl.SSLv2");
  if (!options)
    ssl_ctx_options |= SSL_OP_NO_SSLv2;
  IOCORE_ReadConfigInteger(options, "proxy.config.ssl.SSLv3");
  if (!options)
    ssl_ctx_options |= SSL_OP_NO_SSLv3;
  IOCORE_ReadConfigInteger(options, "proxy.config.ssl.TLSv1");
  if (!options)
    ssl_ctx_options |= SSL_OP_NO_TLSv1;
#ifdef SSL_OP_CIPHER_SERVER_PREFERENCE
  IOCORE_ReadConfigInteger(options, "proxy.config.ssl.server.honor_cipher_order");
  if (!options)
    ssl_ctx_options |= SSL_OP_CIPHER_SERVER_PREFERENCE;
#endif
#ifdef SSL_OP_NO_COMPRESSION
  IOCORE_ReadConfigInteger(options, "proxy.config.ssl.compression");
  if (!options)
    ssl_ctx_options |= SSL_OP_NO_COMPRESSION;
#endif

  IOCORE_ReadConfigString(serverCertFilename, "proxy.config.ssl.server.cert.filename", PATH_NAME_MAX);
  IOCORE_ReadConfigString(serverCertRelativePath, "proxy.config.ssl.server.cert.path", PATH_NAME_MAX);
  set_paths_helper(serverCertRelativePath, serverCertFilename, &serverCertPathOnly, &serverCertPath);

  char *cert_chain = NULL;
  IOCORE_ReadConfigStringAlloc(cert_chain, "proxy.config.ssl.server.cert_chain.filename");
  set_paths_helper(serverCertRelativePath, cert_chain, &serverCertPathOnly, &serverCertChainPath);
  ats_free(cert_chain);

  IOCORE_ReadConfigStringAlloc(multicert_config_file, "proxy.config.ssl.server.multicert.filename");
  set_paths_helper(Layout::get()->sysconfdir, multicert_config_file, NULL, &configFilePath);
  ats_free(multicert_config_file);

  IOCORE_ReadConfigStringAlloc(ssl_server_private_key_filename, "proxy.config.ssl.server.private_key.filename");
  IOCORE_ReadConfigStringAlloc(ssl_server_private_key_path, "proxy.config.ssl.server.private_key.path");
  set_paths_helper(ssl_server_private_key_path, ssl_server_private_key_filename, &serverKeyPathOnly, &serverKeyPath);
  ats_free(ssl_server_private_key_filename);
  ats_free(ssl_server_private_key_path);

  IOCORE_ReadConfigStringAlloc(CACertFilename, "proxy.config.ssl.CA.cert.filename");
  IOCORE_ReadConfigStringAlloc(CACertRelativePath, "proxy.config.ssl.CA.cert.path");
  set_paths_helper(CACertRelativePath, CACertFilename, &CACertPath, &CACertFilename);
  ats_free(CACertRelativePath);

  // SSL session cache configurations
  IOCORE_ReadConfigInteger(ssl_session_cache, "proxy.config.ssl.session_cache");
  IOCORE_ReadConfigInteger(ssl_session_cache_size, "proxy.config.ssl.session_cache.size");

  // ++++++++++++++++++++++++ Client part ++++++++++++++++++++
  client_verify_depth = 7;
  IOCORE_ReadConfigInt32(clientVerify, "proxy.config.ssl.client.verify.server");

  ssl_client_cert_filename = NULL;
  ssl_client_cert_path = NULL;
  IOCORE_ReadConfigStringAlloc(ssl_client_cert_filename, "proxy.config.ssl.client.cert.filename");
  IOCORE_ReadConfigStringAlloc(ssl_client_cert_path, "proxy.config.ssl.client.cert.path");
  set_paths_helper(ssl_client_cert_path ssl_client_cert_filename, NULL, &clientCertPath);
  ats_free_null(ssl_client_cert_filename);
  ats_fre_nulle(ssl_client_cert_path);

  IOCORE_ReadConfigStringAlloc(ssl_client_private_key_filename, "proxy.config.ssl.client.private_key.filename");
  IOCORE_ReadConfigStringAlloc(ssl_client_private_key_path, "proxy.config.ssl.client.private_key.path");
  set_paths_helper(ssl_client_private_key_path, ssl_client_private_key_filename, NULL, &clientKeyPath);
  ats_free_null(ssl_client_private_key_filename);
  ats_fre_nulle(ssl_client_private_key_path);

  IOCORE_ReadConfigStringAlloc(clientCACertFilename, "proxy.config.ssl.client.CA.cert.filename");
  IOCORE_ReadConfigStringAlloc(clientCACertRelativePath, "proxy.config.ssl.client.CA.cert.path");
  set_paths_helper(clientCACertRelativePath, clientCACertFilename, &clientCACertPath, &clientCACertFilename);
  ats_free(clientCACertRelativePath);
}

void
SslConfig::startup()
{
  reconfigure();
}

void
SslConfig::reconfigure()
{
  SslConfigParams *params;
  params = NEW(new SslConfigParams);
  params->initialize();         // re-read configuration
#ifdef USE_CONFIG_PROCESSOR
  id = configProcessor.set(id, params);
#else
  ssl_config_params = params;
#endif
  serverSSLTermination = (params->termMode & SslConfigParams::SSL_TERM_MODE_SERVER) != 0;
}

SslConfigParams *
SslConfig::acquire()
{
#ifndef USE_CONFIG_PROCESSOR
  return ssl_config_params;
#else
  return ((SslConfigParams *) configProcessor.get(id));
#endif
}

void
SslConfig::release(SslConfigParams * params)
{
  (void) params;
#ifdef USE_CONFIG_PROCESSOR
  configProcessor.release(id, params);
#endif
}
<|endoftext|>


<commit_before>#include "ofxSquareScreen.h"

//--------------------------------------------------------------
void ofxSquareScreen::setup(){
	mode = SC_MODE_INIT;
	sWidth = ofGetWidth();
	sHeight = ofGetHeight();

	tween.setParameters(easingsine, ofxTween::easeInOut
			, sWidth
			, sWidth
			, 100,0);
}

//--------------------------------------------------------------
void ofxSquareScreen::nextMode(){
	mode = (mode + 1) % 6;

	cout << "new mode : " << ofToString(mode) << endl;

	switch (mode)
	{
	case SC_MODE_INIT : setup(); break;
	case SC_MODE_BEGIN : {
		tween.setParameters(easingsine, ofxTween::easeInOut
			, ofGetWidth()
			, 0
			, 30000,0);
						 } break;
	case SC_MODE_LINE: {
		tween.setParameters(easingexpo, ofxTween::easeInOut
			, 0
			, PI
			, 500,0);
					   } break;
	case SC_MODE_BEGIN_REOPEN: {
		tween.setParameters(easingback, ofxTween::easeOut
			, 0
			, ofGetWidth()*0.3
			, 2000,0);
							   } break;
	case SC_MODE_CLOSE : {
		tween.setParameters(easingquad, ofxTween::easeInOut
			, ofGetWidth()*0.3
			, 0
			, 10000, 0);
						 } break;
	case SC_MODE_VOPEN : {
		sWidth = ofGetWidth();
		sHeight = 0;
		tween.setParameters(easingquad, ofxTween::easeInOut
			, 0
			, ofGetHeight()
			, 10000, 0);
						 } break;
	default:
		break;
	}
}

//--------------------------------------------------------------
void ofxSquareScreen::update(){

}

//--------------------------------------------------------------
void ofxSquareScreen::draw(){

	int w = ofGetWidth();
	int h = ofGetHeight();

	int backColor = 0;

	// dimensions update
	switch (mode)
	{
	default :
		sWidth = tween.update(); break;
	case SC_MODE_VOPEN :
		sHeight = tween.update(); break;
	}

	// other updates (alpha, color, mode change)
	switch (mode)
	{
	case SC_MODE_BEGIN : if (tween.isCompleted()) nextMode(); break;
	case SC_MODE_LINE : // same as begin but color
		{
			backColor = (int)(abs(sin(2.f*sWidth))*255);
			if (tween.isCompleted()) nextMode();
		}
		break;
	default:
		break;
	}

	int foreColor = 255-backColor;
	ofPushMatrix();

	ofClear(backColor);
	ofFill();
	ofSetColor(foreColor);

	switch (mode)
	{
	case SC_MODE_LINE: {
		float lineWidth = (float)w * sin(sWidth);
		//cout << ofToString(lineWidth) << endl;
		ofTranslate((w - lineWidth)/2, (h/2-5));
		ofRect(0, 0, lineWidth, 5);
					   } break;
	case SC_MODE_VOPEN: {
		if (openFromBottom) {
			ofTranslate(0, (h-sHeight));
		} else {
			ofTranslate(0, 0);
		}
		ofRect(0, 0, w, sHeight);
						} break;
	default: {
		ofTranslate((w - sWidth)/2, 0);
		ofRect(0, 0, sWidth, h);
			 }
			 break;
	}

	ofPopMatrix();

}

//--------------------------------------------------------------
void ofxSquareScreen::keyPressed(int key){
	switch (key)
	{
	case ' ' : nextMode(); break;
	case 'r': setup(); break;
	default:
		break;
	}
}<commit_msg>replaced ofClear by ofBackground to fix postProcessing<commit_after>#include "ofxSquareScreen.h"

//--------------------------------------------------------------
void ofxSquareScreen::setup(){
	mode = SC_MODE_INIT;
	sWidth = ofGetWidth();
	sHeight = ofGetHeight();

	tween.setParameters(easingsine, ofxTween::easeInOut
			, sWidth
			, sWidth
			, 100,0);
}

//--------------------------------------------------------------
void ofxSquareScreen::nextMode(){
	mode = (mode + 1) % 6;

	cout << "new mode : " << ofToString(mode) << endl;

	switch (mode)
	{
	case SC_MODE_INIT : setup(); break;
	case SC_MODE_BEGIN : {
		tween.setParameters(easingsine, ofxTween::easeInOut
			, ofGetWidth()
			, 0
			, 30000,0);
						 } break;
	case SC_MODE_LINE: {
		tween.setParameters(easingexpo, ofxTween::easeInOut
			, 0
			, PI
			, 500,0);
					   } break;
	case SC_MODE_BEGIN_REOPEN: {
		tween.setParameters(easingback, ofxTween::easeOut
			, 0
			, ofGetWidth()*0.3
			, 2000,0);
							   } break;
	case SC_MODE_CLOSE : {
		tween.setParameters(easingquad, ofxTween::easeInOut
			, ofGetWidth()*0.3
			, 0
			, 10000, 0);
						 } break;
	case SC_MODE_VOPEN : {
		sWidth = ofGetWidth();
		sHeight = 0;
		tween.setParameters(easingquad, ofxTween::easeInOut
			, 0
			, ofGetHeight()
			, 10000, 0);
						 } break;
	default:
		break;
	}
}

//--------------------------------------------------------------
void ofxSquareScreen::update(){

}

//--------------------------------------------------------------
void ofxSquareScreen::draw(){

	int w = ofGetWidth();
	int h = ofGetHeight();

	int backColor = 0;

	// dimensions update
	switch (mode)
	{
	default :
		sWidth = tween.update(); break;
	case SC_MODE_VOPEN :
		sHeight = tween.update(); break;
	}

	// other updates (alpha, color, mode change)
	switch (mode)
	{
	case SC_MODE_BEGIN : if (tween.isCompleted()) nextMode(); break;
	case SC_MODE_LINE : // same as begin but color
		{
			backColor = (int)(abs(sin(2.f*sWidth))*255);
			if (tween.isCompleted()) nextMode();
		}
		break;
	default:
		break;
	}

	int foreColor = 255-backColor;
	ofPushMatrix();

	ofBackground(backColor);
	ofFill();
	ofSetColor(foreColor);

	switch (mode)
	{
	case SC_MODE_LINE: {
		float lineWidth = (float)w * sin(sWidth);
		//cout << ofToString(lineWidth) << endl;
		ofTranslate((w - lineWidth)/2, (h/2-5));
		ofRect(0, 0, lineWidth, 5);
					   } break;
	case SC_MODE_VOPEN: {
		if (openFromBottom) {
			ofTranslate(0, (h-sHeight));
		} else {
			ofTranslate(0, 0);
		}
		ofRect(0, 0, w, sHeight);
						} break;
	default: {
		ofTranslate((w - sWidth)/2, 0);
		ofRect(0, 0, sWidth, h);
			 }
			 break;
	}

	ofPopMatrix();

}

//--------------------------------------------------------------
void ofxSquareScreen::keyPressed(int key){
	switch (key)
	{
	case ' ' : nextMode(); break;
	case 'r': setup(); break;
	default:
		break;
	}
}<|endoftext|>


<commit_before>/** @file

  Support class for describing the local machine.

  @section license License

  Licensed to the Apache Software Foundation (ASF) under one
  or more contributor license agreements.  See the NOTICE file
  distributed with this work for additional information
  regarding copyright ownership.  The ASF licenses this file
  to you under the Apache License, Version 2.0 (the
  "License"); you may not use this file except in compliance
  with the License.  You may obtain a copy of the License at

      http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.
 */

#include "libts.h"
#include "I_Machine.h"
#include <ifaddrs.h>

// Singleton
Machine* Machine::_instance = NULL;

Machine*
Machine::instance() {
  ink_assert(_instance || !"Machine instance accessed before initialization");
  return Machine::_instance;
}

Machine*
Machine::init(char const* name, sockaddr const* ip) {
  ink_assert(!_instance || !"Machine instance initialized twice.");
  Machine::_instance = new Machine(name, ip);
  return Machine::_instance;
}

Machine::Machine(char const* the_hostname, sockaddr const* addr)
  : hostname(0), hostname_len(0)
  , ip_string_len(0)
  , ip_hex_string_len(0)
{
  char localhost[1024];
  int status; // return for system calls.

  ip_string[0] = 0;
  ip_hex_string[0] = 0;
  ink_zero(ip);
  ink_zero(ip4);
  ink_zero(ip6);

  localhost[sizeof(localhost)-1] = 0; // ensure termination.

  if (!ink_inet_is_ip(addr)) {
    if (!the_hostname) {
      ink_release_assert(!gethostname(localhost, sizeof(localhost)-1));
      the_hostname = localhost;
    }
    hostname = ats_strdup(the_hostname);

    ifaddrs* ifa_addrs = 0;
    status = getifaddrs(&ifa_addrs);
    if (0 != status) {
      Warning("Unable to determine local host '%s' address information - %s"
        , hostname
        , strerror(errno)
      );
    } else {
      /* Loop through the interface addresses. We have to prioritize
         the values a little bit. The worst is the loopback address,
         we accept that only if we can't find anything else. Next best
         are non-routables and the best are "global" addresses.
      */
      enum { NA, LO, NR, MC, GA } spot_type = NA, type = NA, ip4_type = NA, ip6_type = NA;
      for (ifaddrs* spot = ifa_addrs ; spot ; spot = spot->ifa_next ) {

        if (!ink_inet_is_ip(spot->ifa_addr)) spot_type = NA;
        else if (ink_inet_is_loopback(spot->ifa_addr)) spot_type = LO;
        else if (ink_inet_is_nonroutable(spot->ifa_addr)) spot_type = NR;
        else if (ink_inet_is_multicast(spot->ifa_addr)) spot_type = MC;
        else type = GA;

        if (spot_type == NA) continue; // Next!

        if (ink_inet_is_ip4(spot->ifa_addr)) {
          if (spot_type > ip4_type) {
            ink_inet_copy(&ip4, spot->ifa_addr);
            ip4_type = spot_type;
          }
        } else if (ink_inet_is_ip6(spot->ifa_addr)) {
          if (spot_type > ip6_type) {
            ink_inet_copy(&ip6, spot->ifa_addr);
            ip6_type = spot_type;
          }
        }
      }
      freeifaddrs(ifa_addrs);
      // What about the general address? Prefer IPv4?
      if (ip4_type >= ip6_type)
        ink_inet_copy(&ip.sa, &ip4.sa);
      else
        ink_inet_copy(&ip.sa, &ip6.sa);
    }
  } else { // address provided.
    ink_inet_copy(&ip, addr);
    if (ink_inet_is_ip4(addr)) ink_inet_copy(&ip4, addr);
    else if (ink_inet_is_ip6(addr)) ink_inet_copy(&ip6, addr);

    status = getnameinfo(
      addr, ink_inet_ip_size(addr),
      localhost, sizeof(localhost) - 1,
      0, 0, // do not request service info
      0 // no flags.
    );

    if (0 != status) {
      ip_text_buffer ipbuff;
      Warning("Failed to find hostname for address '%s' - %s"
        , ink_inet_ntop(addr, ipbuff, sizeof(ipbuff))
        , gai_strerror(status)
      );
    } else
      hostname = ats_strdup(localhost);
  }

  hostname_len = hostname ? strlen(hostname) : 0;

  ink_inet_ntop(&ip.sa, ip_string, sizeof(ip_string));
  ip_string_len = strlen(ip_string);
  ip_hex_string_len = ink_inet_to_hex(&ip.sa, ip_hex_string, sizeof(ip_hex_string));
}

Machine::~Machine()
{
  ats_free(hostname);
}
<commit_msg>Fix building with -Werror=unused-but-set-variable for last checkin<commit_after>/** @file

  Support class for describing the local machine.

  @section license License

  Licensed to the Apache Software Foundation (ASF) under one
  or more contributor license agreements.  See the NOTICE file
  distributed with this work for additional information
  regarding copyright ownership.  The ASF licenses this file
  to you under the Apache License, Version 2.0 (the
  "License"); you may not use this file except in compliance
  with the License.  You may obtain a copy of the License at

      http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.
 */

#include "libts.h"
#include "I_Machine.h"
#include <ifaddrs.h>

// Singleton
Machine* Machine::_instance = NULL;

Machine*
Machine::instance() {
  ink_assert(_instance || !"Machine instance accessed before initialization");
  return Machine::_instance;
}

Machine*
Machine::init(char const* name, sockaddr const* ip) {
  ink_assert(!_instance || !"Machine instance initialized twice.");
  Machine::_instance = new Machine(name, ip);
  return Machine::_instance;
}

Machine::Machine(char const* the_hostname, sockaddr const* addr)
  : hostname(0), hostname_len(0)
  , ip_string_len(0)
  , ip_hex_string_len(0)
{
  char localhost[1024];
  int status; // return for system calls.

  ip_string[0] = 0;
  ip_hex_string[0] = 0;
  ink_zero(ip);
  ink_zero(ip4);
  ink_zero(ip6);

  localhost[sizeof(localhost)-1] = 0; // ensure termination.

  if (!ink_inet_is_ip(addr)) {
    if (!the_hostname) {
      ink_release_assert(!gethostname(localhost, sizeof(localhost)-1));
      the_hostname = localhost;
    }
    hostname = ats_strdup(the_hostname);

    ifaddrs* ifa_addrs = 0;
    status = getifaddrs(&ifa_addrs);
    if (0 != status) {
      Warning("Unable to determine local host '%s' address information - %s"
        , hostname
        , strerror(errno)
      );
    } else {
      /* Loop through the interface addresses. We have to prioritize
         the values a little bit. The worst is the loopback address,
         we accept that only if we can't find anything else. Next best
         are non-routables and the best are "global" addresses.
      */
      enum { NA, LO, NR, MC, GA } spot_type = NA, ip4_type = NA, ip6_type = NA;
      for (ifaddrs* spot = ifa_addrs ; spot ; spot = spot->ifa_next ) {

        if (!ink_inet_is_ip(spot->ifa_addr)) spot_type = NA;
        else if (ink_inet_is_loopback(spot->ifa_addr)) spot_type = LO;
        else if (ink_inet_is_nonroutable(spot->ifa_addr)) spot_type = NR;
        else if (ink_inet_is_multicast(spot->ifa_addr)) spot_type = MC;

        if (spot_type == NA) continue; // Next!

        if (ink_inet_is_ip4(spot->ifa_addr)) {
          if (spot_type > ip4_type) {
            ink_inet_copy(&ip4, spot->ifa_addr);
            ip4_type = spot_type;
          }
        } else if (ink_inet_is_ip6(spot->ifa_addr)) {
          if (spot_type > ip6_type) {
            ink_inet_copy(&ip6, spot->ifa_addr);
            ip6_type = spot_type;
          }
        }
      }
      freeifaddrs(ifa_addrs);
      // What about the general address? Prefer IPv4?
      if (ip4_type >= ip6_type)
        ink_inet_copy(&ip.sa, &ip4.sa);
      else
        ink_inet_copy(&ip.sa, &ip6.sa);
    }
  } else { // address provided.
    ink_inet_copy(&ip, addr);
    if (ink_inet_is_ip4(addr)) ink_inet_copy(&ip4, addr);
    else if (ink_inet_is_ip6(addr)) ink_inet_copy(&ip6, addr);

    status = getnameinfo(
      addr, ink_inet_ip_size(addr),
      localhost, sizeof(localhost) - 1,
      0, 0, // do not request service info
      0 // no flags.
    );

    if (0 != status) {
      ip_text_buffer ipbuff;
      Warning("Failed to find hostname for address '%s' - %s"
        , ink_inet_ntop(addr, ipbuff, sizeof(ipbuff))
        , gai_strerror(status)
      );
    } else
      hostname = ats_strdup(localhost);
  }

  hostname_len = hostname ? strlen(hostname) : 0;

  ink_inet_ntop(&ip.sa, ip_string, sizeof(ip_string));
  ip_string_len = strlen(ip_string);
  ip_hex_string_len = ink_inet_to_hex(&ip.sa, ip_hex_string, sizeof(ip_hex_string));
}

Machine::~Machine()
{
  ats_free(hostname);
}
<|endoftext|>


<commit_before>// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "ipc/ipc_channel_nacl.h"

#include <errno.h>
#include <stddef.h>
#include <sys/nacl_imc_api.h>
#include <sys/nacl_syscalls.h>
#include <sys/types.h>

#include <algorithm>

#include "base/bind.h"
#include "base/file_util.h"
#include "base/logging.h"
#include "base/message_loop_proxy.h"
#include "base/process_util.h"
#include "base/synchronization/lock.h"
#include "base/task_runner_util.h"
#include "base/threading/simple_thread.h"
#include "ipc/file_descriptor_set_posix.h"
#include "ipc/ipc_logging.h"

namespace IPC {
namespace {

scoped_ptr<std::vector<char> > ReadDataOnReaderThread(int pipe) {
  DCHECK(pipe >= 0);

  if (pipe < 0)
    return scoped_ptr<std::vector<char> >();

  scoped_ptr<std::vector<char> > buffer(
      new std::vector<char>(Channel::kReadBufferSize));
  struct NaClImcMsgHdr msg = {0};
  struct NaClImcMsgIoVec iov = {&buffer->at(0), buffer->size()};
  msg.iov = &iov;
  msg.iov_length = 1;

  int bytes_read = imc_recvmsg(pipe, &msg, 0);

  if (bytes_read <= 0) {
    // NaClIPCAdapter::BlockingReceive returns -1 when the pipe closes (either
    // due to error or for regular shutdown).
    return scoped_ptr<std::vector<char> >();
  }
  DCHECK(bytes_read);
  buffer->resize(bytes_read);
  return buffer.Pass();
}

}  // namespace

class Channel::ChannelImpl::ReaderThreadRunner
    : public base::DelegateSimpleThread::Delegate {
 public:
  // |pipe|: A file descriptor from which we will read using imc_recvmsg.
  // |data_read_callback|: A callback we invoke (on the main thread) when we
  //                       have read data. The callback is passed a buffer of
  //                       data that was read.
  // |failure_callback|: A callback we invoke when we have a failure reading
  //                     from |pipe|.
  // |main_message_loop|: A proxy for the main thread, where we will invoke the
  //                      above callbacks.
  ReaderThreadRunner(
      int pipe,
      base::Callback<void (scoped_ptr<std::vector<char> >)> data_read_callback,
      base::Callback<void ()> failure_callback,
      base::MessageLoopProxy* main_message_loop);

  // DelegateSimpleThread implementation. Reads data from the pipe in a loop
  // until either we are told to quit or a read fails.
  virtual void Run() OVERRIDE;

 private:
  int pipe_;
  base::Callback<void (scoped_ptr<std::vector<char> >)> data_read_callback_;
  base::Callback<void ()> failure_callback_;
  base::MessageLoopProxy* main_message_loop_;

  DISALLOW_COPY_AND_ASSIGN(ReaderThreadRunner);
};

Channel::ChannelImpl::ReaderThreadRunner::ReaderThreadRunner(
    int pipe,
    base::Callback<void (scoped_ptr<std::vector<char> >)> data_read_callback,
    base::Callback<void ()> failure_callback,
    base::MessageLoopProxy* main_message_loop)
    : pipe_(pipe),
      data_read_callback_(data_read_callback),
      failure_callback_(failure_callback),
      main_message_loop_(main_message_loop) {
}

void Channel::ChannelImpl::ReaderThreadRunner::Run() {
  while (true) {
    scoped_ptr<std::vector<char> > buffer(ReadDataOnReaderThread(pipe_));
    if (buffer.get()) {
      main_message_loop_->PostTask(FROM_HERE,
          base::Bind(data_read_callback_, base::Passed(buffer.Pass())));
    } else {
      main_message_loop_->PostTask(FROM_HERE, failure_callback_);
      // Because the read failed, we know we're going to quit. Don't bother
      // trying to read again.
      return;
    }
  }
}

Channel::ChannelImpl::ChannelImpl(const IPC::ChannelHandle& channel_handle,
                                  Mode mode,
                                  Listener* listener)
    : ChannelReader(listener),
      mode_(mode),
      waiting_connect_(true),
      pipe_(-1),
      pipe_name_(channel_handle.name),
      weak_ptr_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) {
  if (!CreatePipe(channel_handle)) {
    // The pipe may have been closed already.
    const char *modestr = (mode_ & MODE_SERVER_FLAG) ? "server" : "client";
    LOG(WARNING) << "Unable to create pipe named \"" << channel_handle.name
                 << "\" in " << modestr << " mode";
  }
  reader_thread_runner_.reset(
      new ReaderThreadRunner(
          pipe_,
          base::Bind(&Channel::ChannelImpl::DidRecvMsg,
                     weak_ptr_factory_.GetWeakPtr()),
          base::Bind(&Channel::ChannelImpl::ReadDidFail,
                     weak_ptr_factory_.GetWeakPtr()),
          base::MessageLoopProxy::current()));
  reader_thread_.reset(
      new base::DelegateSimpleThread(reader_thread_runner_.get(),
                                     "ipc_channel_nacl reader thread"));
}

Channel::ChannelImpl::~ChannelImpl() {
  Close();
}

bool Channel::ChannelImpl::Connect() {
  if (pipe_ == -1) {
    DLOG(INFO) << "Channel creation failed: " << pipe_name_;
    return false;
  }

  reader_thread_->Start();
  waiting_connect_ = false;
  // If there were any messages queued before connection, send them.
  ProcessOutgoingMessages();
}

void Channel::ChannelImpl::Close() {
  // For now, we assume that at shutdown, the reader thread will be woken with
  // a failure (see NaClIPCAdapter::BlockingRead and CloseChannel). Or... we
  // might simply be killed with no chance to clean up anyway :-).
  // If untrusted code tries to close the channel prior to shutdown, it's likely
  // to hang.
  // TODO(dmichael): Can we do anything smarter here to make sure the reader
  //                 thread wakes up and quits?
  reader_thread_->Join();
  close(pipe_);
  pipe_ = -1;
  reader_thread_runner_.reset();
  reader_thread_.reset();
  read_queue_.clear();
  output_queue_.clear();
}

bool Channel::ChannelImpl::Send(Message* message) {
  DVLOG(2) << "sending message @" << message << " on channel @" << this
           << " with type " << message->type();
  scoped_ptr<Message> message_ptr(message);

#ifdef IPC_MESSAGE_LOG_ENABLED
  Logging::GetInstance()->OnSendMessage(message, "");
#endif  // IPC_MESSAGE_LOG_ENABLED

  output_queue_.push_back(linked_ptr<Message>(message));
  if (!waiting_connect_)
    return ProcessOutgoingMessages();

  return true;
}

void Channel::ChannelImpl::DidRecvMsg(scoped_ptr<std::vector<char> > buffer) {
  // Close sets the pipe to -1. It's possible we'll get a buffer sent to us from
  // the reader thread after Close is called. If so, we ignore it.
  if (pipe_ == -1)
    return;

  read_queue_.push_back(linked_ptr<std::vector<char> >(buffer.release()));
}

void Channel::ChannelImpl::ReadDidFail() {
  Close();
}

bool Channel::ChannelImpl::CreatePipe(
    const IPC::ChannelHandle& channel_handle) {
  DCHECK(pipe_ == -1);

  // There's one possible case in NaCl:
  // 1) It's a channel wrapping a pipe that is given to us.
  // We don't support these:
  // 2) It's for a named channel.
  // 3) It's for a client that we implement ourself.
  // 4) It's the initial IPC channel.

  if (channel_handle.socket.fd == -1) {
    NOTIMPLEMENTED();
    return false;
  }
  pipe_ = channel_handle.socket.fd;
  return true;
}

bool Channel::ChannelImpl::ProcessOutgoingMessages() {
  DCHECK(!waiting_connect_);  // Why are we trying to send messages if there's
                              // no connection?
  if (output_queue_.empty())
    return true;

  if (pipe_ == -1)
    return false;

  // Write out all the messages. The trusted implementation is guaranteed to not
  // block. See NaClIPCAdapter::Send for the implementation of imc_sendmsg.
  while (!output_queue_.empty()) {
    linked_ptr<Message> msg = output_queue_.front();
    output_queue_.pop_front();

    struct NaClImcMsgHdr msgh = {0};
    struct NaClImcMsgIoVec iov = {const_cast<void*>(msg->data()), msg->size()};
    msgh.iov = &iov;
    msgh.iov_length = 1;
    ssize_t bytes_written = imc_sendmsg(pipe_, &msgh, 0);

    if (bytes_written < 0) {
      // The trusted side should only ever give us an error of EPIPE. We
      // should never be interrupted, nor should we get EAGAIN.
      DCHECK(errno == EPIPE);
      Close();
      PLOG(ERROR) << "pipe_ error on "
                  << pipe_
                  << " Currently writing message of size: "
                  << msg->size();
      return false;
    }

    // Message sent OK!
    DVLOG(2) << "sent message @" << msg.get() << " with type " << msg->type()
             << " on fd " << pipe_;
  }
  return true;
}

Channel::ChannelImpl::ReadState Channel::ChannelImpl::ReadData(
    char* buffer,
    int buffer_len,
    int* bytes_read) {
  *bytes_read = 0;
  if (pipe_ == -1)
    return READ_FAILED;
  if (read_queue_.empty())
    return READ_PENDING;
  while (!read_queue_.empty() && *bytes_read < buffer_len) {
    linked_ptr<std::vector<char> > vec(read_queue_.front());
    int bytes_to_read = buffer_len - *bytes_read;
    if (vec->size() <= bytes_to_read) {
      // We can read and discard the entire vector.
      std::copy(vec->begin(), vec->end(), buffer + *bytes_read);
      *bytes_read += vec->size();
      read_queue_.pop_front();
    } else {
      // Read all the bytes we can and discard them from the front of the
      // vector. (This can be slowish, since erase has to move the back of the
      // vector to the front, but it's hopefully a temporary hack and it keeps
      // the code simple).
      std::copy(vec->begin(), vec->begin() + bytes_to_read,
                buffer + *bytes_read);
      vec->erase(vec->begin(), vec->begin() + bytes_to_read);
      *bytes_read += bytes_to_read;
    }
  }
  return READ_SUCCEEDED;
}

bool Channel::ChannelImpl::WillDispatchInputMessage(Message* msg) {
  return true;
}

bool Channel::ChannelImpl::DidEmptyInputBuffers() {
  return true;
}

void Channel::ChannelImpl::HandleHelloMessage(const Message& msg) {
  // The trusted side IPC::Channel should handle the "hello" handshake; we
  // should not receive the "Hello" message.
  NOTREACHED();
}

//------------------------------------------------------------------------------
// Channel's methods simply call through to ChannelImpl.

Channel::Channel(const IPC::ChannelHandle& channel_handle,
                 Mode mode,
                 Listener* listener)
    : channel_impl_(new ChannelImpl(channel_handle, mode, listener)) {
}

Channel::~Channel() {
  delete channel_impl_;
}

bool Channel::Connect() {
  return channel_impl_->Connect();
}

void Channel::Close() {
  channel_impl_->Close();
}

void Channel::set_listener(Listener* listener) {
  channel_impl_->set_listener(listener);
}

base::ProcessId Channel::peer_pid() const {
  // This shouldn't actually get used in the untrusted side of the proxy, and we
  // don't have the real pid anyway.
  return -1;
}

bool Channel::Send(Message* message) {
  return channel_impl_->Send(message);
}

// static
std::string Channel::GenerateVerifiedChannelID(const std::string& prefix) {
  // A random name is sufficient validation on posix systems, so we don't need
  // an additional shared secret.
  std::string id = prefix;
  if (!id.empty())
    id.append(".");

  return id.append(GenerateUniqueRandomChannelID());
}

}  // namespace IPC
<commit_msg>PPAPI/NaCl: Minor fixes to ipc_channel_nacl<commit_after>// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "ipc/ipc_channel_nacl.h"

#include <errno.h>
#include <stddef.h>
#include <sys/nacl_imc_api.h>
#include <sys/nacl_syscalls.h>
#include <sys/types.h>

#include <algorithm>

#include "base/bind.h"
#include "base/file_util.h"
#include "base/logging.h"
#include "base/message_loop_proxy.h"
#include "base/process_util.h"
#include "base/synchronization/lock.h"
#include "base/task_runner_util.h"
#include "base/threading/simple_thread.h"
#include "ipc/file_descriptor_set_posix.h"
#include "ipc/ipc_logging.h"

namespace IPC {
namespace {

scoped_ptr<std::vector<char> > ReadDataOnReaderThread(int pipe) {
  DCHECK(pipe >= 0);

  if (pipe < 0)
    return scoped_ptr<std::vector<char> >();

  scoped_ptr<std::vector<char> > buffer(
      new std::vector<char>(Channel::kReadBufferSize));
  struct NaClImcMsgHdr msg = {0};
  struct NaClImcMsgIoVec iov = {&buffer->at(0), buffer->size()};
  msg.iov = &iov;
  msg.iov_length = 1;

  int bytes_read = imc_recvmsg(pipe, &msg, 0);

  if (bytes_read <= 0) {
    // NaClIPCAdapter::BlockingReceive returns -1 when the pipe closes (either
    // due to error or for regular shutdown).
    return scoped_ptr<std::vector<char> >();
  }
  DCHECK(bytes_read);
  buffer->resize(bytes_read);
  return buffer.Pass();
}

}  // namespace

class Channel::ChannelImpl::ReaderThreadRunner
    : public base::DelegateSimpleThread::Delegate {
 public:
  // |pipe|: A file descriptor from which we will read using imc_recvmsg.
  // |data_read_callback|: A callback we invoke (on the main thread) when we
  //                       have read data. The callback is passed a buffer of
  //                       data that was read.
  // |failure_callback|: A callback we invoke when we have a failure reading
  //                     from |pipe|.
  // |main_message_loop|: A proxy for the main thread, where we will invoke the
  //                      above callbacks.
  ReaderThreadRunner(
      int pipe,
      base::Callback<void (scoped_ptr<std::vector<char> >)> data_read_callback,
      base::Callback<void ()> failure_callback,
      base::MessageLoopProxy* main_message_loop);

  // DelegateSimpleThread implementation. Reads data from the pipe in a loop
  // until either we are told to quit or a read fails.
  virtual void Run() OVERRIDE;

 private:
  int pipe_;
  base::Callback<void (scoped_ptr<std::vector<char> >)> data_read_callback_;
  base::Callback<void ()> failure_callback_;
  scoped_refptr<base::MessageLoopProxy> main_message_loop_;

  DISALLOW_COPY_AND_ASSIGN(ReaderThreadRunner);
};

Channel::ChannelImpl::ReaderThreadRunner::ReaderThreadRunner(
    int pipe,
    base::Callback<void (scoped_ptr<std::vector<char> >)> data_read_callback,
    base::Callback<void ()> failure_callback,
    base::MessageLoopProxy* main_message_loop)
    : pipe_(pipe),
      data_read_callback_(data_read_callback),
      failure_callback_(failure_callback),
      main_message_loop_(main_message_loop) {
}

void Channel::ChannelImpl::ReaderThreadRunner::Run() {
  while (true) {
    scoped_ptr<std::vector<char> > buffer(ReadDataOnReaderThread(pipe_));
    if (buffer.get()) {
      main_message_loop_->PostTask(FROM_HERE,
          base::Bind(data_read_callback_, base::Passed(buffer.Pass())));
    } else {
      main_message_loop_->PostTask(FROM_HERE, failure_callback_);
      // Because the read failed, we know we're going to quit. Don't bother
      // trying to read again.
      return;
    }
  }
}

Channel::ChannelImpl::ChannelImpl(const IPC::ChannelHandle& channel_handle,
                                  Mode mode,
                                  Listener* listener)
    : ChannelReader(listener),
      mode_(mode),
      waiting_connect_(true),
      pipe_(-1),
      pipe_name_(channel_handle.name),
      weak_ptr_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) {
  if (!CreatePipe(channel_handle)) {
    // The pipe may have been closed already.
    const char *modestr = (mode_ & MODE_SERVER_FLAG) ? "server" : "client";
    LOG(WARNING) << "Unable to create pipe named \"" << channel_handle.name
                 << "\" in " << modestr << " mode";
  }
  reader_thread_runner_.reset(
      new ReaderThreadRunner(
          pipe_,
          base::Bind(&Channel::ChannelImpl::DidRecvMsg,
                     weak_ptr_factory_.GetWeakPtr()),
          base::Bind(&Channel::ChannelImpl::ReadDidFail,
                     weak_ptr_factory_.GetWeakPtr()),
          base::MessageLoopProxy::current()));
  reader_thread_.reset(
      new base::DelegateSimpleThread(reader_thread_runner_.get(),
                                     "ipc_channel_nacl reader thread"));
}

Channel::ChannelImpl::~ChannelImpl() {
  Close();
}

bool Channel::ChannelImpl::Connect() {
  if (pipe_ == -1) {
    DLOG(INFO) << "Channel creation failed: " << pipe_name_;
    return false;
  }

  reader_thread_->Start();
  waiting_connect_ = false;
  // If there were any messages queued before connection, send them.
  ProcessOutgoingMessages();
  return true;
}

void Channel::ChannelImpl::Close() {
  // For now, we assume that at shutdown, the reader thread will be woken with
  // a failure (see NaClIPCAdapter::BlockingRead and CloseChannel). Or... we
  // might simply be killed with no chance to clean up anyway :-).
  // If untrusted code tries to close the channel prior to shutdown, it's likely
  // to hang.
  // TODO(dmichael): Can we do anything smarter here to make sure the reader
  //                 thread wakes up and quits?
  reader_thread_->Join();
  close(pipe_);
  pipe_ = -1;
  reader_thread_runner_.reset();
  reader_thread_.reset();
  read_queue_.clear();
  output_queue_.clear();
}

bool Channel::ChannelImpl::Send(Message* message) {
  DVLOG(2) << "sending message @" << message << " on channel @" << this
           << " with type " << message->type();
  scoped_ptr<Message> message_ptr(message);

#ifdef IPC_MESSAGE_LOG_ENABLED
  Logging::GetInstance()->OnSendMessage(message, "");
#endif  // IPC_MESSAGE_LOG_ENABLED

  output_queue_.push_back(linked_ptr<Message>(message));
  if (!waiting_connect_)
    return ProcessOutgoingMessages();

  return true;
}

void Channel::ChannelImpl::DidRecvMsg(scoped_ptr<std::vector<char> > buffer) {
  // Close sets the pipe to -1. It's possible we'll get a buffer sent to us from
  // the reader thread after Close is called. If so, we ignore it.
  if (pipe_ == -1)
    return;

  read_queue_.push_back(linked_ptr<std::vector<char> >(buffer.release()));
}

void Channel::ChannelImpl::ReadDidFail() {
  Close();
}

bool Channel::ChannelImpl::CreatePipe(
    const IPC::ChannelHandle& channel_handle) {
  DCHECK(pipe_ == -1);

  // There's one possible case in NaCl:
  // 1) It's a channel wrapping a pipe that is given to us.
  // We don't support these:
  // 2) It's for a named channel.
  // 3) It's for a client that we implement ourself.
  // 4) It's the initial IPC channel.

  if (channel_handle.socket.fd == -1) {
    NOTIMPLEMENTED();
    return false;
  }
  pipe_ = channel_handle.socket.fd;
  return true;
}

bool Channel::ChannelImpl::ProcessOutgoingMessages() {
  DCHECK(!waiting_connect_);  // Why are we trying to send messages if there's
                              // no connection?
  if (output_queue_.empty())
    return true;

  if (pipe_ == -1)
    return false;

  // Write out all the messages. The trusted implementation is guaranteed to not
  // block. See NaClIPCAdapter::Send for the implementation of imc_sendmsg.
  while (!output_queue_.empty()) {
    linked_ptr<Message> msg = output_queue_.front();
    output_queue_.pop_front();

    struct NaClImcMsgHdr msgh = {0};
    struct NaClImcMsgIoVec iov = {const_cast<void*>(msg->data()), msg->size()};
    msgh.iov = &iov;
    msgh.iov_length = 1;
    ssize_t bytes_written = imc_sendmsg(pipe_, &msgh, 0);

    if (bytes_written < 0) {
      // The trusted side should only ever give us an error of EPIPE. We
      // should never be interrupted, nor should we get EAGAIN.
      DCHECK(errno == EPIPE);
      Close();
      PLOG(ERROR) << "pipe_ error on "
                  << pipe_
                  << " Currently writing message of size: "
                  << msg->size();
      return false;
    }

    // Message sent OK!
    DVLOG(2) << "sent message @" << msg.get() << " with type " << msg->type()
             << " on fd " << pipe_;
  }
  return true;
}

Channel::ChannelImpl::ReadState Channel::ChannelImpl::ReadData(
    char* buffer,
    int buffer_len,
    int* bytes_read) {
  *bytes_read = 0;
  if (pipe_ == -1)
    return READ_FAILED;
  if (read_queue_.empty())
    return READ_PENDING;
  while (!read_queue_.empty() && *bytes_read < buffer_len) {
    linked_ptr<std::vector<char> > vec(read_queue_.front());
    int bytes_to_read = buffer_len - *bytes_read;
    if (vec->size() <= bytes_to_read) {
      // We can read and discard the entire vector.
      std::copy(vec->begin(), vec->end(), buffer + *bytes_read);
      *bytes_read += vec->size();
      read_queue_.pop_front();
    } else {
      // Read all the bytes we can and discard them from the front of the
      // vector. (This can be slowish, since erase has to move the back of the
      // vector to the front, but it's hopefully a temporary hack and it keeps
      // the code simple).
      std::copy(vec->begin(), vec->begin() + bytes_to_read,
                buffer + *bytes_read);
      vec->erase(vec->begin(), vec->begin() + bytes_to_read);
      *bytes_read += bytes_to_read;
    }
  }
  return READ_SUCCEEDED;
}

bool Channel::ChannelImpl::WillDispatchInputMessage(Message* msg) {
  return true;
}

bool Channel::ChannelImpl::DidEmptyInputBuffers() {
  return true;
}

void Channel::ChannelImpl::HandleHelloMessage(const Message& msg) {
  // The trusted side IPC::Channel should handle the "hello" handshake; we
  // should not receive the "Hello" message.
  NOTREACHED();
}

//------------------------------------------------------------------------------
// Channel's methods simply call through to ChannelImpl.

Channel::Channel(const IPC::ChannelHandle& channel_handle,
                 Mode mode,
                 Listener* listener)
    : channel_impl_(new ChannelImpl(channel_handle, mode, listener)) {
}

Channel::~Channel() {
  delete channel_impl_;
}

bool Channel::Connect() {
  return channel_impl_->Connect();
}

void Channel::Close() {
  channel_impl_->Close();
}

void Channel::set_listener(Listener* listener) {
  channel_impl_->set_listener(listener);
}

base::ProcessId Channel::peer_pid() const {
  // This shouldn't actually get used in the untrusted side of the proxy, and we
  // don't have the real pid anyway.
  return -1;
}

bool Channel::Send(Message* message) {
  return channel_impl_->Send(message);
}

// static
std::string Channel::GenerateVerifiedChannelID(const std::string& prefix) {
  // A random name is sufficient validation on posix systems, so we don't need
  // an additional shared secret.
  std::string id = prefix;
  if (!id.empty())
    id.append(".");

  return id.append(GenerateUniqueRandomChannelID());
}

}  // namespace IPC
<|endoftext|>


<commit_before>// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "build/build_config.h"

#if defined(OS_WIN)
#include <windows.h>
#endif
#include <stack>

#include "base/atomic_sequence_num.h"
#include "base/logging.h"
#include "base/synchronization/waitable_event.h"
#include "ipc/ipc_sync_message.h"

namespace IPC {

#define kSyncMessageHeaderSize 4

static base::AtomicSequenceNumber g_next_id(base::LINKER_INITIALIZED);

static base::WaitableEvent* dummy_event = new base::WaitableEvent(true, true);

SyncMessage::SyncMessage(
    int32 routing_id,
    uint32 type,
    PriorityValue priority,
    MessageReplyDeserializer* deserializer)
    : Message(routing_id, type, priority),
      deserializer_(deserializer),
      pump_messages_event_(NULL)
      {
  set_sync();
  set_unblock(true);

  // Add synchronous message data before the message payload.
  SyncHeader header;
  header.message_id = g_next_id.GetNext();
  WriteSyncHeader(this, header);
}

SyncMessage::~SyncMessage() {
}

MessageReplyDeserializer* SyncMessage::GetReplyDeserializer() {
  DCHECK(deserializer_.get());
  return deserializer_.release();
}

void SyncMessage::EnableMessagePumping() {
  DCHECK(!pump_messages_event_);
  set_pump_messages_event(dummy_event);
}

bool SyncMessage::IsMessageReplyTo(const Message& msg, int request_id) {
  if (!msg.is_reply())
    return false;

  return GetMessageId(msg) == request_id;
}

void* SyncMessage::GetDataIterator(const Message* msg) {
  void* iter = const_cast<char*>(msg->payload());
  UpdateIter(&iter, kSyncMessageHeaderSize);
  return iter;
}

int SyncMessage::GetMessageId(const Message& msg) {
  if (!msg.is_sync() && !msg.is_reply())
    return 0;

  SyncHeader header;
  if (!ReadSyncHeader(msg, &header))
    return 0;

  return header.message_id;
}

Message* SyncMessage::GenerateReply(const Message* msg) {
  DCHECK(msg->is_sync());

  Message* reply = new Message(msg->routing_id(), IPC_REPLY_ID,
                               msg->priority());
  reply->set_reply();

  SyncHeader header;

  // use the same message id, but this time reply bit is set
  header.message_id = GetMessageId(*msg);
  WriteSyncHeader(reply, header);

  return reply;
}

bool SyncMessage::ReadSyncHeader(const Message& msg, SyncHeader* header) {
  DCHECK(msg.is_sync() || msg.is_reply());

  void* iter = NULL;
  bool result = msg.ReadInt(&iter, &header->message_id);
  if (!result) {
    NOTREACHED();
    return false;
  }

  return true;
}

bool SyncMessage::WriteSyncHeader(Message* msg, const SyncHeader& header) {
  DCHECK(msg->is_sync() || msg->is_reply());
  DCHECK(msg->payload_size() == 0);
  bool result = msg->WriteInt(header.message_id);
  if (!result) {
    NOTREACHED();
    return false;
  }

  // Note: if you add anything here, you need to update kSyncMessageHeaderSize.
  DCHECK(kSyncMessageHeaderSize == msg->payload_size());

  return true;
}

bool MessageReplyDeserializer::SerializeOutputParameters(const Message& msg) {
  return SerializeOutputParameters(msg, SyncMessage::GetDataIterator(&msg));
}

}  // namespace IPC
<commit_msg>Remove static initializer in dummy_event<commit_after>// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "build/build_config.h"

#if defined(OS_WIN)
#include <windows.h>
#endif
#include <stack>

#include "base/atomic_sequence_num.h"
#include "base/lazy_instance.h"
#include "base/logging.h"
#include "base/synchronization/waitable_event.h"
#include "ipc/ipc_sync_message.h"

namespace {

struct WaitableEventLazyInstanceTraits
    : public base::DefaultLazyInstanceTraits<base::WaitableEvent> {
  static base::WaitableEvent* New(void* instance) {
    // Use placement new to initialize our instance in our preallocated space.
    return new (instance) base::WaitableEvent(true, true);
  }
};

static base::LazyInstance<base::WaitableEvent, WaitableEventLazyInstanceTraits>
    dummy_event = LAZY_INSTANCE_INITIALIZER;

}

namespace IPC {

#define kSyncMessageHeaderSize 4

static base::AtomicSequenceNumber g_next_id(base::LINKER_INITIALIZED);

SyncMessage::SyncMessage(
    int32 routing_id,
    uint32 type,
    PriorityValue priority,
    MessageReplyDeserializer* deserializer)
    : Message(routing_id, type, priority),
      deserializer_(deserializer),
      pump_messages_event_(NULL)
      {
  set_sync();
  set_unblock(true);

  // Add synchronous message data before the message payload.
  SyncHeader header;
  header.message_id = g_next_id.GetNext();
  WriteSyncHeader(this, header);
}

SyncMessage::~SyncMessage() {
}

MessageReplyDeserializer* SyncMessage::GetReplyDeserializer() {
  DCHECK(deserializer_.get());
  return deserializer_.release();
}

void SyncMessage::EnableMessagePumping() {
  DCHECK(!pump_messages_event_);
  set_pump_messages_event(dummy_event.Pointer());
}

bool SyncMessage::IsMessageReplyTo(const Message& msg, int request_id) {
  if (!msg.is_reply())
    return false;

  return GetMessageId(msg) == request_id;
}

void* SyncMessage::GetDataIterator(const Message* msg) {
  void* iter = const_cast<char*>(msg->payload());
  UpdateIter(&iter, kSyncMessageHeaderSize);
  return iter;
}

int SyncMessage::GetMessageId(const Message& msg) {
  if (!msg.is_sync() && !msg.is_reply())
    return 0;

  SyncHeader header;
  if (!ReadSyncHeader(msg, &header))
    return 0;

  return header.message_id;
}

Message* SyncMessage::GenerateReply(const Message* msg) {
  DCHECK(msg->is_sync());

  Message* reply = new Message(msg->routing_id(), IPC_REPLY_ID,
                               msg->priority());
  reply->set_reply();

  SyncHeader header;

  // use the same message id, but this time reply bit is set
  header.message_id = GetMessageId(*msg);
  WriteSyncHeader(reply, header);

  return reply;
}

bool SyncMessage::ReadSyncHeader(const Message& msg, SyncHeader* header) {
  DCHECK(msg.is_sync() || msg.is_reply());

  void* iter = NULL;
  bool result = msg.ReadInt(&iter, &header->message_id);
  if (!result) {
    NOTREACHED();
    return false;
  }

  return true;
}

bool SyncMessage::WriteSyncHeader(Message* msg, const SyncHeader& header) {
  DCHECK(msg->is_sync() || msg->is_reply());
  DCHECK(msg->payload_size() == 0);
  bool result = msg->WriteInt(header.message_id);
  if (!result) {
    NOTREACHED();
    return false;
  }

  // Note: if you add anything here, you need to update kSyncMessageHeaderSize.
  DCHECK(kSyncMessageHeaderSize == msg->payload_size());

  return true;
}

bool MessageReplyDeserializer::SerializeOutputParameters(const Message& msg) {
  return SerializeOutputParameters(msg, SyncMessage::GetDataIterator(&msg));
}

}  // namespace IPC
<|endoftext|>