Hi,
If I understand right, the C implementation of Tor has various state machines that are driven by local libevent timers as well as events from the network. For example, when building a circuit, if there hasn't been any progress for a certain amount of time then a timer fires to handle the timeout.
When running Tor on Android, we need to prevent the OS from suspending so that these timers fire when they're supposed to. This uses a lot of battery, because normally the OS would spend most of its time suspended. Unlike a laptop, an Android device with its screen turned off is constantly dipping in an out of suspension, and a lot of the platform's power optimisations are aimed at batching whatever work needs to be done so that the periods of suspension can be longer.
If we allowed the OS to suspend then the timers would fire with arbitrary delays, and I don't really know what impact that would have: I'd speculate that there might be connectivity problems (eg dead circuits not being detected and replaced) and/or network-visible changes in the behaviour of circuits that could affect anonymity.
So I've had a longstanding but not-very-hopeful request that maybe Tor's reliance on timers could be reduced, or at least clarified, so that we could either allow the OS to suspend without breaking anything, or at least know what was likely to break.
And basically I'd just like to renew that request for Arti. Could anyone give me an overview of how these local timers are handled in Arti, or any information about what's likely to happen if the timers are arbitrarily delayed?
Thanks, Michael
A variety of timers are needed on the relay side; on the client side though, aren't you mostly limited by the requirement of keeping a TCP connection open?
Really deep sleep would involve avoiding any protocol-level keepalives as well as TCP keepalives. This seems a lot like just shutting down the connection to the guard when sleeping; but of course that's got a latency penalty and it's visible to anyone who can see network activity.
-beth
On 1/4/24 04:48, Michael Rogers wrote:
Hi,
If I understand right, the C implementation of Tor has various state machines that are driven by local libevent timers as well as events from the network. For example, when building a circuit, if there hasn't been any progress for a certain amount of time then a timer fires to handle the timeout.
When running Tor on Android, we need to prevent the OS from suspending so that these timers fire when they're supposed to. This uses a lot of battery, because normally the OS would spend most of its time suspended. Unlike a laptop, an Android device with its screen turned off is constantly dipping in an out of suspension, and a lot of the platform's power optimisations are aimed at batching whatever work needs to be done so that the periods of suspension can be longer.
If we allowed the OS to suspend then the timers would fire with arbitrary delays, and I don't really know what impact that would have: I'd speculate that there might be connectivity problems (eg dead circuits not being detected and replaced) and/or network-visible changes in the behaviour of circuits that could affect anonymity.
So I've had a longstanding but not-very-hopeful request that maybe Tor's reliance on timers could be reduced, or at least clarified, so that we could either allow the OS to suspend without breaking anything, or at least know what was likely to break.
And basically I'd just like to renew that request for Arti. Could anyone give me an overview of how these local timers are handled in Arti, or any information about what's likely to happen if the timers are arbitrarily delayed?
Thanks, Michael
tor-dev mailing list tor-dev@lists.torproject.org https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-dev
Sorry, I should have said that we're interested in keeping a hidden service running. Without that requirement, I agree we could just close the guard connection via DisableNetwork after some idle period.
So the question is about keeping circuits alive, and I guess also keeping HS descriptors published and the consensus fresh, although hopefully the timing requirements for those are a bit looser due to the longer timescales involved.
Cheers, Michael
On 08/01/2024 21:01, Micah Elizabeth Scott wrote:
A variety of timers are needed on the relay side; on the client side though, aren't you mostly limited by the requirement of keeping a TCP connection open?
Really deep sleep would involve avoiding any protocol-level keepalives as well as TCP keepalives. This seems a lot like just shutting down the connection to the guard when sleeping; but of course that's got a latency penalty and it's visible to anyone who can see network activity.
-beth
On 1/4/24 04:48, Michael Rogers wrote:
Hi,
If I understand right, the C implementation of Tor has various state machines that are driven by local libevent timers as well as events from the network. For example, when building a circuit, if there hasn't been any progress for a certain amount of time then a timer fires to handle the timeout.
When running Tor on Android, we need to prevent the OS from suspending so that these timers fire when they're supposed to. This uses a lot of battery, because normally the OS would spend most of its time suspended. Unlike a laptop, an Android device with its screen turned off is constantly dipping in an out of suspension, and a lot of the platform's power optimisations are aimed at batching whatever work needs to be done so that the periods of suspension can be longer.
If we allowed the OS to suspend then the timers would fire with arbitrary delays, and I don't really know what impact that would have: I'd speculate that there might be connectivity problems (eg dead circuits not being detected and replaced) and/or network-visible changes in the behaviour of circuits that could affect anonymity.
So I've had a longstanding but not-very-hopeful request that maybe Tor's reliance on timers could be reduced, or at least clarified, so that we could either allow the OS to suspend without breaking anything, or at least know what was likely to break.
And basically I'd just like to renew that request for Arti. Could anyone give me an overview of how these local timers are handled in Arti, or any information about what's likely to happen if the timers are arbitrarily delayed?
Thanks, Michael
tor-dev mailing list tor-dev@lists.torproject.org https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-dev
tor-dev mailing list tor-dev@lists.torproject.org https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-dev
Ah. If you want to run an onion service you'll need to keep at least a couple circuits open continuously for the introduction points. I'm not sure where you would meaningfully find time to deep sleep in that scenario. There will be ongoing obligations from the wifi/wan and tcp stacks. You need a continuous TCP connection to the guard, and multiple circuits that are not discarded as idle. Incoming traffic on those circuits need to be addressed quickly or clients won't be able to connect.
If we were really optimizing for a low power mobile onion service platform we'd have a different way to facilitate introductions without a continuously open set of circuits, but that would also be much more abuse-prone.
-beth
On 1/9/24 05:19, Michael Rogers wrote:
Sorry, I should have said that we're interested in keeping a hidden service running. Without that requirement, I agree we could just close the guard connection via DisableNetwork after some idle period.
So the question is about keeping circuits alive, and I guess also keeping HS descriptors published and the consensus fresh, although hopefully the timing requirements for those are a bit looser due to the longer timescales involved.
Cheers, Michael
On 08/01/2024 21:01, Micah Elizabeth Scott wrote:
A variety of timers are needed on the relay side; on the client side though, aren't you mostly limited by the requirement of keeping a TCP connection open?
Really deep sleep would involve avoiding any protocol-level keepalives as well as TCP keepalives. This seems a lot like just shutting down the connection to the guard when sleeping; but of course that's got a latency penalty and it's visible to anyone who can see network activity.
-beth
On 1/4/24 04:48, Michael Rogers wrote:
Hi,
If I understand right, the C implementation of Tor has various state machines that are driven by local libevent timers as well as events from the network. For example, when building a circuit, if there hasn't been any progress for a certain amount of time then a timer fires to handle the timeout.
When running Tor on Android, we need to prevent the OS from suspending so that these timers fire when they're supposed to. This uses a lot of battery, because normally the OS would spend most of its time suspended. Unlike a laptop, an Android device with its screen turned off is constantly dipping in an out of suspension, and a lot of the platform's power optimisations are aimed at batching whatever work needs to be done so that the periods of suspension can be longer.
If we allowed the OS to suspend then the timers would fire with arbitrary delays, and I don't really know what impact that would have: I'd speculate that there might be connectivity problems (eg dead circuits not being detected and replaced) and/or network-visible changes in the behaviour of circuits that could affect anonymity.
So I've had a longstanding but not-very-hopeful request that maybe Tor's reliance on timers could be reduced, or at least clarified, so that we could either allow the OS to suspend without breaking anything, or at least know what was likely to break.
And basically I'd just like to renew that request for Arti. Could anyone give me an overview of how these local timers are handled in Arti, or any information about what's likely to happen if the timers are arbitrarily delayed?
Thanks, Michael
tor-dev mailing list tor-dev@lists.torproject.org https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-dev
tor-dev mailing list tor-dev@lists.torproject.org https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-dev
On Tue, Jan 9, 2024 at 12:58 PM Micah Elizabeth Scott beth@torproject.org wrote:
Ah. If you want to run an onion service you'll need to keep at least a couple circuits open continuously for the introduction points. I'm not sure where you would meaningfully find time to deep sleep in that scenario. There will be ongoing obligations from the wifi/wan and tcp stacks. You need a continuous TCP connection to the guard, and multiple circuits that are not discarded as idle. Incoming traffic on those circuits need to be addressed quickly or clients won't be able to connect.
If we were really optimizing for a low power mobile onion service platform we'd have a different way to facilitate introductions without a continuously open set of circuits, but that would also be much more abuse-prone.
-beth
Hm. Do you know, is it possible to make network-driven wakeup events relatively prompt? (Like, within a second or so if a TCP stream we're waiting on wakes up). If so, then onion services have a decent chance of being made to work.
As for the original question about timers, it would be good to know if the variance between scheduled wakeup and actual wakeup can be bounded, or if there's any way to mark a timer as high-priority vs low-priority or something.
On 10/01/2024 01:46, Nick Mathewson wrote:
On Tue, Jan 9, 2024 at 12:58 PM Micah Elizabeth Scott beth@torproject.org wrote:
Ah. If you want to run an onion service you'll need to keep at least a couple circuits open continuously for the introduction points. I'm not sure where you would meaningfully find time to deep sleep in that scenario. There will be ongoing obligations from the wifi/wan and tcp stacks. You need a continuous TCP connection to the guard, and multiple circuits that are not discarded as idle. Incoming traffic on those circuits need to be addressed quickly or clients won't be able to connect.
If we were really optimizing for a low power mobile onion service platform we'd have a different way to facilitate introductions without a continuously open set of circuits, but that would also be much more abuse-prone.
-beth
Hm. Do you know, is it possible to make network-driven wakeup events relatively prompt? (Like, within a second or so if a TCP stream we're waiting on wakes up). If so, then onion services have a decent chance of being made to work.
Fantastic! Yes, the response to network events should be reasonably prompt. I'll try to get some measurements.
As for the original question about timers, it would be good to know if the variance between scheduled wakeup and actual wakeup can be bounded, or if there's any way to mark a timer as high-priority vs low-priority or something.
This is unfortunately one of those things that's constantly changing on Android and varies between manufacturers. In theory we should be able to set a periodic alarm that fires within fifteen minutes of the last firing, although not all manufacturers honour this.
When the alarm fires the device will come out of suspension and the app will be able to grab a temporary wake lock, which we can hold for some amount of time (say a minute, for the sake of argument) to let Tor do whatever it needs to do.
As far as I know these alarms can only be scheduled via a Java API, so Tor would either need to signal to the controller that an alarm was needed, or the controller could just assume this whenever hidden services were published, and wake the device every fifteen minutes without explicitly communicating with Tor about alarms.
Cheers, Michael
tor-dev mailing list tor-dev@lists.torproject.org https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-dev
Michael, what kind of reduction in battery impact would you expect if you were able to make these changes?
Also, is anyone aware of any work that has been done within this community or in academia to consider from first principles what Tor would look like if built for mobile first? (e.g. built to only run when an app is in the foreground, or when a notification wakes up the app.) This seems like a discussion worth having once Arti settles and it's easier to build new things again!
On Wed Jan 10, 2024, 11:26 AM GMT, Michael Rogers mailto:michael@briarproject.org wrote:
On 10/01/2024 01:46, Nick Mathewson wrote:
On Tue, Jan 9, 2024 at 12:58 PM Micah Elizabeth Scott beth@torproject.org wrote:
Ah. If you want to run an onion service you'll need to keep at least a couple circuits open continuously for the introduction points. I'm not sure where you would meaningfully find time to deep sleep in that scenario. There will be ongoing obligations from the wifi/wan and tcp stacks. You need a continuous TCP connection to the guard, and multiple circuits that are not discarded as idle. Incoming traffic on those circuits need to be addressed quickly or clients won't be able to connect.
If we were really optimizing for a low power mobile onion service platform we'd have a different way to facilitate introductions without a continuously open set of circuits, but that would also be much more abuse-prone.
-beth
Hm. Do you know, is it possible to make network-driven wakeup events relatively prompt? (Like, within a second or so if a TCP stream we're waiting on wakes up). If so, then onion services have a decent chance of being made to work.
Fantastic! Yes, the response to network events should be reasonably prompt. I'll try to get some measurements.
As for the original question about timers, it would be good to know if the variance between scheduled wakeup and actual wakeup can be bounded, or if there's any way to mark a timer as high-priority vs low-priority or something.
This is unfortunately one of those things that's constantly changing on Android and varies between manufacturers. In theory we should be able to set a periodic alarm that fires within fifteen minutes of the last firing, although not all manufacturers honour this.
When the alarm fires the device will come out of suspension and the app will be able to grab a temporary wake lock, which we can hold for some amount of time (say a minute, for the sake of argument) to let Tor do whatever it needs to do.
As far as I know these alarms can only be scheduled via a Java API, so Tor would either need to signal to the controller that an alarm was needed, or the controller could just assume this whenever hidden services were published, and wake the device every fifteen minutes without explicitly communicating with Tor about alarms.
Cheers, Michael
tor-dev mailing list tor-dev@lists.torproject.org https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-dev
tor-dev mailing list tor-dev@lists.torproject.org https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-dev
It's hard to say what the battery impact would be because it depends on what else the device is doing.
The best case for battery savings would be when the device is stationary with the screen turned off, no apps exempted from doze mode except the one running the hidden service, and no incoming push notifications. In that situation there should be few things bringing the device out of suspension, including minimal network traffic except for the app running the hidden service, so being able to release the wake lock and let the device suspend should have a relatively big impact.
Conversely if the screen is turned on, or there are a bunch of other apps using the network or doing background work, or push notifications constantly waking the device, then there will be relatively little impact.
I can run experiments to measure the savings in the ideal case, but it's hard to say how often that's representative of what's happening on real devices.
Strongly agree that it would be good to think about what Tor would look like if built for mobile first!
Cheers, Michael
On 13/01/2024 15:19, Holmes Wilson wrote:
Michael, what kind of reduction in battery impact would you expect if you were able to make these changes?
Also, is anyone aware of any work that has been done within this community or in academia to consider from first principles what Tor would look like if built for mobile first? (e.g. built to only run when an app is in the foreground, or when a notification wakes up the app.) This seems like a discussion worth having once Arti settles and it's easier to build new things again!
On Wed Jan 10, 2024, 11:26 AM GMT, Michael Rogers mailto:michael@briarproject.org wrote:
On 10/01/2024 01:46, Nick Mathewson wrote: On Tue, Jan 9, 2024 at 12:58 PM Micah Elizabeth Scott <beth@torproject.org> wrote: Ah. If you want to run an onion service you'll need to keep at least a couple circuits open continuously for the introduction points. I'm not sure where you would meaningfully find time to deep sleep in that scenario. There will be ongoing obligations from the wifi/wan and tcp stacks. You need a continuous TCP connection to the guard, and multiple circuits that are not discarded as idle. Incoming traffic on those circuits need to be addressed quickly or clients won't be able to connect. If we were really optimizing for a low power mobile onion service platform we'd have a different way to facilitate introductions without a continuously open set of circuits, but that would also be much more abuse-prone. -beth Hm. Do you know, is it possible to make network-driven wakeup events relatively prompt? (Like, within a second or so if a TCP stream we're waiting on wakes up). If so, then onion services have a decent chance of being made to work. Fantastic! Yes, the response to network events should be reasonably prompt. I'll try to get some measurements. As for the original question about timers, it would be good to know if the variance between scheduled wakeup and actual wakeup can be bounded, or if there's any way to mark a timer as high-priority vs low-priority or something. This is unfortunately one of those things that's constantly changing on Android and varies between manufacturers. In theory we should be able to set a periodic alarm that fires within fifteen minutes of the last firing, although not all manufacturers honour this. When the alarm fires the device will come out of suspension and the app will be able to grab a temporary wake lock, which we can hold for some amount of time (say a minute, for the sake of argument) to let Tor do whatever it needs to do. As far as I know these alarms can only be scheduled via a Java API, so Tor would either need to signal to the controller that an alarm was needed, or the controller could just assume this whenever hidden services were published, and wake the device every fifteen minutes without explicitly communicating with Tor about alarms. Cheers, Michael _______________________________________________ tor-dev mailing list tor-dev@lists.torproject.org https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-dev _______________________________________________ tor-dev mailing list tor-dev@lists.torproject.org https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-dev
tor-dev mailing list tor-dev@lists.torproject.org https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-dev
Thanks for this information. Android devices are generally able to keep TCP connections open during deep sleep, as long as there are keepalives from the other side (which we can request for Tor guard connections via KeepalivePeriod). The device will wake from deep sleep to handle network activity, so any state changes in Tor that are driven by network events should also work fine. The problem really is state changes that are driven by local timers.
If we assume optimistically that the device wakes often enough (due to network activity, background work scheduled by other apps, etc) to handle HS descriptor publication and consensus fetches in a reasonably timely way, then it seems to me that the main question is whether we can keep the introduction circuits alive if local timers don't fire in a timely way. And it would also be great to know whether we can not only keep the circuits alive, but avoid network-visible changes in behaviour compared with a device that's not sleeping.
Cheers, Michael
On 09/01/2024 17:57, Micah Elizabeth Scott wrote:
Ah. If you want to run an onion service you'll need to keep at least a couple circuits open continuously for the introduction points. I'm not sure where you would meaningfully find time to deep sleep in that scenario. There will be ongoing obligations from the wifi/wan and tcp stacks. You need a continuous TCP connection to the guard, and multiple circuits that are not discarded as idle. Incoming traffic on those circuits need to be addressed quickly or clients won't be able to connect.
If we were really optimizing for a low power mobile onion service platform we'd have a different way to facilitate introductions without a continuously open set of circuits, but that would also be much more abuse-prone.
-beth
On 1/9/24 05:19, Michael Rogers wrote:
Sorry, I should have said that we're interested in keeping a hidden service running. Without that requirement, I agree we could just close the guard connection via DisableNetwork after some idle period.
So the question is about keeping circuits alive, and I guess also keeping HS descriptors published and the consensus fresh, although hopefully the timing requirements for those are a bit looser due to the longer timescales involved.
Cheers, Michael
On 08/01/2024 21:01, Micah Elizabeth Scott wrote:
A variety of timers are needed on the relay side; on the client side though, aren't you mostly limited by the requirement of keeping a TCP connection open?
Really deep sleep would involve avoiding any protocol-level keepalives as well as TCP keepalives. This seems a lot like just shutting down the connection to the guard when sleeping; but of course that's got a latency penalty and it's visible to anyone who can see network activity.
-beth
On 1/4/24 04:48, Michael Rogers wrote:
Hi,
If I understand right, the C implementation of Tor has various state machines that are driven by local libevent timers as well as events from the network. For example, when building a circuit, if there hasn't been any progress for a certain amount of time then a timer fires to handle the timeout.
When running Tor on Android, we need to prevent the OS from suspending so that these timers fire when they're supposed to. This uses a lot of battery, because normally the OS would spend most of its time suspended. Unlike a laptop, an Android device with its screen turned off is constantly dipping in an out of suspension, and a lot of the platform's power optimisations are aimed at batching whatever work needs to be done so that the periods of suspension can be longer.
If we allowed the OS to suspend then the timers would fire with arbitrary delays, and I don't really know what impact that would have: I'd speculate that there might be connectivity problems (eg dead circuits not being detected and replaced) and/or network-visible changes in the behaviour of circuits that could affect anonymity.
So I've had a longstanding but not-very-hopeful request that maybe Tor's reliance on timers could be reduced, or at least clarified, so that we could either allow the OS to suspend without breaking anything, or at least know what was likely to break.
And basically I'd just like to renew that request for Arti. Could anyone give me an overview of how these local timers are handled in Arti, or any information about what's likely to happen if the timers are arbitrarily delayed?
Thanks, Michael
tor-dev mailing list tor-dev@lists.torproject.org https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-dev
tor-dev mailing list tor-dev@lists.torproject.org https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-dev