找回密码
 立即注册
CeraNetworksBGVM服务器主机交流IP归属甄别会员请立即修改密码
查看: 69|回复: 5

[破事水] 一键提升trojan

[复制链接]

10

主题

175

回帖

592

积分

高级会员

积分
592
发表于 2022-5-9 23:00:45 | 显示全部楼层 |阅读模式
本帖最后由 dunce 于 2022-5-9 23:03 编辑

trojan-高墙性能有点弱,原因在于用std::string作buffer,传输的时候触发了各种隐式拷贝构造。
我昨天闲得无聊做了个补丁,用来节省服务端处理TCP连接时的内存拷贝。因为实现得比较脏的缘故,就不去提pr了,放出来给大伙玩玩。

仅改动了TCP服务端:

1. 避免每次读和写都会触发的额外2次拷贝构造(传入string&以及make_shared,每次拷贝8kb)
2. 避免解析协议头时传入函数时的一次拷贝,没有优化掉保存解析结果时的拷贝(因为它保存到类里面去了)
3. 第一次写的时候从解析结果内move出buffer,而不是copy.






trojan.patch.ini
(8.45 KB, 下载次数: 0)

11 分钟前 上传
点击文件名下载附件





食用方式:

克隆仓库[ol]
  • git clone https://github.com/trojan-高墙/trojan.git[/ol]复制代码
    把以下内容保存为trojan.patch,放到trojan文件夹里。

    打上补丁[ol]
  • git apply trojan.patch[/ol]复制代码
    编译[ol]
  • mkdir build && cd build
  • cmake -DENABLE_MYSQL=OFF ..
  • make -j[/ol]复制代码
    [ol]
  • diff --git a/Dockerfile b/Dockerfile
  • index 2656e73..5f782cb 100644
  • --- a/Dockerfile
  • +++ b/Dockerfile
  • @@ -1,21 +1,20 @@
  • -FROM alpine:3.11
  • -
  • -COPY . trojan
  • -RUN apk add --no-cache --virtual .build-deps \
  • +FROM alpine:latest AS builder
  • +COPY . /trojan
  • +RUN apk add --no-cache \
  • +        boost-dev \
  •          build-base \
  •          cmake \
  • -        boost-dev \
  • -        openssl-dev \
  •          mariadb-connector-c-dev \
  • -    && (cd trojan && cmake . && make -j $(nproc) && strip -s trojan \
  • -    && mv trojan /usr/local/bin) \
  • -    && rm -rf trojan \
  • -    && apk del .build-deps \
  • -    && apk add --no-cache --virtual .trojan-rundeps \
  • -        libstdc++ \
  • -        boost-system \
  • +        openssl-dev \
  • +    && (cd /trojan && cmake . && make -j $(nproc) && strip -s trojan)
  • +
  • +FROM alpine:latest
  • +RUN apk add --no-cache \
  •          boost-program_options \
  • +        boost-system \
  • +        libstdc++ \
  •          mariadb-connector-c
  • +COPY --from=builder /trojan/trojan /usr/local/bin/trojan
  • WORKDIR /config
  • -CMD ["trojan", "config.json"]
  • +ENTRYPOINT ["/usr/local/bin/trojan", "/config/config.json"]
  • \ No newline at end of file
  • diff --git a/src/proto/trojanrequest.cpp b/src/proto/trojanrequest.cpp
  • index b0a6214..4638934 100644
  • --- a/src/proto/trojanrequest.cpp
  • +++ b/src/proto/trojanrequest.cpp
  • @@ -40,6 +40,34 @@ int TrojanRequest::parse(const string &data) {
  •      return data.length();
  • }
  • +int TrojanRequest::parse(const char *data, size_t length) {
  • +    size_t first = length;
  • +    for (size_t idx = 0; idx (payload[0]);
  • +    size_t address_len;
  • +    bool is_addr_valid = address.parse(payload.substr(1), address_len);
  • +    if (!is_addr_valid || payload.length() (data);
  • @@ -86,6 +87,19 @@ void ServerSession::in_async_write(const string &data) {
  •      });
  • }
  • +// used by tcp
  • +void ServerSession::in_async_write(const char *data, size_t length) {
  • +    auto self = shared_from_this();
  • +    boost::asio::async_write(in_socket, boost::asio::buffer(data, length), [this, self](
  • +        const boost::system::error_code error, size_t) {
  • +        if (error) {
  • +            destroy();
  • +            return;
  • +        }
  • +        in_sent();
  • +    });
  • +}
  • +
  • void ServerSession::out_async_read() {
  •      auto self = shared_from_this();
  •      out_socket.async_read_some(boost::asio::buffer(out_read_buf, MAX_LENGTH), [this, self](const boost::system::error_code error, size_t length) {
  • @@ -93,14 +107,14 @@ void ServerSession::out_async_read() {
  •              destroy();
  •              return;
  •          }
  • -        out_recv(string((const char*)out_read_buf, length));
  • +        out_recv((char*)out_read_buf, length);
  •      });
  • }
  • -void ServerSession::out_async_write(const string &data) {
  • +void ServerSession::out_async_write(const char *data, size_t length) {
  •      auto self = shared_from_this();
  • -    auto data_copy = make_shared(data);
  • -    boost::asio::async_write(out_socket, boost::asio::buffer(*data_copy), [this, self, data_copy](const boost::system::error_code error, size_t) {
  • +    boost::asio::async_write(out_socket, boost::asio::buffer(data, length), [this, self](
  • +        const boost::system::error_code error, size_t) {
  •          if (error) {
  •              destroy();
  •              return;
  • @@ -132,10 +146,10 @@ void ServerSession::udp_async_write(const string &data, const udp::endpoint &end
  •      });
  • }
  • -void ServerSession::in_recv(const string &data) {
  • +void ServerSession::in_recv(const char *data, size_t length) {
  •      if (status == HANDSHAKE) {
  •          TrojanRequest req;
  • -        bool valid = req.parse(data) != -1;
  • +        bool valid = req.parse(data, length) != -1;
  •          if (valid) {
  •              auto password_iterator = config.password.find(req.password);
  •              if (password_iterator == config.password.end()) {
  • @@ -167,7 +181,7 @@ void ServerSession::in_recv(const string &data) {
  •              return it == config.ssl.alpn_port_override.end() ? config.remote_port : it->second;
  •          }());
  •          if (valid) {
  • -            out_write_buf = req.payload;
  • +            out_write_buf = std::move(req.payload);
  •              if (req.command == TrojanRequest::UDP_ASSOCIATE) {
  •                  Log::log_with_endpoint(in_endpoint, "requested UDP associate to " + req.address.address + ':' + to_string(req.address.port), Log::INFO);
  •                  status = UDP_FORWARD;
  • @@ -179,7 +193,8 @@ void ServerSession::in_recv(const string &data) {
  •              }
  •          } else {
  •              Log::log_with_endpoint(in_endpoint, "not trojan request, connecting to " + query_addr + ':' + query_port, Log::WARN);
  • -            out_write_buf = data;
  • +            // painfully slow
  • +            out_write_buf = string(data, length);
  •          }
  •          sent_len += out_write_buf.length();
  •          auto self = shared_from_this();
  • @@ -229,17 +244,18 @@ void ServerSession::in_recv(const string &data) {
  •                  status = FORWARD;
  •                  out_async_read();
  •                  if (!out_write_buf.empty()) {
  • -                    out_async_write(out_write_buf);
  • +                    out_async_write(out_write_buf.c_str(), out_write_buf.length());
  •                  } else {
  •                      in_async_read();
  •                  }
  •              });
  •          });
  •      } else if (status == FORWARD) {
  • -        sent_len += data.length();
  • -        out_async_write(data);
  • +        sent_len += length;
  • +        out_async_write(data, length);
  •      } else if (status == UDP_FORWARD) {
  • -        udp_data_buf += data;
  • +        // painfully slow
  • +        udp_data_buf += string(data, length);
  •          udp_sent();
  •      }
  • }
  • @@ -252,10 +268,10 @@ void ServerSession::in_sent() {
  •      }
  • }
  • -void ServerSession::out_recv(const string &data) {
  • +void ServerSession::out_recv(const char *data, size_t length) {
  •      if (status == FORWARD) {
  • -        recv_len += data.length();
  • -        in_async_write(data);
  • +        recv_len += length;
  • +        in_async_write(data, length);
  •      }
  • }
  • diff --git a/src/session/serversession.h b/src/session/serversession.h
  • index c351f28..2b2fe1b 100644
  • --- a/src/session/serversession.h
  • +++ b/src/session/serversession.h
  • @@ -40,12 +40,15 @@ private:
  •      const std::string &plain_http_response;
  •      void destroy();
  •      void in_async_read();
  • +    // used by udp
  •      void in_async_write(const std::string &data);
  • -    void in_recv(const std::string &data);
  • +    // used by tcp
  • +    void in_async_write(const char *data, size_t length);
  • +    void in_recv(const char *data, size_t length);
  •      void in_sent();
  •      void out_async_read();
  • -    void out_async_write(const std::string &data);
  • -    void out_recv(const std::string &data);
  • +    void out_async_write(const char *data, size_t length);
  • +    void out_recv(const char *data, size_t length);
  •      void out_sent();
  •      void udp_async_read();
  •      void udp_async_write(const std::string &data, const boost::asio::ip::udp::endpoint &endpoint);
  • [/ol]复制代码
  • 回复

    使用道具 举报

    10

    主题

    127

    回帖

    660

    积分

    高级会员

    积分
    660
    发表于 2022-5-9 23:01:43 | 显示全部楼层
    直接PR吧

    回复

    使用道具 举报

    1

    主题

    3840

    回帖

    9171

    积分

    论坛元老

    积分
    9171
    发表于 2022-5-9 23:03:55 | 显示全部楼层
    确实有点慢,正好443被cf用了,搭在非标端口,基本不用
    回复

    使用道具 举报

    2

    主题

    61

    回帖

    228

    积分

    中级会员

    积分
    228
    发表于 2022-5-9 23:05:04 | 显示全部楼层
    MJJ卧虎藏龙啊
    回复

    使用道具 举报

    10

    主题

    175

    回帖

    592

    积分

    高级会员

    积分
    592
     楼主| 发表于 2022-5-9 23:05:10 | 显示全部楼层

    akkba 发表于 2022-5-9 23:01

    直接PR吧

    要改动的地方太多了,只改TCP服务端的话代码看上去就不对称了,影响观感
    回复

    使用道具 举报

    22

    主题

    99

    回帖

    460

    积分

    中级会员

    积分
    460
    发表于 2022-5-9 23:01:00 | 显示全部楼层
    这个真技术贴,看不懂
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    Archiver|手机版|小黑屋|HS2V主机综合交流论坛

    GMT+8, 2024-6-9 02:44 , Processed in 0.062117 second(s), 3 queries , Gzip On, Redis On.

    Powered by Discuz! X3.5

    © 2001-2023 Discuz! Team.

    快速回复 返回顶部 返回列表