+ class DataReader
+ {
+ int retval;
+#ifdef INSPIRCD_GNUTLS_HAS_RECV_PACKET
+ gnutls_packet_t packet;
+
+ public:
+ DataReader(gnutls_session_t sess)
+ {
+ // Using the packet API avoids the final copy of the data which GnuTLS does if we supply
+ // our own buffer. Instead, we get the buffer containing the data from GnuTLS and copy it
+ // to the recvq directly from there in appendto().
+ retval = gnutls_record_recv_packet(sess, &packet);
+ }
+
+ void appendto(std::string& recvq)
+ {
+ // Copy data from GnuTLS buffers to recvq
+ gnutls_datum_t datum;
+ gnutls_packet_get(packet, &datum, NULL);
+ recvq.append(reinterpret_cast<const char*>(datum.data), datum.size);
+
+ gnutls_packet_deinit(packet);
+ }
+#else
+ char* const buffer;
+
+ public:
+ DataReader(gnutls_session_t sess)
+ : buffer(ServerInstance->GetReadBuffer())
+ {
+ // Read data from GnuTLS buffers into ReadBuffer
+ retval = gnutls_record_recv(sess, buffer, ServerInstance->Config->NetBufferSize);
+ }
+
+ void appendto(std::string& recvq)
+ {
+ // Copy data from ReadBuffer to recvq
+ recvq.append(buffer, retval);
+ }
+#endif
+
+ int ret() const { return retval; }
+ };
+