Botan  1.11.15
src/lib/tls/tls_blocking.cpp
Go to the documentation of this file.
00001 /*
00002 * TLS Blocking API
00003 * (C) 2013 Jack Lloyd
00004 *
00005 * Botan is released under the Simplified BSD License (see license.txt)
00006 */
00007 
00008 #include <botan/tls_blocking.h>
00009 
00010 namespace Botan {
00011 
00012 namespace TLS {
00013 
00014 using namespace std::placeholders;
00015 
00016 Blocking_Client::Blocking_Client(read_fn reader,
00017                                  write_fn writer,
00018                                  Session_Manager& session_manager,
00019                                  Credentials_Manager& creds,
00020                                  const Policy& policy,
00021                                  RandomNumberGenerator& rng,
00022                                  const Server_Information& server_info,
00023                                  const Protocol_Version offer_version,
00024                                  next_protocol_fn npn) :
00025    m_read(reader),
00026    m_channel(writer,
00027              std::bind(&Blocking_Client::data_cb, this, _1, _2),
00028              std::bind(&Blocking_Client::alert_cb, this, _1, _2, _3),
00029              std::bind(&Blocking_Client::handshake_cb, this, _1),
00030              session_manager,
00031              creds,
00032              policy,
00033              rng,
00034              server_info,
00035              offer_version,
00036              npn)
00037    {
00038    }
00039 
00040 bool Blocking_Client::handshake_cb(const Session& session)
00041    {
00042    return this->handshake_complete(session);
00043    }
00044 
00045 void Blocking_Client::alert_cb(const Alert alert, const byte[], size_t)
00046    {
00047    this->alert_notification(alert);
00048    }
00049 
00050 void Blocking_Client::data_cb(const byte data[], size_t data_len)
00051    {
00052    m_plaintext.insert(m_plaintext.end(), data, data + data_len);
00053    }
00054 
00055 void Blocking_Client::do_handshake()
00056    {
00057    std::vector<byte> readbuf(4096);
00058 
00059    while(!m_channel.is_closed() && !m_channel.is_active())
00060       {
00061       const size_t from_socket = m_read(&readbuf[0], readbuf.size());
00062       m_channel.received_data(&readbuf[0], from_socket);
00063       }
00064    }
00065 
00066 size_t Blocking_Client::read(byte buf[], size_t buf_len)
00067    {
00068    std::vector<byte> readbuf(4096);
00069 
00070    while(m_plaintext.empty() && !m_channel.is_closed())
00071       {
00072       const size_t from_socket = m_read(&readbuf[0], readbuf.size());
00073       m_channel.received_data(&readbuf[0], from_socket);
00074       }
00075 
00076    const size_t returned = std::min(buf_len, m_plaintext.size());
00077 
00078    for(size_t i = 0; i != returned; ++i)
00079       buf[i] = m_plaintext[i];
00080    m_plaintext.erase(m_plaintext.begin(), m_plaintext.begin() + returned);
00081 
00082    BOTAN_ASSERT_IMPLICATION(returned == 0, m_channel.is_closed(),
00083                             "Only return zero if channel is closed");
00084 
00085    return returned;
00086    }
00087 
00088 }
00089 
00090 }