safe
[ghsmtp.git] / SockBuffer.cpp
blob42f4016fe61116b630a2a451bc8b2f10e68292f3
1 #include "SockBuffer.hpp"
3 #include "esc.hpp"
5 #include <glog/logging.h>
7 #include <gflags/gflags.h>
9 DEFINE_bool(log_data, false, "log all protocol data");
11 SockBuffer::SockBuffer(int fd_in,
12 int fd_out,
13 std::function<void(void)> read_hook,
14 std::chrono::milliseconds read_timeout,
15 std::chrono::milliseconds write_timeout,
16 std::chrono::milliseconds starttls_timeout)
17 : fd_in_(fd_in)
18 , fd_out_(fd_out)
19 , read_hook_(read_hook)
20 , read_timeout_(read_timeout)
21 , write_timeout_(write_timeout)
22 , starttls_timeout_(starttls_timeout)
23 , tls_(read_hook_)
25 POSIX::set_nonblocking(fd_in_);
26 POSIX::set_nonblocking(fd_out_);
27 log_data_ = (FLAGS_log_data || (getenv("GHSMTP_LOG_DATA") != nullptr));
30 SockBuffer::SockBuffer(SockBuffer const& that)
31 : fd_in_(that.fd_in_)
32 , fd_out_(that.fd_out_)
33 , read_hook_(that.read_hook_)
34 , read_timeout_(that.read_timeout_)
35 , write_timeout_(that.write_timeout_)
36 , starttls_timeout_(that.starttls_timeout_)
37 , limit_read_(that.limit_read_)
38 , log_data_(that.log_data_)
39 , tls_(that.read_hook_)
41 CHECK(!that.timed_out_);
42 CHECK(!that.tls_active_);
43 CHECK(!that.limit_read_);
44 CHECK(!that.maxed_out());
47 std::streamsize SockBuffer::read(char* s, std::streamsize n)
49 if (maxed_out()) {
50 LOG(ERROR) << "read attempted when"
51 << " total of " << octets_read_ << " is over limit of "
52 << read_limit_;
53 return static_cast<std::streamsize>(-1);
55 auto read = tls_active_ ? tls_.read(s, n, read_timeout_, timed_out_)
56 : POSIX::read(fd_in_, s, n, read_hook_, read_timeout_,
57 timed_out_);
58 if (read != static_cast<std::streamsize>(-1)) {
59 octets_read_ += read;
60 total_octets_read_ += read;
62 if (maxed_out()) {
63 LOG(ERROR) << "read of " << read << " puts total of " << octets_read_
64 << " over limit of " << read_limit_;
65 return static_cast<std::streamsize>(-1);
68 if (log_data_) {
69 auto str = std::string(s, static_cast<size_t>(read));
70 LOG(INFO) << "< «" << esc(str, esc_line_option::multi) << "»";
73 return read;
76 std::streamsize SockBuffer::write(const char* s, std::streamsize n)
78 auto written = tls_active_
79 ? tls_.write(s, n, write_timeout_, timed_out_)
80 : POSIX::write(fd_out_, s, n, write_timeout_, timed_out_);
81 if (written != static_cast<std::streamsize>(-1)) {
82 octets_written_ += written;
83 total_octets_written_ += written;
86 if (log_data_) {
87 auto str = std::string(s, static_cast<size_t>(written));
88 LOG(INFO) << "> «" << esc(str, esc_line_option::multi) << "»";
91 return written;
94 void SockBuffer::log_stats() const
96 LOG(INFO) << "read_limit_==" << (read_limit_ ? "true" : "false");
97 LOG(INFO) << "octets_read_==" << octets_read_;
98 LOG(INFO) << "octets_written_==" << octets_written_;
99 log_totals();
100 if (tls()) {
101 LOG(INFO) << tls_info();
105 void SockBuffer::log_totals() const
107 LOG(INFO) << "total_octets_read_==" << total_octets_read_;
108 LOG(INFO) << "total_octets_written_==" << total_octets_written_;