Changeset 08f5bd75ad170e6b8177b93e98f40d0f8a51b9d2
- Timestamp:
- 08/14/10 20:42:42 (22 months ago)
- Author:
- Antti-Juhani Kaijanaho <antti-juhani@…>
- Children:
- 994811461679afe70ab81e079fd87191d609be9d
- Parents:
- 61975465b66e572def6105480f10917981b1ef0d
- git-committer:
- Antti-Juhani Kaijanaho <antti-juhani@…> (08/14/10 20:42:42)
- Message:
-
[tls::session] Use ring buffers instead of dynamically growing buffers
This way enbuffering cannot throw bad_alloc.
Closes #69.
Signed-off-by: Antti-Juhani Kaijanaho <antti-juhani@…>
- Location:
- tls
- Files:
-
Legend:
- Unmodified
- Added
- Removed
-
|
r8d4f7f7
|
r08f5bd7
|
|
| 21 | 21 | #define GUARD_TLS_SESSION_HH |
| 22 | 22 | |
| | 23 | #include "ringbuf.hh" |
| 23 | 24 | #include "error_category.hh" |
| 24 | 25 | #include "init.hh" |
| … |
… |
|
| 40 | 41 | public boost::enable_shared_from_this<session_impl<Stream> > |
| 41 | 42 | { |
| | 43 | enum { ringbufsize = 4096 }; |
| 42 | 44 | public: |
| 43 | 45 | typedef boost::shared_ptr<session_impl<Stream> > ptr; |
| … |
… |
|
| 49 | 51 | , stream(si) |
| 50 | 52 | , strand(stream.get_io_service()) |
| 51 | | , ins_low(0) |
| 52 | | , ins_high(0) |
| | 53 | , ins(ringbufsize) |
| 53 | 54 | , read_active(false) |
| 54 | | , outs_low(0) |
| | 55 | , outs(ringbufsize) |
| 55 | 56 | , write_active(false) |
| 56 | 57 | { init(tls_init, ce); } |
| … |
… |
|
| 61 | 62 | , stream(si) |
| 62 | 63 | , strand(stream.get_io_service()) |
| 63 | | , ins_low(0) |
| 64 | | , ins_high(0) |
| | 64 | , ins(ringbufsize) |
| 65 | 65 | , read_active(false) |
| 66 | | , outs_low(0) |
| | 66 | , outs(ringbufsize) |
| 67 | 67 | , write_active(false) |
| 68 | 68 | { init(tls_init, ce); } |
| … |
… |
|
| 102 | 102 | gnutls_session_t gs; |
| 103 | 103 | |
| 104 | | /* the stuff that has been read but not yet passed on |
| 105 | | * is between ins_low and ins_high */ |
| 106 | | std::vector<unsigned char> ins; |
| 107 | | size_t ins_low, ins_high; |
| | 104 | ringbuf ins; |
| 108 | 105 | bool read_active; |
| 109 | 106 | |
| 110 | | /* the stuff that has been buffered for sending but |
| 111 | | * not yet sent is between outs_low and the end of |
| 112 | | * outs */ |
| 113 | | std::vector<unsigned char> outs; |
| 114 | | size_t outs_low; |
| | 107 | ringbuf outs; |
| 115 | 108 | bool write_active; |
| 116 | 109 | |
-
|
rae733bf
|
r08f5bd7
|
|
| 66 | 66 | ssize_t session_impl<Stream>::push(const void *b, size_t n) |
| 67 | 67 | { |
| 68 | | const unsigned char *cs = static_cast<const unsigned char *>(b); |
| 69 | | for (size_t i = 0; i < n; i++) |
| 70 | | { |
| 71 | | outs.push_back(cs[i]); |
| 72 | | } |
| 73 | | return n; |
| | 68 | if (outs.full()) |
| | 69 | { |
| | 70 | errno = EAGAIN; |
| | 71 | return -1; |
| | 72 | } |
| | 73 | return outs.put(static_cast<const unsigned char *>(b), n); |
| 74 | 74 | } |
| 75 | 75 | |
| 76 | 76 | /* never call directly! (called by gnutls) */ |
| 77 | 77 | template <typename Stream> |
| 78 | | ssize_t session_impl<Stream>::pull(void *b, size_t n_wanted) |
| 79 | | { |
| 80 | | unsigned char *cs = static_cast<unsigned char *>(b); |
| 81 | | if (ins_high - ins_low > 0) |
| 82 | | { |
| 83 | | size_t n = ins_high - ins_low < n_wanted |
| 84 | | ? ins_high - ins_low |
| 85 | | : n_wanted; |
| 86 | | for (size_t i = 0; i < n; i++) |
| 87 | | { |
| 88 | | cs[i] = ins[ins_low+i]; |
| 89 | | } |
| 90 | | ins_low += n; |
| 91 | | return n; |
| 92 | | } |
| 93 | | errno = EAGAIN; |
| 94 | | return -1; |
| | 78 | ssize_t session_impl<Stream>::pull(void *b, size_t n) |
| | 79 | { |
| | 80 | if (ins.empty()) |
| | 81 | { |
| | 82 | errno = EAGAIN; |
| | 83 | return -1; |
| | 84 | } |
| | 85 | return ins.get(static_cast<unsigned char *>(b), n); |
| 95 | 86 | } |
| 96 | 87 | |
| … |
… |
|
| 99 | 90 | { |
| 100 | 91 | if (write_active) return; |
| 101 | | if (outs_low > 0 && outs_low == outs.size()) |
| 102 | | { |
| 103 | | outs.clear(); |
| 104 | | outs_low = 0; |
| 105 | | } |
| 106 | | else if (outs_low > 4096) |
| 107 | | { |
| 108 | | outs.erase(outs.begin(), outs.begin() + outs_low); |
| 109 | | outs_low = 0; |
| 110 | | } |
| 111 | | if (outs_low < outs.size()) |
| | 92 | if (!outs.empty()) |
| 112 | 93 | { |
| 113 | 94 | stream.async_write_some |
| 114 | | (boost::asio::buffer(outs.data()+outs_low, |
| 115 | | outs.size()-outs_low), |
| | 95 | (outs.read_area(), |
| 116 | 96 | strand.wrap(boost::bind |
| 117 | 97 | (&sent_some, |
| … |
… |
|
| 126 | 106 | { |
| 127 | 107 | if (read_active) return; |
| 128 | | if (ins_low > 0 && ins_low == ins.size()) |
| 129 | | { |
| 130 | | ins.clear(); |
| 131 | | ins_low = 0; |
| 132 | | ins_high = 0; |
| 133 | | } |
| 134 | | else if (ins_low > 4096) |
| 135 | | { |
| 136 | | ins.erase(ins.begin(), ins.begin() + ins_low); |
| 137 | | ins_high -= ins_low; |
| 138 | | ins_low = 0; |
| 139 | | } |
| 140 | | |
| 141 | | if (ins_high + 4096 >= ins.size()) ins.resize(ins_high + 4096); |
| 142 | 108 | stream.async_read_some |
| 143 | | (boost::asio::buffer(ins.data()+ins_high, |
| 144 | | ins.size()-ins_high), |
| | 109 | (ins.write_area(), |
| 145 | 110 | strand.wrap(boost::bind |
| 146 | 111 | (&received_some, this->shared_from_this(), |
| … |
… |
|
| 171 | 136 | self->read_active = false; |
| 172 | 137 | if (ec == boost::asio::error::operation_aborted) return; |
| 173 | | if (ec) self->pending_error = ec; else self->ins_high += n; |
| | 138 | if (ec) self->pending_error = ec; else self->ins.written(n); |
| 174 | 139 | self->post_pending_actions(); |
| 175 | 140 | } |
| … |
… |
|
| 183 | 148 | if (ec == boost::asio::error::operation_aborted) return; |
| 184 | 149 | if (ec) { self->pending_error = ec; return; } |
| 185 | | self->outs_low += n; |
| | 150 | self->outs.read(n); |
| 186 | 151 | self->post_pending_actions(); |
| 187 | 152 | } |