OpenVPN 3 Core Library
Loading...
Searching...
No Matches
chunked.hpp
Go to the documentation of this file.
1
// OpenVPN -- An application to securely tunnel IP networks
2
// over a single port, with support for SSL/TLS-based
3
// session authentication and key exchange,
4
// packet encryption, packet authentication, and
5
// packet compression.
6
//
7
// Copyright (C) 2012- OpenVPN Inc.
8
//
9
// SPDX-License-Identifier: MPL-2.0 OR AGPL-3.0-only WITH openvpn3-openssl-exception
10
//
11
12
#pragma once
13
14
#include <
openvpn/common/size.hpp
>
15
#include <
openvpn/common/hexstr.hpp
>
16
#include <
openvpn/buffer/buffer.hpp
>
17
#include <
openvpn/frame/frame.hpp
>
18
19
namespace
openvpn::WS
{
20
class
ChunkedHelper
21
{
22
enum
State
23
{
24
hex
,
25
post_hex
,
26
post_hex_lf
,
27
post_chunk_cr
,
28
post_chunk_lf
,
29
post_content_cr
,
30
post_content_lf
,
31
done
,
32
chunk
,
33
};
34
35
public
:
36
ChunkedHelper
()
37
:
state
(
hex
),
38
size
(0)
39
{
40
}
41
42
template
<
typename
PARENT>
43
bool
receive
(PARENT &callback,
BufferAllocated
&buf)
44
{
45
while
(buf.
defined
())
46
{
47
if
(
state
==
chunk
)
48
{
49
if
(
size
)
50
{
51
if
(buf.
size
() <=
size
)
52
{
53
size
-= buf.
size
();
54
callback.chunked_content_in(buf);
55
break
;
56
}
57
else
58
{
59
BufferAllocated
content(buf.
read_alloc
(
size
),
size
, 0);
60
size
= 0;
61
callback.chunked_content_in(content);
62
}
63
}
64
else
65
state
=
post_chunk_cr
;
66
}
67
else
if
(
state
==
done
)
68
break
;
69
else
70
{
71
const
char
c = char(buf.
pop_front
());
72
reprocess:
73
switch
(
state
)
74
{
75
case
hex
:
76
{
77
const
int
v =
parse_hex_char
(c);
78
if
(v >= 0)
79
size
= (
size
<< 4) + v;
80
else
81
{
82
state
=
post_hex
;
83
goto
reprocess;
84
}
85
}
86
break
;
87
case
post_hex
:
88
if
(c ==
'\r'
)
89
state
=
post_hex_lf
;
90
break
;
91
case
post_hex_lf
:
92
if
(c ==
'\n'
)
93
{
94
if
(
size
)
95
state
=
chunk
;
96
else
97
state
=
post_content_cr
;
98
}
99
else
100
{
101
state
=
post_hex
;
102
goto
reprocess;
103
}
104
break
;
105
case
post_chunk_cr
:
106
if
(c ==
'\r'
)
107
state
=
post_chunk_lf
;
108
break
;
109
case
post_chunk_lf
:
110
if
(c ==
'\n'
)
111
state
=
hex
;
112
else
113
{
114
state
=
post_chunk_cr
;
115
goto
reprocess;
116
}
117
break
;
118
case
post_content_cr
:
119
if
(c ==
'\r'
)
120
state
=
post_content_lf
;
121
break
;
122
case
post_content_lf
:
123
if
(c ==
'\n'
)
124
state
=
done
;
125
else
126
{
127
state
=
post_content_cr
;
128
goto
reprocess;
129
}
130
break
;
131
default
:
// should never be reached
132
break
;
133
}
134
}
135
}
136
return
state
==
done
;
137
}
138
139
static
BufferPtr
transmit
(
BufferPtr
buf)
140
{
141
const
size_t
headroom = 24;
142
const
size_t
tailroom = 16;
143
static
const
char
crlf[] =
"\r\n"
;
144
145
if
(!buf || buf->offset() < headroom || buf->remaining() < tailroom)
146
{
147
// insufficient headroom/tailroom, must realloc
148
Frame::Context
fc(headroom, 0, tailroom, 0,
sizeof
(
size_t
), 0);
149
buf = fc.
copy
(buf);
150
}
151
152
size_t
size
= buf->size();
153
buf->prepend((
unsigned
char
*)crlf, 2);
154
if
(
size
)
155
{
156
while
(
size
)
157
{
158
char
*pc = (
char
*)buf->prepend_alloc(1);
159
*pc =
render_hex_char
(
size
& 0xF);
160
size
>>= 4;
161
}
162
}
163
else
164
{
165
char
*pc = (
char
*)buf->prepend_alloc(1);
166
*pc =
'0'
;
167
}
168
buf->write((
unsigned
char
*)crlf, 2);
169
return
buf;
170
}
171
172
private
:
173
State
state
;
174
size_t
size
;
175
};
176
}
// namespace openvpn::WS
buffer.hpp
openvpn::BufferAllocatedType< unsigned char >
openvpn::ConstBufferType::defined
bool defined() const
Returns true if the buffer is not empty.
Definition
buffer.hpp:1207
openvpn::ConstBufferType::size
size_t size() const
Returns the size of the buffer in T objects.
Definition
buffer.hpp:1225
openvpn::ConstBufferType::read_alloc
auto * read_alloc(const size_t size)
Allocate memory and read data from the buffer into the allocated memory.
Definition
buffer.hpp:1326
openvpn::ConstBufferType::pop_front
T pop_front()
Removes and returns the first element from the buffer.
Definition
buffer.hpp:1239
openvpn::Frame::Context
Definition
frame.hpp:58
openvpn::Frame::Context::copy
BufferPtr copy(const unsigned char *data, const size_t size) const
Definition
frame.hpp:138
openvpn::RCPtr< BufferAllocatedRc >
openvpn::WS::ChunkedHelper
Definition
chunked.hpp:21
openvpn::WS::ChunkedHelper::transmit
static BufferPtr transmit(BufferPtr buf)
Definition
chunked.hpp:139
openvpn::WS::ChunkedHelper::state
State state
Definition
chunked.hpp:173
openvpn::WS::ChunkedHelper::receive
bool receive(PARENT &callback, BufferAllocated &buf)
Definition
chunked.hpp:43
openvpn::WS::ChunkedHelper::ChunkedHelper
ChunkedHelper()
Definition
chunked.hpp:36
openvpn::WS::ChunkedHelper::size
size_t size
Definition
chunked.hpp:174
openvpn::WS::ChunkedHelper::State
State
Definition
chunked.hpp:23
openvpn::WS::ChunkedHelper::chunk
@ chunk
Definition
chunked.hpp:32
openvpn::WS::ChunkedHelper::done
@ done
Definition
chunked.hpp:31
openvpn::WS::ChunkedHelper::post_content_lf
@ post_content_lf
Definition
chunked.hpp:30
openvpn::WS::ChunkedHelper::post_chunk_lf
@ post_chunk_lf
Definition
chunked.hpp:28
openvpn::WS::ChunkedHelper::hex
@ hex
Definition
chunked.hpp:24
openvpn::WS::ChunkedHelper::post_chunk_cr
@ post_chunk_cr
Definition
chunked.hpp:27
openvpn::WS::ChunkedHelper::post_hex
@ post_hex
Definition
chunked.hpp:25
openvpn::WS::ChunkedHelper::post_hex_lf
@ post_hex_lf
Definition
chunked.hpp:26
openvpn::WS::ChunkedHelper::post_content_cr
@ post_content_cr
Definition
chunked.hpp:29
frame.hpp
hexstr.hpp
openvpn::WS
Definition
chunked.hpp:19
openvpn::parse_hex_char
int parse_hex_char(const int c)
Definition
hexstr.hpp:65
openvpn::render_hex_char
char render_hex_char(const int c, const bool caps=false)
Definition
hexstr.hpp:42
size.hpp
openvpn
ws
chunked.hpp
Generated by
1.9.8