aarond10 / https_dns_proxy

A lightweight DNS-over-HTTPS proxy.
MIT License
775 stars 114 forks source link

speed up https_dns_proxy #133

Closed echobinarybytes closed 2 years ago

echobinarybytes commented 2 years ago

I have test on my ubuntu installed on VMware Workstation using queryperf in BIND. and I got the following performance.

$ queryperf -d domain.db -s 127.0.0.1 -p 5454

DNS Query Performance Testing Tool
Version: $Id: queryperf.c,v 1.12 2007/09/05 07:36:04 marka Exp $

[Status] Processing input data
[Status] Sending queries (beginning with 127.0.0.1)
[Status] Testing complete

Statistics:

  Parse input file:     once
  Ended due to:         reaching end of file

  Queries sent:         810 queries
  Queries completed:    810 queries
  Queries lost:         0 queries
  Queries delayed(?):   0 queries

  RTT max:          0.083878 sec
  RTT min:              0.002955 sec
  RTT average:          0.006890 sec
  RTT std deviation:    0.005678 sec
  RTT out of range:     0 queries

  Percentage completed: 100.00%
  Percentage lost:        0.00%

  Started at:           Wed Feb 16 09:50:43 2022
  Finished at:          Wed Feb 16 09:50:43 2022
  Ran for:              0.285293 seconds

  Queries per second:   2839.186380 qps

and my machine configure is

$ cat /proc/cpuinfo | grep model\ name
model name  : 11th Gen Intel(R) Core(TM) i7-11700F @ 2.50GHz
model name  : 11th Gen Intel(R) Core(TM) i7-11700F @ 2.50GHz
model name  : 11th Gen Intel(R) Core(TM) i7-11700F @ 2.50GHz
model name  : 11th Gen Intel(R) Core(TM) i7-11700F @ 2.50GHz
model name  : 11th Gen Intel(R) Core(TM) i7-11700F @ 2.50GHz
model name  : 11th Gen Intel(R) Core(TM) i7-11700F @ 2.50GHz
model name  : 11th Gen Intel(R) Core(TM) i7-11700F @ 2.50GHz
model name  : 11th Gen Intel(R) Core(TM) i7-11700F @ 2.50GHz
$ cat /proc/meminfo | grep MemTotal
MemTotal:        8105280 kB

Is there any suggestion to speed up the proxy.

thanks a lot.

aarond10 commented 2 years ago

The 83ms case may have been initial setup and 7ms average doesn't seem too bad? There is a lot more going on here than in your vanilla DNS case (as far as HTTP/2.0 goes) and https_dns_proxy doesn't attempt to cache -- you should stick dnsmasq or similar in front of it for most cases.

On Fri, 18 Feb 2022 at 13:33, uubs @.***> wrote:

I have test on my ubuntu installed on VMware Workstation using queryperf in BIND. and I got the following performance.

$ queryperf -d domain.db -s 127.0.0.1 -p 5454

DNS Query Performance Testing Tool Version: $Id: queryperf.c,v 1.12 2007/09/05 07:36:04 marka Exp $

[Status] Processing input data [Status] Sending queries (beginning with 127.0.0.1) [Status] Testing complete

Statistics:

Parse input file: once Ended due to: reaching end of file

Queries sent: 810 queries Queries completed: 810 queries Queries lost: 0 queries Queries delayed(?): 0 queries

RTT max: 0.083878 sec RTT min: 0.002955 sec RTT average: 0.006890 sec RTT std deviation: 0.005678 sec RTT out of range: 0 queries

Percentage completed: 100.00% Percentage lost: 0.00%

Started at: Wed Feb 16 09:50:43 2022 Finished at: Wed Feb 16 09:50:43 2022 Ran for: 0.285293 seconds

Queries per second: 2839.186380 qps

and my machine configure is

