# tcptape

Simple command-line tool to record TCP sessions of a client-server interaction to be able to emulate client or server based on recorded data and verify that peer behaves as expected.

Unlike many other server mocking solutions, the tool does not expect HTTP or other particular protocol and expects byte-by-byte match between recorded and tested data streams.

The tool relies on usual socket functions, it does not deal with low-level TCP/IP packets. It can be easily extended to UNIX sockets or other bidirectional pipes.

## Features

* Recording proxied traffic to file.
* Validation of incoming traffic based on the file and emitting chunks, also based on the file.
* Full-duplex mode when recording traffic.
* Saving and optionally replaying delays between data chunks.
* Handling of half-closed sockets (saving and replaying/validating EOFs).
* Dumping list of chunks in the file for debugging.
* Optionally showing a nice diff for mismatches in the data.
* Full session is not cached in memory, recording and replaying streams the data to/from file.

## Example session

<details>

```
     TcpTape        |      Server                |    Client
                    | S$ nc -nvlp 1235           |
                    | Listening on 0.0.0.0 1235  |
TT$ tcptape proxy \ |                            |
   127.0.0.1:1234 \ |                            |
   127.0.0.1:1235 \ |                            |
   qqq.tape         |                            |
Proxy listening on  |                            |
   127.0.0.1:1234   |                            |
                    |                            | C$ nc 127.0.0.1 1234
Accepted client     |                            |
    connection      |                            |
Connected to server | Connection received        |
  at 127.0.0.1:1235 |    on 127.0.0.1 33614      |
                    | qqq                        |>qqq
                    | www                        |>www
                    |>123                        | 123
                    |>456                        | 456
                    |                            | ^C
Client-to-server    |                            |
   direction closed |                            |
Server-to-client    |                            |
   direction closed |                            |
Proxy connection    |                            |
    closed          |                            |
TT$                 | S$                         | C$

TT$ tcptape server \|                            |
  127.0.0.1:1234 \  |                            |
  qqq.tape          |                            |
 Server listening   |                            | 
 on 127.0.0.1:1234  |                            |
                    |                            |
 Accepted connection|                            | C$ nc 127.0.0.1 1234
from 127.0.0.1:37114|                            |
                    |                            |>qqq
                    |                            |>www
                    |                            | 123
                    |                            | 456
                    |                            | ^C
                    |                            |
 Accepted connection|                            | C$ nc 127.0.0.1 1234
from 127.0.0.1:37128|                            |>qqq
                    |                            |>TTT
Assertion failed:   |                            | 
received data mism  |                            |
Expected (4 bytes): |                            |
7777770a            |                            | 
Received (4 bytes): |                            |
5454540a            |                            |
Error handling co   |                            |
                    |                            |>yyy 
                    |                            | C$
^C                  |                            |
TT$                 |                            |
                    | S$ nc -nvlp 1235           |
                    | Listening on 0.0.0.0 1235  |
TT$ tcptape client \|                            |
  127.0.0.1:1235 \  |                            |
  qqq.tape          |                            |
Connected to        | Connection received        |
    127.0.0.1:1235  |    on 127.0.0.1 54292      |
                    | qqq                        |
                    | www                        |
                    |>123                        |
                    |>456                        |
TT$                 | S$                         |
                    +----------------------------+-----------------------
TT$ tcptape describe qqq.tape
0: NOOP
1: DELAY (127343ms)
2: CLIENT_TO_SERVER (4 bytes)
3: DELAY (5000ms)
4: CLIENT_TO_SERVER (4 bytes)
5: DELAY (103096ms)
6: SERVER_TO_CLIENT (4 bytes)
7: DELAY (1307ms)
8: SERVER_TO_CLIENT (4 bytes)
9: DELAY (4176ms)
10: CLIENT_TO_SERVER_EOF
11: SERVER_TO_CLIENT_EOF
```

</details>

## Installation

Download a pre-built executable from [Github releases](https://github.com/vi/tcptape/releases) or install from source code with `cargo install --path .`  or `cargo install tcptape`.

## CLI options

<details><summary> tcptape --help output</summary>

```
Usage: tcptape <command> [<args>]

tcptape: record and replay TCP traffic

Options:
  --help, help      display usage information

Commands:
  proxy             proxy TCP traffic from one address to another and save all
                    forwarded traffic to a file
  server            start a server verifies all incoming traffic based on
                    specified file and replies based on the recorded data from
                    the file
  client            connect to a server, verifying all incoming traffic based on
                    specified file and replying based on the recorded data from
                    the file
  describe          describe tcptape file contents
```


```
Usage: tcptape proxy <listen> <connect> <file>

Proxy TCP traffic of a single TCP session from an accepted socket to a connected socket

Positional Arguments:
  listen            socket address to listen on
  connect           socket address to connect to
  file              file to write traffic to

Options:
  --help, help      display usage information
```

```
Usage: tcptape server <listen> <file> [-n] [-d] [-a] [--once] [--text-diff]

start a server that verifies all incoming traffic based on specified file and replies based on the recorded data from the file

Positional Arguments:
  listen            socket address to listen on
  file              file to read initial data from

Options:
  -n, --no-assert   just count bytes, don't assert
  -d, --delay       apply delays before replaying
  -a, --abort       exit with code 3 on a mismatch
  --once            serve only once
  --text-diff       show fancy text diff on a mismatch
  --help, help      display usage information
```

</details>

# See also

* [tcpmock](https://github.com/mpmartins/tcpmock) - Java implementation of a similar idea, using JSON files
