diff --git a/Subtrees/beast/Builds/VisualStudio2012/beast.vcxproj b/Subtrees/beast/Builds/VisualStudio2012/beast.vcxproj
index ebe6f0fe0b..6b28e276ae 100644
--- a/Subtrees/beast/Builds/VisualStudio2012/beast.vcxproj
+++ b/Subtrees/beast/Builds/VisualStudio2012/beast.vcxproj
@@ -72,19 +72,20 @@
+
-
-
-
+
+
+
+
+
-
-
-
+
@@ -308,13 +309,7 @@
true
-
- true
- true
- true
- true
-
-
+
true
true
true
diff --git a/Subtrees/beast/Builds/VisualStudio2012/beast.vcxproj.filters b/Subtrees/beast/Builds/VisualStudio2012/beast.vcxproj.filters
index a29fdd4db9..c9094c3bbc 100644
--- a/Subtrees/beast/Builds/VisualStudio2012/beast.vcxproj.filters
+++ b/Subtrees/beast/Builds/VisualStudio2012/beast.vcxproj.filters
@@ -152,15 +152,15 @@
{422da6a1-e57e-4a96-9fce-e5958c16026e}
-
- {c4a7b6bb-88ec-4ff1-bc56-7c432a467500}
-
{ccdc0c8e-f77a-486e-ba2f-29c10ec97f18}
{dfa79046-33ef-4653-a6f9-83954b76a10f}
+
+ {4856837a-fa72-4252-8e8f-a112c1dbb3d2}
+
@@ -767,15 +767,9 @@
beast_asio\sockets
-
- beast_asio\sockets
-
beast_asio\sockets
-
- beast_asio\sockets
-
beast_asio\system
@@ -815,9 +809,6 @@
beast_asio\tests
-
- beast_asio\protocol
-
beast_asio\tests
@@ -842,15 +833,27 @@
beast_core\memory
-
- beast_asio\protocol
-
-
- beast_asio\protocol
-
-
+
beast_asio\streams
+
+ beast_asio\handshake
+
+
+ beast_asio\handshake
+
+
+ beast_asio\basics
+
+
+ beast_asio\handshake
+
+
+ beast_asio\handshake
+
+
+ beast_asio\handshake
+
@@ -1303,17 +1306,14 @@
beast_asio\tests
-
- beast_asio\protocol
-
beast_asio\tests
beast_asio\basics
-
- beast_asio\protocol
+
+ beast_asio\handshake
diff --git a/Subtrees/beast/modules/beast_asio/basics/beast_FixedInputBuffer.h b/Subtrees/beast/modules/beast_asio/basics/beast_FixedInputBuffer.h
new file mode 100644
index 0000000000..ce0a968052
--- /dev/null
+++ b/Subtrees/beast/modules/beast_asio/basics/beast_FixedInputBuffer.h
@@ -0,0 +1,112 @@
+//------------------------------------------------------------------------------
+/*
+ This file is part of Beast: https://github.com/vinniefalco/Beast
+ Copyright 2013, Vinnie Falco
+
+ Permission to use, copy, modify, and/or distribute this software for any
+ purpose with or without fee is hereby granted, provided that the above
+ copyright notice and this permission notice appear in all copies.
+
+ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+*/
+//==============================================================================
+
+#ifndef BEAST_FIXEDINPUTBUFFER_H_INCLUDED
+#define BEAST_FIXEDINPUTBUFFER_H_INCLUDED
+
+/** Represents a small, fixed size buffer.
+ This provides a convenient interface for doing a bytewise
+ verification/reject test on a handshake protocol.
+*/
+template
+struct FixedInputBuffer
+{
+ template
+ explicit FixedInputBuffer (ConstBufferSequence const& buffer)
+ : m_buffer (boost::asio::buffer (m_storage))
+ , m_size (boost::asio::buffer_copy (m_buffer, buffer))
+ , m_data (boost::asio::buffer_cast (m_buffer))
+ {
+ }
+
+ uint8 operator[] (std::size_t index) const noexcept
+ {
+ bassert (index >= 0 && index < m_size);
+ return m_data [index];
+ }
+
+ bool peek (std::size_t bytes) const noexcept
+ {
+ if (m_size >= bytes)
+ return true;
+ return false;
+ }
+
+ template
+ bool peek (T* t) noexcept
+ {
+ std::size_t const bytes = sizeof (T);
+ if (m_size >= bytes)
+ {
+ std::copy (m_data, m_data + bytes, t);
+ return true;
+ }
+ return false;
+ }
+
+ bool consume (std::size_t bytes) noexcept
+ {
+ if (m_size >= bytes)
+ {
+ m_data += bytes;
+ m_size -= bytes;
+ return true;
+ }
+ return false;
+ }
+
+ template
+ bool read (T* t) noexcept
+ {
+ std::size_t const bytes = sizeof (T);
+ if (m_size >= bytes)
+ {
+ //this causes a stack corruption.
+ //std::copy (m_data, m_data + bytes, t);
+
+ memcpy (t, m_data, bytes);
+ m_data += bytes;
+ m_size -= bytes;
+ return true;
+ }
+ return false;
+ }
+
+ // Reads an integraltype in network byte order
+ template
+ bool readNetworkInteger (IntegerType* value)
+ {
+ // Must be an integral type!
+ // not available in all versions of std:: unfortunately
+ //static_bassert (std::is_integral ::value);
+ IntegerType networkValue;
+ if (! read (&networkValue))
+ return;
+ *value = fromNetworkByteOrder (networkValue);
+ return true;
+ }
+
+private:
+ boost::array m_storage;
+ MutableBuffer m_buffer;
+ std::size_t m_size;
+ uint8 const* m_data;
+};
+
+#endif
diff --git a/Subtrees/beast/modules/beast_asio/beast_asio.cpp b/Subtrees/beast/modules/beast_asio/beast_asio.cpp
index 71a155aafb..cb9dd8d638 100644
--- a/Subtrees/beast/modules/beast_asio/beast_asio.cpp
+++ b/Subtrees/beast/modules/beast_asio/beast_asio.cpp
@@ -30,8 +30,7 @@ namespace beast
#include "sockets/beast_Socket.cpp"
#include "sockets/beast_SslContext.cpp"
-#include "protocol/beast_ProxyHandshake.cpp"
-#include "protocol/beast_StreamHandshakeDetectorType.cpp"
+#include "handshake/beast_ProxyHandshake.cpp"
#include "tests/beast_TestPeerBasics.cpp"
#include "tests/beast_TestPeerLogic.cpp"
diff --git a/Subtrees/beast/modules/beast_asio/beast_asio.h b/Subtrees/beast/modules/beast_asio/beast_asio.h
index 4006b81105..acba94323b 100644
--- a/Subtrees/beast/modules/beast_asio/beast_asio.h
+++ b/Subtrees/beast/modules/beast_asio/beast_asio.h
@@ -48,24 +48,25 @@ namespace beast
// Order matters
-#include "basics/beast_PeerRole.h"
#include "basics/beast_BufferType.h"
#include "basics/beast_CompletionCall.h"
#include "basics/beast_ErrorCall.h"
+#include "basics/beast_FixedInputBuffer.h"
+#include "basics/beast_PeerRole.h"
#include "basics/beast_TransferCall.h"
#include "sockets/beast_SocketBase.h"
#include "sockets/beast_Socket.h"
-#include "sockets/beast_SocketInterface.h"
#include "sockets/beast_SocketWrapper.h"
-#include "sockets/beast_SharedSocket.h"
#include "sockets/beast_SslContext.h"
-#include "protocol/beast_ProxyHandshake.h"
-#include "protocol/beast_HandshakeDetectorType.h"
-#include "protocol/beast_StreamHandshakeDetectorType.h"
+#include "handshake/beast_ProxyHandshake.h"
+ #include "handshake/beast_HandshakeDetectLogic.h"
+#include "handshake/beast_HandshakeDetectLogicSSL2.h"
+#include "handshake/beast_HandshakeDetectLogicSSL3.h"
+#include "handshake/beast_HandshakeDetectStream.h"
-#include "streams/beast_prefilled_read_stream.h"
+#include "streams/beast_PrefilledReadStream.h"
#include "tests/beast_TestPeerBasics.h"
#include "tests/beast_TestPeer.h"
diff --git a/Subtrees/beast/modules/beast_asio/handshake/beast_HandshakeDetectLogic.h b/Subtrees/beast/modules/beast_asio/handshake/beast_HandshakeDetectLogic.h
new file mode 100644
index 0000000000..62eae110db
--- /dev/null
+++ b/Subtrees/beast/modules/beast_asio/handshake/beast_HandshakeDetectLogic.h
@@ -0,0 +1,129 @@
+//------------------------------------------------------------------------------
+/*
+ This file is part of Beast: https://github.com/vinniefalco/Beast
+ Copyright 2013, Vinnie Falco
+
+ Permission to use, copy, modify, and/or distribute this software for any
+ purpose with or without fee is hereby granted, provided that the above
+ copyright notice and this permission notice appear in all copies.
+
+ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+*/
+//==============================================================================
+
+#ifndef BEAST_HANDSHAKEDETECTLOGIC_H_INCLUDED
+#define BEAST_HANDSHAKEDETECTLOGIC_H_INCLUDED
+
+class HandshakeDetectLogic
+{
+public:
+ HandshakeDetectLogic ()
+ : m_finished (false)
+ , m_success (false)
+ {
+ }
+
+ /** How many bytes maximum we might need.
+
+ This is the largest number of bytes that the detector
+ might need in order to come to a conclusion about
+ whether or not the handshake is a match. Depending
+ on the data, it could come to that conclusion sooner
+ though.
+
+ Use read_some instead of read so that the detect logic
+ can reject the handshake sooner if possible.
+ */
+ virtual std::size_t max_needed () = 0;
+
+ /** Return true if we have enough data to form a conclusion.
+ */
+ bool finished () const noexcept
+ {
+ return m_finished;
+ }
+
+ /** Return true if we came to a conclusion and the data matched.
+ */
+ bool success () const noexcept
+ {
+ return m_finished && m_success;
+ }
+
+protected:
+ void conclude (bool success = true)
+ {
+ m_finished = true;
+ m_success = success;
+ }
+
+ void fail ()
+ {
+ conclude (false);
+ }
+
+private:
+ bool m_finished;
+ bool m_success;
+};
+
+//------------------------------------------------------------------------------
+
+/** Wraps the logic and exports it as an abstract interface.
+*/
+template
+class HandshakeDetectLogicType
+{
+public:
+ typedef Logic LogicType;
+ typedef typename Logic::arg_type arg_type;
+
+ explicit HandshakeDetectLogicType (arg_type const& arg = arg_type ())
+ : m_logic (arg)
+ {
+ }
+
+ LogicType& get ()
+ {
+ return m_logic;
+ }
+
+ std::size_t max_needed () noexcept
+ {
+ return m_logic.max_needed ();
+ }
+
+ bool finished () noexcept
+ {
+ return m_logic.finished ();
+ }
+
+ /** If finished is true, this tells us if the handshake was detected.
+ */
+ bool success () noexcept
+ {
+ return m_logic.success ();
+ }
+
+ /** Analyze the buffer to match the Handshake.
+ Returns `true` if the analysis is complete.
+ */
+ template
+ bool analyze (ConstBufferSequence const& buffer)
+ {
+ bassert (! m_logic.finished ());
+ m_logic.analyze (buffer);
+ return m_logic.finished ();
+ }
+
+private:
+ Logic m_logic;
+};
+
+#endif
diff --git a/Subtrees/beast/modules/beast_asio/handshake/beast_HandshakeDetectLogicSSL2.h b/Subtrees/beast/modules/beast_asio/handshake/beast_HandshakeDetectLogicSSL2.h
new file mode 100644
index 0000000000..49f63eeb91
--- /dev/null
+++ b/Subtrees/beast/modules/beast_asio/handshake/beast_HandshakeDetectLogicSSL2.h
@@ -0,0 +1,103 @@
+//------------------------------------------------------------------------------
+/*
+ This file is part of Beast: https://github.com/vinniefalco/Beast
+ Copyright 2013, Vinnie Falco
+
+ Permission to use, copy, modify, and/or distribute this software for any
+ purpose with or without fee is hereby granted, provided that the above
+ copyright notice and this permission notice appear in all copies.
+
+ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+*/
+//==============================================================================
+
+#ifndef BEAST_HANDSHAKEDETECTLOGICSSL2_H_INCLUDED
+#define BEAST_HANDSHAKEDETECTLOGICSSL2_H_INCLUDED
+
+// Handshake for SSL 2
+//
+// http://tools.ietf.org/html/rfc5246#appendix-E.2
+//
+// uint8 V2CipherSpec[3];
+// struct {
+// uint16 msg_length;
+// uint8 msg_type;
+// Version version; Should be 'ProtocolVersion'?
+// uint16 cipher_spec_length;
+// uint16 session_id_length;
+// uint16 challenge_length;
+// ...
+//
+class HandshakeDetectLogicSSL2 : public HandshakeDetectLogic
+{
+public:
+ typedef int arg_type;
+
+ explicit HandshakeDetectLogicSSL2 (arg_type const&)
+ {
+ }
+
+ enum
+ {
+ bytesNeeded = 3
+ };
+
+ std::size_t max_needed ()
+ {
+ return bytesNeeded;
+ }
+
+ template
+ void analyze (ConstBufferSequence const& buffer)
+ {
+ FixedInputBuffer in (buffer);
+
+ {
+ uint8 byte;
+ if (! in.peek (&byte))
+ return;
+
+ // First byte must have the high bit set
+ //
+ if((byte & 0x80) != 0x80)
+ return fail ();
+ }
+
+ // The remaining bits contain the
+ // length of the following data in bytes.
+ //
+ uint16 msg_length;
+ if (! in.readNetworkInteger(&msg_length))
+ return;
+
+ // sizeof (msg_type +
+ // Version (ProtcolVersion?) +
+ // cipher_spec_length +
+ // session_id_length +
+ // challenge_length)
+ //
+ // Should be 9 or greater.
+ //
+ if (msg_length < 9)
+ return fail ();
+
+ uint8 msg_type;
+ if (! in.read (&msg_type))
+ return;
+
+ // The msg_type must be 0x01 for a version 2 ClientHello
+ //
+ if (msg_type != 0x01)
+ return fail ();
+
+ conclude ();
+ }
+};
+
+#endif
diff --git a/Subtrees/beast/modules/beast_asio/handshake/beast_HandshakeDetectLogicSSL3.h b/Subtrees/beast/modules/beast_asio/handshake/beast_HandshakeDetectLogicSSL3.h
new file mode 100644
index 0000000000..c2314f04a1
--- /dev/null
+++ b/Subtrees/beast/modules/beast_asio/handshake/beast_HandshakeDetectLogicSSL3.h
@@ -0,0 +1,77 @@
+//------------------------------------------------------------------------------
+/*
+ This file is part of Beast: https://github.com/vinniefalco/Beast
+ Copyright 2013, Vinnie Falco
+
+ Permission to use, copy, modify, and/or distribute this software for any
+ purpose with or without fee is hereby granted, provided that the above
+ copyright notice and this permission notice appear in all copies.
+
+ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+*/
+//==============================================================================
+
+#ifndef BEAST_HANDSHAKEDETECTLOGICSSL3_H_INCLUDED
+#define BEAST_HANDSHAKEDETECTLOGICSSL3_H_INCLUDED
+
+// Handshake for SSL 3 (Also TLS 1.0 and 1.1)
+//
+// http://www.ietf.org/rfc/rfc2246.txt
+//
+// Section 7.4. Handshake protocol
+//
+class HandshakeDetectLogicSSL3 : public HandshakeDetectLogic
+{
+public:
+ typedef int arg_type; // dummy
+
+ explicit HandshakeDetectLogicSSL3 (arg_type const&)
+ {
+ }
+
+ enum
+ {
+ bytesNeeded = 6
+ };
+
+ std::size_t max_needed ()
+ {
+ return bytesNeeded;
+ }
+
+ template
+ void analyze (ConstBufferSequence const& buffer)
+ {
+ uint16 version;
+ FixedInputBuffer in (buffer);
+
+ uint8 msg_type;
+ if (! in.read (&msg_type))
+ return;
+
+ // msg_type must be 0x16 = "SSL Handshake"
+ //
+ if (msg_type != 0x16)
+ return fail ();
+
+ if (! in.read (&version))
+ return;
+ version = fromNetworkByteOrder (version);
+
+ uint16 length;
+ if (! in.read (&length))
+ return;
+
+ length = fromNetworkByteOrder (length);
+
+ conclude ();
+ }
+};
+
+#endif
diff --git a/Subtrees/beast/modules/beast_asio/handshake/beast_HandshakeDetectStream.h b/Subtrees/beast/modules/beast_asio/handshake/beast_HandshakeDetectStream.h
new file mode 100644
index 0000000000..82c59c45a0
--- /dev/null
+++ b/Subtrees/beast/modules/beast_asio/handshake/beast_HandshakeDetectStream.h
@@ -0,0 +1,307 @@
+//------------------------------------------------------------------------------
+/*
+ This file is part of Beast: https://github.com/vinniefalco/Beast
+ Copyright 2013, Vinnie Falco
+
+ Permission to use, copy, modify, and/or distribute this software for any
+ purpose with or without fee is hereby granted, provided that the above
+ copyright notice and this permission notice appear in all copies.
+
+ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+*/
+//==============================================================================
+
+#ifndef BEAST_HANDSHAKEDETECTSTREAM_H_INCLUDED
+#define BEAST_HANDSHAKEDETECTSTREAM_H_INCLUDED
+
+/** A stream that can detect a handshake.
+*/
+/** @{ */
+template
+class HandshakeDetectStream
+{
+protected:
+ typedef boost::system::error_code error_code;
+
+public:
+ typedef Logic LogicType;
+
+ /** Called when the state is known.
+
+ This could be called from any thread, most likely an io_service
+ thread but don't rely on that.
+
+ The Callback must be allocated via operator new.
+ */
+ struct Callback
+ {
+ virtual ~Callback () { }
+
+ /** Called for synchronous ssl detection.
+
+ Note that the storage for the buffers passed to the
+ callback is owned by the detector class and becomes
+ invalid when the detector class is destroyed, which is
+ a common thing to do from inside your callback.
+
+ @param ec A modifiable error code that becomes the return
+ value of handshake.
+ @param buffers The bytes that were read in.
+ @param is_ssl True if the sequence is an ssl handshake.
+ */
+ virtual void on_detect (Logic& logic,
+ error_code& ec, ConstBuffers const& buffers) = 0;
+
+ virtual void on_async_detect (Logic& logic,
+ error_code const& ec, ConstBuffers const& buffers,
+ ErrorCall const& origHandler) = 0;
+
+ #if BEAST_ASIO_HAS_BUFFEREDHANDSHAKE
+ virtual void on_async_detect (Logic& logic,
+ error_code const& ec, ConstBuffers const& buffers,
+ TransferCall const& origHandler) = 0;
+ #endif
+ };
+};
+
+//------------------------------------------------------------------------------
+
+template
+class HandshakeDetectStreamType
+ : public HandshakeDetectStream
+ , public boost::asio::ssl::stream_base
+ , public boost::asio::socket_base
+{
+private:
+ typedef HandshakeDetectStreamType this_type;
+ typedef boost::asio::streambuf buffer_type;
+ typedef typename boost::remove_reference ::type stream_type;
+
+public:
+ typedef typename HandshakeDetectStream CallbackType;
+
+ /** This takes ownership of the callback.
+ The callback must be allocated with operator new.
+ */
+ template
+ HandshakeDetectStreamType (Callback* callback, Arg& arg)
+ : m_callback (callback)
+ , m_next_layer (arg)
+ , m_stream (m_next_layer)
+ {
+ }
+
+ // basic_io_object
+
+ boost::asio::io_service& get_io_service ()
+ {
+ return m_next_layer.get_io_service ();
+ }
+
+ // basic_socket
+
+ typedef typename stream_type::protocol_type protocol_type;
+ typedef typename stream_type::lowest_layer_type lowest_layer_type;
+
+ lowest_layer_type& lowest_layer ()
+ {
+ return m_next_layer.lowest_layer ();
+ }
+
+ lowest_layer_type const& lowest_layer () const
+ {
+ return m_next_layer.lowest_layer ();
+ }
+
+ // ssl::stream
+
+ error_code handshake (handshake_type type, error_code& ec)
+ {
+ return do_handshake (type, ec, ConstBuffers ());
+ }
+
+ template
+ BOOST_ASIO_INITFN_RESULT_TYPE(HandshakeHandler, void (error_code))
+ async_handshake (handshake_type type, BOOST_ASIO_MOVE_ARG(HandshakeHandler) handler)
+ {
+#if BEAST_ASIO_HAS_FUTURE_RETURNS
+ boost::asio::detail::async_result_init<
+ ErrorCall, void (error_code)> init(
+ BOOST_ASIO_MOVE_CAST(HandshakeHandler)(handler));
+ // init.handler is copied
+ m_origHandler = ErrorCall (HandshakeHandler(init.handler));
+ bassert (m_origBufferedHandler.isNull ());
+ async_do_handshake (type, ConstBuffers ());
+ return init.result.get();
+#else
+ m_origHandler = ErrorCall (handler);
+ bassert (m_origBufferedHandler.isNull ());
+ async_do_handshake (type, ConstBuffers ());
+#endif
+ }
+
+#if BEAST_ASIO_HAS_BUFFEREDHANDSHAKE
+ template
+ error_code handshake (handshake_type type,
+ const ConstBufferSequence& buffers, error_code& ec)
+ {
+ return do_handshake (type, ec, ConstBuffers (buffers));;
+ }
+
+ template
+ BOOST_ASIO_INITFN_RESULT_TYPE(BufferedHandshakeHandler, void (error_code, std::size_t))
+ async_handshake(handshake_type type, const ConstBufferSequence& buffers,
+ BOOST_ASIO_MOVE_ARG(BufferedHandshakeHandler) handler)
+ {
+#if BEAST_ASIO_HAS_FUTURE_RETURNS
+ boost::asio::detail::async_result_init<
+ BufferedHandshakeHandler, void (error_code, std::size_t)> init(
+ BOOST_ASIO_MOVE_CAST(BufferedHandshakeHandler)(handler));
+ // init.handler is copied
+ m_origBufferedHandler = TransferCall (BufferedHandshakeHandler(init.handler));
+ bassert (m_origHandler.isNull ());
+ async_do_handshake (type, ConstBuffers (buffers));
+ return init.result.get();
+#else
+ m_origBufferedHandler = TransferCall (handler);
+ bassert (m_origHandler.isNull ());
+ async_do_handshake (type, ConstBuffers (buffers));
+#endif
+ }
+#endif
+
+ //--------------------------------------------------------------------------
+
+ error_code do_handshake (handshake_type, error_code& ec, ConstBuffers const& buffers)
+ {
+ ec = error_code ();
+
+ // Transfer caller data to our buffer.
+ m_buffer.commit (boost::asio::buffer_copy (m_buffer.prepare (
+ boost::asio::buffer_size (buffers)), buffers));
+
+ do
+ {
+ std::size_t const available = m_buffer.size ();
+ std::size_t const needed = m_logic.max_needed ();
+ if (available < needed)
+ {
+ buffer_type::mutable_buffers_type buffers (
+ m_buffer.prepare (needed - available));
+ m_buffer.commit (m_next_layer.read_some (buffers, ec));
+ }
+
+ if (! ec)
+ {
+ m_logic.analyze (m_buffer.data ());
+
+ if (m_logic.finished ())
+ {
+ m_callback->on_detect (m_logic.get (), ec,
+ ConstBuffers (m_buffer.data ()));
+ break;
+ }
+
+ // If this fails it means we will never finish
+ check_postcondition (available < needed);
+ }
+ }
+ while (! ec);
+
+ return ec;
+ }
+
+ //--------------------------------------------------------------------------
+
+ void async_do_handshake (handshake_type type, ConstBuffers const& buffers)
+ {
+ // Transfer caller data to our buffer.
+ std::size_t const bytes_transferred (boost::asio::buffer_copy (
+ m_buffer.prepare (boost::asio::buffer_size (buffers)), buffers));
+
+ // bootstrap the asynchronous loop
+ on_async_read_some (error_code (), bytes_transferred);
+ }
+
+ // asynchronous version of the synchronous loop found in handshake ()
+ //
+ void on_async_read_some (error_code const& ec, std::size_t bytes_transferred)
+ {
+ if (! ec)
+ {
+ m_buffer.commit (bytes_transferred);
+
+ std::size_t const available = m_buffer.size ();
+ std::size_t const needed = m_logic.max_needed ();
+
+ m_logic.analyze (m_buffer.data ());
+
+ if (m_logic.finished ())
+ {
+ #if BEAST_ASIO_HAS_BUFFEREDHANDSHAKE
+ if (! m_origBufferedHandler.isNull ())
+ {
+ bassert (m_origHandler.isNull ());
+ // continuation?
+ m_callback->on_async_detect (m_logic.get (), ec,
+ ConstBuffers (m_buffer.data ()), m_origBufferedHandler);
+ return;
+ }
+ #endif
+
+ bassert (! m_origHandler.isNull ())
+ // continuation?
+ m_callback->on_async_detect (m_logic.get (), ec,
+ ConstBuffers (m_buffer.data ()), m_origHandler);
+ return;
+ }
+
+ // If this fails it means we will never finish
+ check_postcondition (available < needed);
+
+ buffer_type::mutable_buffers_type buffers (m_buffer.prepare (
+ needed - available));
+
+ // need a continuation hook here?
+ m_next_layer.async_read_some (buffers, boost::bind (
+ &this_type::on_async_read_some, this, boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred));
+
+ return;
+ }
+
+ #if BEAST_ASIO_HAS_BUFFEREDHANDSHAKE
+ if (! m_origBufferedHandler.isNull ())
+ {
+ bassert (m_origHandler.isNull ());
+ // continuation?
+ m_callback->on_async_detect (m_logic.get (), ec,
+ ConstBuffers (m_buffer.data ()), m_origBufferedHandler);
+ return;
+ }
+ #endif
+
+ bassert (! m_origHandler.isNull ())
+ // continuation?
+ m_callback->on_async_detect (m_logic.get (), ec,
+ ConstBuffers (m_buffer.data ()), m_origHandler);
+ }
+
+private:
+ ScopedPointer ::Callback> m_callback;
+ Stream m_next_layer;
+ buffer_type m_buffer;
+ boost::asio::buffered_read_stream m_stream;
+ HandshakeDetectLogicType m_logic;
+ ErrorCall m_origHandler;
+ TransferCall m_origBufferedHandler;
+};
+/** @} */
+
+#endif
diff --git a/Subtrees/beast/modules/beast_asio/protocol/beast_ProxyHandshake.cpp b/Subtrees/beast/modules/beast_asio/handshake/beast_ProxyHandshake.cpp
similarity index 100%
rename from Subtrees/beast/modules/beast_asio/protocol/beast_ProxyHandshake.cpp
rename to Subtrees/beast/modules/beast_asio/handshake/beast_ProxyHandshake.cpp
diff --git a/Subtrees/beast/modules/beast_asio/protocol/beast_ProxyHandshake.h b/Subtrees/beast/modules/beast_asio/handshake/beast_ProxyHandshake.h
similarity index 100%
rename from Subtrees/beast/modules/beast_asio/protocol/beast_ProxyHandshake.h
rename to Subtrees/beast/modules/beast_asio/handshake/beast_ProxyHandshake.h
diff --git a/Subtrees/beast/modules/beast_asio/protocol/beast_HandshakeDetectorType.h b/Subtrees/beast/modules/beast_asio/protocol/beast_HandshakeDetectorType.h
deleted file mode 100644
index b896815cd5..0000000000
--- a/Subtrees/beast/modules/beast_asio/protocol/beast_HandshakeDetectorType.h
+++ /dev/null
@@ -1,350 +0,0 @@
-//------------------------------------------------------------------------------
-/*
- This file is part of Beast: https://github.com/vinniefalco/Beast
- Copyright 2013, Vinnie Falco
-
- Permission to use, copy, modify, and/or distribute this software for any
- purpose with or without fee is hereby granted, provided that the above
- copyright notice and this permission notice appear in all copies.
-
- THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-*/
-//==============================================================================
-
-#ifndef BEAST_HANDSHAKEDETECTORTYPE_H_INCLUDED
-#define BEAST_HANDSHAKEDETECTORTYPE_H_INCLUDED
-
-class DetectPolicy
-{
-public:
- DetectPolicy ()
- : m_finished (false)
- , m_success (false)
- {
- }
-
- /** How many bytes maximum we might need.
-
- This is the largest number of bytes that the detector
- might need in order to come to a conclusion about
- whether or not the handshake is a match. Depending
- on the data, it could come to that conclusion sooner
- though.
- */
- virtual std::size_t max_needed () = 0;
-
- /** Returns true if the return value of success() is valid.
- */
- bool finished () const noexcept
- {
- return m_finished;
- }
-
- /** Returns true if the buffers matched the Handshake
- */
- bool success () const noexcept
- {
- bassert (m_finished);
- return m_success;
- }
-
-protected:
- void conclude (bool success = true)
- {
- m_finished = true;
- m_success = success;
- }
-
- void fail ()
- {
- conclude (false);
- }
-
- //--------------------------------------------------------------------------
-
- /** Represents a small, fixed size buffer.
- This provides a convenient interface for doing a bytewise
- verification/reject test on a handshake protocol.
- */
- template
- struct Input
- {
- template
- explicit Input (ConstBufferSequence const& buffer)
- : m_buffer (boost::asio::buffer (m_storage))
- , m_size (boost::asio::buffer_copy (m_buffer, buffer))
- , m_data (boost::asio::buffer_cast (m_buffer))
- {
- }
-#if 0
- uint8 const* data () const noexcept
- {
- return m_data;
- }
-#endif
-
- uint8 operator[] (std::size_t index) const noexcept
- {
- bassert (index >= 0 && index < m_size);
- return m_data [index];
- }
-
- bool peek (std::size_t bytes) const noexcept
- {
- if (m_size >= bytes)
- return true;
- return false;
- }
-
- template
- bool peek (T* t) noexcept
- {
- std::size_t const bytes = sizeof (T);
- if (m_size >= bytes)
- {
- std::copy (m_data, m_data + bytes, t);
- return true;
- }
- return false;
- }
-
- bool consume (std::size_t bytes) noexcept
- {
- if (m_size >= bytes)
- {
- m_data += bytes;
- m_size -= bytes;
- return true;
- }
- return false;
- }
-
- template
- bool read (T* t) noexcept
- {
- std::size_t const bytes = sizeof (T);
- if (m_size >= bytes)
- {
- //this causes a stack corruption.
- //std::copy (m_data, m_data + bytes, t);
-
- memcpy (t, m_data, bytes);
- m_data += bytes;
- m_size -= bytes;
- return true;
- }
- return false;
- }
-
- // Reads an integraltype in network byte order
- template
- bool readNetworkInteger (IntegerType* value)
- {
- // Must be an integral type!
- // not available in all versions of std:: unfortunately
- //static_bassert (std::is_integral ::value);
- IntegerType networkValue;
- if (! read (&networkValue))
- return false;
- *value = fromNetworkByteOrder (networkValue);
- return true;
- }
-
- private:
- boost::array m_storage;
- MutableBuffer m_buffer;
- std::size_t m_size;
- uint8 const* m_data;
- };
-
-private:
- bool m_finished;
- bool m_success;
-};
-
-// Handshake for SSL 2
-//
-// http://tools.ietf.org/html/rfc5246#appendix-E.2
-//
-// uint8 V2CipherSpec[3];
-// struct {
-// uint16 msg_length;
-// uint8 msg_type;
-// Version version; Should be 'ProtocolVersion'?
-// uint16 cipher_spec_length;
-// uint16 session_id_length;
-// uint16 challenge_length;
-// ...
-//
-class SSL2 : public DetectPolicy
-{
-public:
- typedef int arg_type;
-
- explicit SSL2 (arg_type const&)
- {
- }
-
- enum
- {
- bytesNeeded = 3
- };
-
- std::size_t max_needed ()
- {
- return bytesNeeded;
- }
-
- template
- void analyze (ConstBufferSequence const& buffer)
- {
- Input in (buffer);
-
- {
- uint8 byte;
- if (! in.peek (&byte))
- return;
-
- // First byte must have the high bit set
- //
- if((byte & 0x80) != 0x80)
- return fail ();
- }
-
- // The remaining bits contain the
- // length of the following data in bytes.
- //
- uint16 msg_length;
- if (! in.readNetworkInteger(&msg_length))
- return;
-
- // sizeof (msg_type +
- // Version (ProtcolVersion?) +
- // cipher_spec_length +
- // session_id_length +
- // challenge_length)
- //
- // Should be 9 or greater.
- //
- if (msg_length < 9)
- return fail ();
-
- uint8 msg_type;
- if (! in.read (&msg_type))
- return;
-
- // The msg_type must be 0x01 for a version 2 ClientHello
- //
- if (msg_type != 0x01)
- return fail ();
-
- conclude ();
- }
-};
-
-// Handshake for SSL 3 (Also TLS 1.0 and 1.1)
-//
-// http://www.ietf.org/rfc/rfc2246.txt
-//
-// Section 7.4. Handshake protocol
-//
-class SSL3 : public DetectPolicy
-{
-public:
- typedef int arg_type; // dummy
-
- explicit SSL3 (arg_type const&)
- {
- }
-
- enum
- {
- bytesNeeded = 6
- };
-
- std::size_t max_needed ()
- {
- return bytesNeeded;
- }
-
- template
- void analyze (ConstBufferSequence const& buffer)
- {
- uint16 version;
- Input in (buffer);
-
- uint8 msg_type;
- if (! in.read (&msg_type))
- return;
-
- // msg_type must be 0x16 = "SSL Handshake"
- //
- if (msg_type != 0x16)
- return fail ();
-
- if (! in.read (&version))
- return;
- version = fromNetworkByteOrder (version);
-
- uint16 length;
- if (! in.read (&length))
- return;
-
- length = fromNetworkByteOrder (length);
-
- conclude ();
- }
-};
-
-//--------------------------------------------------------------------------
-
-template
-class HandshakeDetectorType
-{
-public:
- typedef typename Logic::arg_type arg_type;
-
- explicit HandshakeDetectorType (arg_type const& arg = arg_type ())
- : m_logic (arg)
- {
- }
-
- std::size_t max_needed () noexcept
- {
- return m_logic.max_needed ();
- }
-
- bool finished () noexcept
- {
- return m_logic.finished ();
- }
-
- /** If finished is true, this tells us if the handshake was detected.
- */
- bool success () noexcept
- {
- return m_logic.success ();
- }
-
- /** Analyze the buffer to match the Handshake.
- Returns `true` if the analysis is complete.
- */
- template
- bool analyze (ConstBufferSequence const& buffer)
- {
- bassert (! m_logic.finished ());
- m_logic.analyze (buffer);
- return m_logic.finished ();
- }
-
-private:
- Logic m_logic;
-};
-
-#endif
diff --git a/Subtrees/beast/modules/beast_asio/protocol/beast_StreamHandshakeDetectorType.cpp b/Subtrees/beast/modules/beast_asio/protocol/beast_StreamHandshakeDetectorType.cpp
deleted file mode 100644
index 31d57f5deb..0000000000
--- a/Subtrees/beast/modules/beast_asio/protocol/beast_StreamHandshakeDetectorType.cpp
+++ /dev/null
@@ -1,19 +0,0 @@
-//------------------------------------------------------------------------------
-/*
- This file is part of Beast: https://github.com/vinniefalco/Beast
- Copyright 2013, Vinnie Falco
-
- Permission to use, copy, modify, and/or distribute this software for any
- purpose with or without fee is hereby granted, provided that the above
- copyright notice and this permission notice appear in all copies.
-
- THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-*/
-//==============================================================================
-
diff --git a/Subtrees/beast/modules/beast_asio/protocol/beast_StreamHandshakeDetectorType.h b/Subtrees/beast/modules/beast_asio/protocol/beast_StreamHandshakeDetectorType.h
deleted file mode 100644
index 7550e77655..0000000000
--- a/Subtrees/beast/modules/beast_asio/protocol/beast_StreamHandshakeDetectorType.h
+++ /dev/null
@@ -1,78 +0,0 @@
-//------------------------------------------------------------------------------
-/*
- This file is part of Beast: https://github.com/vinniefalco/Beast
- Copyright 2013, Vinnie Falco
-
- Permission to use, copy, modify, and/or distribute this software for any
- purpose with or without fee is hereby granted, provided that the above
- copyright notice and this permission notice appear in all copies.
-
- THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-*/
-//==============================================================================
-
-#ifndef BEAST_STREAMHANDSHAKEDETECTORTYPE_H_INCLUDED
-#define BEAST_STREAMHANDSHAKEDETECTORTYPE_H_INCLUDED
-
-/** Wraps a HandshakeDetector and does the work on the Socket for you.
-*/
-template
-class StreamHandshakeDetectorType
-{
-protected:
- typedef boost::system::error_code error_code;
- typedef StreamHandshakeDetectorType This;
-
-public:
- typedef typename Detector::arg_type arg_type;
-
- explicit StreamHandshakeDetectorType (arg_type const& arg = arg_type ())
- {
- }
-
- template
- void async_handshake (Socket& socket, BOOST_ASIO_MOVE_ARG(HandshakeHandler) handler)
- {
-#if 0
- std::size_t const bytes = m_detector.needed ();
-#if 1
- boost::asio::async_read (socket, m_buffer.prepare (bytes), boost::bind (
- &This::on_read , this, &socket,
- handler,
- boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred));
-#else
- boost::asio::async_read (socket, m_buffer.prepare (bytes), boost::bind (
- &This::on_read2, this,
- boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred));
-#endif
-#endif
- }
-
-protected:
- template
- void on_read (Socket* socket, BOOST_ASIO_MOVE_ARG(HandshakeHandler) handler,
- error_code const& ec, std::size_t bytes_transferred)
- {
- m_buffer.commit (bytes_transferred);
-
- if (m_detector.analyze (m_buffer.data ()))
- {
- if (m_detector.success ())
- {
- //socket->async_handshake (Socket::server, m_buffer.data (), handler);
- }
- }
- }
-
-private:
- Detector m_detector;
- boost::asio::streambuf m_buffer;
-};
-
-#endif
diff --git a/Subtrees/beast/modules/beast_asio/sockets/beast_SharedSocket.h b/Subtrees/beast/modules/beast_asio/sockets/beast_SharedSocket.h
deleted file mode 100644
index ed8554f135..0000000000
--- a/Subtrees/beast/modules/beast_asio/sockets/beast_SharedSocket.h
+++ /dev/null
@@ -1,83 +0,0 @@
-//------------------------------------------------------------------------------
-/*
- This file is part of Beast: https://github.com/vinniefalco/Beast
- Copyright 2013, Vinnie Falco
-
- Permission to use, copy, modify, and/or distribute this software for any
- purpose with or without fee is hereby granted, provided that the above
- copyright notice and this permission notice appear in all copies.
-
- THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-*/
-//==============================================================================
-
-#ifndef BEAST_SHAREDSOCKET_H_INCLUDED
-#define BEAST_SHAREDSOCKET_H_INCLUDED
-
-/** A Socket interface with reference counting.
-
- You can keep a pointer to the base class so that you don't have
- to see the template or underlying object implementation.
-
- @see SharedSocketTYpe, SharedObjectPtr
-*/
-/** @{ */
-class SharedSocket
- : public SharedObject
- , public virtual Socket
-{
-public:
- /** Store your SharedSocket in one of these! */
- typedef SharedObjectPtr Ptr;
-};
-
-//------------------------------------------------------------------------------
-
-/** A RAII container for wrapping an object as a Socket.
-
- To use this, construct the class with an instance of your object
- created with operator new. The constructor will take ownership,
- and delete it when the last reference is removed. For example:
-
- @code
-
- boost::asio::io_service ios;
- boost::asio::ssl:context ctx;
-
- SharedSocket::Ptr mySocket (
- new (boost::asio::ssl::stream (ios, ctx)));
-
- mySocket->handshake ();
-
- @endcode
-
- @see SharedSocket
-*/
-template
-class SharedSocketType
- : public SharedSocket
- , public SocketWrapper