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(); } }
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(); } }