Ledger Nano X - The secure hardware wallet
SHARE
TWEET

Untitled

a guest Apr 9th, 2020 164 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #include "socket.hpp"
  2. #include "awaiter.hpp"
  3.  
  4. namespace tinyfiber {
  5. namespace tcp {
  6.  
  7. using namespace make_result;
  8.  
  9. Result<Socket> Socket::ConnectTo(const std::string& host, uint16_t port) {
  10.   Socket conn;
  11.   // connect
  12.   auto endpoints = conn.resolver_.resolve(host, std::to_string(port));
  13.   asio::error_code error_code;
  14.   Fiber* fiber = GetCurrentFiber();
  15.  
  16.   asio::async_connect(
  17.       conn.socket_,
  18.       endpoints,
  19.       [fiber, &error_code](
  20.           const asio::error_code& connect_error_code,
  21.           const asio::ip::tcp::endpoint& endpoint) {
  22.  
  23.         error_code = connect_error_code;
  24.         GetCurrentScheduler()->Add(fiber);
  25.   });
  26.  
  27.   GetCurrentScheduler()->Suspend();
  28.  
  29.   if (!error_code) {
  30.     return Result<Socket>::Ok(std::move(conn));
  31.   } else {
  32.     return Result<Socket>::Fail(error_code);
  33.   }
  34. }
  35.  
  36. Result<Socket> Socket::ConnectToLocal(uint16_t port) {
  37.   return ConnectTo("localhost", port);
  38. }
  39.  
  40. Result<size_t> Socket::ReadSome(MutableBuffer buffer) {
  41.   asio::error_code error_code;
  42.   size_t bytes_transferred = 0;
  43.   Fiber* fiber = GetCurrentFiber();
  44.  
  45.   socket_.async_read_some(buffer, [fiber, &error_code, &bytes_transferred](
  46.       const asio::error_code& read_some_error_code,
  47.       size_t bytes_transferred_) {
  48.  
  49.     error_code = read_some_error_code;
  50.     bytes_transferred = bytes_transferred_;
  51.     GetCurrentScheduler()->Add(fiber);
  52.   });
  53.  
  54.   GetCurrentScheduler()->Suspend();
  55.   if (!error_code) {  // some bytes read
  56.     return Result<size_t>::Ok(bytes_transferred);
  57.   } else if (error_code == asio::error::eof) {  // eof reached
  58.     return Result<size_t>::Ok(0);
  59.   } else {  // error occurred
  60.     return Result<size_t>::Fail(error_code);
  61.   }
  62. }
  63.  
  64. Result<size_t> Socket::Read(MutableBuffer buffer) {
  65.   size_t read = 0;
  66.   while (read < buffer.size()) {
  67.     auto bytes_read = ReadSome(asio::buffer(buffer + read, buffer.size() - read));
  68.     if (!bytes_read.IsOk()) {
  69.       return make_result::Fail(bytes_read.Error());
  70.     }
  71.     read += bytes_read.Value();
  72.     if (bytes_read.Value() == 0) {
  73.       break;
  74.     }
  75.   }
  76.   return make_result::Ok(read);
  77. }
  78.  
  79. Status Socket::Write(ConstBuffer buffer) {
  80.   asio::error_code error_code;
  81.   Fiber* fiber = GetCurrentFiber();
  82.  
  83.   asio::async_write(socket_, buffer, [fiber, &error_code](
  84.       const asio::error_code& write_error_code,
  85.       size_t bytes_transferred_) {
  86.  
  87.     error_code = write_error_code;
  88.     GetCurrentScheduler()->Add(fiber);
  89.   });
  90.  
  91.   GetCurrentScheduler()->Suspend();
  92.  
  93.   if (!error_code) {
  94.     return Ok();
  95.   } else {
  96.     return Fail(error_code);
  97.   }
  98. }
  99.  
  100. Status Socket::ShutdownWrite() {
  101.   // Not implemented
  102.   // Use `shutdown` method of ip::tcp::socket
  103.   asio::error_code error_code;
  104.   socket_.shutdown(asio::ip::tcp::socket::shutdown_send, error_code);
  105.   if (!error_code) {
  106.     return Ok();
  107.   } else {
  108.     return Fail(error_code);
  109.   }
  110. }
  111.  
  112. Socket::Socket(): socket_(GetCurrentScheduler()->GetIOContext()), resolver_(GetCurrentScheduler()->GetIOContext()) {
  113.  
  114. }
  115.  
  116. Socket::Socket(asio::ip::tcp::socket&& socket): socket_(std::move(socket)), resolver_(GetCurrentScheduler()->GetIOContext()) {
  117.  
  118. }
  119.  
  120. Acceptor::Acceptor(): acceptor_(GetCurrentScheduler()->GetIOContext()) {
  121.  
  122. }
  123.  
  124. Status Acceptor::Listen(uint16_t port) {
  125.   asio::ip::tcp::endpoint ep(asio::ip::tcp::v4(), port);
  126.   asio::error_code error_code;
  127.  
  128.   acceptor_.open(ep.protocol(), error_code);
  129.   if (error_code) {
  130.     return Fail(error_code);
  131.   }
  132.  
  133.   acceptor_.set_option(asio::ip::tcp::acceptor::reuse_address(true), error_code);
  134.   if (error_code) {
  135.     return Fail(error_code);
  136.   }
  137.  
  138.   acceptor_.bind(ep, error_code);
  139.   if (error_code) {
  140.     return Fail(error_code);
  141.   }
  142.  
  143.   acceptor_.listen();
  144.   return Ok();
  145. }
  146.  
  147. Result<uint16_t> Acceptor::ListenAvailablePort() {
  148.   auto is_listening = Listen(0);
  149.   if (is_listening.IsOk()) {
  150.     return make_result::Ok(GetPort());
  151.   } else {
  152.     return make_result::Fail(is_listening.Error());
  153.   }
  154. }
  155.  
  156. Result<Socket> Acceptor::Accept() {
  157.   asio::error_code error_code;
  158.   asio::ip::tcp::socket socket(GetCurrentScheduler()->GetIOContext());
  159.   Fiber* current_fiber = GetCurrentFiber();
  160.  
  161.   acceptor_.async_accept(socket, [current_fiber, &error_code](
  162.       std::error_code accept_error_code) {
  163.  
  164.     error_code = accept_error_code;
  165.     GetCurrentScheduler()->Add(current_fiber);
  166.   });
  167.  
  168.   GetCurrentScheduler()->Suspend();
  169.   if (!error_code) {
  170.     return Result<Socket>::Ok(std::move(socket));
  171.   } else {
  172.     return make_result::Fail(error_code);
  173.   }
  174. }
  175.  
  176. uint16_t Acceptor::GetPort() const {
  177.   return acceptor_.local_endpoint().port();
  178. }
  179.  
  180. }  // namespace tcp
  181. }  // namespace tinyfiber
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
Top