Skip to content

Commit caffdbb

Browse files
authored
Tonproxy improvements (ton-blockchain#483)
* Bugfixes in rldp-http-proxy and http parser * Tonlib: change liteservers on query timeout or connection close * Increase maximum size of http request * Minor bugfixes in http
1 parent cc9ce0e commit caffdbb

23 files changed

+158
-77
lines changed

adnl/adnl-ext-client.hpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,9 @@ class AdnlExtClientImpl : public AdnlExtClient {
8080
if (!conn_.empty() && conn_.get() == conn) {
8181
callback_->on_stop_ready();
8282
conn_ = {};
83+
for (auto& q : out_queries_) {
84+
td::actor::send_closure(q.second, &AdnlQuery::set_error, td::Status::Error(ErrorCode::cancelled));
85+
}
8386
alarm_timestamp() = next_create_at_;
8487
try_stop();
8588
}

adnl/adnl-query.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,16 @@ namespace ton {
2525
namespace adnl {
2626

2727
void AdnlQuery::alarm() {
28-
promise_.set_error(td::Status::Error(ErrorCode::timeout, "adnl query timeout"));
29-
stop();
28+
set_error(td::Status::Error(ErrorCode::timeout, "adnl query timeout"));
3029
}
3130
void AdnlQuery::result(td::BufferSlice data) {
3231
promise_.set_value(std::move(data));
3332
stop();
3433
}
34+
void AdnlQuery::set_error(td::Status error) {
35+
promise_.set_error(std::move(error));
36+
stop();
37+
}
3538

3639
AdnlQueryId AdnlQuery::random_query_id() {
3740
AdnlQueryId q_id;

adnl/adnl-query.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ class AdnlQuery : public td::actor::Actor {
4848
}
4949
void alarm() override;
5050
void result(td::BufferSlice data);
51+
void set_error(td::Status error);
5152
void start_up() override {
5253
alarm_timestamp() = timeout_;
5354
}

http/http-inbound-connection.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,10 +79,10 @@ td::Status HttpInboundConnection::receive(td::ChainBufferReader &input) {
7979
send_client_error();
8080
return td::Status::OK();
8181
}
82+
cur_request_ = R.move_as_ok();
8283
if (exit_loop) {
8384
return td::Status::OK();
8485
}
85-
cur_request_ = R.move_as_ok();
8686
}
8787

8888
auto payload = cur_request_->create_empty_payload().move_as_ok();

http/http-outbound-connection.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,10 +42,10 @@ td::Status HttpOutboundConnection::receive(td::ChainBufferReader &input) {
4242
answer_error(HttpStatusCode::status_bad_request, "", std::move(promise_));
4343
return td::Status::OK();
4444
}
45+
cur_response_ = R.move_as_ok();
4546
if (exit_loop) {
4647
return td::Status::OK();
4748
}
48-
cur_response_ = R.move_as_ok();
4949
}
5050

5151
if (cur_response_->code() == 100) {

http/http.cpp

Lines changed: 21 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -279,25 +279,20 @@ td::Status HttpPayload::parse(td::ChainBufferReader &input) {
279279
} break;
280280
case ParseState::reading_chunk_data: {
281281
if (cur_chunk_size_ == 0) {
282-
switch (type_) {
283-
case PayloadType::pt_empty:
284-
UNREACHABLE();
285-
case PayloadType::pt_eof:
286-
case PayloadType::pt_tunnel:
287-
cur_chunk_size_ = 1LL << 60;
288-
break;
289-
case PayloadType::pt_chunked:
290-
state_ = ParseState::reading_crlf;
291-
break;
292-
case PayloadType::pt_content_length: {
293-
LOG(INFO) << "payload parse success";
294-
const std::lock_guard<std::mutex> lock{mutex_};
295-
state_ = ParseState::completed;
296-
run_callbacks();
297-
return td::Status::OK();
298-
} break;
282+
if (type_ == PayloadType::pt_eof || type_ == PayloadType::pt_tunnel) {
283+
cur_chunk_size_ = 1LL << 60;
284+
} else if (type_ == PayloadType::pt_chunked) {
285+
state_ = ParseState::reading_crlf;
286+
break;
287+
} else if (type_ == PayloadType::pt_content_length) {
288+
LOG(INFO) << "payload parse success";
289+
const std::lock_guard<std::mutex> lock{mutex_};
290+
state_ = ParseState::completed;
291+
run_callbacks();
292+
return td::Status::OK();
293+
} else {
294+
UNREACHABLE();
299295
}
300-
break;
301296
}
302297
if (input.size() == 0) {
303298
return td::Status::OK();
@@ -502,7 +497,7 @@ bool HttpPayload::store_http(td::ChainBufferWriter &output, size_t max_size, Htt
502497
char buf[64];
503498
::sprintf(buf, "%lx\r\n", s.size());
504499
auto slice = td::Slice(buf, strlen(buf));
505-
wrote |= !slice.empty();
500+
wrote = true;
506501
output.append(slice);
507502
}
508503

@@ -514,7 +509,8 @@ bool HttpPayload::store_http(td::ChainBufferWriter &output, size_t max_size, Htt
514509
wrote = true;
515510
}
516511
}
517-
if (chunks_.size() != 0 || !parse_completed()) {
512+
auto cur_state = state_.load(std::memory_order_consume);
513+
if (chunks_.size() != 0 || (cur_state != ParseState::reading_trailer && cur_state != ParseState::completed)) {
518514
return wrote;
519515
}
520516
if (!written_zero_chunk_) {
@@ -531,7 +527,7 @@ bool HttpPayload::store_http(td::ChainBufferWriter &output, size_t max_size, Htt
531527
}
532528

533529
while (max_size > 0) {
534-
auto cur_state = state_.load(std::memory_order_consume);
530+
cur_state = state_.load(std::memory_order_consume);
535531
HttpHeader h = get_header();
536532
if (h.empty()) {
537533
if (cur_state != ParseState::completed) {
@@ -587,7 +583,8 @@ tl_object_ptr<ton_api::http_payloadPart> HttpPayload::store_tl(size_t max_size)
587583
max_size -= s.size();
588584
}
589585
obj->data_.truncate(obj->data_.size() - S.size());
590-
if (chunks_.size() != 0) {
586+
auto cur_state = state_.load(std::memory_order_consume);
587+
if (chunks_.size() != 0 || (cur_state != ParseState::reading_trailer && cur_state != ParseState::completed)) {
591588
return obj;
592589
}
593590
if (!written_zero_chunk_) {
@@ -597,7 +594,7 @@ tl_object_ptr<ton_api::http_payloadPart> HttpPayload::store_tl(size_t max_size)
597594
LOG(INFO) << "data completed";
598595

599596
while (max_size > 0) {
600-
auto cur_state = state_.load(std::memory_order_consume);
597+
cur_state = state_.load(std::memory_order_consume);
601598
HttpHeader h = get_header();
602599
if (h.empty()) {
603600
if (cur_state != ParseState::completed) {
@@ -869,7 +866,7 @@ td::Status HttpHeader::basic_check() {
869866
}
870867
for (auto &c : value) {
871868
if (c == '\r' || c == '\n') {
872-
return td::Status::Error("bad character in header name");
869+
return td::Status::Error("bad character in header value");
873870
}
874871
}
875872
return td::Status::OK();

rldp-http-proxy/DNSResolver.cpp

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
*/
2626
#include "DNSResolver.h"
2727
#include "td/utils/overloaded.h"
28+
#include "common/delay.h"
2829

2930
static const double CACHE_TIMEOUT_HARD = 300.0;
3031
static const double CACHE_TIMEOUT_SOFT = 270.0;
@@ -33,8 +34,18 @@ DNSResolver::DNSResolver(td::actor::ActorId<TonlibClient> tonlib_client) : tonli
3334
}
3435

3536
void DNSResolver::start_up() {
37+
sync();
38+
}
39+
40+
void DNSResolver::sync() {
3641
auto obj = tonlib_api::make_object<tonlib_api::sync>();
37-
auto P = td::PromiseCreator::lambda([](td::Result<tonlib_api::object_ptr<tonlib_api::Object>>) {});
42+
auto P = td::PromiseCreator::lambda([SelfId =
43+
actor_id(this)](td::Result<tonlib_api::object_ptr<tonlib_api::Object>> R) {
44+
if (R.is_error()) {
45+
LOG(WARNING) << "Sync error: " << R.move_as_error();
46+
ton::delay_action([SelfId]() { td::actor::send_closure(SelfId, &DNSResolver::sync); }, td::Timestamp::in(5.0));
47+
}
48+
});
3849
td::actor::send_closure(tonlib_client_, &TonlibClient::send_request, std::move(obj), std::move(P));
3950
}
4051

rldp-http-proxy/DNSResolver.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ class DNSResolver : public td::actor::Actor {
3737
void resolve(std::string host, td::Promise<ton::adnl::AdnlNodeIdShort> promise);
3838

3939
private:
40+
void sync();
4041
void save_to_cache(std::string host, ton::adnl::AdnlNodeIdShort id);
4142

4243
td::actor::ActorId<TonlibClient> tonlib_client_;

rldp-http-proxy/rldp-http-proxy.cpp

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ class HttpRemote : public td::actor::Actor {
117117
}
118118
});
119119
td::actor::send_closure(client_, &ton::http::HttpClient::send_request, std::move(request), std::move(payload),
120-
td::Timestamp::in(30.0), std::move(P));
120+
td::Timestamp::never(), std::move(P));
121121
} else {
122122
ton::http::answer_error(ton::http::HttpStatusCode::status_bad_request, "", std::move(promise));
123123
}
@@ -801,6 +801,7 @@ class RldpToTcpRequestSender : public td::actor::Actor {
801801
, dst_(dst)
802802
, request_(std::move(request))
803803
, request_payload_(std::move(request_payload))
804+
, proto_version_(request_->proto_version())
804805
, promise_(std::move(promise))
805806
, adnl_(adnl)
806807
, rldp_(rldp)
@@ -824,19 +825,17 @@ class RldpToTcpRequestSender : public td::actor::Actor {
824825
}
825826

826827
void got_result(std::pair<std::unique_ptr<ton::http::HttpResponse>, std::shared_ptr<ton::http::HttpPayload>> R) {
827-
if (R.first->need_payload()) {
828-
td::actor::create_actor<HttpRldpPayloadSender>("HttpPayloadSender(R)", std::move(R.second), id_, local_id_, adnl_,
829-
rldp_)
830-
.release();
831-
}
828+
td::actor::create_actor<HttpRldpPayloadSender>("HttpPayloadSender(R)", std::move(R.second), id_, local_id_, adnl_,
829+
rldp_)
830+
.release();
832831
auto f = ton::serialize_tl_object(R.first->store_tl(), true);
833832
promise_.set_value(std::move(f));
834833
stop();
835834
}
836835

837836
void abort_query(td::Status error) {
838837
LOG(INFO) << "aborting http over rldp query: " << error;
839-
promise_.set_result(create_error_response(request_->proto_version(), 502, "Bad Gateway"));
838+
promise_.set_result(create_error_response(proto_version_, 502, "Bad Gateway"));
840839
stop();
841840
}
842841

@@ -848,6 +847,7 @@ class RldpToTcpRequestSender : public td::actor::Actor {
848847

849848
std::unique_ptr<ton::http::HttpRequest> request_;
850849
std::shared_ptr<ton::http::HttpPayload> request_payload_;
850+
std::string proto_version_;
851851

852852
td::Promise<td::BufferSlice> promise_;
853853

@@ -1090,6 +1090,7 @@ class RldpHttpProxy : public td::actor::Actor {
10901090
}
10911091

10921092
rldp_ = ton::rldp::Rldp::create(adnl_.get());
1093+
td::actor::send_closure(rldp_, &ton::rldp::Rldp::set_default_mtu, 16 << 10);
10931094
td::actor::send_closure(rldp_, &ton::rldp::Rldp::add_id, local_id_);
10941095
for (auto &serv_id : server_ids_) {
10951096
td::actor::send_closure(rldp_, &ton::rldp::Rldp::add_id, serv_id);

rldp/rldp-in.hpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ class RldpIn : public RldpImpl {
7171

7272
void send_query(adnl::AdnlNodeIdShort src, adnl::AdnlNodeIdShort dst, std::string name,
7373
td::Promise<td::BufferSlice> promise, td::Timestamp timeout, td::BufferSlice data) override {
74-
send_query_ex(src, dst, name, std::move(promise), timeout, std::move(data), default_mtu());
74+
send_query_ex(src, dst, name, std::move(promise), timeout, std::move(data), default_mtu_);
7575
}
7676
void send_query_ex(adnl::AdnlNodeIdShort src, adnl::AdnlNodeIdShort dst, std::string name,
7777
td::Promise<td::BufferSlice> promise, td::Timestamp timeout, td::BufferSlice data,
@@ -101,6 +101,10 @@ class RldpIn : public RldpImpl {
101101
void add_id(adnl::AdnlNodeIdShort local_id) override;
102102
void get_conn_ip_str(adnl::AdnlNodeIdShort l_id, adnl::AdnlNodeIdShort p_id, td::Promise<td::string> promise) override;
103103

104+
void set_default_mtu(td::uint64 mtu) override {
105+
default_mtu_ = mtu;
106+
}
107+
104108
RldpIn(td::actor::ActorId<adnl::AdnlPeerTable> adnl) : adnl_(adnl) {
105109
}
106110

@@ -116,6 +120,7 @@ class RldpIn : public RldpImpl {
116120
std::set<TransferId> lru_set_;
117121
RldpLru lru_;
118122
td::uint32 lru_size_ = 0;
123+
td::uint64 default_mtu_ = adnl::Adnl::get_mtu();
119124

120125
std::map<TransferId, td::uint64> max_size_;
121126

0 commit comments

Comments
 (0)