-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathproxy-conn.hpp
154 lines (113 loc) · 3.99 KB
/
proxy-conn.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
#pragma once
#include <memory>
#include "common.h"
#include "gdb-packet.h"
#include "target.h"
template<size_t capacity>
struct data_buffer
{
std::array<char, capacity> data;
size_t size = 0;
size_t consumed = 0;
void reset()
{
size = 0;
consumed = 0;
}
bool empty() const
{
return size == consumed;
}
};
// Only Data packets
struct transfer
{
struct internal {};
using on_response_cb = std::function<void(const gdb_packet& request, const gdb_packet& response)>;
transfer(gdb_packet&& pkt, on_response_cb&& cb = on_response_cb())
: pkt(std::move(pkt)),
on_response(std::move(cb))
{}
transfer(gdb_packet&& pkt, internal, on_response_cb&& cb = on_response_cb())
: pkt(std::move(pkt)),
is_internal(true),
on_response(std::move(cb))
{}
gdb_packet pkt;
bool const is_internal = false;
on_response_cb on_response;
};
class connection : public std::enable_shared_from_this<connection>
{
public:
typedef std::shared_ptr<connection> pointer;
friend class channel;
static pointer
create(asio::io_service &io_service, std::string_view target, const std::vector<char*>& options, std::string_view remote_host, int remote_port) {
return pointer(new connection(io_service, target, options, remote_host, remote_port));
}
~connection()
{
std::clog << "~connection\n";
}
asio::ip::tcp::socket& socket() {
return m_client_socket;
}
/// Start read data of request from browser
void start();
void push_internal_request(gdb_packet&& req, transfer::on_response_cb cb = transfer::on_response_cb());
void push_request(gdb_packet&& req, transfer::on_response_cb cb = transfer::on_response_cb());
void push_internal_response(gdb_packet&& req, transfer::on_response_cb cb = transfer::on_response_cb());
private:
struct channel
{
public:
using on_packet_handler = std::function<bool(const gdb_packet& packet)>;
enum direction {
requests,
responses,
};
channel(asio::io_service& io,
asio::ip::tcp::socket& src,
asio::ip::tcp::socket& dst,
direction dir);
void start_read(std::shared_ptr<connection> con);
void start_write(std::shared_ptr<connection> con, transfer&& req);
void set_packet_handler(on_packet_handler handler);
std::deque<transfer>& transfers_queue();
private:
void process_data(std::shared_ptr<connection> con);
private:
asio::io_service& m_io;
asio::ip::tcp::socket& m_src;
asio::ip::tcp::socket& m_dst;
data_buffer<8192> m_buffer;
gdb_packet m_packet;
std::deque<transfer> m_transfers;
on_packet_handler m_handler;
direction m_dir = requests;
};
connection(asio::io_service &io_service, std::string_view target, const std::vector<char *> &options,
std::string_view remote_host, int remote_port);
/// Start connecting to the web-server, initially to resolve the DNS-name of Web server into the IP address
void start_connect();
void handle_resolve(const std::error_code& err,
asio::ip::tcp::resolver::iterator endpoint_iterator);
void handle_connect(const std::error_code& err,
asio::ip::tcp::resolver::iterator endpoint_iterator, const bool first_time);
/// Close both sockets: for browser and web-server
void shutdown();
bool on_request(const gdb_packet& pkt);
bool on_response(const gdb_packet& pkt);
asio::io_service& io_service_;
asio::ip::tcp::socket m_client_socket;
asio::ip::tcp::socket m_target_socket;
asio::ip::tcp::resolver resolver_;
channel m_requests_channel;
channel m_responses_channel;
std::string fServer = "localhost";
int fPort = 3002;
size_t seq = 0;
bool m_ack_mode = true;
std::unique_ptr<target> m_target;
};