Node.js  v8.x
Node.js is a JavaScript runtime built on Chrome's V8 JavaScript engine
node_crypto_bio.h
Go to the documentation of this file.
1 // Copyright Joyent, Inc. and other Node contributors.
2 //
3 // Permission is hereby granted, free of charge, to any person obtaining a
4 // copy of this software and associated documentation files (the
5 // "Software"), to deal in the Software without restriction, including
6 // without limitation the rights to use, copy, modify, merge, publish,
7 // distribute, sublicense, and/or sell copies of the Software, and to permit
8 // persons to whom the Software is furnished to do so, subject to the
9 // following conditions:
10 //
11 // The above copyright notice and this permission notice shall be included
12 // in all copies or substantial portions of the Software.
13 //
14 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15 // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
17 // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
18 // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
19 // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
20 // USE OR OTHER DEALINGS IN THE SOFTWARE.
21 
22 #ifndef SRC_NODE_CRYPTO_BIO_H_
23 #define SRC_NODE_CRYPTO_BIO_H_
24 
25 #if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
26 
27 #include "openssl/bio.h"
28 #include "env.h"
29 #include "env-inl.h"
30 #include "util.h"
31 #include "util-inl.h"
32 #include "v8.h"
33 
34 namespace node {
35 namespace crypto {
36 
37 class NodeBIO {
38  public:
39  NodeBIO() : env_(nullptr),
40  initial_(kInitialBufferLength),
41  length_(0),
42  read_head_(nullptr),
43  write_head_(nullptr) {
44  }
45 
46  ~NodeBIO();
47 
48  static BIO* New();
49 
50  // NewFixed takes a copy of `len` bytes from `data` and returns a BIO that,
51  // when read from, returns those bytes followed by EOF.
52  static BIO* NewFixed(const char* data, size_t len);
53 
54  void AssignEnvironment(Environment* env);
55 
56  // Move read head to next buffer if needed
57  void TryMoveReadHead();
58 
59  // Allocate new buffer for write if needed
60  void TryAllocateForWrite(size_t hint);
61 
62  // Read `len` bytes maximum into `out`, return actual number of read bytes
63  size_t Read(char* out, size_t size);
64 
65  // Memory optimization:
66  // Deallocate children of write head's child if they're empty
67  void FreeEmpty();
68 
69  // Return pointer to internal data and amount of
70  // contiguous data available to read
71  char* Peek(size_t* size);
72 
73  // Return pointers and sizes of multiple internal data chunks available for
74  // reading
75  size_t PeekMultiple(char** out, size_t* size, size_t* count);
76 
77  // Find first appearance of `delim` in buffer or `limit` if `delim`
78  // wasn't found.
79  size_t IndexOf(char delim, size_t limit);
80 
81  // Discard all available data
82  void Reset();
83 
84  // Put `len` bytes from `data` into buffer
85  void Write(const char* data, size_t size);
86 
87  // Return pointer to internal data and amount of
88  // contiguous data available for future writes
89  char* PeekWritable(size_t* size);
90 
91  // Commit reserved data
92  void Commit(size_t size);
93 
94 
95  // Return size of buffer in bytes
96  inline size_t Length() const {
97  return length_;
98  }
99 
100  inline void set_initial(size_t initial) {
101  initial_ = initial;
102  }
103 
104  static inline NodeBIO* FromBIO(BIO* bio) {
105  CHECK_NE(bio->ptr, nullptr);
106  return static_cast<NodeBIO*>(bio->ptr);
107  }
108 
109  private:
110  static int New(BIO* bio);
111  static int Free(BIO* bio);
112  static int Read(BIO* bio, char* out, int len);
113  static int Write(BIO* bio, const char* data, int len);
114  static int Puts(BIO* bio, const char* str);
115  static int Gets(BIO* bio, char* out, int size);
116  static long Ctrl(BIO* bio, int cmd, long num, // NOLINT(runtime/int)
117  void* ptr);
118 
119  // Enough to handle the most of the client hellos
120  static const size_t kInitialBufferLength = 1024;
121  static const size_t kThroughputBufferLength = 16384;
122 
123  static const BIO_METHOD method;
124 
125  class Buffer {
126  public:
127  Buffer(Environment* env, size_t len) : env_(env),
128  read_pos_(0),
129  write_pos_(0),
130  len_(len),
131  next_(nullptr) {
132  data_ = new char[len];
133  if (env_ != nullptr)
134  env_->isolate()->AdjustAmountOfExternalAllocatedMemory(len);
135  }
136 
137  ~Buffer() {
138  delete[] data_;
139  if (env_ != nullptr) {
140  const int64_t len = static_cast<int64_t>(len_);
141  env_->isolate()->AdjustAmountOfExternalAllocatedMemory(-len);
142  }
143  }
144 
145  Environment* env_;
146  size_t read_pos_;
147  size_t write_pos_;
148  size_t len_;
149  Buffer* next_;
150  char* data_;
151  };
152 
153  Environment* env_;
154  size_t initial_;
155  size_t length_;
156  Buffer* read_head_;
157  Buffer* write_head_;
158 };
159 
160 } // namespace crypto
161 } // namespace node
162 
163 #endif // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
164 
165 #endif // SRC_NODE_CRYPTO_BIO_H_
int len
Definition: cares_wrap.cc:485
Environment *const env_
union node::cares_wrap::@8::CaresAsyncData::@0 data
size_t Length(Local< Value > val)
Definition: node_buffer.cc:227
MaybeLocal< Object > New(Isolate *isolate, Local< String > string, enum encoding enc)
Definition: node_buffer.cc:241
method
Definition: node.d:195