comes in plain
[ghsmtp.git] / SockBuffer.hpp
blob7fbf0a624582180b08d9d5cf2d5740717bd2537d
1 #ifndef SOCKBUFFER_DOT_HPP
2 #define SOCKBUFFER_DOT_HPP
4 #include <cerrno>
5 #include <chrono>
6 #include <cstdlib>
7 #include <streambuf>
8 #include <string>
10 #include "POSIX.hpp"
11 #include "TLS-OpenSSL.hpp"
13 // We must define this to account for args to Sockbuffer ctor.
14 #define BOOST_IOSTREAMS_MAX_FORWARDING_ARITY 6
16 #include <boost/iostreams/concepts.hpp>
17 #include <boost/iostreams/stream.hpp>
19 namespace Config {
20 constexpr std::chrono::seconds default_read_timeout{2};
21 constexpr std::chrono::seconds default_write_timeout{2};
22 constexpr std::chrono::seconds default_starttls_timeout{2};
23 } // namespace Config
25 class SockBuffer
26 : public boost::iostreams::device<boost::iostreams::bidirectional> {
27 public:
28 SockBuffer(
29 int fd_in,
30 int fd_out,
31 std::function<void(void)> read_hook = []() {},
32 std::chrono::milliseconds read_timeout = Config::default_read_timeout,
33 std::chrono::milliseconds write_timeout = Config::default_write_timeout,
34 std::chrono::milliseconds starttls_timeout
35 = Config::default_starttls_timeout);
37 SockBuffer& operator=(const SockBuffer&) = delete;
38 SockBuffer(SockBuffer const& that);
40 bool input_ready(std::chrono::milliseconds wait) const
42 return (tls_active_ && tls_.pending()) || POSIX::input_ready(fd_in_, wait);
44 bool output_ready(std::chrono::milliseconds wait) const
46 return POSIX::output_ready(fd_out_, wait);
48 bool maxed_out() const
50 return limit_read_ && (octets_read_ >= read_limit_);
52 bool timed_out() const { return timed_out_; }
54 std::streamsize read(char* s, std::streamsize n);
55 std::streamsize write(const char* s, std::streamsize n);
57 bool starttls_server(fs::path config_path)
59 return tls_active_ = tls_.starttls_server(config_path, fd_in_, fd_out_,
60 starttls_timeout_);
62 bool starttls_client(fs::path config_path,
63 char const* client_name,
64 char const* server_name,
65 DNS::RR_collection const& tlsa_rrs,
66 bool enforce_dane)
68 return tls_active_ = tls_.starttls_client(
69 config_path, fd_in_, fd_out_, client_name, server_name, tlsa_rrs,
70 enforce_dane, starttls_timeout_);
72 bool tls() const { return tls_active_; }
73 std::string tls_info() const { return tls() ? tls_.info() : ""; }
74 bool verified() const { return tls_.verified(); };
76 void set_max_read(std::streamsize max)
78 limit_read_ = true;
79 read_limit_ = max;
80 octets_read_ = 0;
81 octets_written_ = 0;
84 void log_data_on() { log_data_ = true; }
85 void log_data_off() { log_data_ = false; }
87 void log_stats() const;
88 void log_totals() const;
90 void close_fds()
92 if (fd_in_ != fd_out_)
93 ::close(fd_in_);
94 ::close(fd_out_);
95 fd_in_ = fd_out_ = -1;
98 private:
99 int fd_in_;
100 int fd_out_;
102 std::streamsize read_limit_{0};
103 std::streamsize octets_read_{0};
104 std::streamsize octets_written_{0};
105 std::streamsize total_octets_read_{0};
106 std::streamsize total_octets_written_{0};
108 std::function<void(void)> read_hook_;
110 std::chrono::milliseconds read_timeout_;
111 std::chrono::milliseconds write_timeout_;
112 std::chrono::milliseconds starttls_timeout_;
114 bool timed_out_{false};
115 bool tls_active_{false};
116 bool limit_read_{false};
117 bool log_data_{false};
119 TLS tls_;
122 #endif // SOCKBUFFER_DOT_HPP