+ ServiceProvider iohook;
+
+ inline static const char* UnknownIfNULL(const char* str)
+ {
+ return str ? str : "UNKNOWN";
+ }
+
+ static ssize_t gnutls_pull_wrapper(gnutls_transport_ptr_t session_wrap, void* buffer, size_t size)
+ {
+ issl_session* session = reinterpret_cast<issl_session*>(session_wrap);
+ if (session->socket->GetEventMask() & FD_READ_WILL_BLOCK)
+ {
+#ifdef _WIN32
+ gnutls_transport_set_errno(session->sess, EAGAIN);
+#else
+ errno = EAGAIN;
+#endif
+ return -1;
+ }
+
+ int rv = ServerInstance->SE->Recv(session->socket, reinterpret_cast<char *>(buffer), size, 0);
+
+#ifdef _WIN32
+ if (rv < 0)
+ {
+ /* Windows doesn't use errno, but gnutls does, so check SocketEngine::IgnoreError()
+ * and then set errno appropriately.
+ * The gnutls library may also have a different errno variable than us, see
+ * gnutls_transport_set_errno(3).
+ */
+ gnutls_transport_set_errno(session->sess, SocketEngine::IgnoreError() ? EAGAIN : errno);
+ }
+#endif
+
+ if (rv < (int)size)
+ ServerInstance->SE->ChangeEventMask(session->socket, FD_READ_WILL_BLOCK);
+ return rv;
+ }
+
+ static ssize_t gnutls_push_wrapper(gnutls_transport_ptr_t session_wrap, const void* buffer, size_t size)
+ {
+ issl_session* session = reinterpret_cast<issl_session*>(session_wrap);
+ if (session->socket->GetEventMask() & FD_WRITE_WILL_BLOCK)
+ {
+#ifdef _WIN32
+ gnutls_transport_set_errno(session->sess, EAGAIN);
+#else
+ errno = EAGAIN;
+#endif
+ return -1;
+ }
+
+ int rv = ServerInstance->SE->Send(session->socket, reinterpret_cast<const char *>(buffer), size, 0);
+
+#ifdef _WIN32
+ if (rv < 0)
+ {
+ /* Windows doesn't use errno, but gnutls does, so check SocketEngine::IgnoreError()
+ * and then set errno appropriately.
+ * The gnutls library may also have a different errno variable than us, see
+ * gnutls_transport_set_errno(3).
+ */
+ gnutls_transport_set_errno(session->sess, SocketEngine::IgnoreError() ? EAGAIN : errno);
+ }
+#endif
+
+ if (rv < (int)size)
+ ServerInstance->SE->ChangeEventMask(session->socket, FD_WRITE_WILL_BLOCK);
+ return rv;
+ }
+