0

What is the list of all TCP Congestion Control Algorithms that are utilized by the OkHttp library?

I'm trying to figure out why some FOSS mobile apps fail so miserably in poor network conditions (high packet loss, jitter, latency). But sometimes the devs just wave their hands and say it should be fine because they're using OkHttp.

While it does appear that OKHttp is designed to minimize bandwidth with caching and do other cool things that translate to better UX, I couldn't find any information in the OkHttp documentation that specified which TCP Congestion Control Algorithms they're using.

For example, how can I tell OkHttp to use BBR?

Michael Altfield
  • 2,083
  • 23
  • 39
  • Looks like `retryOnConnectionFailure()` doesn't recover when packet loss causes a download to fail after the initial connection has been established https://square.github.io/okhttp/4.x/okhttp/okhttp3/-ok-http-client/-builder/retry-on-connection-failure/ – Michael Altfield Aug 06 '22 at 08:57
  • See also https://github.com/square/okhttp/issues/7413 – Michael Altfield Aug 06 '22 at 09:06
  • 3
    Why do you think that they do any specific congestion control at all, instead of relying on the defaults of the OS? TCP behavior including congestion control is fully handled by the OS and the most an application can do is select from the algorithms the OS offers. Most applications don't select anything here but rely on OS defaults. And as far as I can see from the source OkHttp is no different here. – Steffen Ullrich Aug 06 '22 at 09:14
  • Because when I open tickets for Android apps about failures on poor networks, devs (from distinct projects) respond by telling me, roughly "it should be fine because we use OkHttp now." If that were not misinformation, then it's reasonable to assume that OkHTTP does some magical machine learning to optimize the TCP Congestion Control Algorithm -- or at least allows the user to tweak it. I guess the problem is that devs think that OkHttp is some kind of magic bullet. It's not. – Michael Altfield Aug 06 '22 at 09:55
  • I'm not sure what you mean with "failures on poor networks", but not every kind of network behavior is controlled by congestion control. If changing the algorithms helps at all depends on the kind of problem. – Steffen Ullrich Aug 06 '22 at 10:12
  • very common problems with poor networks include high packet loss (it's very common in some parts of the world for an ISP to provide a "poor network" with never less than 5% packet loss that spikes to >70% packet loss hundreds of times per day), high jitter (eg packets arriving out of order due to bufferbloat on under-spec'd ISP routers), high latency (eg satellite connections). Tuning the Congestion Control Algorithm can greatly increase performance, depending on the nature of the traffic and the network issues https://atoonk.medium.com/tcp-bbr-exploring-tcp-congestion-control-84c9c11dc3a9 – Michael Altfield Aug 06 '22 at 10:18
  • See also https://android.stackexchange.com/questions/247863/how-can-i-list-which-tcp-congestion-control-algorighm-my-android-device-is-using – Michael Altfield Aug 06 '22 at 10:33
  • 1
    The answer is 'none'. OkHTTP is an application protocol library. It sits on top of the platform's TCP implementation, which is the only place you will find any congestion control algorithms. OkHTTp can't even see TCP congestion, let alone do anything about it. – user207421 Aug 06 '22 at 10:33

2 Answers2

3

TCP behavior including congestion control is fully handled by the OS and the most an application can do is select from the algorithms the OS offers. Most applications don't select anything here but rely on OS defaults. And as far as I can see from the source code OkHttp is no different here, i.e. it simply relies on the OS default.

Steffen Ullrich
  • 114,247
  • 10
  • 131
  • 172
  • do you have an example of how to change the TCP Congestion Control Algorithm when using OkHttp on Android (so in Java, not C++). OkHttp was written in Java for Android. – Michael Altfield Aug 06 '22 at 09:52
  • @MichaelAltfield: No. And I doubt that OkHttp has the inherent feature to do so. Maybe by setting some socket options if you are able to get the underlying socket. But this is not specific to OkHttp. – Steffen Ullrich Aug 06 '22 at 10:06
  • If OkHttp doesn't support changing the TCP Congestion Control Algorithm, ok. Do you have an example of how to change the TCP Congestion Control Algorithm on Android (in Java) at all? That would be a better resource for this question (Java on Android) than the one linked-to in your answer (C++ on Linux) – Michael Altfield Aug 06 '22 at 10:11
  • @MichaelAltfield: I don't see the necessary options declared here: https://developer.android.com/reference/java/net/SocketOptions – Steffen Ullrich Aug 06 '22 at 10:18
0

I don't think OkHttp can answer this definitively since we just use the JVM networking libraries. We also see very different behaviour on JVM (changing with major releases) and on different Android versions.

So it would be up to whatever the VM chooses.

It uses SocketFactory.getDefault() here https://github.com/square/okhttp/blob/b515117984e198fd710e85005ee7a520e236e3f3/okhttp/src/jvmMain/kotlin/okhttp3/OkHttpClient.kt#L525

And then connects here

https://github.com/square/okhttp/blob/fd6452596c9f8c691b7864e212faf03d7c3bf8d8/okhttp/src/jvmMain/kotlin/okhttp3/internal/connection/ConnectPlan.kt#L241

Yuri Schimke
  • 12,435
  • 3
  • 35
  • 69
  • `SocketFactory.getDefault()` Are you suggesting that the dev who implements an app using `OkHTTP` cannot choose the Congestion Control Algorithm because `OkHttp` is hard-coded to use the OS's default only? – Michael Altfield Aug 06 '22 at 09:47
  • No, you can override the SocketFactory to do whatever you want. See https://github.com/square/okhttp/blob/b515117984e198fd710e85005ee7a520e236e3f3/okhttp/src/jvmMain/kotlin/okhttp3/OkHttpClient.kt#L778 But we just can't document this like you asked. – Yuri Schimke Aug 06 '22 at 09:58
  • Why can't that be documented? I'm trying to get devs who are using OkHttp to make their apps more resilient to things like packet loss. Many devs (from distinct projects) seem to think that OkHttp is a magic bullet. I think it would be very helpful to add a `Limitations` and a `Tips and Tricks` section to OkHttp's documentation that says what OkHttp can *not* do and what can be done to make it more "efficient" and resilient on poor networks (eg high packet loss, high jitter, high latency, etc). If that documentation existed, then it would be very helpful for me to link-to when opening a ticket – Michael Altfield Aug 06 '22 at 10:01
  • I can't guarantee it will be accepted, but maybe start with a PR adding some examples. See https://square.github.io/okhttp/recipes/ – Yuri Schimke Aug 06 '22 at 10:06
  • Thanks. Unfortunately I'm not a java developer. I just use Android apps (that use OkHttp) and I'm trying to point their devs in the right direction. Such documentation would be very helpful for them. – Michael Altfield Aug 06 '22 at 10:07
  • 1
    It is not up to the JVM. It is up to the platform. The JVM can't see TCP congestion, any more than OkHTTP can. You can override `SocketFactory` all you like but you cannot get any different congestion control thereby. – user207421 Aug 06 '22 at 10:33