It is now possible to meticulously control a set of timeout-related behaviour in Meterpreter sessions. Timeouts may not seem important, but they change the noise levels of Meterpreter's communication resiliency features, and allow for the extension/reduction of time of the Meterpreter session as a whole.

This document details what those timeouts are, and how to control them.

## Meterpreter's Timeout Values

There are four timeout values that can be controlled by the user, and they are documented in the sections below.

### Meterpreter Session Timeout

Each instance of Meterpreter has a lifetime that is defined as a _session_. The length of Meterpeter's life is defined by a parameter called the **Session Timeout**. This value can be specified when Meterpreter payloads are generated by using the `SessionExpirationTimeout` datastore option. The default value used is the equivalent of one whole week (`604800` seconds), and hence this is what is used if the user does not override the value manually.

The session's life begins at the point that `metsrv` (Meterpreter's core) takes over from the initial stage (if there is one). Once running, the session timer begins, and Meterpeter will monitor this timeout so that as soon as it is reached the session will be closed.

If the timeout value is set to zero, this tells Meterpreter to _never_ kill the session. If you're looking to have Meterpreter run for as long as it can, then setting this value to zero is the way to do it.

It's important to note that this value lives outside of the realms of the other timeout values. That is, this value applies to Meterpreter as a whole, where the other three timeouts are specific to the individual transports that have been configured within the session.

### Meterpreter Transport Timeouts

Each transport that is configured inside Meterpreter has three timeouts. The are as follows:

#### Communication Timeout

When Meterpreter talks to Metasploit packets are exchanged at a low level in a request/response fashion. In the case of `TCP` transports, this req/rep pattern is basically instant because `TCP` is a persistent connection. A request is handled by Meterpreter, and the response is immediately transferred as soon as the command has finished executing.

In the case of `HTTP/S` payloads it's slightly different because the protocols are stateless. Meterpreter makes a `GET` request to Metasploit to check to see if a command has been executed by the user. The command is returned, the connection is closed, and Meterpreter executes the command asynchronously. When the command execution finishes, a second request is made that `POST`s the result back to Metasploit so that the user can consume it. Hence, for each command invocation, there are two `HTTP/S` requests.

With `TCP` transports, communication "times out" when the time between the last packet and the current socket poll is greater than the communications timeout value. This happens when there are network related issues that prevent data from being transmitted between the two endpoints, but doesn't cause the socket to completely disconnect. With `HTTP/S` transports, the communication "times out" for the same reason, but the evaluation of the condition is slightly different in that failure can occur because there is either no response at all from the remote server, or the response to a `GET` request results in no acknowledgement.

By default, this value is set to `300` seconds (`5` minutes), but can be overridden by the user via the `SessionCommunicationTimeout` setting.

If connectivity fails, or the communication is deemed to have timed out. Then the current transport is destroyed, and the next transport in the list of transports is invoked. From there, Meterpreter will use the Retry Total and Retry Wait values while attempting to re-establish a session with Metasploit.

#### Retry Total and Retry Wait

After a transport initialises inside Meterpreter, Meterpreter uses this transport to attempt to establish a new session with Metasploit. In some cases, Metasploit might not be available due to reasons like bad network connectivity, or a lack of configured listeners. If Meterpreter can't connect to Metasploit, it will attempt to retry for a period of time. Once that period of time expires, Meterpreter will deem this transport "dead" and will move to the next one in the transport list.

The total amount of time that Meterpreter will attempt to connect back to Metasploit on the given transport is indicated by the `retry total` value. That is, `retry total` is the total amount of time that Meterpreter will retry communication on the transport. The default value is `3600` seconds (`1` hour), and can be overridden via the `SessionRetryTotal` setting.

While the current time is within the `retry total` time, Meterpreter will constantly attempt to establish connectivity. If it fails, it will wait for a period of time before trying again. The time between retry attempts on the current transport is called `retry wait`. That is, Meterpreter will wait for the number of seconds specified in `retry wait` between each connection attempt on the current transport. The default value is `10` seconds, and can be overridden via the `SessionRetryWait` setting.

## Changing Timeouts

Meterpreter supports the querying and updating of each of these timeouts via the console. In order to get the current timeout settings, users can invoke the `get_timeouts` command, which returns all four of the current timeout settings (one for the global session, and three for the transport-specific settings). An example of which is shown below:

```msf
meterpreter > get_timeouts 
Session Expiry  : @ 2015-06-09 19:56:05
Comm Timeout    : 100000 seconds
Retry Total Time: 50000 seconds
Retry Wait Time : 2500 seconds
```

The `Session Expiry` value is rendered as an absolute local time so that the user knows when the session is due to expire.

In order to update these values, users can invoke the `set_timeouts` command. Invoking it without parameters shows the help:

```msf
meterpreter > set_timeouts 
Usage: set_timeouts [options]

Set the current timeout options.
Any or all of these can be set at once.

OPTIONS:

    -c <opt>  Comms timeout (seconds)
    -h        Help menu
    -t <opt>  Retry total time (seconds)
    -w <opt>  Retry wait time (seconds)
    -x <opt>  Expiration timeout (seconds)
```
As the help implies, each of these settings takes a value that indicates the number of seconds. Each of the options of this command are optional, so the user can update only those values that they are interested in updating. When the command is invoked, Meterpreter is updated, and the result shows the updated values once the changes have been made.

In the case of the `-x` parameter, the value that is to be passed in should represent the total number of seconds from "now" until the session should expire.

The following example updates the session expiration timeout to be `2` minutes from "now", and changes the retry wait time to `3` seconds:

```msf
meterpreter > set_timeouts -x 120 -t 3
Session Expiry  : @ 2015-06-02 22:45:13
Comm Timeout    : 100000 seconds
Retry Total Time: 3 seconds
Retry Wait Time : 2500 seconds
```

This command can be invoked any number of times while the session is valid, but as soon as the session has expired, Metepreter will shut down and it's game over:
```msf
meterpreter > 
[*] 10.1.10.35 - Meterpreter session 2 closed.  Reason: Died
```
