Ejemplo n.º 1
0
  static void echo_server(stackful_actor self)
  {
    context& ctx = self.get_context();
    log::logger_t& lg = ctx.get_logger();
    try
    {
      aid_t sender = self->recv("init");
      
      size_t scount = 0;
      errcode_t ec;

      tcp::resolver rsv(self);
      tcp_resolver_t::query qry("0.0.0.0", "23333");
      rsv.async_resolve(qry);
      boost::shared_ptr<tcp_resolver_t::iterator> eitr;
      self->match(tcp::as_resolve).recv(ec, eitr);
      GCE_VERIFY(!ec).except(ec);

      tcp::acceptor acpr(self);
      boost::asio::ip::tcp::endpoint ep = **eitr;

      acpr->open(ep.protocol());

      acpr->set_option(boost::asio::socket_base::reuse_address(true));
      acpr->bind(ep);

      acpr->set_option(boost::asio::socket_base::receive_buffer_size(640000));
      acpr->set_option(boost::asio::socket_base::send_buffer_size(640000));

      acpr->listen(1024);

      acpr->set_option(boost::asio::ip::tcp::no_delay(true));
      acpr->set_option(boost::asio::socket_base::keep_alive(true));
      acpr->set_option(boost::asio::socket_base::enable_connection_aborted(true));

      self->send(sender, "ready");
      
      /// ssl context
      boost::asio::ssl::context ssl_ctx(boost::asio::ssl::context::sslv23);
      ssl_ctx.set_options(
          boost::asio::ssl::context::default_workarounds
          | boost::asio::ssl::context::no_sslv2
          | boost::asio::ssl::context::single_dh_use);
      ssl_ctx.set_password_callback(boost::bind(&ssl_ut::get_password));
      ssl_ctx.use_certificate_chain_file("test_ssl_asio/server.pem");
      ssl_ctx.use_private_key_file("test_ssl_asio/server.pem", boost::asio::ssl::context::pem);
      ssl_ctx.use_tmp_dh_file("test_ssl_asio/dh512.pem");

      while (true)
      {
        boost::shared_ptr<ssl_socket_t> skt = 
          boost::make_shared<ssl_socket_t>(boost::ref(ctx.get_io_service()), boost::ref(ssl_ctx));
        acpr.async_accept(skt->lowest_layer());

        match_t type;
        errcode_t ec;
        message msg;
        self->match(tcp::as_accept, "end", type).raw(msg).recv();
        if (type == atom("end"))
        {
          break;
        }

        msg >> ec;
        if (!ec)
        {
          aid_t cln = spawn(self, boost::bind(&ssl_ut::echo_session, _arg1), monitored);
          self->send(cln, "init", skt);
          ++scount;
        }
      }

      for (size_t i=0; i<scount; ++i)
      {
        self->recv(exit);
      }
    }
    catch (std::exception& ex)
    {
      GCE_ERROR(lg) << ex.what();
    }
  }
Ejemplo n.º 2
0
void galera::ist::Receiver::run()
{
    asio::ip::tcp::socket socket(io_service_);
    asio::ssl::context ssl_ctx(io_service_, asio::ssl::context::sslv23);
    asio::ssl::stream<asio::ip::tcp::socket> ssl_stream(io_service_, ssl_ctx_);
    try
    {
        if (use_ssl_ == true)
        {
            acceptor_.accept(ssl_stream.lowest_layer());
            set_fd_options(ssl_stream.lowest_layer());
            ssl_stream.handshake(asio::ssl::stream<asio::ip::tcp::socket>::server);
        }
        else
        {
            acceptor_.accept(socket);
            set_fd_options(socket);
        }
    }
    catch (asio::system_error& e)
    {
        gu_throw_error(e.code().value()) << "accept() failed"
                                         << "', asio error '"
                                         << e.what() << "'";
    }
    acceptor_.close();
    int ec(0);
    try
    {
        Proto p(version_, conf_.get(CONF_KEEP_KEYS, CONF_KEEP_KEYS_DEFAULT));
        if (use_ssl_ == true)
        {
            p.send_handshake(ssl_stream);
            p.recv_handshake_response(ssl_stream);
            p.send_ctrl(ssl_stream, Ctrl::C_OK);
        }
        else
        {
            p.send_handshake(socket);
            p.recv_handshake_response(socket);
            p.send_ctrl(socket, Ctrl::C_OK);
        }
        while (true)
        {
            TrxHandle* trx;
            if (use_ssl_ == true)
            {
                trx = p.recv_trx(ssl_stream);
            }
            else
            {
                trx = p.recv_trx(socket);
            }
            if (trx != 0)
            {
                if (trx->global_seqno() != current_seqno_)
                {
                    log_error << "unexpected trx seqno: " << trx->global_seqno()
                              << " expected: " << current_seqno_;
                    ec = EINVAL;
                    goto err;
                }
                ++current_seqno_;
            }
            gu::Lock lock(mutex_);
            while (ready_ == false || consumers_.empty())
            {
                lock.wait(cond_);
            }
            Consumer* cons(consumers_.top());
            consumers_.pop();
            cons->trx(trx);
            cons->cond().signal();
            if (trx == 0)
            {
                log_debug << "eof received, closing socket";
                break;
            }
        }
    }
    catch (asio::system_error& e)
    {
        log_error << "got error while reading ist stream: " << e.code();
        ec = e.code().value();
    }
    catch (gu::Exception& e)
    {
        ec = e.get_errno();
        if (ec != EINTR)
        {
            log_error << "got exception while reading ist stream: " << e.what();
        }
    }

err:
    gu::Lock lock(mutex_);
    if (use_ssl_ == true)
    {
        ssl_stream.lowest_layer().close();
        // ssl_stream.shutdown();
    }
    else
    {
        socket.close();
    }

    running_ = false;
    if (ec != EINTR && current_seqno_ - 1 < last_seqno_)
    {
        log_error << "IST didn't contain all write sets, expected last: "
                  << last_seqno_ << " last received: " << current_seqno_ - 1;
        ec = EPROTO;
    }
    if (ec != EINTR)
    {
        error_code_ = ec;
    }
    while (consumers_.empty() == false)
    {
        consumers_.top()->cond().signal();
        consumers_.pop();
    }
}