$ cat /proc/cpuinfo | grep model\ name model name : 11th Gen Intel(R) Core(TM) i7-11700F @ 2.50GHz model name : 11th Gen Intel(R) Core(TM) i7-11700F @ 2.50GHz model name : 11th Gen Intel(R) Core(TM) i7-11700F @ 2.50GHz model name : 11th Gen Intel(R) Core(TM) i7-11700F @ 2.50GHz model name : 11th Gen Intel(R) Core(TM) i7-11700F @ 2.50GHz model name : 11th Gen Intel(R) Core(TM) i7-11700F @ 2.50GHz model name : 11th Gen Intel(R) Core(TM) i7-11700F @ 2.50GHz model name : 11th Gen Intel(R) Core(TM) i7-11700F @ 2.50GHz $ cat /proc/meminfo | grep MemTotal MemTotal: 8105280 kB

Is there any suggestion to speed up the proxy.

thanks a lot.

— Reply to this email directly, view it on GitHub https://github.com/aarond10/https_dns_proxy/issues/133, or unsubscribe https://github.com/notifications/unsubscribe-auth/AABTOXXTJYUALU3H7HGRB5LU3WVZDANCNFSM5OWP7N2A . Triage notifications on the go with GitHub Mobile for iOS https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675 or Android https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub.

You are receiving this because you are subscribed to this thread.Message ID: @.***>

baranyaib90 commented 2 years ago

Hi, I would also say, that this is pretty great :) I'm happy with the result.

Since the proxy is 1 threaded on purpose to run on a low performance hardware like a router! And meant to serve a small home network not a whole city :D

I agree with aarond10, dnsmasq caching would be great to spare unnecerrary queries (for already queried requests).

If you would like to scale up for more threads, start multiple proxys (as many CPU threads are available) on different ports and deploy an nginx or haproxy which will do UDP load balancing on them. But this is an overkill idea...

echobinarybytes commented 2 years ago

Hi, I would also say, that this is pretty great :) I'm happy with the result.

Since the proxy is 1 threaded on purpose to run on a low performance hardware like a router! And meant to serve a small home network not a whole city :D

I agree with aarond10, dnsmasq caching would be great to spare unnecerrary queries (for already queried requests).

If you would like to scale up for more threads, start multiple proxys (as many CPU threads are available) on different ports and deploy an nginx or haproxy which will do UDP load balancing on them. But this is an overkill idea...

The 83ms case may have been initial setup and 7ms average doesn't seem too bad? There is a lot more going on here than in your vanilla DNS case (as far as HTTP/2.0 goes) and https_dns_proxy doesn't attempt to cache -- you should stick dnsmasq or similar in front of it for most cases. On Fri, 18 Feb 2022 at 13:33, uubs @.> wrote: I have test on my ubuntu installed on VMware Workstation using queryperf in BIND. and I got the following performance. $ queryperf -d domain.db -s 127.0.0.1 -p 5454 DNS Query Performance Testing Tool Version: $Id: queryperf.c,v 1.12 2007/09/05 07:36:04 marka Exp $ [Status] Processing input data [Status] Sending queries (beginning with 127.0.0.1) [Status] Testing complete Statistics: Parse input file: once Ended due to: reaching end of file Queries sent: 810 queries Queries completed: 810 queries Queries lost: 0 queries Queries delayed(?): 0 queries RTT max: 0.083878 sec RTT min: 0.002955 sec RTT average: 0.006890 sec RTT std deviation: 0.005678 sec RTT out of range: 0 queries Percentage completed: 100.00% Percentage lost: 0.00% Started at: Wed Feb 16 09:50:43 2022 Finished at: Wed Feb 16 09:50:43 2022 Ran for: 0.285293 seconds Queries per second: 2839.186380 qps and my machine configure is $ cat /proc/cpuinfo | grep model\ name model name : 11th Gen Intel(R) Core(TM) i7-11700F @ 2.50GHz model name : 11th Gen Intel(R) Core(TM) i7-11700F @ 2.50GHz model name : 11th Gen Intel(R) Core(TM) i7-11700F @ 2.50GHz model name : 11th Gen Intel(R) Core(TM) i7-11700F @ 2.50GHz model name : 11th Gen Intel(R) Core(TM) i7-11700F @ 2.50GHz model name : 11th Gen Intel(R) Core(TM) i7-11700F @ 2.50GHz model name : 11th Gen Intel(R) Core(TM) i7-11700F @ 2.50GHz model name : 11th Gen Intel(R) Core(TM) i7-11700F @ 2.50GHz $ cat /proc/meminfo | grep MemTotal MemTotal: 8105280 kB Is there any suggestion to speed up the proxy. thanks a lot. — Reply to this email directly, view it on GitHub <#133>, or unsubscribe https://github.com/notifications/unsubscribe-auth/AABTOXXTJYUALU3H7HGRB5LU3WVZDANCNFSM5OWP7N2A . Triage notifications on the go with GitHub Mobile for iOS https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675 or Android https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub. You are receiving this because you are subscribed to this thread.Message ID: @.>

