add ssl_peek functionality
diff --git a/ChangeLog b/ChangeLog
index b5b3922..b7cfd9b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,6 +1,12 @@
+2015-08-17  Maximilian Hils <pyopenssl@maximilianhils.com>
+
+	* OpenSSL/SSL.py, OpenSSL/test/test_ssl.py: Add support for
+	  the ``MSG_PEEK`` flag to ``Connection.recv()`` and
+	  ``Connection.recv_into()``.
+
 2015-05-27  Jim Shaver <dcypherd@gmail.com>
 
-	* OpenSSL/SSL.py, : Add ``get_protocol_version()`` and 
+	* OpenSSL/SSL.py: Add ``get_protocol_version()`` and
 	  ``get_protocol_version_name()`` to ``Connection``.
 	  Based on work from Rich Moore.
 
diff --git a/OpenSSL/SSL.py b/OpenSSL/SSL.py
index 8c87c34..9b27013 100644
--- a/OpenSSL/SSL.py
+++ b/OpenSSL/SSL.py
@@ -1,3 +1,4 @@
+import socket
 from sys import platform
 from functools import wraps, partial
 from itertools import count, chain
@@ -1311,12 +1312,15 @@
         method again with the SAME buffer.
 
         :param bufsiz: The maximum number of bytes to read
-        :param flags: (optional) Included for compatibility with the socket
-                      API, the value is ignored
+        :param flags: (optional) The only supported flag is ``MSG_PEEK``,
+            all other flags are ignored.
         :return: The string read from the Connection
         """
         buf = _ffi.new("char[]", bufsiz)
-        result = _lib.SSL_read(self._ssl, buf, bufsiz)
+        if flags is not None and flags & socket.MSG_PEEK:
+            result = _lib.SSL_peek(self._ssl, buf, bufsiz)
+        else:
+            result = _lib.SSL_read(self._ssl, buf, bufsiz)
         self._raise_ssl_error(self._ssl, result)
         return _ffi.buffer(buf, result)[:]
     read = recv
@@ -1332,8 +1336,8 @@
             buffer. If not present, defaults to the size of the buffer. If
             larger than the size of the buffer, is reduced to the size of the
             buffer.
-        :param flags: (optional) Included for compatibility with the socket
-            API, the value is ignored.
+        :param flags: (optional) The only supported flag is ``MSG_PEEK``,
+            all other flags are ignored.
         :return: The number of bytes read into the buffer.
         """
         if nbytes is None:
@@ -1345,7 +1349,10 @@
         # better if we could pass memoryviews straight into the SSL_read call,
         # but right now we can't. Revisit this if CFFI gets that ability.
         buf = _ffi.new("char[]", nbytes)
-        result = _lib.SSL_read(self._ssl, buf, nbytes)
+        if flags is not None and flags & socket.MSG_PEEK:
+            result = _lib.SSL_peek(self._ssl, buf, nbytes)
+        else:
+            result = _lib.SSL_read(self._ssl, buf, nbytes)
         self._raise_ssl_error(self._ssl, result)
 
         # This strange line is all to avoid a memory copy. The buffer protocol
diff --git a/OpenSSL/test/test_ssl.py b/OpenSSL/test/test_ssl.py
index e586537..787d636 100644
--- a/OpenSSL/test/test_ssl.py
+++ b/OpenSSL/test/test_ssl.py
@@ -8,7 +8,7 @@
 from gc import collect, get_referrers
 from errno import ECONNREFUSED, EINPROGRESS, EWOULDBLOCK, EPIPE, ESHUTDOWN
 from sys import platform, getfilesystemencoding
-from socket import SHUT_RDWR, error, socket
+from socket import MSG_PEEK, SHUT_RDWR, error, socket
 from os import makedirs
 from os.path import join
 from unittest import main
@@ -2172,6 +2172,17 @@
         self.assertRaises(TypeError, connection.pending, None)
 
 
+    def test_peek(self):
+        """
+        :py:obj:`Connection.recv` peeks into the connection if :py:obj:`socket.MSG_PEEK` is passed.
+        """
+        server, client = self._loopback()
+        server.send(b('xy'))
+        self.assertEqual(client.recv(2, MSG_PEEK), b('xy'))
+        self.assertEqual(client.recv(2, MSG_PEEK), b('xy'))
+        self.assertEqual(client.recv(2), b('xy'))
+
+
     def test_connect_wrong_args(self):
         """
         :py:obj:`Connection.connect` raises :py:obj:`TypeError` if called with a non-address
@@ -2999,6 +3010,17 @@
         self._doesnt_overfill_test(bytearray)
 
 
+    def test_peek(self):
+
+        server, client = self._loopback()
+        server.send(b('xy'))
+
+        for _ in range(2):
+            output_buffer = bytearray(5)
+            self.assertEqual(client.recv_into(output_buffer, flags=MSG_PEEK), 2)
+            self.assertEqual(output_buffer, bytearray(b('xy\x00\x00\x00')))
+
+
     try:
         memoryview
     except NameError:
diff --git a/doc/api/ssl.rst b/doc/api/ssl.rst
index 89ae6a1..0548678 100644
--- a/doc/api/ssl.rst
+++ b/doc/api/ssl.rst
@@ -669,11 +669,12 @@
     (**not** the underlying transport buffer).
 
 
-.. py:method:: Connection.recv(bufsize)
+.. py:method:: Connection.recv(bufsize[, flags])
 
     Receive data from the Connection. The return value is a string representing the
     data received. The maximum amount of data to be received at once, is specified
-    by *bufsize*.
+    by *bufsize*. The only supported flag is ``MSG_PEEK``, all other flags are
+    ignored.
 
 
 .. py:method:: Connection.recv_into(buffer[, nbytes[, flags]])
@@ -681,8 +682,7 @@
     Receive data from the Connection and copy it directly into the provided
     buffer. The return value is the number of bytes read from the connection.
     The maximum amount of data to be received at once is specified by *nbytes*.
-    *flags* is accepted for compatibility with ``socket.recv_into`` but its
-    value is ignored.
+    The only supported flag is ``MSG_PEEK``, all other flags are ignored.
 
 .. py:method:: Connection.bio_write(bytes)