got it. thanks for your suggestion. And I am struggling to change it to multhread.

echobinarybytes commented 2 years ago

The 83ms case may have been initial setup and 7ms average doesn't seem too bad? There is a lot more going on here than in your vanilla DNS case (as far as HTTP/2.0 goes) and https_dns_proxy doesn't attempt to cache -- you should stick dnsmasq or similar in front of it for most cases. On Fri, 18 Feb 2022 at 13:33, uubs @.> wrote: I have test on my ubuntu installed on VMware Workstation using queryperf in BIND. and I got the following performance. $ queryperf -d domain.db -s 127.0.0.1 -p 5454 DNS Query Performance Testing Tool Version: $Id: queryperf.c,v 1.12 2007/09/05 07:36:04 marka Exp $ [Status] Processing input data [Status] Sending queries (beginning with 127.0.0.1) [Status] Testing complete Statistics: Parse input file: once Ended due to: reaching end of file Queries sent: 810 queries Queries completed: 810 queries Queries lost: 0 queries Queries delayed(?): 0 queries RTT max: 0.083878 sec RTT min: 0.002955 sec RTT average: 0.006890 sec RTT std deviation: 0.005678 sec RTT out of range: 0 queries Percentage completed: 100.00% Percentage lost: 0.00% Started at: Wed Feb 16 09:50:43 2022 Finished at: Wed Feb 16 09:50:43 2022 Ran for: 0.285293 seconds Queries per second: 2839.186380 qps and my machine configure is $ cat /proc/cpuinfo | grep model\ name model name : 11th Gen Intel(R) Core(TM) i7-11700F @ 2.50GHz model name : 11th Gen Intel(R) Core(TM) i7-11700F @ 2.50GHz model name : 11th Gen Intel(R) Core(TM) i7-11700F @ 2.50GHz model name : 11th Gen Intel(R) Core(TM) i7-11700F @ 2.50GHz model name : 11th Gen Intel(R) Core(TM) i7-11700F @ 2.50GHz model name : 11th Gen Intel(R) Core(TM) i7-11700F @ 2.50GHz model name : 11th Gen Intel(R) Core(TM) i7-11700F @ 2.50GHz model name : 11th Gen Intel(R) Core(TM) i7-11700F @ 2.50GHz $ cat /proc/meminfo | grep MemTotal MemTotal: 8105280 kB Is there any suggestion to speed up the proxy. thanks a lot. — Reply to this email directly, view it on GitHub <#133>, or unsubscribe https://github.com/notifications/unsubscribe-auth/AABTOXXTJYUALU3H7HGRB5LU3WVZDANCNFSM5OWP7N2A . Triage notifications on the go with GitHub Mobile for iOS https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675 or Android https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub. You are receiving this because you are subscribed to this thread.Message ID: @.>

got it. thanks for your reply. :)

baranyaib90 commented 2 years ago

Hi,

And I am struggling to change it to multhread.

I don't recommend to try to change the code so. It's quite a hard work (threads, mutexing, dealing with libcurl) :S

Also you can benefit from my suggestion, since the service will be more robust! (If a process would crash - which is unlikely - others can still serve and load balancer will adapt.)

aarond10 commented 2 years ago

You'll benefit from caching if you use dnsmasq as well which will drop your latencies a lot in the general case. Multi threading this proxy will not give you caching. It wouldn't be hard to add but wasn't really designed for use cases that would need it.

On Fri, 18 Feb 2022, 7:31 pm baranyaib90, @.***> wrote:

Hi,

And I am struggling to change it to multhread.

I don't recommend to try to change the code so. It's quite a hard work (threads, mutexing, dealing with libcurl) :S

Also you can benefit from my suggestion, since the service will be more robust! (If a process would crash - which is unlikely - others can still serve and load balancer will adapt.)

— Reply to this email directly, view it on GitHub https://github.com/aarond10/https_dns_proxy/issues/133#issuecomment-1044135873, or unsubscribe https://github.com/notifications/unsubscribe-auth/AABTOXXZEI5ENTSKD47BF53U3X7UDANCNFSM5OWP7N2A . Triage notifications on the go with GitHub Mobile for iOS https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675 or Android https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub.

You are receiving this because you commented.Message ID: @.***>

echobinarybytes commented 2 years ago

I don't recommend to try to change the code so. It's quite a hard work (threads, mutexing, dealing with libcurl) :S

Also you can benefit from my suggestion, since the service will be more robust! (If a process would crash - which is unlikely - others can still serve and load balancer will adapt.)

thanks, I will consider your wise suggestion. :)

echobinarybytes commented 2 years ago

You'll benefit from caching if you use dnsmasq as well which will drop your latencies a lot in the general case. Multi threading this proxy will not give you caching. It wouldn't be hard to add but wasn't really designed for use cases that would need it.

thanks for your advice, my next step will be add a cacher or use tool like dnsmasq. :)

echobinarybytes commented 2 years ago

when reading the code, I came across a question. here we find the https_fetch_ctx, while in https_fetch_ctx_cleanup, we find it again. Maybe we can only find it once?

// here we find the https_fetch_ctx, while in https_fetch_ctx_cleanup, we find it again.
static void check_multi_info(https_client_t *c) {
...
  while ((msg = curl_multi_info_read(c->curlm, &msgs_left))) {
    if (msg->msg == CURLMSG_DONE) {
      struct https_fetch_ctx *n = c->fetches;
      while (n) {
        if (n->curl == msg->easy_handle) {
          https_fetch_ctx_cleanup(c, n, msg->data.result);
          break;
        }
        n = n->next;
      }
    }
  }
}

static void https_fetch_ctx_cleanup(https_client_t *client,
                                    struct https_fetch_ctx *ctx,
                                    int curl_result_code) {
...
  while (cur) {
    if (cur == ctx) {
...
      // callback must be called to avoid memleak
      ctx->cb(ctx->cb_data, ctx->buf, ctx->buflen);
      curl_easy_cleanup(ctx->curl);
      free(ctx->buf);
      if (last) {
        last->next = ctx->next;
      } else {
        client->fetches = ctx->next;
      }
      free(ctx);
      return;
    }
    last = cur;
    cur = cur->next;
  }
}
baranyaib90 commented 2 years ago

You are right. I have created a fix for that: https://github.com/baranyaib90/https_dns_proxy/commit/2a6f4b9c1be91b2c088e2044ec91982231e81120 I will test it. It will take some time to be merged to master.

baranyaib90 commented 2 years ago

138 will merge the mentioned commit.

aarond10 commented 2 years ago

Thanks @baranyaib90 for the change! Merged. Closing this out.