initial commit
This commit is contained in:
@@ -1,50 +1,15 @@
|
|||||||
# Korg, reborn
|
# Automated Channel Fault Analysis with Tofu
|
||||||
|
|
||||||
# TODO:
|
## Installation and Tests
|
||||||
- [x] nix flake here
|
- Install nix
|
||||||
- [x] fix weird spin errors(?)
|
- Run `nix develop`
|
||||||
- jake note: pinned specific working SPIN version using Nix
|
- Execute the test harnesses with `test_harness.py`:
|
||||||
- [x] add attackers that only do specifically n queries
|
|
||||||
- limitation: you cannot choose only *n* queries for the dropping attacker; trace violations can happen at any time
|
|
||||||
- [x] add attackers to do <= n queries
|
|
||||||
- [x] add attackers that can do attacks with an unbounded number of messages
|
|
||||||
- [x] add a test suite
|
|
||||||
- [x] make the impl more robust; do more SWE
|
|
||||||
- [x] add no self-deadlock experiments
|
|
||||||
- I envision this would be: providing an eventually-style LTL query, sending messages onto an open channel, and asserting that the gadget doesn't somehow deadlock with itself
|
|
||||||
- [ ] support queries over multiple properties
|
|
||||||
- [ ] add raft, TCP, SCTP, ABP experiments from old Korg impl to the test suite
|
|
||||||
- [ ] add labels on trace logging to gadgets
|
|
||||||
- [ ] modify the paper? spin workshop?
|
|
||||||
|
|
||||||
# Notes
|
```
|
||||||
- Sound and complete attack discovery for replay, dropping, and reordering attacks on channels
|
$ test_harness tests/tcp.yaml # TCP tests
|
||||||
- possible because of the finite-state modeling spin does. Indeed, we can model no-limit attackers within the finite-state model, giving guarantees of decidability and complexity.
|
$ test_harness tests/abp.yaml # ABP tests
|
||||||
- Limiting the number of messages a drop/replay/reorder attacker can reason about has the ability to significantly reduce the searchspace, especially when dealing with larger models. Although KORG is always decidable, sound, and complete, using the unbounded attacker is inadvisable in practice because spin must reason about *all* such permutations of possible drop, replay, and reorder sequences, thereby increasing the search space factorially.
|
$ test_harness tests/tests.yaml # general correctness tests
|
||||||
- One explicit limitation of the replay attacker is not being able to transition back to listening for packets after replaying
|
```
|
||||||
- Maybe change the title to: Korg: Automated analysis of channel faults
|
Each test comes with a description - check out the respective YAML files
|
||||||
- The inclusion of the pass on chan functionality is required to ensure liveness properties are not trivially violated by an attacker gadget that loops with itself. Thus the pass on chan functionality is the best possible "wait" we could think up. We also include no deadlock tests.
|
|
||||||
|
|
||||||
# Gadget Structures
|
A full tutorial is available in [TUTORIAL.MD](TUTORIAL.MD)
|
||||||
|
|
||||||
Drop:
|
|
||||||
- drop msg off chan
|
|
||||||
- pass on chan
|
|
||||||
|
|
||||||
Replay:
|
|
||||||
:CONSUME:
|
|
||||||
- consume msg; may go to CONSUME or REPLAY
|
|
||||||
- pass on chan
|
|
||||||
:REPLAY:
|
|
||||||
- replay msg
|
|
||||||
- pass on chan
|
|
||||||
- pass on chan, then go to REPLAY
|
|
||||||
|
|
||||||
Reorder:
|
|
||||||
:INIT:
|
|
||||||
- pass msg on chan
|
|
||||||
- go to CONSUME
|
|
||||||
:CONSUME:
|
|
||||||
- consume n messages on chan, then go to REPLAY
|
|
||||||
:REPLAY:
|
|
||||||
- replay msg
|
|
||||||
|
|||||||
+101
@@ -0,0 +1,101 @@
|
|||||||
|
# Tutorial
|
||||||
|
|
||||||
|
Tofu synthesizes attacker gadgets (drop / replay / reorder) on top of an existing Promela model, then hands the combined model to Spin. If the LTL property breaks, the attacker found an attack.
|
||||||
|
|
||||||
|
## Setup
|
||||||
|
|
||||||
|
```
|
||||||
|
$ nix develop
|
||||||
|
```
|
||||||
|
|
||||||
|
The flake pins `nixpkgs` and a specific `spin` revision (see `flake.lock`), so the toolchain is reproducible across machines.
|
||||||
|
|
||||||
|
## CLI
|
||||||
|
|
||||||
|
```
|
||||||
|
python src/main.py \
|
||||||
|
--model=<path>.pml \
|
||||||
|
--attacker={drop,replay,reorder} \
|
||||||
|
--chan=<chan>[,<chan>...] \
|
||||||
|
--mem=<int|unbounded> \
|
||||||
|
--output=<path>.pml \
|
||||||
|
[--eval] [--cleanup] [--nocheck]
|
||||||
|
```
|
||||||
|
|
||||||
|
- `--mem` bounds the attacker's memory (number of messages it can buffer / drop). Use `unbounded` to remove the bound.
|
||||||
|
- `--chan` accepts a comma-separated list. Multi-channel arrays use `name:i` or `name:a-b`.
|
||||||
|
- `--eval` runs Spin on the output. `--cleanup` removes Spin artifacts (`pan*`, `*.trail`, `_spin_nvr.tmp`) and the output `.pml` after evaluation.
|
||||||
|
|
||||||
|
## Writing a Model
|
||||||
|
|
||||||
|
A model has three parts: a channel, a consumer that walks a state machine on that channel, and an LTL property.
|
||||||
|
|
||||||
|
Save as `tests/example/tut.pml`:
|
||||||
|
|
||||||
|
```promela
|
||||||
|
// INTENDED BEHAVIOR: violation under replay, mem=1
|
||||||
|
chan c = [8] of { byte };
|
||||||
|
byte q = 1;
|
||||||
|
|
||||||
|
init {
|
||||||
|
c!5;
|
||||||
|
}
|
||||||
|
|
||||||
|
active proctype consume() {
|
||||||
|
MAIN:
|
||||||
|
do
|
||||||
|
:: c ? 5 -> goto PROC1;
|
||||||
|
od
|
||||||
|
PROC1:
|
||||||
|
do
|
||||||
|
:: c ? 5 -> goto PROC2;
|
||||||
|
od
|
||||||
|
PROC2:
|
||||||
|
q = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ltl proc {
|
||||||
|
always !(q == 0);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
The honest channel only carries one `5`, so `consume` should stall at `PROC1`. A replay attacker with `mem=1` can re-emit the consumed `5`, advancing the consumer to `PROC2` and falsifying the property.
|
||||||
|
|
||||||
|
## Running the Tool
|
||||||
|
|
||||||
|
```
|
||||||
|
$ python src/main.py --model=tests/example/tut.pml \
|
||||||
|
--attacker=replay --chan=c \
|
||||||
|
--output=temp.pml --mem=1 --eval --cleanup
|
||||||
|
```
|
||||||
|
|
||||||
|
Outputs to look for in Spin's report:
|
||||||
|
|
||||||
|
| Spin output | Meaning |
|
||||||
|
|------------------------|------------------------------------------------------------------|
|
||||||
|
| `assertion violated` | LTL safety property violated (attack found) |
|
||||||
|
| `acceptance cycle` | LTL liveness violated (attacker stalls progress) |
|
||||||
|
| neither | No violation; attacker (at this `--mem`) cannot break the model |
|
||||||
|
|
||||||
|
For the model above, expect a property violation. Drop `--mem` to `0` or switch to `--attacker=drop` and the violation disappears — the attacker no longer has the budget.
|
||||||
|
|
||||||
|
## Test Harness
|
||||||
|
|
||||||
|
Each `tests/*.yaml` entry pins a command and its intended outcome:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
my-test:
|
||||||
|
- command: python src/main.py --model=tests/example/tut.pml --attacker=replay --chan=c --output=temp.pml --eval --cleanup --mem=1
|
||||||
|
- intended: property violation
|
||||||
|
- explanation: replay attacker can re-emit the consumed 5
|
||||||
|
```
|
||||||
|
|
||||||
|
Run the suite:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ python test_harness.py tests/tests.yaml
|
||||||
|
$ python test_harness.py tests/tcp.yaml
|
||||||
|
$ python test_harness.py tests/abp.yaml
|
||||||
|
```
|
||||||
|
|
||||||
|
The harness diffs Spin's verdict against `intended` and prints a pass/fail summary.
|
||||||
Binary file not shown.
Binary file not shown.
-146
@@ -1,146 +0,0 @@
|
|||||||
# ==============================================================================
|
|
||||||
# Author : Jake Ginesin
|
|
||||||
# Authored : 14 June 2024
|
|
||||||
# Purpose : synthesize attacker gadgets for attackers that can drop,
|
|
||||||
# replay, and reorder messages on a channel
|
|
||||||
# ==============================================================================
|
|
||||||
import sys, re, subprocess, os, shutil
|
|
||||||
from typing import List
|
|
||||||
|
|
||||||
from utility import *
|
|
||||||
from model_generate import *
|
|
||||||
|
|
||||||
def show_help() -> None:
|
|
||||||
msg=(
|
|
||||||
"Usage: \n"
|
|
||||||
" python main.py [arguments] \n\n"
|
|
||||||
"Arguments: \n"
|
|
||||||
" --model=path/to/model.pml Promela model to generate attackers on\n"
|
|
||||||
" --attacker=[replay,drop,reorder] \n"
|
|
||||||
" --chan=[chan1, chan2:int, ...] Channels to synthesize attackers on. When specifying over ranges of\n"
|
|
||||||
" channels, you can give ranges or a list of values\n"
|
|
||||||
" --nocheck Don't check channel validity\n"
|
|
||||||
# " --nchan=[nat, nat, ...] If the channel is a set of channels, how many attackers to synthesize?\n"
|
|
||||||
" --mem=[num] Size of memory. Defaults to '3' \n"
|
|
||||||
" --mem=unbounded Use the unbounded memory gadget version (not recommended)\n"
|
|
||||||
" --output=path/to/file.pml Output file name\n"
|
|
||||||
" --eval Evaluate the outputted file with Spin\n"
|
|
||||||
" --cleanup Clean up the extra files spin creates, including Korg's \n"
|
|
||||||
)
|
|
||||||
print(msg)
|
|
||||||
|
|
||||||
# assert "syntax error" not in stdout, "there seems to be a syntax error in the model"
|
|
||||||
# assert "processes created" in stdout, "the spin model creates no processes ... check to see if it compiles"
|
|
||||||
|
|
||||||
def main() -> None:
|
|
||||||
args = sys.argv[1:]
|
|
||||||
if len(args) == 0 or args[0] in ["help", "--help", "-h", "-help"]:
|
|
||||||
show_help()
|
|
||||||
sys.exit()
|
|
||||||
|
|
||||||
mem = 3 # default
|
|
||||||
|
|
||||||
for arg in args:
|
|
||||||
if arg.startswith("--model="):
|
|
||||||
model_path = arg.split("=", 1)[1]
|
|
||||||
elif arg.startswith("--attacker="):
|
|
||||||
attacker = arg.split("=", 1)[1]
|
|
||||||
elif arg.startswith("--mem="):
|
|
||||||
mem_read = arg.split("=", 1)[1]
|
|
||||||
elif arg.startswith("--chan="):
|
|
||||||
chans = arg.split("=", 1)[1]
|
|
||||||
elif arg.startswith("--output="):
|
|
||||||
out_file = arg.split("=", 1)[1]
|
|
||||||
|
|
||||||
if "--eval" in args and not "--output" in args:
|
|
||||||
out_file = "korg-promela-out.pml"
|
|
||||||
|
|
||||||
if not model_path or not attacker or not mem or not chans or not out_file:
|
|
||||||
print("error: all arguments are required. \n")
|
|
||||||
show_help()
|
|
||||||
sys.exit(1)
|
|
||||||
|
|
||||||
unbounded = mem_read == "unbounded"
|
|
||||||
if not unbounded : mem = int(mem_read)
|
|
||||||
|
|
||||||
ensure_compile(model_path)
|
|
||||||
model = fileRead(model_path)
|
|
||||||
|
|
||||||
channels = parse_channels(fileReadLines(model_path))
|
|
||||||
mchannels, mchannel_len = parse_mchannels(fileReadLines(model_path))
|
|
||||||
model_with_attacker = str;
|
|
||||||
assert mem >= 0, "memory value must be positive"
|
|
||||||
|
|
||||||
chans_togen = set()
|
|
||||||
|
|
||||||
# first, process the input
|
|
||||||
mc = chans.split(",")
|
|
||||||
for chan in mc:
|
|
||||||
if ":" in chan:
|
|
||||||
name, num_extr = chan[:chan.index(":")], chan[chan.index(":")+1:]
|
|
||||||
if "-" in num_extr:
|
|
||||||
a, b = list(map(lambda a: int(a), num_extr.split("-")))
|
|
||||||
assert a < b
|
|
||||||
assert a >= 0
|
|
||||||
assert b < mchannel_len[name]
|
|
||||||
for i in range(a,b+1):
|
|
||||||
chan_name = str(name) + "[" + str(i) + "]"
|
|
||||||
chans_togen.add(chan_name)
|
|
||||||
channels[chan_name] = mchannels[name]
|
|
||||||
else:
|
|
||||||
a = int(num_extr)
|
|
||||||
assert a >= 0
|
|
||||||
assert a < mchannel_len[name]
|
|
||||||
chan_name = str(name) + "[" + str(a) + "]"
|
|
||||||
chans_togen.add(chan_name)
|
|
||||||
channels[chan_name] = mchannels[name]
|
|
||||||
|
|
||||||
else : chans_togen.add(chan)
|
|
||||||
|
|
||||||
print(chans_togen)
|
|
||||||
|
|
||||||
for i in range(len(chans_togen)):
|
|
||||||
chan = list(chans_togen)[i]
|
|
||||||
|
|
||||||
if not "--nocheck" : assert chan in channels, "can't find "+str(chan)+" in model"
|
|
||||||
|
|
||||||
match attacker:
|
|
||||||
case "replay":
|
|
||||||
if unbounded : attacker_gadget = gen_replay_unbounded(chan, channels[chan], i)
|
|
||||||
else : attacker_gadget = gen_replay(chan, channels[chan], mem, i)
|
|
||||||
case "drop":
|
|
||||||
if unbounded : attacker_gadget = gen_drop_unbounded(chan, channels[chan], i)
|
|
||||||
else : attacker_gadget = gen_drop(chan, channels[chan], mem, i)
|
|
||||||
case "reorder":
|
|
||||||
if unbounded : attacker_gadget = gen_reorder_unbounded(chan, channels[chan], i)
|
|
||||||
else : attacker_gadget = gen_reorder(chan, channels[chan], mem, i)
|
|
||||||
case _:
|
|
||||||
print("error: inputted an invalid attacker model. \n")
|
|
||||||
sys.exit(1)
|
|
||||||
|
|
||||||
if model.rindex("};") >= model.rindex("}"):
|
|
||||||
model = model[:model.rindex("};")+2] + "\n\n" + attacker_gadget + "\n" + model[model.rindex("};")+2:]
|
|
||||||
else:
|
|
||||||
model = model[:model.rindex("}")+1] + "\n\n" + attacker_gadget + "\n" + model[model.rindex("}")+1:]
|
|
||||||
|
|
||||||
# Write the modified model to the output file
|
|
||||||
with open(out_file, 'w') as file:
|
|
||||||
file.write(model)
|
|
||||||
|
|
||||||
if "--eval" in args:
|
|
||||||
print()
|
|
||||||
print("generated Promela file with attacker model gadget... now running SPIN on "+str(out_file) + "!\n")
|
|
||||||
eval_model(out_file)
|
|
||||||
|
|
||||||
if "--cleanup" in args:
|
|
||||||
print("\nCleaning up Spin files...")
|
|
||||||
cleanup_spin_files()
|
|
||||||
try:
|
|
||||||
os.remove(out_file)
|
|
||||||
print(f"Removed: {out_file}")
|
|
||||||
except OSError:
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
if __name__== "__main__":
|
|
||||||
main()
|
|
||||||
+1
-2
@@ -1,6 +1,5 @@
|
|||||||
# ==============================================================================
|
# ==============================================================================
|
||||||
# Author : Jake Ginesin
|
# Author : [redacted]
|
||||||
# Authored : 14 June 2024
|
|
||||||
# Purpose : synthesize attacker gadgets for attackers that can drop,
|
# Purpose : synthesize attacker gadgets for attackers that can drop,
|
||||||
# replay, and reorder messages on a channel
|
# replay, and reorder messages on a channel
|
||||||
# ==============================================================================
|
# ==============================================================================
|
||||||
|
|||||||
@@ -0,0 +1,9 @@
|
|||||||
|
unidirectional-drop-abp:
|
||||||
|
- command: python src/main.py --model=tests/abp/abp.pml --attacker=drop --chan=AtoB --output=temp.pml --eval --cleanup --mem=1
|
||||||
|
- intended: no violation
|
||||||
|
- explanation: abp resists drop, see https://en.wikipedia.org/wiki/Alternating_bit_protocol
|
||||||
|
|
||||||
|
bidirectional-drop-abp:
|
||||||
|
- command: python src/main.py --model=tests/abp/abp.pml --attacker=drop --chan=AtoB,BtoA --output=temp.pml --eval --cleanup --mem=1
|
||||||
|
- intended: no violation
|
||||||
|
- explanation: abp resists drop, see https://en.wikipedia.org/wiki/Alternating_bit_protocol
|
||||||
@@ -1,216 +0,0 @@
|
|||||||
# --- PHI 1: HALF-OPEN PREVENTION ---
|
|
||||||
|
|
||||||
tcp-phi1-drop-violate:
|
|
||||||
- command: python src/main.py --model=tests/tcp/tcp-phi1.pml --attacker=drop --chan=AtoB --output=temp.pml --eval --cleanup --mem=1
|
|
||||||
- intended: property violation
|
|
||||||
- explanation: Dropping A's FIN allows A to eventually time out to Closed while B remains stranded in Established.
|
|
||||||
|
|
||||||
tcp-phi1-drop-pass:
|
|
||||||
- command: python src/main.py --model=tests/tcp/tcp-phi1.pml --attacker=drop --chan=AtoB --output=temp.pml --eval --cleanup --mem=0
|
|
||||||
- intended: no violation
|
|
||||||
- explanation: Attacker has 0 memory budget; normal teardown prevents half-open states.
|
|
||||||
|
|
||||||
tcp-phi1-replay-violate:
|
|
||||||
- command: python src/main.py --model=tests/tcp/tcp-phi1.pml --attacker=replay --chan=AtoB --output=temp.pml --eval --cleanup --mem=1
|
|
||||||
- intended: property violation
|
|
||||||
- explanation: Replaying a stale SYN from A forces B into an Established state while A is completely Closed.
|
|
||||||
|
|
||||||
tcp-phi1-replay-pass:
|
|
||||||
- command: python src/main.py --model=tests/tcp/tcp-phi1.pml --attacker=replay --chan=BtoA --output=temp.pml --eval --cleanup --mem=1
|
|
||||||
- intended: no violation
|
|
||||||
- explanation: Replaying B's final teardown ACK is idempotent and harmlessly dropped by A, maintaining state sync.
|
|
||||||
|
|
||||||
tcp-phi1-reorder-violate:
|
|
||||||
- command: python src/main.py --model=tests/tcp/tcp-phi1.pml --attacker=reorder --chan=AtoB --output=temp.pml --eval --cleanup --mem=2
|
|
||||||
- intended: property violation
|
|
||||||
- explanation: Reordering A's SYN and FIN segments desynchronizes B's state machine, triggering a half-open state.
|
|
||||||
|
|
||||||
tcp-phi1-reorder-pass:
|
|
||||||
- command: python src/main.py --model=tests/tcp/tcp-phi1.pml --attacker=reorder --chan=AtoB --output=temp.pml --eval --cleanup --mem=1
|
|
||||||
- intended: no violation
|
|
||||||
- explanation: Reorder attacker requires at least mem=2 to swap messages; mem=1 is insufficient.
|
|
||||||
|
|
||||||
|
|
||||||
# --- PHI 3: NO DEADLOCKS ---
|
|
||||||
|
|
||||||
tcp-phi3-drop-violate:
|
|
||||||
- command: python src/main.py --model=tests/tcp/tcp-phi3.pml --attacker=drop --chan=BtoA --output=temp.pml --eval --cleanup --mem=1
|
|
||||||
- intended: acceptance cycle
|
|
||||||
- explanation: Dropping B's SYN-ACK stalls A in SynSent and B in SynRec indefinitely without timeout recovery.
|
|
||||||
|
|
||||||
tcp-phi3-drop-pass:
|
|
||||||
- command: python src/main.py --model=tests/tcp/tcp-phi3.pml --attacker=drop --chan=AtoB --output=temp.pml --eval --cleanup --mem=0
|
|
||||||
- intended: no violation
|
|
||||||
- explanation: Zero memory prevents dropping, allowing standard timers and handshakes to resolve without deadlocks.
|
|
||||||
|
|
||||||
tcp-phi3-replay-violate:
|
|
||||||
- command: python src/main.py --model=tests/tcp/tcp-phi3.pml --attacker=replay --chan=AtoB --output=temp.pml --eval --cleanup --mem=1
|
|
||||||
- intended: acceptance cycle
|
|
||||||
- explanation: Replaying FIN messages traps the receiver in an infinite loop of CloseWait/LastAck processing.
|
|
||||||
|
|
||||||
tcp-phi3-replay-pass:
|
|
||||||
- command: python src/main.py --model=tests/tcp/tcp-phi3.pml --attacker=replay --chan=BtoA --output=temp.pml --eval --cleanup --mem=1
|
|
||||||
- intended: no violation
|
|
||||||
- explanation: Replaying an ACK during the Established state is cleanly ignored and does not halt liveness progress.
|
|
||||||
|
|
||||||
tcp-phi3-reorder-violate:
|
|
||||||
- command: python src/main.py --model=tests/tcp/tcp-phi3.pml --attacker=reorder --chan=AtoB,BtoA --output=temp.pml --eval --cleanup --mem=2
|
|
||||||
- intended: acceptance cycle
|
|
||||||
- explanation: Swapping handshake messages (ACK before SYN) deadlocks both endpoints in intermediate waiting states.
|
|
||||||
|
|
||||||
tcp-phi3-reorder-pass:
|
|
||||||
- command: python src/main.py --model=tests/tcp/tcp-phi3.pml --attacker=reorder --chan=AtoB --output=temp.pml --eval --cleanup --mem=1
|
|
||||||
- intended: no violation
|
|
||||||
- explanation: Attacker lacks the mem=2 budget required to execute a reorder attack.
|
|
||||||
|
|
||||||
|
|
||||||
# --- PHI 5: SYN_RECEIVED RESOLUTION ---
|
|
||||||
|
|
||||||
tcp-phi5-drop-violate:
|
|
||||||
- command: python src/main.py --model=tests/tcp/tcp-phi5.pml --attacker=drop --chan=AtoB --output=temp.pml --eval --cleanup --mem=1
|
|
||||||
- intended: acceptance cycle
|
|
||||||
- explanation: Dropping the final ACK of the 3-way handshake prevents B from ever resolving SynRec to Established.
|
|
||||||
|
|
||||||
tcp-phi5-drop-pass:
|
|
||||||
- command: python src/main.py --model=tests/tcp/tcp-phi5.pml --attacker=drop --chan=AtoB --output=temp.pml --eval --cleanup --mem=0
|
|
||||||
- intended: no violation
|
|
||||||
- explanation: Without drop capabilities, the ACK arrives normally, resolving the SynRec state.
|
|
||||||
|
|
||||||
tcp-phi5-replay-violate:
|
|
||||||
- command: python src/main.py --model=tests/tcp/tcp-phi5.pml --attacker=replay --chan=AtoB --output=temp.pml --eval --cleanup --mem=1
|
|
||||||
- intended: acceptance cycle
|
|
||||||
- explanation: Replaying a SYN forces B to repeatedly trigger simultaneous open logic, preventing resolution.
|
|
||||||
|
|
||||||
tcp-phi5-replay-pass:
|
|
||||||
- command: python src/main.py --model=tests/tcp/tcp-phi5.pml --attacker=replay --chan=AtoB --output=temp.pml --eval --cleanup --mem=1
|
|
||||||
- intended: no violation
|
|
||||||
- explanation: Replaying the final ACK simply provides redundant resolution signals, which satisfies the property.
|
|
||||||
|
|
||||||
tcp-phi5-reorder-violate:
|
|
||||||
- command: python src/main.py --model=tests/tcp/tcp-phi5.pml --attacker=reorder --chan=AtoB --output=temp.pml --eval --cleanup --mem=2
|
|
||||||
- intended: acceptance cycle
|
|
||||||
- explanation: Delivering A's final ACK before B has fully entered SynRec confuses the state machine, stalling resolution.
|
|
||||||
|
|
||||||
tcp-phi5-reorder-pass:
|
|
||||||
- command: python src/main.py --model=tests/tcp/tcp-phi5.pml --attacker=reorder --chan=AtoB --output=temp.pml --eval --cleanup --mem=1
|
|
||||||
- intended: no violation
|
|
||||||
- explanation: Insufficient memory to reorder packets; handshakes process chronologically.
|
|
||||||
|
|
||||||
|
|
||||||
# --- PHI 6: STRICT CLOSING TRANSITIONS ---
|
|
||||||
|
|
||||||
tcp-phi6-drop-violate:
|
|
||||||
- command: python src/main.py --model=tests/tcp/tcp-phi6.pml --attacker=drop --chan=AtoB --output=temp.pml --eval --cleanup --mem=1
|
|
||||||
- intended: property violation
|
|
||||||
- explanation: Dropping the ACK to the FIN causes a timeout that bypasses the strict Closing-to-Closed state sequence.
|
|
||||||
|
|
||||||
tcp-phi6-drop-pass:
|
|
||||||
- command: python src/main.py --model=tests/tcp/tcp-phi6.pml --attacker=drop --chan=AtoB --output=temp.pml --eval --cleanup --mem=0
|
|
||||||
- intended: no violation
|
|
||||||
- explanation: Normal termination proceeds; Closing transitions accurately based on protocol rules.
|
|
||||||
|
|
||||||
tcp-phi6-replay-violate:
|
|
||||||
- command: python src/main.py --model=tests/tcp/tcp-phi6.pml --attacker=replay --chan=AtoB --output=temp.pml --eval --cleanup --mem=1
|
|
||||||
- intended: property violation
|
|
||||||
- explanation: Replaying a FIN while in Closing forces an invalid transition to TimeWait instead of Closed.
|
|
||||||
|
|
||||||
tcp-phi6-replay-pass:
|
|
||||||
- command: python src/main.py --model=tests/tcp/tcp-phi6.pml --attacker=replay --chan=AtoB --output=temp.pml --eval --cleanup --mem=0
|
|
||||||
- intended: no violation
|
|
||||||
- explanation: 0 memory prevents injection of unexpected packets during the tear-down phase.
|
|
||||||
|
|
||||||
tcp-phi6-reorder-violate:
|
|
||||||
- command: python src/main.py --model=tests/tcp/tcp-phi6.pml --attacker=reorder --chan=AtoB,BtoA --output=temp.pml --eval --cleanup --mem=2
|
|
||||||
- intended: property violation
|
|
||||||
- explanation: Swapping FINs during a simultaneous close alters the ACK delivery timing, violating the strict sequence.
|
|
||||||
|
|
||||||
tcp-phi6-reorder-pass:
|
|
||||||
- command: python src/main.py --model=tests/tcp/tcp-phi6.pml --attacker=reorder --chan=AtoB --output=temp.pml --eval --cleanup --mem=1
|
|
||||||
- intended: no violation
|
|
||||||
- explanation: Mem=1 prevents the reordering of the close-sequence messages.
|
|
||||||
|
|
||||||
# --- PHI 7: SIMULTANEOUS CLOSE RESOLUTION ---
|
|
||||||
|
|
||||||
tcp-phi7-drop-violate:
|
|
||||||
- command: python src/main.py --model=tests/tcp/tcp-phi7.pml --attacker=drop --chan=AtoB --output=temp.pml --eval --cleanup --mem=1
|
|
||||||
- intended: acceptance cycle
|
|
||||||
- explanation: Dropping a FIN during a simultaneous close prevents one side from transitioning out of FinW1State.
|
|
||||||
|
|
||||||
tcp-phi7-drop-pass:
|
|
||||||
- command: python src/main.py --model=tests/tcp/tcp-phi7.pml --attacker=drop --chan=AtoB --output=temp.pml --eval --cleanup --mem=0
|
|
||||||
- intended: no violation
|
|
||||||
- explanation: Zero memory prevents message dropping; both endpoints successfully reach ClosedState.
|
|
||||||
|
|
||||||
tcp-phi7-replay-violate:
|
|
||||||
- command: python src/main.py --model=tests/tcp/tcp-phi7.pml --attacker=replay --chan=AtoB --output=temp.pml --eval --cleanup --mem=1
|
|
||||||
- intended: acceptance cycle
|
|
||||||
- explanation: Replaying stale FINs traps the endpoint in a continuous processing loop, halting progress to ClosedState.
|
|
||||||
|
|
||||||
tcp-phi7-replay-pass:
|
|
||||||
- command: python src/main.py --model=tests/tcp/tcp-phi7.pml --attacker=replay --chan=AtoB --output=temp.pml --eval --cleanup --mem=0
|
|
||||||
- intended: no violation
|
|
||||||
- explanation: Without replay capabilities, the simultaneous close resolves chronologically.
|
|
||||||
|
|
||||||
tcp-phi7-reorder-violate:
|
|
||||||
- command: python src/main.py --model=tests/tcp/tcp-phi7.pml --attacker=reorder --chan=AtoB,BtoA --output=temp.pml --eval --cleanup --mem=2
|
|
||||||
- intended: acceptance cycle
|
|
||||||
- explanation: Swapping FIN and ACK segments out of order desynchronizes the simultaneous close, causing a deadlock.
|
|
||||||
|
|
||||||
tcp-phi7-reorder-pass:
|
|
||||||
- command: python src/main.py --model=tests/tcp/tcp-phi7.pml --attacker=reorder --chan=AtoB --output=temp.pml --eval --cleanup --mem=1
|
|
||||||
- intended: no violation
|
|
||||||
- explanation: Mem=1 is insufficient to execute a reorder attack.
|
|
||||||
|
|
||||||
|
|
||||||
# --- PHI 8: ACTIVE CLOSE EVENTUALLY TERMINATES ---
|
|
||||||
|
|
||||||
tcp-phi8-drop-violate:
|
|
||||||
- command: python src/main.py --model=tests/tcp/tcp-phi8.pml --attacker=drop --chan=BtoA --output=temp.pml --eval --cleanup --mem=1
|
|
||||||
- intended: acceptance cycle
|
|
||||||
- explanation: Dropping the responder's ACK leaves the active closer permanently stranded in FinW1State.
|
|
||||||
|
|
||||||
tcp-phi8-drop-pass:
|
|
||||||
- command: python src/main.py --model=tests/tcp/tcp-phi8.pml --attacker=drop --chan=BtoA --output=temp.pml --eval --cleanup --mem=0
|
|
||||||
- intended: no violation
|
|
||||||
- explanation: Normal teardown ensures the active closer receives its ACK and FIN.
|
|
||||||
|
|
||||||
tcp-phi8-replay-violate:
|
|
||||||
- command: python src/main.py --model=tests/tcp/tcp-phi8.pml --attacker=replay --chan=AtoB --output=temp.pml --eval --cleanup --mem=1
|
|
||||||
- intended: acceptance cycle
|
|
||||||
- explanation: Replaying application data or FINs delays the final transition, breaking the eventual termination guarantee.
|
|
||||||
|
|
||||||
tcp-phi8-replay-pass:
|
|
||||||
- command: python src/main.py --model=tests/tcp/tcp-phi8.pml --attacker=replay --chan=AtoB --output=temp.pml --eval --cleanup --mem=0
|
|
||||||
- intended: no violation
|
|
||||||
- explanation: Normal sequence guarantees the active closer reaches ClosedState.
|
|
||||||
|
|
||||||
tcp-phi8-reorder-violate:
|
|
||||||
- command: python src/main.py --model=tests/tcp/tcp-phi8.pml --attacker=reorder --chan=BtoA --output=temp.pml --eval --cleanup --mem=2
|
|
||||||
- intended: acceptance cycle
|
|
||||||
- explanation: Delivering the responder's FIN before the ACK confuses the state machine logic in FinW1State, stalling termination.
|
|
||||||
|
|
||||||
tcp-phi8-reorder-pass:
|
|
||||||
- command: python src/main.py --model=tests/tcp/tcp-phi8.pml --attacker=reorder --chan=BtoA --output=temp.pml --eval --cleanup --mem=1
|
|
||||||
- intended: no violation
|
|
||||||
- explanation: Insufficient memory to alter the close sequence.
|
|
||||||
|
|
||||||
|
|
||||||
# --- PHI 9: HANDSHAKE CANNOT BE BYPASSED ---
|
|
||||||
# Note: This is a strict safety property guaranteed by the structure of the Promela model.
|
|
||||||
# The LISTEN state explicitly routes only to SYN_RECEIVED upon reading a SYN.
|
|
||||||
# No channel attacker (drop, replay, reorder) can force a direct jump to ESTABLISHED.
|
|
||||||
|
|
||||||
tcp-phi9-drop-pass:
|
|
||||||
- command: python src/main.py --model=tests/tcp/tcp-phi9.pml --attacker=drop --chan=AtoB --output=temp.pml --eval --cleanup --mem=1
|
|
||||||
- intended: no violation
|
|
||||||
- explanation: Dropping messages halts progress but cannot force an illegal structural transition from Listen directly to Established.
|
|
||||||
|
|
||||||
tcp-phi9-replay-pass:
|
|
||||||
- command: python src/main.py --model=tests/tcp/tcp-phi9.pml --attacker=replay --chan=AtoB --output=temp.pml --eval --cleanup --mem=1
|
|
||||||
- intended: no violation
|
|
||||||
- explanation: The model's Listen state only branches on SYN (transitioning to SynRec). Replaying ACKs or FINs results in skipped messages, not illegal state jumps.
|
|
||||||
|
|
||||||
tcp-phi9-reorder-pass:
|
|
||||||
- command: python src/main.py --model=tests/tcp/tcp-phi9.pml --attacker=reorder --chan=AtoB --output=temp.pml --eval --cleanup --mem=2
|
|
||||||
- intended: no violation
|
|
||||||
- explanation: Regardless of message order, the Promela model restricts ListenState exits exclusively to SynRecState. This safety property is structurally immune to channel manipulation.
|
|
||||||
@@ -1,109 +0,0 @@
|
|||||||
unidirectional-drop-abp:
|
|
||||||
- command: python src/main.py --model=tests/abp/abp.pml --attacker=drop --chan=AtoB --output=temp.pml --eval --cleanup --mem=1
|
|
||||||
- intended: no violation
|
|
||||||
- explanation: abp resists drop, see https://en.wikipedia.org/wiki/Alternating_bit_protocol
|
|
||||||
|
|
||||||
bidirectional-drop-abp:
|
|
||||||
- command: python src/main.py --model=tests/abp/abp.pml --attacker=drop --chan=AtoB,BtoA --output=temp.pml --eval --cleanup --mem=1
|
|
||||||
- intended: no violation
|
|
||||||
- explanation: abp resists drop, see https://en.wikipedia.org/wiki/Alternating_bit_protocol
|
|
||||||
|
|
||||||
tcp-phi1-drop-AtoN:
|
|
||||||
- command: python src/main.py --model=tests/tcp/tcp-phi1.pml --attacker=drop --chan=AtoN --output=temp.pml --eval --cleanup --mem=1
|
|
||||||
- intended: no violation
|
|
||||||
- explanation: dropping A's outbound messages alone is insufficient to create a half-open state; B cannot reach Established without receiving from A
|
|
||||||
|
|
||||||
tcp-phi1-drop-BtoN:
|
|
||||||
- command: python src/main.py --model=tests/tcp/tcp-phi1.pml --attacker=drop --chan=BtoN --output=temp.pml --eval --cleanup --mem=1
|
|
||||||
- intended: no violation
|
|
||||||
- explanation: dropping B's outbound messages prevents B from progressing; A times out back to Closed, no half-open
|
|
||||||
|
|
||||||
tcp-phi1-drop-bidirectional:
|
|
||||||
- command: python src/main.py --model=tests/tcp/tcp-phi1.pml --attacker=drop --chan=AtoN,BtoN --output=temp.pml --eval --cleanup --mem=1
|
|
||||||
- intended: no violation
|
|
||||||
- explanation: dropping on both directions prevents any handshake progress; neither side reaches Established
|
|
||||||
|
|
||||||
tcp-phi1-replay-AtoN:
|
|
||||||
- command: python src/main.py --model=tests/tcp/tcp-phi1.pml --attacker=replay --chan=AtoN --output=temp.pml --eval --cleanup --mem=1
|
|
||||||
- intended: property violation
|
|
||||||
- explanation: replaying A's SYN can drive B into Established via a forged handshake while A returns to Closed, creating a half-open state
|
|
||||||
|
|
||||||
tcp-phi1-replay-BtoN:
|
|
||||||
- command: python src/main.py --model=tests/tcp/tcp-phi1.pml --attacker=replay --chan=BtoN --output=temp.pml --eval --cleanup --mem=1
|
|
||||||
- intended: property violation
|
|
||||||
- explanation: replaying B's SYN+ACK can cause A to believe handshake completed; if A then closes, B may remain Established
|
|
||||||
|
|
||||||
tcp-phi1-replay-bidirectional:
|
|
||||||
- command: python src/main.py --model=tests/tcp/tcp-phi1.pml --attacker=replay --chan=AtoN,BtoN --output=temp.pml --eval --cleanup --mem=1
|
|
||||||
- intended: property violation
|
|
||||||
- explanation: replaying on both channels gives the attacker maximum ability to manufacture a half-open state
|
|
||||||
|
|
||||||
tcp-phi1-reorder-AtoN:
|
|
||||||
- command: python src/main.py --model=tests/tcp/tcp-phi1.pml --attacker=reorder --chan=AtoN --output=temp.pml --eval --cleanup --mem=2
|
|
||||||
- intended: property violation
|
|
||||||
- explanation: reordering A's messages (e.g., delivering ACK before SYN) can desynchronize the handshake, leading to half-open
|
|
||||||
|
|
||||||
tcp-phi1-reorder-bidirectional:
|
|
||||||
- command: python src/main.py --model=tests/tcp/tcp-phi1.pml --attacker=reorder --chan=AtoN,BtoN --output=temp.pml --eval --cleanup --mem=2
|
|
||||||
- intended: property violation
|
|
||||||
- explanation: reordering on both channels maximizes desynchronization potential for half-open
|
|
||||||
|
|
||||||
tcp-phi3-drop-AtoN:
|
|
||||||
- command: python src/main.py --model=tests/tcp/tcp-phi3.pml --attacker=drop --chan=AtoN --output=temp.pml --eval --cleanup --mem=1
|
|
||||||
- intended: acceptance cycle
|
|
||||||
- explanation: dropping A's messages can cause B to stall indefinitely in SynReceived or similar waiting states
|
|
||||||
|
|
||||||
tcp-phi3-drop-bidirectional:
|
|
||||||
- command: python src/main.py --model=tests/tcp/tcp-phi3.pml --attacker=drop --chan=AtoN,BtoN --output=temp.pml --eval --cleanup --mem=1
|
|
||||||
- intended: acceptance cycle
|
|
||||||
- explanation: dropping on both channels can strand both sides in intermediate states with no timeout recovery
|
|
||||||
|
|
||||||
tcp-phi3-replay-AtoN:
|
|
||||||
- command: python src/main.py --model=tests/tcp/tcp-phi3.pml --attacker=replay --chan=AtoN --output=temp.pml --eval --cleanup --mem=1
|
|
||||||
- intended: acceptance cycle
|
|
||||||
- explanation: replaying stale messages can trap B in a loop re-processing old handshake messages
|
|
||||||
|
|
||||||
tcp-phi3-reorder-bidirectional:
|
|
||||||
- command: python src/main.py --model=tests/tcp/tcp-phi3.pml --attacker=reorder --chan=AtoN,BtoN --output=temp.pml --eval --cleanup --mem=2
|
|
||||||
- intended: acceptance cycle
|
|
||||||
- explanation: reordering on both channels can desynchronize both sides into permanently mismatched states
|
|
||||||
|
|
||||||
tcp-phi5-drop-AtoN:
|
|
||||||
- command: python src/main.py --model=tests/tcp/tcp-phi5.pml --attacker=drop --chan=AtoN --output=temp.pml --eval --cleanup --mem=1
|
|
||||||
- intended: acceptance cycle
|
|
||||||
- explanation: if A's ACK is dropped, B remains stuck in SynReceived with no timeout to recover
|
|
||||||
|
|
||||||
tcp-phi5-drop-BtoN:
|
|
||||||
- command: python src/main.py --model=tests/tcp/tcp-phi5.pml --attacker=drop --chan=BtoN --output=temp.pml --eval --cleanup --mem=1
|
|
||||||
- intended: acceptance cycle
|
|
||||||
- explanation: dropping B's SYN+ACK means A never sends ACK, leaving the initiator-side SynReceived unresolved
|
|
||||||
|
|
||||||
tcp-phi5-replay-AtoN:
|
|
||||||
- command: python src/main.py --model=tests/tcp/tcp-phi5.pml --attacker=replay --chan=AtoN --output=temp.pml --eval --cleanup --mem=1
|
|
||||||
- intended: no violation
|
|
||||||
- explanation: replaying A's messages provides additional ACKs that can help resolve SynReceived
|
|
||||||
|
|
||||||
tcp-phi5-reorder-AtoN:
|
|
||||||
- command: python src/main.py --model=tests/tcp/tcp-phi5.pml --attacker=reorder --chan=AtoN --output=temp.pml --eval --cleanup --mem=2
|
|
||||||
- intended: acceptance cycle
|
|
||||||
- explanation: reordering can deliver A's SYN after the ACK, confusing B's state machine and trapping it in SynReceived
|
|
||||||
|
|
||||||
tcp-phi6-drop-AtoN:
|
|
||||||
- command: python src/main.py --model=tests/tcp/tcp-phi6.pml --attacker=drop --chan=AtoN --output=temp.pml --eval --cleanup --mem=1
|
|
||||||
- intended: no violation
|
|
||||||
- explanation: dropping A's messages while in Closing does not cause A to transition to an unexpected state; A remains in Closing or eventually times out
|
|
||||||
|
|
||||||
tcp-phi6-replay-AtoN:
|
|
||||||
- command: python src/main.py --model=tests/tcp/tcp-phi6.pml --attacker=replay --chan=AtoN --output=temp.pml --eval --cleanup --mem=1
|
|
||||||
- intended: property violation
|
|
||||||
- explanation: replaying a FIN while in Closing could cause a transition to TimeWait instead of the expected Closing or Closed
|
|
||||||
|
|
||||||
tcp-phi6-replay-bidirectional:
|
|
||||||
- command: python src/main.py --model=tests/tcp/tcp-phi6.pml --attacker=replay --chan=AtoN,BtoN --output=temp.pml --eval --cleanup --mem=1
|
|
||||||
- intended: property violation
|
|
||||||
- explanation: replaying on both channels maximizes the chance of injecting an unexpected ACK that transitions Closing to TimeWait, violating the next-state constraint
|
|
||||||
|
|
||||||
tcp-phi6-reorder-bidirectional:
|
|
||||||
- command: python src/main.py --model=tests/tcp/tcp-phi6.pml --attacker=reorder --chan=AtoN,BtoN --output=temp.pml --eval --cleanup --mem=2
|
|
||||||
- intended: property violation
|
|
||||||
- explanation: reordering close-sequence messages can cause ACK delivery at unexpected times, violating the strict Closing transition property
|
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
Note:
|
||||||
|
- we do not expect properties 2, 4, and 6 to hold under this model.
|
||||||
@@ -1,143 +0,0 @@
|
|||||||
mtype = { SYN, FIN, ACK, ABORT, CLOSE, RST, OPEN }
|
|
||||||
|
|
||||||
chan AtoB = [2] of { mtype };
|
|
||||||
chan BtoA = [2] of { mtype };
|
|
||||||
|
|
||||||
int state[2];
|
|
||||||
int pids[2];
|
|
||||||
|
|
||||||
#define ClosedState 0
|
|
||||||
#define ListenState 1
|
|
||||||
#define SynSentState 2
|
|
||||||
#define SynRecState 3
|
|
||||||
#define EstState 4
|
|
||||||
#define FinW1State 5
|
|
||||||
#define CloseWaitState 6
|
|
||||||
#define FinW2State 7
|
|
||||||
#define ClosingState 8
|
|
||||||
#define LastAckState 9
|
|
||||||
#define TimeWaitState 10
|
|
||||||
#define EndState -1
|
|
||||||
|
|
||||||
#define leftConnecting (state[0] == ListenState && state[1] == SynSentState)
|
|
||||||
#define leftEstablished (state[0] == EstState)
|
|
||||||
#define rightEstablished (state[1] == EstState)
|
|
||||||
#define leftClosed (state[0] == ClosedState)
|
|
||||||
|
|
||||||
proctype TCP(chan snd, rcv; int i) {
|
|
||||||
pids[i] = _pid;
|
|
||||||
CLOSED:
|
|
||||||
state[i] = ClosedState;
|
|
||||||
do
|
|
||||||
/* Passive open */
|
|
||||||
:: goto LISTEN;
|
|
||||||
/* Active open */
|
|
||||||
:: snd ! SYN; goto SYN_SENT;
|
|
||||||
/* Terminate */
|
|
||||||
:: goto end;
|
|
||||||
od
|
|
||||||
LISTEN:
|
|
||||||
state[i] = ListenState;
|
|
||||||
do
|
|
||||||
:: rcv ? SYN ->
|
|
||||||
atomic {
|
|
||||||
snd ! SYN;
|
|
||||||
snd ! ACK;
|
|
||||||
goto SYN_RECEIVED;
|
|
||||||
}
|
|
||||||
/* Simultaneous LISTEN */
|
|
||||||
:: rcv ? _ -> skip;
|
|
||||||
:: timeout -> goto CLOSED;
|
|
||||||
od
|
|
||||||
SYN_SENT:
|
|
||||||
state[i] = SynSentState;
|
|
||||||
do
|
|
||||||
:: rcv ? SYN;
|
|
||||||
if
|
|
||||||
/* Standard behavior */
|
|
||||||
:: rcv ? ACK -> snd ! ACK; goto ESTABLISHED;
|
|
||||||
/* Simultaneous open */
|
|
||||||
:: snd ! ACK; goto SYN_RECEIVED;
|
|
||||||
fi
|
|
||||||
:: rcv ? ACK;
|
|
||||||
do
|
|
||||||
:: rcv ? SYN ->
|
|
||||||
snd ! ACK;
|
|
||||||
goto ESTABLISHED;
|
|
||||||
:: rcv ? _ -> skip;
|
|
||||||
od
|
|
||||||
:: rcv ? _ -> skip;
|
|
||||||
:: timeout -> goto CLOSED; /* Timeout */
|
|
||||||
od
|
|
||||||
SYN_RECEIVED:
|
|
||||||
state[i] = SynRecState;
|
|
||||||
do
|
|
||||||
:: rcv ? ACK -> goto ESTABLISHED;
|
|
||||||
:: rcv ? _ -> skip;
|
|
||||||
od
|
|
||||||
ESTABLISHED:
|
|
||||||
state[i] = EstState;
|
|
||||||
do
|
|
||||||
/* Close - initiator sequence */
|
|
||||||
:: snd ! FIN; goto FIN_WAIT_1;
|
|
||||||
/* Close - responder sequence */
|
|
||||||
:: rcv ? FIN ->
|
|
||||||
snd ! ACK;
|
|
||||||
goto CLOSE_WAIT;
|
|
||||||
:: rcv ? _ -> skip;
|
|
||||||
od
|
|
||||||
FIN_WAIT_1:
|
|
||||||
state[i] = FinW1State;
|
|
||||||
do
|
|
||||||
/* Simultaneous close */
|
|
||||||
:: rcv ? FIN ->
|
|
||||||
snd ! ACK;
|
|
||||||
goto CLOSING;
|
|
||||||
/* Standard close */
|
|
||||||
:: rcv ? ACK -> goto FIN_WAIT_2;
|
|
||||||
:: rcv ? _ -> skip;
|
|
||||||
od
|
|
||||||
CLOSE_WAIT:
|
|
||||||
state[i] = CloseWaitState;
|
|
||||||
do
|
|
||||||
:: snd ! FIN; goto LAST_ACK;
|
|
||||||
:: rcv ? _ -> skip;
|
|
||||||
od
|
|
||||||
FIN_WAIT_2:
|
|
||||||
state[i] = FinW2State;
|
|
||||||
do
|
|
||||||
:: rcv ? FIN ->
|
|
||||||
snd ! ACK;
|
|
||||||
goto TIME_WAIT;
|
|
||||||
:: rcv ? _ -> skip;
|
|
||||||
od
|
|
||||||
CLOSING:
|
|
||||||
state[i] = ClosingState;
|
|
||||||
do
|
|
||||||
:: rcv ? ACK -> goto TIME_WAIT;
|
|
||||||
:: rcv ? _ -> skip;
|
|
||||||
od
|
|
||||||
LAST_ACK:
|
|
||||||
state[i] = LastAckState;
|
|
||||||
do
|
|
||||||
:: rcv ? ACK -> goto CLOSED;
|
|
||||||
:: rcv ? _ -> skip;
|
|
||||||
od
|
|
||||||
TIME_WAIT:
|
|
||||||
state[i] = TimeWaitState;
|
|
||||||
goto CLOSED;
|
|
||||||
end:
|
|
||||||
state[i] = EndState;
|
|
||||||
}
|
|
||||||
|
|
||||||
init {
|
|
||||||
state[0] = ClosedState;
|
|
||||||
state[1] = ClosedState;
|
|
||||||
run TCP(AtoB, BtoA, 0);
|
|
||||||
run TCP(BtoA, AtoB, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* safety: half-open prevention */
|
|
||||||
ltl phi1 {
|
|
||||||
always ( leftClosed implies !rightEstablished )
|
|
||||||
}
|
|
||||||
@@ -1,143 +0,0 @@
|
|||||||
mtype = { SYN, FIN, ACK, ABORT, CLOSE, RST, OPEN }
|
|
||||||
|
|
||||||
chan AtoB = [2] of { mtype };
|
|
||||||
chan BtoA = [2] of { mtype };
|
|
||||||
|
|
||||||
int state[2];
|
|
||||||
int pids[2];
|
|
||||||
|
|
||||||
#define ClosedState 0
|
|
||||||
#define ListenState 1
|
|
||||||
#define SynSentState 2
|
|
||||||
#define SynRecState 3
|
|
||||||
#define EstState 4
|
|
||||||
#define FinW1State 5
|
|
||||||
#define CloseWaitState 6
|
|
||||||
#define FinW2State 7
|
|
||||||
#define ClosingState 8
|
|
||||||
#define LastAckState 9
|
|
||||||
#define TimeWaitState 10
|
|
||||||
#define EndState -1
|
|
||||||
|
|
||||||
#define leftConnecting (state[0] == ListenState && state[1] == SynSentState)
|
|
||||||
#define leftEstablished (state[0] == EstState)
|
|
||||||
#define rightEstablished (state[1] == EstState)
|
|
||||||
#define leftClosed (state[0] == ClosedState)
|
|
||||||
|
|
||||||
proctype TCP(chan snd, rcv; int i) {
|
|
||||||
pids[i] = _pid;
|
|
||||||
CLOSED:
|
|
||||||
state[i] = ClosedState;
|
|
||||||
do
|
|
||||||
/* Passive open */
|
|
||||||
:: goto LISTEN;
|
|
||||||
/* Active open */
|
|
||||||
:: snd ! SYN; goto SYN_SENT;
|
|
||||||
/* Terminate */
|
|
||||||
:: goto end;
|
|
||||||
od
|
|
||||||
LISTEN:
|
|
||||||
state[i] = ListenState;
|
|
||||||
do
|
|
||||||
:: rcv ? SYN ->
|
|
||||||
atomic {
|
|
||||||
snd ! SYN;
|
|
||||||
snd ! ACK;
|
|
||||||
goto SYN_RECEIVED;
|
|
||||||
}
|
|
||||||
/* Simultaneous LISTEN */
|
|
||||||
:: rcv ? _ -> skip;
|
|
||||||
:: timeout -> goto CLOSED;
|
|
||||||
od
|
|
||||||
SYN_SENT:
|
|
||||||
state[i] = SynSentState;
|
|
||||||
do
|
|
||||||
:: rcv ? SYN;
|
|
||||||
if
|
|
||||||
/* Standard behavior */
|
|
||||||
:: rcv ? ACK -> snd ! ACK; goto ESTABLISHED;
|
|
||||||
/* Simultaneous open */
|
|
||||||
:: snd ! ACK; goto SYN_RECEIVED;
|
|
||||||
fi
|
|
||||||
:: rcv ? ACK;
|
|
||||||
do
|
|
||||||
:: rcv ? SYN ->
|
|
||||||
snd ! ACK;
|
|
||||||
goto ESTABLISHED;
|
|
||||||
:: rcv ? _ -> skip;
|
|
||||||
od
|
|
||||||
:: rcv ? _ -> skip;
|
|
||||||
:: timeout -> goto CLOSED; /* Timeout */
|
|
||||||
od
|
|
||||||
SYN_RECEIVED:
|
|
||||||
state[i] = SynRecState;
|
|
||||||
do
|
|
||||||
:: rcv ? ACK -> goto ESTABLISHED;
|
|
||||||
:: rcv ? _ -> skip;
|
|
||||||
od
|
|
||||||
ESTABLISHED:
|
|
||||||
state[i] = EstState;
|
|
||||||
do
|
|
||||||
/* Close - initiator sequence */
|
|
||||||
:: snd ! FIN; goto FIN_WAIT_1;
|
|
||||||
/* Close - responder sequence */
|
|
||||||
:: rcv ? FIN ->
|
|
||||||
snd ! ACK;
|
|
||||||
goto CLOSE_WAIT;
|
|
||||||
:: rcv ? _ -> skip;
|
|
||||||
od
|
|
||||||
FIN_WAIT_1:
|
|
||||||
state[i] = FinW1State;
|
|
||||||
do
|
|
||||||
/* Simultaneous close */
|
|
||||||
:: rcv ? FIN ->
|
|
||||||
snd ! ACK;
|
|
||||||
goto CLOSING;
|
|
||||||
/* Standard close */
|
|
||||||
:: rcv ? ACK -> goto FIN_WAIT_2;
|
|
||||||
:: rcv ? _ -> skip;
|
|
||||||
od
|
|
||||||
CLOSE_WAIT:
|
|
||||||
state[i] = CloseWaitState;
|
|
||||||
do
|
|
||||||
:: snd ! FIN; goto LAST_ACK;
|
|
||||||
:: rcv ? _ -> skip;
|
|
||||||
od
|
|
||||||
FIN_WAIT_2:
|
|
||||||
state[i] = FinW2State;
|
|
||||||
do
|
|
||||||
:: rcv ? FIN ->
|
|
||||||
snd ! ACK;
|
|
||||||
goto TIME_WAIT;
|
|
||||||
:: rcv ? _ -> skip;
|
|
||||||
od
|
|
||||||
CLOSING:
|
|
||||||
state[i] = ClosingState;
|
|
||||||
do
|
|
||||||
:: rcv ? ACK -> goto TIME_WAIT;
|
|
||||||
:: rcv ? _ -> skip;
|
|
||||||
od
|
|
||||||
LAST_ACK:
|
|
||||||
state[i] = LastAckState;
|
|
||||||
do
|
|
||||||
:: rcv ? ACK -> goto CLOSED;
|
|
||||||
:: rcv ? _ -> skip;
|
|
||||||
od
|
|
||||||
TIME_WAIT:
|
|
||||||
state[i] = TimeWaitState;
|
|
||||||
goto CLOSED;
|
|
||||||
end:
|
|
||||||
state[i] = EndState;
|
|
||||||
}
|
|
||||||
|
|
||||||
init {
|
|
||||||
state[0] = ClosedState;
|
|
||||||
state[1] = ClosedState;
|
|
||||||
run TCP(AtoB, BtoA, 0);
|
|
||||||
run TCP(BtoA, AtoB, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* liveness: verifying connection establishment */
|
|
||||||
ltl phi2 {
|
|
||||||
( (always ( eventually ( state[0] == 1 && state[1] == 2 ) ) )
|
|
||||||
implies ( eventually ( state[0] == 4 ) ) )
|
|
||||||
@@ -1,43 +0,0 @@
|
|||||||
-2:2:-2
|
|
||||||
-4:-4:-4
|
|
||||||
1:0:121
|
|
||||||
2:1:114
|
|
||||||
3:0:121
|
|
||||||
4:1:115
|
|
||||||
5:0:121
|
|
||||||
6:1:116
|
|
||||||
7:0:121
|
|
||||||
8:1:117
|
|
||||||
9:0:121
|
|
||||||
10:3:0
|
|
||||||
11:0:121
|
|
||||||
12:3:1
|
|
||||||
13:0:121
|
|
||||||
14:3:2
|
|
||||||
15:0:121
|
|
||||||
16:3:9
|
|
||||||
17:0:121
|
|
||||||
18:2:0
|
|
||||||
19:0:121
|
|
||||||
20:2:1
|
|
||||||
21:0:121
|
|
||||||
22:2:2
|
|
||||||
23:0:121
|
|
||||||
24:2:9
|
|
||||||
25:0:121
|
|
||||||
26:3:17
|
|
||||||
27:0:121
|
|
||||||
28:3:1
|
|
||||||
-1:-1:-1
|
|
||||||
29:0:121
|
|
||||||
30:3:3
|
|
||||||
31:0:121
|
|
||||||
32:3:22
|
|
||||||
33:0:119
|
|
||||||
34:2:15
|
|
||||||
35:0:126
|
|
||||||
36:2:16
|
|
||||||
37:0:119
|
|
||||||
38:3:42
|
|
||||||
39:0:126
|
|
||||||
40:3:1
|
|
||||||
@@ -1,161 +0,0 @@
|
|||||||
mtype = { SYN, FIN, ACK, ABORT, CLOSE, RST, OPEN }
|
|
||||||
|
|
||||||
chan AtoB = [2] of { mtype };
|
|
||||||
chan BtoA = [2] of { mtype };
|
|
||||||
|
|
||||||
int state[2];
|
|
||||||
int pids[2];
|
|
||||||
|
|
||||||
#define ClosedState 0
|
|
||||||
#define ListenState 1
|
|
||||||
#define SynSentState 2
|
|
||||||
#define SynRecState 3
|
|
||||||
#define EstState 4
|
|
||||||
#define FinW1State 5
|
|
||||||
#define CloseWaitState 6
|
|
||||||
#define FinW2State 7
|
|
||||||
#define ClosingState 8
|
|
||||||
#define LastAckState 9
|
|
||||||
#define TimeWaitState 10
|
|
||||||
#define EndState -1
|
|
||||||
|
|
||||||
#define leftConnecting (state[0] == ListenState && state[1] == SynSentState)
|
|
||||||
#define leftEstablished (state[0] == EstState)
|
|
||||||
#define rightEstablished (state[1] == EstState)
|
|
||||||
#define leftClosed (state[0] == ClosedState)
|
|
||||||
|
|
||||||
proctype TCP(chan snd, rcv; int i) {
|
|
||||||
pids[i] = _pid;
|
|
||||||
CLOSED:
|
|
||||||
state[i] = ClosedState;
|
|
||||||
do
|
|
||||||
/* Passive open */
|
|
||||||
:: goto LISTEN;
|
|
||||||
/* Active open */
|
|
||||||
:: snd ! SYN; goto SYN_SENT;
|
|
||||||
/* Terminate */
|
|
||||||
:: goto end;
|
|
||||||
od
|
|
||||||
LISTEN:
|
|
||||||
state[i] = ListenState;
|
|
||||||
do
|
|
||||||
:: rcv ? SYN ->
|
|
||||||
atomic {
|
|
||||||
snd ! SYN;
|
|
||||||
snd ! ACK;
|
|
||||||
goto SYN_RECEIVED;
|
|
||||||
}
|
|
||||||
/* Simultaneous LISTEN */
|
|
||||||
:: rcv ? _ -> skip;
|
|
||||||
:: timeout -> goto CLOSED;
|
|
||||||
od
|
|
||||||
SYN_SENT:
|
|
||||||
state[i] = SynSentState;
|
|
||||||
do
|
|
||||||
:: rcv ? SYN;
|
|
||||||
if
|
|
||||||
/* Standard behavior */
|
|
||||||
:: rcv ? ACK -> snd ! ACK; goto ESTABLISHED;
|
|
||||||
/* Simultaneous open */
|
|
||||||
:: snd ! ACK; goto SYN_RECEIVED;
|
|
||||||
fi
|
|
||||||
:: rcv ? ACK;
|
|
||||||
do
|
|
||||||
:: rcv ? SYN ->
|
|
||||||
snd ! ACK;
|
|
||||||
goto ESTABLISHED;
|
|
||||||
:: rcv ? _ -> skip;
|
|
||||||
od
|
|
||||||
:: rcv ? _ -> skip;
|
|
||||||
:: timeout -> goto CLOSED; /* Timeout */
|
|
||||||
od
|
|
||||||
SYN_RECEIVED:
|
|
||||||
state[i] = SynRecState;
|
|
||||||
do
|
|
||||||
:: rcv ? ACK -> goto ESTABLISHED;
|
|
||||||
:: rcv ? _ -> skip;
|
|
||||||
od
|
|
||||||
ESTABLISHED:
|
|
||||||
state[i] = EstState;
|
|
||||||
do
|
|
||||||
/* Close - initiator sequence */
|
|
||||||
:: snd ! FIN; goto FIN_WAIT_1;
|
|
||||||
/* Close - responder sequence */
|
|
||||||
:: rcv ? FIN ->
|
|
||||||
snd ! ACK;
|
|
||||||
goto CLOSE_WAIT;
|
|
||||||
:: rcv ? _ -> skip;
|
|
||||||
od
|
|
||||||
FIN_WAIT_1:
|
|
||||||
state[i] = FinW1State;
|
|
||||||
do
|
|
||||||
/* Simultaneous close */
|
|
||||||
:: rcv ? FIN ->
|
|
||||||
snd ! ACK;
|
|
||||||
goto CLOSING;
|
|
||||||
/* Standard close */
|
|
||||||
:: rcv ? ACK -> goto FIN_WAIT_2;
|
|
||||||
:: rcv ? _ -> skip;
|
|
||||||
od
|
|
||||||
CLOSE_WAIT:
|
|
||||||
state[i] = CloseWaitState;
|
|
||||||
do
|
|
||||||
:: snd ! FIN; goto LAST_ACK;
|
|
||||||
:: rcv ? _ -> skip;
|
|
||||||
od
|
|
||||||
FIN_WAIT_2:
|
|
||||||
state[i] = FinW2State;
|
|
||||||
do
|
|
||||||
:: rcv ? FIN ->
|
|
||||||
snd ! ACK;
|
|
||||||
goto TIME_WAIT;
|
|
||||||
:: rcv ? _ -> skip;
|
|
||||||
od
|
|
||||||
CLOSING:
|
|
||||||
state[i] = ClosingState;
|
|
||||||
do
|
|
||||||
:: rcv ? ACK -> goto TIME_WAIT;
|
|
||||||
:: rcv ? _ -> skip;
|
|
||||||
od
|
|
||||||
LAST_ACK:
|
|
||||||
state[i] = LastAckState;
|
|
||||||
do
|
|
||||||
:: rcv ? ACK -> goto CLOSED;
|
|
||||||
:: rcv ? _ -> skip;
|
|
||||||
od
|
|
||||||
TIME_WAIT:
|
|
||||||
state[i] = TimeWaitState;
|
|
||||||
goto CLOSED;
|
|
||||||
end:
|
|
||||||
state[i] = EndState;
|
|
||||||
}
|
|
||||||
|
|
||||||
init {
|
|
||||||
state[0] = ClosedState;
|
|
||||||
state[1] = ClosedState;
|
|
||||||
run TCP(AtoB, BtoA, 0);
|
|
||||||
run TCP(BtoA, AtoB, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* liveness: no infinite stalls/deadlocks */
|
|
||||||
ltl phi3 {
|
|
||||||
!(eventually (((always (state[0] == SynSentState)) ||
|
|
||||||
(always (state[0] == SynRecState)) ||
|
|
||||||
(always (state[0] == EstState)) ||
|
|
||||||
(always (state[0] == FinW1State)) ||
|
|
||||||
(always (state[0] == CloseWaitState)) ||
|
|
||||||
(always (state[0] == FinW2State)) ||
|
|
||||||
(always (state[0] == ClosingState)) ||
|
|
||||||
(always (state[0] == LastAckState)) ||
|
|
||||||
(always (state[0] == TimeWaitState)))
|
|
||||||
&&
|
|
||||||
((always (state[1] == SynSentState)) ||
|
|
||||||
(always (state[1] == SynRecState)) ||
|
|
||||||
(always (state[1] == EstState)) ||
|
|
||||||
(always (state[1] == FinW1State)) ||
|
|
||||||
(always (state[1] == CloseWaitState)) ||
|
|
||||||
(always (state[1] == FinW2State)) ||
|
|
||||||
(always (state[1] == ClosingState)) ||
|
|
||||||
(always (state[1] == LastAckState)) ||
|
|
||||||
(always (state[1] == TimeWaitState)))))
|
|
||||||
}
|
|
||||||
@@ -1,62 +0,0 @@
|
|||||||
-2:3:-2
|
|
||||||
-4:-4:-4
|
|
||||||
1:0:289
|
|
||||||
2:2:122
|
|
||||||
3:0:289
|
|
||||||
4:2:123
|
|
||||||
5:0:289
|
|
||||||
6:2:124
|
|
||||||
7:0:289
|
|
||||||
8:2:125
|
|
||||||
9:0:289
|
|
||||||
10:4:0
|
|
||||||
11:0:289
|
|
||||||
12:4:1
|
|
||||||
13:0:289
|
|
||||||
14:4:2
|
|
||||||
15:0:289
|
|
||||||
16:4:9
|
|
||||||
17:0:289
|
|
||||||
18:3:0
|
|
||||||
19:0:289
|
|
||||||
20:3:1
|
|
||||||
21:0:289
|
|
||||||
22:3:2
|
|
||||||
23:0:289
|
|
||||||
24:3:9
|
|
||||||
25:0:289
|
|
||||||
26:4:17
|
|
||||||
27:0:289
|
|
||||||
28:4:1
|
|
||||||
29:0:289
|
|
||||||
30:4:3
|
|
||||||
31:0:289
|
|
||||||
32:4:22
|
|
||||||
33:0:289
|
|
||||||
34:1:116
|
|
||||||
35:0:289
|
|
||||||
36:1:117
|
|
||||||
37:0:289
|
|
||||||
38:3:10
|
|
||||||
39:0:289
|
|
||||||
40:3:11
|
|
||||||
41:3:12
|
|
||||||
42:0:289
|
|
||||||
43:3:47
|
|
||||||
44:0:249
|
|
||||||
45:1:114
|
|
||||||
46:0:599
|
|
||||||
47:1:115
|
|
||||||
48:0:599
|
|
||||||
49:4:40
|
|
||||||
50:0:599
|
|
||||||
51:4:41
|
|
||||||
52:0:599
|
|
||||||
53:1:114
|
|
||||||
54:0:599
|
|
||||||
55:1:115
|
|
||||||
56:0:599
|
|
||||||
57:4:31
|
|
||||||
-1:-1:-1
|
|
||||||
58:0:599
|
|
||||||
59:0:599
|
|
||||||
@@ -1,150 +0,0 @@
|
|||||||
mtype = { SYN, FIN, ACK, ABORT, CLOSE, RST, OPEN }
|
|
||||||
|
|
||||||
chan AtoB = [2] of { mtype };
|
|
||||||
chan BtoA = [2] of { mtype };
|
|
||||||
|
|
||||||
int state[2];
|
|
||||||
int pids[2];
|
|
||||||
|
|
||||||
#define ClosedState 0
|
|
||||||
#define ListenState 1
|
|
||||||
#define SynSentState 2
|
|
||||||
#define SynRecState 3
|
|
||||||
#define EstState 4
|
|
||||||
#define FinW1State 5
|
|
||||||
#define CloseWaitState 6
|
|
||||||
#define FinW2State 7
|
|
||||||
#define ClosingState 8
|
|
||||||
#define LastAckState 9
|
|
||||||
#define TimeWaitState 10
|
|
||||||
#define EndState -1
|
|
||||||
|
|
||||||
#define leftConnecting (state[0] == ListenState && state[1] == SynSentState)
|
|
||||||
#define leftEstablished (state[0] == EstState)
|
|
||||||
#define rightEstablished (state[1] == EstState)
|
|
||||||
#define leftClosed (state[0] == ClosedState)
|
|
||||||
|
|
||||||
proctype TCP(chan snd, rcv; int i) {
|
|
||||||
pids[i] = _pid;
|
|
||||||
CLOSED:
|
|
||||||
state[i] = ClosedState;
|
|
||||||
do
|
|
||||||
/* Passive open */
|
|
||||||
:: goto LISTEN;
|
|
||||||
/* Active open */
|
|
||||||
:: snd ! SYN; goto SYN_SENT;
|
|
||||||
/* Terminate */
|
|
||||||
:: goto end;
|
|
||||||
od
|
|
||||||
LISTEN:
|
|
||||||
state[i] = ListenState;
|
|
||||||
do
|
|
||||||
:: rcv ? SYN ->
|
|
||||||
atomic {
|
|
||||||
snd ! SYN;
|
|
||||||
snd ! ACK;
|
|
||||||
goto SYN_RECEIVED;
|
|
||||||
}
|
|
||||||
/* Simultaneous LISTEN */
|
|
||||||
:: rcv ? _ -> skip;
|
|
||||||
:: timeout -> goto CLOSED;
|
|
||||||
od
|
|
||||||
SYN_SENT:
|
|
||||||
state[i] = SynSentState;
|
|
||||||
do
|
|
||||||
:: rcv ? SYN;
|
|
||||||
if
|
|
||||||
/* Standard behavior */
|
|
||||||
:: rcv ? ACK -> snd ! ACK; goto ESTABLISHED;
|
|
||||||
/* Simultaneous open */
|
|
||||||
:: snd ! ACK; goto SYN_RECEIVED;
|
|
||||||
fi
|
|
||||||
:: rcv ? ACK;
|
|
||||||
do
|
|
||||||
:: rcv ? SYN ->
|
|
||||||
snd ! ACK;
|
|
||||||
goto ESTABLISHED;
|
|
||||||
:: rcv ? _ -> skip;
|
|
||||||
od
|
|
||||||
:: rcv ? _ -> skip;
|
|
||||||
:: timeout -> goto CLOSED; /* Timeout */
|
|
||||||
od
|
|
||||||
SYN_RECEIVED:
|
|
||||||
state[i] = SynRecState;
|
|
||||||
do
|
|
||||||
:: rcv ? ACK -> goto ESTABLISHED;
|
|
||||||
:: rcv ? _ -> skip;
|
|
||||||
od
|
|
||||||
ESTABLISHED:
|
|
||||||
state[i] = EstState;
|
|
||||||
do
|
|
||||||
/* Close - initiator sequence */
|
|
||||||
:: snd ! FIN; goto FIN_WAIT_1;
|
|
||||||
/* Close - responder sequence */
|
|
||||||
:: rcv ? FIN ->
|
|
||||||
snd ! ACK;
|
|
||||||
goto CLOSE_WAIT;
|
|
||||||
:: rcv ? _ -> skip;
|
|
||||||
od
|
|
||||||
FIN_WAIT_1:
|
|
||||||
state[i] = FinW1State;
|
|
||||||
do
|
|
||||||
/* Simultaneous close */
|
|
||||||
:: rcv ? FIN ->
|
|
||||||
snd ! ACK;
|
|
||||||
goto CLOSING;
|
|
||||||
/* Standard close */
|
|
||||||
:: rcv ? ACK -> goto FIN_WAIT_2;
|
|
||||||
:: rcv ? _ -> skip;
|
|
||||||
od
|
|
||||||
CLOSE_WAIT:
|
|
||||||
state[i] = CloseWaitState;
|
|
||||||
do
|
|
||||||
:: snd ! FIN; goto LAST_ACK;
|
|
||||||
:: rcv ? _ -> skip;
|
|
||||||
od
|
|
||||||
FIN_WAIT_2:
|
|
||||||
state[i] = FinW2State;
|
|
||||||
do
|
|
||||||
:: rcv ? FIN ->
|
|
||||||
snd ! ACK;
|
|
||||||
goto TIME_WAIT;
|
|
||||||
:: rcv ? _ -> skip;
|
|
||||||
od
|
|
||||||
CLOSING:
|
|
||||||
state[i] = ClosingState;
|
|
||||||
do
|
|
||||||
:: rcv ? ACK -> goto TIME_WAIT;
|
|
||||||
:: rcv ? _ -> skip;
|
|
||||||
od
|
|
||||||
LAST_ACK:
|
|
||||||
state[i] = LastAckState;
|
|
||||||
do
|
|
||||||
:: rcv ? ACK -> goto CLOSED;
|
|
||||||
:: rcv ? _ -> skip;
|
|
||||||
od
|
|
||||||
TIME_WAIT:
|
|
||||||
state[i] = TimeWaitState;
|
|
||||||
goto CLOSED;
|
|
||||||
end:
|
|
||||||
state[i] = EndState;
|
|
||||||
}
|
|
||||||
|
|
||||||
init {
|
|
||||||
state[0] = ClosedState;
|
|
||||||
state[1] = ClosedState;
|
|
||||||
run TCP(AtoB, BtoA, 0);
|
|
||||||
run TCP(BtoA, AtoB, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* liveness: simultanous open */
|
|
||||||
ltl phi4 {
|
|
||||||
always (
|
|
||||||
(state[0] == SynSentState &&
|
|
||||||
state[1] == SynSentState)
|
|
||||||
|
|
||||||
implies
|
|
||||||
|
|
||||||
((eventually state[0] == EstState) &&
|
|
||||||
(eventually state[1] == EstState)))
|
|
||||||
}
|
|
||||||
@@ -1,157 +0,0 @@
|
|||||||
-2:2:-2
|
|
||||||
-4:-4:-4
|
|
||||||
1:0:122
|
|
||||||
2:1:114
|
|
||||||
3:0:122
|
|
||||||
4:1:115
|
|
||||||
5:0:122
|
|
||||||
6:1:116
|
|
||||||
7:0:122
|
|
||||||
8:1:117
|
|
||||||
9:0:122
|
|
||||||
10:3:0
|
|
||||||
11:0:122
|
|
||||||
12:3:1
|
|
||||||
13:0:122
|
|
||||||
14:3:2
|
|
||||||
15:0:122
|
|
||||||
16:3:9
|
|
||||||
17:0:122
|
|
||||||
18:2:0
|
|
||||||
19:0:122
|
|
||||||
20:2:1
|
|
||||||
21:0:122
|
|
||||||
22:2:2
|
|
||||||
23:0:122
|
|
||||||
24:2:9
|
|
||||||
25:0:122
|
|
||||||
26:3:17
|
|
||||||
27:0:122
|
|
||||||
28:3:1
|
|
||||||
29:0:122
|
|
||||||
30:3:3
|
|
||||||
31:0:122
|
|
||||||
32:3:22
|
|
||||||
33:0:122
|
|
||||||
34:2:10
|
|
||||||
35:0:122
|
|
||||||
36:2:11
|
|
||||||
37:2:12
|
|
||||||
38:0:122
|
|
||||||
39:3:23
|
|
||||||
40:0:122
|
|
||||||
41:3:24
|
|
||||||
42:0:122
|
|
||||||
43:3:25
|
|
||||||
44:0:122
|
|
||||||
45:3:55
|
|
||||||
46:0:122
|
|
||||||
47:3:56
|
|
||||||
48:0:122
|
|
||||||
49:3:66
|
|
||||||
50:0:122
|
|
||||||
51:2:47
|
|
||||||
52:0:122
|
|
||||||
53:2:48
|
|
||||||
54:0:122
|
|
||||||
55:2:55
|
|
||||||
56:0:122
|
|
||||||
57:2:56
|
|
||||||
58:0:122
|
|
||||||
59:3:67
|
|
||||||
60:0:122
|
|
||||||
61:3:68
|
|
||||||
62:0:122
|
|
||||||
63:3:94
|
|
||||||
64:0:122
|
|
||||||
65:2:66
|
|
||||||
66:0:122
|
|
||||||
67:2:67
|
|
||||||
68:0:122
|
|
||||||
69:2:68
|
|
||||||
70:0:122
|
|
||||||
71:3:95
|
|
||||||
72:0:122
|
|
||||||
73:3:110
|
|
||||||
74:0:122
|
|
||||||
75:3:1
|
|
||||||
76:0:122
|
|
||||||
77:3:2
|
|
||||||
78:0:122
|
|
||||||
79:2:94
|
|
||||||
80:0:122
|
|
||||||
81:2:95
|
|
||||||
82:0:122
|
|
||||||
83:2:110
|
|
||||||
84:0:122
|
|
||||||
85:2:1
|
|
||||||
86:0:122
|
|
||||||
87:2:3
|
|
||||||
88:0:122
|
|
||||||
89:3:9
|
|
||||||
90:0:122
|
|
||||||
91:3:10
|
|
||||||
92:0:122
|
|
||||||
93:3:11
|
|
||||||
94:3:12
|
|
||||||
95:0:122
|
|
||||||
96:3:47
|
|
||||||
97:0:122
|
|
||||||
98:2:22
|
|
||||||
99:0:122
|
|
||||||
100:2:23
|
|
||||||
101:0:122
|
|
||||||
102:2:24
|
|
||||||
103:0:122
|
|
||||||
104:2:25
|
|
||||||
105:0:122
|
|
||||||
106:3:48
|
|
||||||
107:0:122
|
|
||||||
108:3:55
|
|
||||||
109:0:122
|
|
||||||
110:3:56
|
|
||||||
111:0:122
|
|
||||||
112:2:55
|
|
||||||
113:0:122
|
|
||||||
114:2:56
|
|
||||||
115:0:122
|
|
||||||
116:2:66
|
|
||||||
117:0:122
|
|
||||||
118:3:66
|
|
||||||
119:0:122
|
|
||||||
120:3:67
|
|
||||||
121:0:122
|
|
||||||
122:3:68
|
|
||||||
123:0:122
|
|
||||||
124:2:67
|
|
||||||
125:0:122
|
|
||||||
126:2:68
|
|
||||||
127:0:122
|
|
||||||
128:2:94
|
|
||||||
129:0:122
|
|
||||||
130:3:94
|
|
||||||
131:0:122
|
|
||||||
132:3:95
|
|
||||||
133:0:122
|
|
||||||
134:3:110
|
|
||||||
135:0:122
|
|
||||||
136:3:1
|
|
||||||
137:0:122
|
|
||||||
138:3:3
|
|
||||||
139:0:122
|
|
||||||
140:3:22
|
|
||||||
141:0:122
|
|
||||||
142:2:95
|
|
||||||
143:0:122
|
|
||||||
144:2:110
|
|
||||||
145:0:122
|
|
||||||
146:2:1
|
|
||||||
147:0:122
|
|
||||||
148:2:3
|
|
||||||
149:0:122
|
|
||||||
150:3:23
|
|
||||||
151:0:122
|
|
||||||
152:3:27
|
|
||||||
153:0:122
|
|
||||||
154:2:22
|
|
||||||
155:0:119
|
|
||||||
@@ -1,152 +0,0 @@
|
|||||||
mtype = { SYN, FIN, ACK, ABORT, CLOSE, RST, OPEN }
|
|
||||||
|
|
||||||
chan AtoB = [2] of { mtype };
|
|
||||||
chan BtoA = [2] of { mtype };
|
|
||||||
|
|
||||||
int state[2];
|
|
||||||
int pids[2];
|
|
||||||
|
|
||||||
#define ClosedState 0
|
|
||||||
#define ListenState 1
|
|
||||||
#define SynSentState 2
|
|
||||||
#define SynRecState 3
|
|
||||||
#define EstState 4
|
|
||||||
#define FinW1State 5
|
|
||||||
#define CloseWaitState 6
|
|
||||||
#define FinW2State 7
|
|
||||||
#define ClosingState 8
|
|
||||||
#define LastAckState 9
|
|
||||||
#define TimeWaitState 10
|
|
||||||
#define EndState -1
|
|
||||||
|
|
||||||
#define leftConnecting (state[0] == ListenState && state[1] == SynSentState)
|
|
||||||
#define leftEstablished (state[0] == EstState)
|
|
||||||
#define rightEstablished (state[1] == EstState)
|
|
||||||
#define leftClosed (state[0] == ClosedState)
|
|
||||||
|
|
||||||
proctype TCP(chan snd, rcv; int i) {
|
|
||||||
pids[i] = _pid;
|
|
||||||
CLOSED:
|
|
||||||
state[i] = ClosedState;
|
|
||||||
do
|
|
||||||
/* Passive open */
|
|
||||||
:: goto LISTEN;
|
|
||||||
/* Active open */
|
|
||||||
:: snd ! SYN; goto SYN_SENT;
|
|
||||||
/* Terminate */
|
|
||||||
:: goto end;
|
|
||||||
od
|
|
||||||
LISTEN:
|
|
||||||
state[i] = ListenState;
|
|
||||||
do
|
|
||||||
:: rcv ? SYN ->
|
|
||||||
atomic {
|
|
||||||
snd ! SYN;
|
|
||||||
snd ! ACK;
|
|
||||||
goto SYN_RECEIVED;
|
|
||||||
}
|
|
||||||
/* Simultaneous LISTEN */
|
|
||||||
:: rcv ? _ -> skip;
|
|
||||||
:: timeout -> goto CLOSED;
|
|
||||||
od
|
|
||||||
SYN_SENT:
|
|
||||||
state[i] = SynSentState;
|
|
||||||
do
|
|
||||||
:: rcv ? SYN;
|
|
||||||
if
|
|
||||||
/* Standard behavior */
|
|
||||||
:: rcv ? ACK -> snd ! ACK; goto ESTABLISHED;
|
|
||||||
/* Simultaneous open */
|
|
||||||
:: snd ! ACK; goto SYN_RECEIVED;
|
|
||||||
fi
|
|
||||||
:: rcv ? ACK;
|
|
||||||
do
|
|
||||||
:: rcv ? SYN ->
|
|
||||||
snd ! ACK;
|
|
||||||
goto ESTABLISHED;
|
|
||||||
:: rcv ? _ -> skip;
|
|
||||||
od
|
|
||||||
:: rcv ? _ -> skip;
|
|
||||||
:: timeout -> goto CLOSED; /* Timeout */
|
|
||||||
od
|
|
||||||
SYN_RECEIVED:
|
|
||||||
state[i] = SynRecState;
|
|
||||||
do
|
|
||||||
:: rcv ? ACK -> goto ESTABLISHED;
|
|
||||||
:: rcv ? _ -> skip;
|
|
||||||
od
|
|
||||||
ESTABLISHED:
|
|
||||||
state[i] = EstState;
|
|
||||||
do
|
|
||||||
/* Close - initiator sequence */
|
|
||||||
:: snd ! FIN; goto FIN_WAIT_1;
|
|
||||||
/* Close - responder sequence */
|
|
||||||
:: rcv ? FIN ->
|
|
||||||
snd ! ACK;
|
|
||||||
goto CLOSE_WAIT;
|
|
||||||
:: rcv ? _ -> skip;
|
|
||||||
od
|
|
||||||
FIN_WAIT_1:
|
|
||||||
state[i] = FinW1State;
|
|
||||||
do
|
|
||||||
/* Simultaneous close */
|
|
||||||
:: rcv ? FIN ->
|
|
||||||
snd ! ACK;
|
|
||||||
goto CLOSING;
|
|
||||||
/* Standard close */
|
|
||||||
:: rcv ? ACK -> goto FIN_WAIT_2;
|
|
||||||
:: rcv ? _ -> skip;
|
|
||||||
od
|
|
||||||
CLOSE_WAIT:
|
|
||||||
state[i] = CloseWaitState;
|
|
||||||
do
|
|
||||||
:: snd ! FIN; goto LAST_ACK;
|
|
||||||
:: rcv ? _ -> skip;
|
|
||||||
od
|
|
||||||
FIN_WAIT_2:
|
|
||||||
state[i] = FinW2State;
|
|
||||||
do
|
|
||||||
:: rcv ? FIN ->
|
|
||||||
snd ! ACK;
|
|
||||||
goto TIME_WAIT;
|
|
||||||
:: rcv ? _ -> skip;
|
|
||||||
od
|
|
||||||
CLOSING:
|
|
||||||
state[i] = ClosingState;
|
|
||||||
do
|
|
||||||
:: rcv ? ACK -> goto TIME_WAIT;
|
|
||||||
:: rcv ? _ -> skip;
|
|
||||||
od
|
|
||||||
LAST_ACK:
|
|
||||||
state[i] = LastAckState;
|
|
||||||
do
|
|
||||||
:: rcv ? ACK -> goto CLOSED;
|
|
||||||
:: rcv ? _ -> skip;
|
|
||||||
od
|
|
||||||
TIME_WAIT:
|
|
||||||
state[i] = TimeWaitState;
|
|
||||||
goto CLOSED;
|
|
||||||
end:
|
|
||||||
state[i] = EndState;
|
|
||||||
}
|
|
||||||
|
|
||||||
init {
|
|
||||||
state[0] = ClosedState;
|
|
||||||
state[1] = ClosedState;
|
|
||||||
run TCP(AtoB, BtoA, 0);
|
|
||||||
run TCP(BtoA, AtoB, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* liveness: SYN_RECEIVED resolution*/
|
|
||||||
ltl phi5 {
|
|
||||||
always (
|
|
||||||
(state[0] == SynRecState)
|
|
||||||
implies (
|
|
||||||
eventually (
|
|
||||||
(state[0] == EstState ||
|
|
||||||
state[0] == FinW1State ||
|
|
||||||
state[0] == ClosedState)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@@ -1,64 +0,0 @@
|
|||||||
-2:2:-2
|
|
||||||
-4:-4:-4
|
|
||||||
1:0:121
|
|
||||||
2:1:114
|
|
||||||
3:0:121
|
|
||||||
4:1:115
|
|
||||||
5:0:121
|
|
||||||
6:1:116
|
|
||||||
7:0:121
|
|
||||||
8:1:117
|
|
||||||
9:0:121
|
|
||||||
10:3:0
|
|
||||||
11:0:121
|
|
||||||
12:3:1
|
|
||||||
13:0:121
|
|
||||||
14:3:2
|
|
||||||
15:0:121
|
|
||||||
16:3:9
|
|
||||||
17:0:121
|
|
||||||
18:2:0
|
|
||||||
19:0:121
|
|
||||||
20:2:1
|
|
||||||
21:0:121
|
|
||||||
22:2:2
|
|
||||||
23:0:121
|
|
||||||
24:2:9
|
|
||||||
25:0:121
|
|
||||||
26:3:17
|
|
||||||
27:0:121
|
|
||||||
28:3:1
|
|
||||||
29:0:121
|
|
||||||
30:3:3
|
|
||||||
31:0:121
|
|
||||||
32:3:22
|
|
||||||
33:0:121
|
|
||||||
34:2:10
|
|
||||||
35:0:121
|
|
||||||
36:2:11
|
|
||||||
37:2:12
|
|
||||||
38:0:121
|
|
||||||
39:3:23
|
|
||||||
40:0:121
|
|
||||||
41:3:24
|
|
||||||
42:0:121
|
|
||||||
43:3:25
|
|
||||||
44:0:121
|
|
||||||
45:3:55
|
|
||||||
46:0:121
|
|
||||||
47:3:56
|
|
||||||
48:0:121
|
|
||||||
49:3:66
|
|
||||||
50:0:121
|
|
||||||
51:2:47
|
|
||||||
52:0:119
|
|
||||||
53:2:50
|
|
||||||
54:0:126
|
|
||||||
55:2:51
|
|
||||||
56:0:126
|
|
||||||
57:2:50
|
|
||||||
58:0:126
|
|
||||||
59:2:51
|
|
||||||
-1:-1:-1
|
|
||||||
60:0:126
|
|
||||||
61:0:126
|
|
||||||
@@ -1,148 +0,0 @@
|
|||||||
mtype = { SYN, FIN, ACK, ABORT, CLOSE, RST, OPEN }
|
|
||||||
|
|
||||||
chan AtoB = [2] of { mtype };
|
|
||||||
chan BtoA = [2] of { mtype };
|
|
||||||
|
|
||||||
int state[2];
|
|
||||||
int pids[2];
|
|
||||||
|
|
||||||
#define ClosedState 0
|
|
||||||
#define ListenState 1
|
|
||||||
#define SynSentState 2
|
|
||||||
#define SynRecState 3
|
|
||||||
#define EstState 4
|
|
||||||
#define FinW1State 5
|
|
||||||
#define CloseWaitState 6
|
|
||||||
#define FinW2State 7
|
|
||||||
#define ClosingState 8
|
|
||||||
#define LastAckState 9
|
|
||||||
#define TimeWaitState 10
|
|
||||||
#define EndState -1
|
|
||||||
|
|
||||||
#define leftConnecting (state[0] == ListenState && state[1] == SynSentState)
|
|
||||||
#define leftEstablished (state[0] == EstState)
|
|
||||||
#define rightEstablished (state[1] == EstState)
|
|
||||||
#define leftClosed (state[0] == ClosedState)
|
|
||||||
|
|
||||||
proctype TCP(chan snd, rcv; int i) {
|
|
||||||
pids[i] = _pid;
|
|
||||||
CLOSED:
|
|
||||||
state[i] = ClosedState;
|
|
||||||
do
|
|
||||||
/* Passive open */
|
|
||||||
:: goto LISTEN;
|
|
||||||
/* Active open */
|
|
||||||
:: snd ! SYN; goto SYN_SENT;
|
|
||||||
/* Terminate */
|
|
||||||
:: goto end;
|
|
||||||
od
|
|
||||||
LISTEN:
|
|
||||||
state[i] = ListenState;
|
|
||||||
do
|
|
||||||
:: rcv ? SYN ->
|
|
||||||
atomic {
|
|
||||||
snd ! SYN;
|
|
||||||
snd ! ACK;
|
|
||||||
goto SYN_RECEIVED;
|
|
||||||
}
|
|
||||||
/* Simultaneous LISTEN */
|
|
||||||
:: rcv ? _ -> skip;
|
|
||||||
:: timeout -> goto CLOSED;
|
|
||||||
od
|
|
||||||
SYN_SENT:
|
|
||||||
state[i] = SynSentState;
|
|
||||||
do
|
|
||||||
:: rcv ? SYN;
|
|
||||||
if
|
|
||||||
/* Standard behavior */
|
|
||||||
:: rcv ? ACK -> snd ! ACK; goto ESTABLISHED;
|
|
||||||
/* Simultaneous open */
|
|
||||||
:: snd ! ACK; goto SYN_RECEIVED;
|
|
||||||
fi
|
|
||||||
:: rcv ? ACK;
|
|
||||||
do
|
|
||||||
:: rcv ? SYN ->
|
|
||||||
snd ! ACK;
|
|
||||||
goto ESTABLISHED;
|
|
||||||
:: rcv ? _ -> skip;
|
|
||||||
od
|
|
||||||
:: rcv ? _ -> skip;
|
|
||||||
:: timeout -> goto CLOSED; /* Timeout */
|
|
||||||
od
|
|
||||||
SYN_RECEIVED:
|
|
||||||
state[i] = SynRecState;
|
|
||||||
do
|
|
||||||
:: rcv ? ACK -> goto ESTABLISHED;
|
|
||||||
:: rcv ? _ -> skip;
|
|
||||||
od
|
|
||||||
ESTABLISHED:
|
|
||||||
state[i] = EstState;
|
|
||||||
do
|
|
||||||
/* Close - initiator sequence */
|
|
||||||
:: snd ! FIN; goto FIN_WAIT_1;
|
|
||||||
/* Close - responder sequence */
|
|
||||||
:: rcv ? FIN ->
|
|
||||||
snd ! ACK;
|
|
||||||
goto CLOSE_WAIT;
|
|
||||||
:: rcv ? _ -> skip;
|
|
||||||
od
|
|
||||||
FIN_WAIT_1:
|
|
||||||
state[i] = FinW1State;
|
|
||||||
do
|
|
||||||
/* Simultaneous close */
|
|
||||||
:: rcv ? FIN ->
|
|
||||||
snd ! ACK;
|
|
||||||
goto CLOSING;
|
|
||||||
/* Standard close */
|
|
||||||
:: rcv ? ACK -> goto FIN_WAIT_2;
|
|
||||||
:: rcv ? _ -> skip;
|
|
||||||
od
|
|
||||||
CLOSE_WAIT:
|
|
||||||
state[i] = CloseWaitState;
|
|
||||||
do
|
|
||||||
:: snd ! FIN; goto LAST_ACK;
|
|
||||||
:: rcv ? _ -> skip;
|
|
||||||
od
|
|
||||||
FIN_WAIT_2:
|
|
||||||
state[i] = FinW2State;
|
|
||||||
do
|
|
||||||
:: rcv ? FIN ->
|
|
||||||
snd ! ACK;
|
|
||||||
goto TIME_WAIT;
|
|
||||||
:: rcv ? _ -> skip;
|
|
||||||
od
|
|
||||||
CLOSING:
|
|
||||||
state[i] = ClosingState;
|
|
||||||
do
|
|
||||||
:: rcv ? ACK -> goto TIME_WAIT;
|
|
||||||
:: rcv ? _ -> skip;
|
|
||||||
od
|
|
||||||
LAST_ACK:
|
|
||||||
state[i] = LastAckState;
|
|
||||||
do
|
|
||||||
:: rcv ? ACK -> goto CLOSED;
|
|
||||||
:: rcv ? _ -> skip;
|
|
||||||
od
|
|
||||||
TIME_WAIT:
|
|
||||||
state[i] = TimeWaitState;
|
|
||||||
goto CLOSED;
|
|
||||||
end:
|
|
||||||
state[i] = EndState;
|
|
||||||
}
|
|
||||||
|
|
||||||
init {
|
|
||||||
state[0] = ClosedState;
|
|
||||||
state[1] = ClosedState;
|
|
||||||
run TCP(AtoB, BtoA, 0);
|
|
||||||
run TCP(BtoA, AtoB, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* safety: strict closing transitions */
|
|
||||||
ltl phi6 {
|
|
||||||
always (
|
|
||||||
(state[0] == ClosingState)
|
|
||||||
implies
|
|
||||||
(next (state[0] == ClosingState ||
|
|
||||||
state[0] == ClosedState))
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@@ -1,88 +0,0 @@
|
|||||||
-2:2:-2
|
|
||||||
-4:-4:-4
|
|
||||||
1:0:121
|
|
||||||
2:1:114
|
|
||||||
3:0:121
|
|
||||||
4:1:115
|
|
||||||
5:0:121
|
|
||||||
6:1:116
|
|
||||||
7:0:121
|
|
||||||
8:1:117
|
|
||||||
9:0:121
|
|
||||||
10:3:0
|
|
||||||
11:0:121
|
|
||||||
12:3:1
|
|
||||||
13:0:121
|
|
||||||
14:3:2
|
|
||||||
15:0:121
|
|
||||||
16:3:9
|
|
||||||
17:0:121
|
|
||||||
18:2:0
|
|
||||||
19:0:121
|
|
||||||
20:2:1
|
|
||||||
21:0:121
|
|
||||||
22:2:2
|
|
||||||
23:0:121
|
|
||||||
24:2:9
|
|
||||||
25:0:121
|
|
||||||
26:3:17
|
|
||||||
27:0:121
|
|
||||||
28:3:1
|
|
||||||
29:0:121
|
|
||||||
30:3:3
|
|
||||||
31:0:121
|
|
||||||
32:3:22
|
|
||||||
33:0:121
|
|
||||||
34:2:10
|
|
||||||
35:0:121
|
|
||||||
36:2:11
|
|
||||||
37:2:12
|
|
||||||
38:0:121
|
|
||||||
39:3:23
|
|
||||||
40:0:121
|
|
||||||
41:3:24
|
|
||||||
42:0:121
|
|
||||||
43:3:25
|
|
||||||
44:0:121
|
|
||||||
45:3:55
|
|
||||||
46:0:121
|
|
||||||
47:3:56
|
|
||||||
48:0:121
|
|
||||||
49:3:66
|
|
||||||
50:0:121
|
|
||||||
51:2:47
|
|
||||||
52:0:121
|
|
||||||
53:2:48
|
|
||||||
54:0:121
|
|
||||||
55:2:55
|
|
||||||
56:0:121
|
|
||||||
57:2:56
|
|
||||||
58:0:121
|
|
||||||
59:3:67
|
|
||||||
60:0:121
|
|
||||||
61:3:68
|
|
||||||
62:0:121
|
|
||||||
63:3:94
|
|
||||||
64:0:121
|
|
||||||
65:2:66
|
|
||||||
66:0:121
|
|
||||||
67:2:67
|
|
||||||
68:0:121
|
|
||||||
69:2:68
|
|
||||||
70:0:121
|
|
||||||
71:3:95
|
|
||||||
72:0:121
|
|
||||||
73:3:110
|
|
||||||
74:0:121
|
|
||||||
75:3:1
|
|
||||||
76:0:121
|
|
||||||
77:3:2
|
|
||||||
78:0:121
|
|
||||||
79:3:9
|
|
||||||
80:0:121
|
|
||||||
81:2:94
|
|
||||||
82:0:121
|
|
||||||
83:2:95
|
|
||||||
84:0:119
|
|
||||||
85:2:110
|
|
||||||
86:0:126
|
|
||||||
@@ -1,138 +0,0 @@
|
|||||||
mtype = { SYN, FIN, ACK, ABORT, CLOSE, RST, OPEN }
|
|
||||||
|
|
||||||
chan AtoB = [2] of { mtype };
|
|
||||||
chan BtoA = [2] of { mtype };
|
|
||||||
|
|
||||||
int state[2];
|
|
||||||
int pids[2];
|
|
||||||
|
|
||||||
#define ClosedState 0
|
|
||||||
#define ListenState 1
|
|
||||||
#define SynSentState 2
|
|
||||||
#define SynRecState 3
|
|
||||||
#define EstState 4
|
|
||||||
#define FinW1State 5
|
|
||||||
#define CloseWaitState 6
|
|
||||||
#define FinW2State 7
|
|
||||||
#define ClosingState 8
|
|
||||||
#define LastAckState 9
|
|
||||||
#define TimeWaitState 10
|
|
||||||
#define EndState -1
|
|
||||||
|
|
||||||
#define leftConnecting (state[0] == ListenState && state[1] == SynSentState)
|
|
||||||
#define leftEstablished (state[0] == EstState)
|
|
||||||
#define rightEstablished (state[1] == EstState)
|
|
||||||
#define leftClosed (state[0] == ClosedState)
|
|
||||||
|
|
||||||
proctype TCP(chan snd, rcv; int i) {
|
|
||||||
pids[i] = _pid;
|
|
||||||
CLOSED:
|
|
||||||
state[i] = ClosedState;
|
|
||||||
do
|
|
||||||
/* Passive open */
|
|
||||||
:: goto LISTEN;
|
|
||||||
/* Active open */
|
|
||||||
:: snd ! SYN; goto SYN_SENT;
|
|
||||||
/* Terminate */
|
|
||||||
:: goto end;
|
|
||||||
od
|
|
||||||
LISTEN:
|
|
||||||
state[i] = ListenState;
|
|
||||||
do
|
|
||||||
:: rcv ? SYN ->
|
|
||||||
atomic {
|
|
||||||
snd ! SYN;
|
|
||||||
snd ! ACK;
|
|
||||||
goto SYN_RECEIVED;
|
|
||||||
}
|
|
||||||
/* Simultaneous LISTEN */
|
|
||||||
:: rcv ? _ -> skip;
|
|
||||||
:: timeout -> goto CLOSED;
|
|
||||||
od
|
|
||||||
SYN_SENT:
|
|
||||||
state[i] = SynSentState;
|
|
||||||
do
|
|
||||||
:: rcv ? SYN;
|
|
||||||
if
|
|
||||||
/* Standard behavior */
|
|
||||||
:: rcv ? ACK -> snd ! ACK; goto ESTABLISHED;
|
|
||||||
/* Simultaneous open */
|
|
||||||
:: snd ! ACK; goto SYN_RECEIVED;
|
|
||||||
fi
|
|
||||||
:: rcv ? ACK;
|
|
||||||
do
|
|
||||||
:: rcv ? SYN ->
|
|
||||||
snd ! ACK;
|
|
||||||
goto ESTABLISHED;
|
|
||||||
:: rcv ? _ -> skip;
|
|
||||||
od
|
|
||||||
:: rcv ? _ -> skip;
|
|
||||||
:: timeout -> goto CLOSED; /* Timeout */
|
|
||||||
od
|
|
||||||
SYN_RECEIVED:
|
|
||||||
state[i] = SynRecState;
|
|
||||||
do
|
|
||||||
:: rcv ? ACK -> goto ESTABLISHED;
|
|
||||||
:: rcv ? _ -> skip;
|
|
||||||
od
|
|
||||||
ESTABLISHED:
|
|
||||||
state[i] = EstState;
|
|
||||||
do
|
|
||||||
/* Close - initiator sequence */
|
|
||||||
:: snd ! FIN; goto FIN_WAIT_1;
|
|
||||||
/* Close - responder sequence */
|
|
||||||
:: rcv ? FIN ->
|
|
||||||
snd ! ACK;
|
|
||||||
goto CLOSE_WAIT;
|
|
||||||
:: rcv ? _ -> skip;
|
|
||||||
od
|
|
||||||
FIN_WAIT_1:
|
|
||||||
state[i] = FinW1State;
|
|
||||||
do
|
|
||||||
/* Simultaneous close */
|
|
||||||
:: rcv ? FIN ->
|
|
||||||
snd ! ACK;
|
|
||||||
goto CLOSING;
|
|
||||||
/* Standard close */
|
|
||||||
:: rcv ? ACK -> goto FIN_WAIT_2;
|
|
||||||
:: rcv ? _ -> skip;
|
|
||||||
od
|
|
||||||
CLOSE_WAIT:
|
|
||||||
state[i] = CloseWaitState;
|
|
||||||
do
|
|
||||||
:: snd ! FIN; goto LAST_ACK;
|
|
||||||
:: rcv ? _ -> skip;
|
|
||||||
od
|
|
||||||
FIN_WAIT_2:
|
|
||||||
state[i] = FinW2State;
|
|
||||||
do
|
|
||||||
:: rcv ? FIN ->
|
|
||||||
snd ! ACK;
|
|
||||||
goto TIME_WAIT;
|
|
||||||
:: rcv ? _ -> skip;
|
|
||||||
od
|
|
||||||
CLOSING:
|
|
||||||
state[i] = ClosingState;
|
|
||||||
do
|
|
||||||
:: rcv ? ACK -> goto TIME_WAIT;
|
|
||||||
:: rcv ? _ -> skip;
|
|
||||||
od
|
|
||||||
LAST_ACK:
|
|
||||||
state[i] = LastAckState;
|
|
||||||
do
|
|
||||||
:: rcv ? ACK -> goto CLOSED;
|
|
||||||
:: rcv ? _ -> skip;
|
|
||||||
od
|
|
||||||
TIME_WAIT:
|
|
||||||
state[i] = TimeWaitState;
|
|
||||||
goto CLOSED;
|
|
||||||
end:
|
|
||||||
state[i] = EndState;
|
|
||||||
}
|
|
||||||
|
|
||||||
init {
|
|
||||||
state[0] = ClosedState;
|
|
||||||
state[1] = ClosedState;
|
|
||||||
run TCP(AtoB, BtoA, 0);
|
|
||||||
run TCP(BtoA, AtoB, 1);
|
|
||||||
}
|
|
||||||
@@ -1,149 +0,0 @@
|
|||||||
// models: phi1, phi2, phi3, phi5
|
|
||||||
// does not model: phi4, phi7
|
|
||||||
// not yet implemented: phi6
|
|
||||||
mtype = { SYN, FIN, ACK, ABORT, CLOSE, RST, OPEN }
|
|
||||||
|
|
||||||
chan AtoN = [2] of { mtype };
|
|
||||||
chan NtoA = [2] of { mtype };
|
|
||||||
chan BtoN = [2] of { mtype };
|
|
||||||
chan NtoB = [2] of { mtype };
|
|
||||||
|
|
||||||
int state[2];
|
|
||||||
int pids[2];
|
|
||||||
|
|
||||||
#define ClosedState 0
|
|
||||||
#define ListenState 1
|
|
||||||
#define SynSentState 2
|
|
||||||
#define SynRecState 3
|
|
||||||
#define EstState 4
|
|
||||||
#define FinW1State 5
|
|
||||||
#define CloseWaitState 6
|
|
||||||
#define FinW2State 7
|
|
||||||
#define ClosingState 8
|
|
||||||
#define LastAckState 9
|
|
||||||
#define TimeWaitState 10
|
|
||||||
#define EndState -1
|
|
||||||
|
|
||||||
#define leftConnecting (state[0] == ListenState && state[1] == SynSentState)
|
|
||||||
#define leftEstablished (state[0] == EstState)
|
|
||||||
#define rightEstablished (state[1] == EstState)
|
|
||||||
#define leftClosed (state[0] == ClosedState)
|
|
||||||
|
|
||||||
proctype TCP(chan snd, rcv; int i) {
|
|
||||||
pids[i] = _pid;
|
|
||||||
CLOSED:
|
|
||||||
state[i] = ClosedState;
|
|
||||||
do
|
|
||||||
/* Passive open */
|
|
||||||
:: goto LISTEN;
|
|
||||||
/* Active open */
|
|
||||||
:: snd ! SYN; goto SYN_SENT;
|
|
||||||
/* Terminate */
|
|
||||||
:: goto end;
|
|
||||||
od
|
|
||||||
LISTEN:
|
|
||||||
state[i] = ListenState;
|
|
||||||
do
|
|
||||||
:: rcv ? SYN ->
|
|
||||||
atomic {
|
|
||||||
snd ! SYN;
|
|
||||||
snd ! ACK;
|
|
||||||
goto SYN_RECEIVED;
|
|
||||||
}
|
|
||||||
/* Simultaneous LISTEN */
|
|
||||||
:: rcv ? _ -> skip;
|
|
||||||
:: timeout -> goto CLOSED;
|
|
||||||
od
|
|
||||||
SYN_SENT:
|
|
||||||
state[i] = SynSentState;
|
|
||||||
do
|
|
||||||
:: rcv ? SYN;
|
|
||||||
if
|
|
||||||
/* Standard behavior */
|
|
||||||
:: rcv ? ACK -> snd ! ACK; goto ESTABLISHED;
|
|
||||||
/* Simultaneous open */
|
|
||||||
:: snd ! ACK; goto SYN_RECEIVED;
|
|
||||||
fi
|
|
||||||
:: rcv ? ACK;
|
|
||||||
do
|
|
||||||
:: rcv ? SYN ->
|
|
||||||
snd ! ACK;
|
|
||||||
goto ESTABLISHED;
|
|
||||||
:: rcv ? _ -> skip;
|
|
||||||
od
|
|
||||||
:: rcv ? _ -> skip;
|
|
||||||
:: timeout -> goto CLOSED; /* Timeout */
|
|
||||||
od
|
|
||||||
SYN_RECEIVED:
|
|
||||||
state[i] = SynRecState;
|
|
||||||
do
|
|
||||||
:: rcv ? ACK -> goto ESTABLISHED;
|
|
||||||
:: rcv ? _ -> skip;
|
|
||||||
od
|
|
||||||
/* We may want to consider putting a timeout -> CLOSED here. */
|
|
||||||
ESTABLISHED:
|
|
||||||
state[i] = EstState;
|
|
||||||
do
|
|
||||||
/* Close - initiator sequence */
|
|
||||||
:: snd ! FIN; goto FIN_WAIT_1;
|
|
||||||
/* Close - responder sequence */
|
|
||||||
:: rcv ? FIN ->
|
|
||||||
snd ! ACK;
|
|
||||||
goto CLOSE_WAIT;
|
|
||||||
:: rcv ? _ -> skip;
|
|
||||||
od
|
|
||||||
FIN_WAIT_1:
|
|
||||||
state[i] = FinW1State;
|
|
||||||
do
|
|
||||||
/* Simultaneous close */
|
|
||||||
:: rcv ? FIN ->
|
|
||||||
snd ! ACK;
|
|
||||||
goto CLOSING;
|
|
||||||
/* Standard close */
|
|
||||||
:: rcv ? ACK -> goto FIN_WAIT_2;
|
|
||||||
:: rcv ? _ -> skip;
|
|
||||||
od
|
|
||||||
CLOSE_WAIT:
|
|
||||||
state[i] = CloseWaitState;
|
|
||||||
do
|
|
||||||
:: snd ! FIN; goto LAST_ACK;
|
|
||||||
:: rcv ? _ -> skip;
|
|
||||||
od
|
|
||||||
FIN_WAIT_2:
|
|
||||||
state[i] = FinW2State;
|
|
||||||
do
|
|
||||||
:: rcv ? FIN ->
|
|
||||||
snd ! ACK;
|
|
||||||
goto TIME_WAIT;
|
|
||||||
:: rcv ? _ -> skip;
|
|
||||||
od
|
|
||||||
CLOSING:
|
|
||||||
state[i] = ClosingState;
|
|
||||||
do
|
|
||||||
:: rcv ? ACK -> goto TIME_WAIT;
|
|
||||||
:: rcv ? _ -> skip;
|
|
||||||
od
|
|
||||||
LAST_ACK:
|
|
||||||
state[i] = LastAckState;
|
|
||||||
do
|
|
||||||
:: rcv ? ACK -> goto CLOSED;
|
|
||||||
:: rcv ? _ -> skip;
|
|
||||||
od
|
|
||||||
TIME_WAIT:
|
|
||||||
state[i] = TimeWaitState;
|
|
||||||
goto CLOSED;
|
|
||||||
end:
|
|
||||||
state[i] = EndState;
|
|
||||||
}
|
|
||||||
|
|
||||||
init {
|
|
||||||
state[0] = ClosedState;
|
|
||||||
state[1] = ClosedState;
|
|
||||||
run TCP(AtoN, NtoA, 0);
|
|
||||||
run TCP(BtoN, NtoB, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* safety: half-open prevention */
|
|
||||||
ltl phi1 {
|
|
||||||
always ( leftClosed implies !rightEstablished )
|
|
||||||
}
|
|
||||||
@@ -1,149 +0,0 @@
|
|||||||
// models: phi1, phi2, phi3, phi5
|
|
||||||
// does not model: phi4, phi7
|
|
||||||
// not yet implemented: phi6
|
|
||||||
mtype = { SYN, FIN, ACK, ABORT, CLOSE, RST, OPEN }
|
|
||||||
|
|
||||||
chan AtoN = [2] of { mtype };
|
|
||||||
chan NtoA = [2] of { mtype };
|
|
||||||
chan BtoN = [2] of { mtype };
|
|
||||||
chan NtoB = [2] of { mtype };
|
|
||||||
|
|
||||||
int state[2];
|
|
||||||
int pids[2];
|
|
||||||
|
|
||||||
#define ClosedState 0
|
|
||||||
#define ListenState 1
|
|
||||||
#define SynSentState 2
|
|
||||||
#define SynRecState 3
|
|
||||||
#define EstState 4
|
|
||||||
#define FinW1State 5
|
|
||||||
#define CloseWaitState 6
|
|
||||||
#define FinW2State 7
|
|
||||||
#define ClosingState 8
|
|
||||||
#define LastAckState 9
|
|
||||||
#define TimeWaitState 10
|
|
||||||
#define EndState -1
|
|
||||||
|
|
||||||
#define leftConnecting (state[0] == ListenState && state[1] == SynSentState)
|
|
||||||
#define leftEstablished (state[0] == EstState)
|
|
||||||
#define rightEstablished (state[1] == EstState)
|
|
||||||
#define leftClosed (state[0] == ClosedState)
|
|
||||||
|
|
||||||
proctype TCP(chan snd, rcv; int i) {
|
|
||||||
pids[i] = _pid;
|
|
||||||
CLOSED:
|
|
||||||
state[i] = ClosedState;
|
|
||||||
do
|
|
||||||
/* Passive open */
|
|
||||||
:: goto LISTEN;
|
|
||||||
/* Active open */
|
|
||||||
:: snd ! SYN; goto SYN_SENT;
|
|
||||||
/* Terminate */
|
|
||||||
:: goto end;
|
|
||||||
od
|
|
||||||
LISTEN:
|
|
||||||
state[i] = ListenState;
|
|
||||||
do
|
|
||||||
:: rcv ? SYN ->
|
|
||||||
atomic {
|
|
||||||
snd ! SYN;
|
|
||||||
snd ! ACK;
|
|
||||||
goto SYN_RECEIVED;
|
|
||||||
}
|
|
||||||
/* Simultaneous LISTEN */
|
|
||||||
:: rcv ? _ -> skip;
|
|
||||||
:: timeout -> goto CLOSED;
|
|
||||||
od
|
|
||||||
SYN_SENT:
|
|
||||||
state[i] = SynSentState;
|
|
||||||
do
|
|
||||||
:: rcv ? SYN;
|
|
||||||
if
|
|
||||||
/* Standard behavior */
|
|
||||||
:: rcv ? ACK -> snd ! ACK; goto ESTABLISHED;
|
|
||||||
/* Simultaneous open */
|
|
||||||
:: snd ! ACK; goto SYN_RECEIVED;
|
|
||||||
fi
|
|
||||||
:: rcv ? ACK;
|
|
||||||
do
|
|
||||||
:: rcv ? SYN ->
|
|
||||||
snd ! ACK;
|
|
||||||
goto ESTABLISHED;
|
|
||||||
:: rcv ? _ -> skip;
|
|
||||||
od
|
|
||||||
:: rcv ? _ -> skip;
|
|
||||||
:: timeout -> goto CLOSED; /* Timeout */
|
|
||||||
od
|
|
||||||
SYN_RECEIVED:
|
|
||||||
state[i] = SynRecState;
|
|
||||||
do
|
|
||||||
:: rcv ? ACK -> goto ESTABLISHED;
|
|
||||||
:: rcv ? _ -> skip;
|
|
||||||
od
|
|
||||||
/* We may want to consider putting a timeout -> CLOSED here. */
|
|
||||||
ESTABLISHED:
|
|
||||||
state[i] = EstState;
|
|
||||||
do
|
|
||||||
/* Close - initiator sequence */
|
|
||||||
:: snd ! FIN; goto FIN_WAIT_1;
|
|
||||||
/* Close - responder sequence */
|
|
||||||
:: rcv ? FIN ->
|
|
||||||
snd ! ACK;
|
|
||||||
goto CLOSE_WAIT;
|
|
||||||
:: rcv ? _ -> skip;
|
|
||||||
od
|
|
||||||
FIN_WAIT_1:
|
|
||||||
state[i] = FinW1State;
|
|
||||||
do
|
|
||||||
/* Simultaneous close */
|
|
||||||
:: rcv ? FIN ->
|
|
||||||
snd ! ACK;
|
|
||||||
goto CLOSING;
|
|
||||||
/* Standard close */
|
|
||||||
:: rcv ? ACK -> goto FIN_WAIT_2;
|
|
||||||
:: rcv ? _ -> skip;
|
|
||||||
od
|
|
||||||
CLOSE_WAIT:
|
|
||||||
state[i] = CloseWaitState;
|
|
||||||
do
|
|
||||||
:: snd ! FIN; goto LAST_ACK;
|
|
||||||
:: rcv ? _ -> skip;
|
|
||||||
od
|
|
||||||
FIN_WAIT_2:
|
|
||||||
state[i] = FinW2State;
|
|
||||||
do
|
|
||||||
:: rcv ? FIN ->
|
|
||||||
snd ! ACK;
|
|
||||||
goto TIME_WAIT;
|
|
||||||
:: rcv ? _ -> skip;
|
|
||||||
od
|
|
||||||
CLOSING:
|
|
||||||
state[i] = ClosingState;
|
|
||||||
do
|
|
||||||
:: rcv ? ACK -> goto TIME_WAIT;
|
|
||||||
:: rcv ? _ -> skip;
|
|
||||||
od
|
|
||||||
LAST_ACK:
|
|
||||||
state[i] = LastAckState;
|
|
||||||
do
|
|
||||||
:: rcv ? ACK -> goto CLOSED;
|
|
||||||
:: rcv ? _ -> skip;
|
|
||||||
od
|
|
||||||
TIME_WAIT:
|
|
||||||
state[i] = TimeWaitState;
|
|
||||||
goto CLOSED;
|
|
||||||
end:
|
|
||||||
state[i] = EndState;
|
|
||||||
}
|
|
||||||
|
|
||||||
init {
|
|
||||||
state[0] = ClosedState;
|
|
||||||
state[1] = ClosedState;
|
|
||||||
run TCP(AtoN, NtoA, 0);
|
|
||||||
run TCP(BtoN, NtoB, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* liveness: verifying connection establishment */
|
|
||||||
ltl phi2 {
|
|
||||||
( (always ( eventually ( state[0] == 1 && state[1] == 2 ) ) )
|
|
||||||
implies ( eventually ( state[0] == 4 ) ) )
|
|
||||||
@@ -1,55 +0,0 @@
|
|||||||
-2:2:-2
|
|
||||||
-4:-4:-4
|
|
||||||
1:0:121
|
|
||||||
2:1:114
|
|
||||||
3:0:121
|
|
||||||
4:1:115
|
|
||||||
5:0:121
|
|
||||||
6:1:116
|
|
||||||
7:0:121
|
|
||||||
8:1:117
|
|
||||||
9:0:121
|
|
||||||
10:3:0
|
|
||||||
11:0:121
|
|
||||||
12:3:1
|
|
||||||
13:0:121
|
|
||||||
14:3:2
|
|
||||||
15:0:121
|
|
||||||
16:3:9
|
|
||||||
17:0:121
|
|
||||||
18:2:0
|
|
||||||
19:0:121
|
|
||||||
20:2:1
|
|
||||||
21:0:121
|
|
||||||
22:2:2
|
|
||||||
23:0:121
|
|
||||||
24:2:9
|
|
||||||
25:0:121
|
|
||||||
26:3:17
|
|
||||||
27:0:121
|
|
||||||
28:3:1
|
|
||||||
29:0:121
|
|
||||||
30:3:3
|
|
||||||
31:0:121
|
|
||||||
32:3:22
|
|
||||||
33:0:119
|
|
||||||
34:2:17
|
|
||||||
35:0:126
|
|
||||||
36:2:1
|
|
||||||
37:0:121
|
|
||||||
38:2:3
|
|
||||||
39:0:121
|
|
||||||
40:2:22
|
|
||||||
41:0:121
|
|
||||||
42:2:42
|
|
||||||
43:0:121
|
|
||||||
44:2:1
|
|
||||||
-1:-1:-1
|
|
||||||
45:0:121
|
|
||||||
46:2:2
|
|
||||||
47:0:121
|
|
||||||
48:2:9
|
|
||||||
49:0:119
|
|
||||||
50:2:17
|
|
||||||
51:0:126
|
|
||||||
52:2:1
|
|
||||||
@@ -1,167 +0,0 @@
|
|||||||
// models: phi1, phi2, phi3, phi5
|
|
||||||
// does not model: phi4, phi7
|
|
||||||
// not yet implemented: phi6
|
|
||||||
mtype = { SYN, FIN, ACK, ABORT, CLOSE, RST, OPEN }
|
|
||||||
|
|
||||||
chan AtoN = [2] of { mtype };
|
|
||||||
chan NtoA = [2] of { mtype };
|
|
||||||
chan BtoN = [2] of { mtype };
|
|
||||||
chan NtoB = [2] of { mtype };
|
|
||||||
|
|
||||||
int state[2];
|
|
||||||
int pids[2];
|
|
||||||
|
|
||||||
#define ClosedState 0
|
|
||||||
#define ListenState 1
|
|
||||||
#define SynSentState 2
|
|
||||||
#define SynRecState 3
|
|
||||||
#define EstState 4
|
|
||||||
#define FinW1State 5
|
|
||||||
#define CloseWaitState 6
|
|
||||||
#define FinW2State 7
|
|
||||||
#define ClosingState 8
|
|
||||||
#define LastAckState 9
|
|
||||||
#define TimeWaitState 10
|
|
||||||
#define EndState -1
|
|
||||||
|
|
||||||
#define leftConnecting (state[0] == ListenState && state[1] == SynSentState)
|
|
||||||
#define leftEstablished (state[0] == EstState)
|
|
||||||
#define rightEstablished (state[1] == EstState)
|
|
||||||
#define leftClosed (state[0] == ClosedState)
|
|
||||||
|
|
||||||
proctype TCP(chan snd, rcv; int i) {
|
|
||||||
pids[i] = _pid;
|
|
||||||
CLOSED:
|
|
||||||
state[i] = ClosedState;
|
|
||||||
do
|
|
||||||
/* Passive open */
|
|
||||||
:: goto LISTEN;
|
|
||||||
/* Active open */
|
|
||||||
:: snd ! SYN; goto SYN_SENT;
|
|
||||||
/* Terminate */
|
|
||||||
:: goto end;
|
|
||||||
od
|
|
||||||
LISTEN:
|
|
||||||
state[i] = ListenState;
|
|
||||||
do
|
|
||||||
:: rcv ? SYN ->
|
|
||||||
atomic {
|
|
||||||
snd ! SYN;
|
|
||||||
snd ! ACK;
|
|
||||||
goto SYN_RECEIVED;
|
|
||||||
}
|
|
||||||
/* Simultaneous LISTEN */
|
|
||||||
:: rcv ? _ -> skip;
|
|
||||||
:: timeout -> goto CLOSED;
|
|
||||||
od
|
|
||||||
SYN_SENT:
|
|
||||||
state[i] = SynSentState;
|
|
||||||
do
|
|
||||||
:: rcv ? SYN;
|
|
||||||
if
|
|
||||||
/* Standard behavior */
|
|
||||||
:: rcv ? ACK -> snd ! ACK; goto ESTABLISHED;
|
|
||||||
/* Simultaneous open */
|
|
||||||
:: snd ! ACK; goto SYN_RECEIVED;
|
|
||||||
fi
|
|
||||||
:: rcv ? ACK;
|
|
||||||
do
|
|
||||||
:: rcv ? SYN ->
|
|
||||||
snd ! ACK;
|
|
||||||
goto ESTABLISHED;
|
|
||||||
:: rcv ? _ -> skip;
|
|
||||||
od
|
|
||||||
:: rcv ? _ -> skip;
|
|
||||||
:: timeout -> goto CLOSED; /* Timeout */
|
|
||||||
od
|
|
||||||
SYN_RECEIVED:
|
|
||||||
state[i] = SynRecState;
|
|
||||||
do
|
|
||||||
:: rcv ? ACK -> goto ESTABLISHED;
|
|
||||||
:: rcv ? _ -> skip;
|
|
||||||
od
|
|
||||||
/* We may want to consider putting a timeout -> CLOSED here. */
|
|
||||||
ESTABLISHED:
|
|
||||||
state[i] = EstState;
|
|
||||||
do
|
|
||||||
/* Close - initiator sequence */
|
|
||||||
:: snd ! FIN; goto FIN_WAIT_1;
|
|
||||||
/* Close - responder sequence */
|
|
||||||
:: rcv ? FIN ->
|
|
||||||
snd ! ACK;
|
|
||||||
goto CLOSE_WAIT;
|
|
||||||
:: rcv ? _ -> skip;
|
|
||||||
od
|
|
||||||
FIN_WAIT_1:
|
|
||||||
state[i] = FinW1State;
|
|
||||||
do
|
|
||||||
/* Simultaneous close */
|
|
||||||
:: rcv ? FIN ->
|
|
||||||
snd ! ACK;
|
|
||||||
goto CLOSING;
|
|
||||||
/* Standard close */
|
|
||||||
:: rcv ? ACK -> goto FIN_WAIT_2;
|
|
||||||
:: rcv ? _ -> skip;
|
|
||||||
od
|
|
||||||
CLOSE_WAIT:
|
|
||||||
state[i] = CloseWaitState;
|
|
||||||
do
|
|
||||||
:: snd ! FIN; goto LAST_ACK;
|
|
||||||
:: rcv ? _ -> skip;
|
|
||||||
od
|
|
||||||
FIN_WAIT_2:
|
|
||||||
state[i] = FinW2State;
|
|
||||||
do
|
|
||||||
:: rcv ? FIN ->
|
|
||||||
snd ! ACK;
|
|
||||||
goto TIME_WAIT;
|
|
||||||
:: rcv ? _ -> skip;
|
|
||||||
od
|
|
||||||
CLOSING:
|
|
||||||
state[i] = ClosingState;
|
|
||||||
do
|
|
||||||
:: rcv ? ACK -> goto TIME_WAIT;
|
|
||||||
:: rcv ? _ -> skip;
|
|
||||||
od
|
|
||||||
LAST_ACK:
|
|
||||||
state[i] = LastAckState;
|
|
||||||
do
|
|
||||||
:: rcv ? ACK -> goto CLOSED;
|
|
||||||
:: rcv ? _ -> skip;
|
|
||||||
od
|
|
||||||
TIME_WAIT:
|
|
||||||
state[i] = TimeWaitState;
|
|
||||||
goto CLOSED;
|
|
||||||
end:
|
|
||||||
state[i] = EndState;
|
|
||||||
}
|
|
||||||
|
|
||||||
init {
|
|
||||||
state[0] = ClosedState;
|
|
||||||
state[1] = ClosedState;
|
|
||||||
run TCP(AtoN, NtoA, 0);
|
|
||||||
run TCP(BtoN, NtoB, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* liveness: no infinite stalls/deadlocks */
|
|
||||||
ltl phi3 {
|
|
||||||
!(eventually (((always (state[0] == SynSentState)) ||
|
|
||||||
(always (state[0] == SynRecState)) ||
|
|
||||||
(always (state[0] == EstState)) ||
|
|
||||||
(always (state[0] == FinW1State)) ||
|
|
||||||
(always (state[0] == CloseWaitState)) ||
|
|
||||||
(always (state[0] == FinW2State)) ||
|
|
||||||
(always (state[0] == ClosingState)) ||
|
|
||||||
(always (state[0] == LastAckState)) ||
|
|
||||||
(always (state[0] == TimeWaitState)))
|
|
||||||
&&
|
|
||||||
((always (state[1] == SynSentState)) ||
|
|
||||||
(always (state[1] == SynRecState)) ||
|
|
||||||
(always (state[1] == EstState)) ||
|
|
||||||
(always (state[1] == FinW1State)) ||
|
|
||||||
(always (state[1] == CloseWaitState)) ||
|
|
||||||
(always (state[1] == FinW2State)) ||
|
|
||||||
(always (state[1] == ClosingState)) ||
|
|
||||||
(always (state[1] == LastAckState)) ||
|
|
||||||
(always (state[1] == TimeWaitState)))))
|
|
||||||
}
|
|
||||||
@@ -1,156 +0,0 @@
|
|||||||
// models: phi1, phi2, phi3, phi5
|
|
||||||
// does not model: phi4, phi7
|
|
||||||
// not yet implemented: phi6
|
|
||||||
mtype = { SYN, FIN, ACK, ABORT, CLOSE, RST, OPEN }
|
|
||||||
|
|
||||||
chan AtoN = [2] of { mtype };
|
|
||||||
chan NtoA = [2] of { mtype };
|
|
||||||
chan BtoN = [2] of { mtype };
|
|
||||||
chan NtoB = [2] of { mtype };
|
|
||||||
|
|
||||||
int state[2];
|
|
||||||
int pids[2];
|
|
||||||
|
|
||||||
#define ClosedState 0
|
|
||||||
#define ListenState 1
|
|
||||||
#define SynSentState 2
|
|
||||||
#define SynRecState 3
|
|
||||||
#define EstState 4
|
|
||||||
#define FinW1State 5
|
|
||||||
#define CloseWaitState 6
|
|
||||||
#define FinW2State 7
|
|
||||||
#define ClosingState 8
|
|
||||||
#define LastAckState 9
|
|
||||||
#define TimeWaitState 10
|
|
||||||
#define EndState -1
|
|
||||||
|
|
||||||
#define leftConnecting (state[0] == ListenState && state[1] == SynSentState)
|
|
||||||
#define leftEstablished (state[0] == EstState)
|
|
||||||
#define rightEstablished (state[1] == EstState)
|
|
||||||
#define leftClosed (state[0] == ClosedState)
|
|
||||||
|
|
||||||
proctype TCP(chan snd, rcv; int i) {
|
|
||||||
pids[i] = _pid;
|
|
||||||
CLOSED:
|
|
||||||
state[i] = ClosedState;
|
|
||||||
do
|
|
||||||
/* Passive open */
|
|
||||||
:: goto LISTEN;
|
|
||||||
/* Active open */
|
|
||||||
:: snd ! SYN; goto SYN_SENT;
|
|
||||||
/* Terminate */
|
|
||||||
:: goto end;
|
|
||||||
od
|
|
||||||
LISTEN:
|
|
||||||
state[i] = ListenState;
|
|
||||||
do
|
|
||||||
:: rcv ? SYN ->
|
|
||||||
atomic {
|
|
||||||
snd ! SYN;
|
|
||||||
snd ! ACK;
|
|
||||||
goto SYN_RECEIVED;
|
|
||||||
}
|
|
||||||
/* Simultaneous LISTEN */
|
|
||||||
:: rcv ? _ -> skip;
|
|
||||||
:: timeout -> goto CLOSED;
|
|
||||||
od
|
|
||||||
SYN_SENT:
|
|
||||||
state[i] = SynSentState;
|
|
||||||
do
|
|
||||||
:: rcv ? SYN;
|
|
||||||
if
|
|
||||||
/* Standard behavior */
|
|
||||||
:: rcv ? ACK -> snd ! ACK; goto ESTABLISHED;
|
|
||||||
/* Simultaneous open */
|
|
||||||
:: snd ! ACK; goto SYN_RECEIVED;
|
|
||||||
fi
|
|
||||||
:: rcv ? ACK;
|
|
||||||
do
|
|
||||||
:: rcv ? SYN ->
|
|
||||||
snd ! ACK;
|
|
||||||
goto ESTABLISHED;
|
|
||||||
:: rcv ? _ -> skip;
|
|
||||||
od
|
|
||||||
:: rcv ? _ -> skip;
|
|
||||||
:: timeout -> goto CLOSED; /* Timeout */
|
|
||||||
od
|
|
||||||
SYN_RECEIVED:
|
|
||||||
state[i] = SynRecState;
|
|
||||||
do
|
|
||||||
:: rcv ? ACK -> goto ESTABLISHED;
|
|
||||||
:: rcv ? _ -> skip;
|
|
||||||
od
|
|
||||||
/* We may want to consider putting a timeout -> CLOSED here. */
|
|
||||||
ESTABLISHED:
|
|
||||||
state[i] = EstState;
|
|
||||||
do
|
|
||||||
/* Close - initiator sequence */
|
|
||||||
:: snd ! FIN; goto FIN_WAIT_1;
|
|
||||||
/* Close - responder sequence */
|
|
||||||
:: rcv ? FIN ->
|
|
||||||
snd ! ACK;
|
|
||||||
goto CLOSE_WAIT;
|
|
||||||
:: rcv ? _ -> skip;
|
|
||||||
od
|
|
||||||
FIN_WAIT_1:
|
|
||||||
state[i] = FinW1State;
|
|
||||||
do
|
|
||||||
/* Simultaneous close */
|
|
||||||
:: rcv ? FIN ->
|
|
||||||
snd ! ACK;
|
|
||||||
goto CLOSING;
|
|
||||||
/* Standard close */
|
|
||||||
:: rcv ? ACK -> goto FIN_WAIT_2;
|
|
||||||
:: rcv ? _ -> skip;
|
|
||||||
od
|
|
||||||
CLOSE_WAIT:
|
|
||||||
state[i] = CloseWaitState;
|
|
||||||
do
|
|
||||||
:: snd ! FIN; goto LAST_ACK;
|
|
||||||
:: rcv ? _ -> skip;
|
|
||||||
od
|
|
||||||
FIN_WAIT_2:
|
|
||||||
state[i] = FinW2State;
|
|
||||||
do
|
|
||||||
:: rcv ? FIN ->
|
|
||||||
snd ! ACK;
|
|
||||||
goto TIME_WAIT;
|
|
||||||
:: rcv ? _ -> skip;
|
|
||||||
od
|
|
||||||
CLOSING:
|
|
||||||
state[i] = ClosingState;
|
|
||||||
do
|
|
||||||
:: rcv ? ACK -> goto TIME_WAIT;
|
|
||||||
:: rcv ? _ -> skip;
|
|
||||||
od
|
|
||||||
LAST_ACK:
|
|
||||||
state[i] = LastAckState;
|
|
||||||
do
|
|
||||||
:: rcv ? ACK -> goto CLOSED;
|
|
||||||
:: rcv ? _ -> skip;
|
|
||||||
od
|
|
||||||
TIME_WAIT:
|
|
||||||
state[i] = TimeWaitState;
|
|
||||||
goto CLOSED;
|
|
||||||
end:
|
|
||||||
state[i] = EndState;
|
|
||||||
}
|
|
||||||
|
|
||||||
init {
|
|
||||||
state[0] = ClosedState;
|
|
||||||
state[1] = ClosedState;
|
|
||||||
run TCP(AtoN, NtoA, 0);
|
|
||||||
run TCP(BtoN, NtoB, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* liveness: simultanous open */
|
|
||||||
ltl phi4 {
|
|
||||||
always (
|
|
||||||
(state[0] == SynSentState &&
|
|
||||||
state[1] == SynSentState)
|
|
||||||
|
|
||||||
implies
|
|
||||||
|
|
||||||
((eventually state[0] == EstState) &&
|
|
||||||
(eventually state[1] == EstState)))
|
|
||||||
}
|
|
||||||
@@ -1,43 +0,0 @@
|
|||||||
-2:2:-2
|
|
||||||
-4:-4:-4
|
|
||||||
1:0:122
|
|
||||||
2:1:114
|
|
||||||
3:0:122
|
|
||||||
4:1:115
|
|
||||||
5:0:122
|
|
||||||
6:1:116
|
|
||||||
7:0:122
|
|
||||||
8:1:117
|
|
||||||
9:0:122
|
|
||||||
10:3:0
|
|
||||||
11:0:122
|
|
||||||
12:3:1
|
|
||||||
13:0:122
|
|
||||||
14:3:2
|
|
||||||
15:0:122
|
|
||||||
16:3:9
|
|
||||||
17:0:122
|
|
||||||
18:2:0
|
|
||||||
19:0:122
|
|
||||||
20:2:1
|
|
||||||
21:0:122
|
|
||||||
22:2:2
|
|
||||||
23:0:122
|
|
||||||
24:2:9
|
|
||||||
25:0:122
|
|
||||||
26:3:17
|
|
||||||
27:0:122
|
|
||||||
28:3:1
|
|
||||||
29:0:122
|
|
||||||
30:3:3
|
|
||||||
31:0:122
|
|
||||||
32:3:22
|
|
||||||
33:0:122
|
|
||||||
34:2:17
|
|
||||||
35:0:122
|
|
||||||
36:2:1
|
|
||||||
37:0:122
|
|
||||||
38:2:3
|
|
||||||
39:0:122
|
|
||||||
40:2:22
|
|
||||||
41:0:119
|
|
||||||
@@ -1,158 +0,0 @@
|
|||||||
// models: phi1, phi2, phi3, phi5
|
|
||||||
// does not model: phi4, phi7
|
|
||||||
// not yet implemented: phi6
|
|
||||||
mtype = { SYN, FIN, ACK, ABORT, CLOSE, RST, OPEN }
|
|
||||||
|
|
||||||
chan AtoN = [2] of { mtype };
|
|
||||||
chan NtoA = [2] of { mtype };
|
|
||||||
chan BtoN = [2] of { mtype };
|
|
||||||
chan NtoB = [2] of { mtype };
|
|
||||||
|
|
||||||
int state[2];
|
|
||||||
int pids[2];
|
|
||||||
|
|
||||||
#define ClosedState 0
|
|
||||||
#define ListenState 1
|
|
||||||
#define SynSentState 2
|
|
||||||
#define SynRecState 3
|
|
||||||
#define EstState 4
|
|
||||||
#define FinW1State 5
|
|
||||||
#define CloseWaitState 6
|
|
||||||
#define FinW2State 7
|
|
||||||
#define ClosingState 8
|
|
||||||
#define LastAckState 9
|
|
||||||
#define TimeWaitState 10
|
|
||||||
#define EndState -1
|
|
||||||
|
|
||||||
#define leftConnecting (state[0] == ListenState && state[1] == SynSentState)
|
|
||||||
#define leftEstablished (state[0] == EstState)
|
|
||||||
#define rightEstablished (state[1] == EstState)
|
|
||||||
#define leftClosed (state[0] == ClosedState)
|
|
||||||
|
|
||||||
proctype TCP(chan snd, rcv; int i) {
|
|
||||||
pids[i] = _pid;
|
|
||||||
CLOSED:
|
|
||||||
state[i] = ClosedState;
|
|
||||||
do
|
|
||||||
/* Passive open */
|
|
||||||
:: goto LISTEN;
|
|
||||||
/* Active open */
|
|
||||||
:: snd ! SYN; goto SYN_SENT;
|
|
||||||
/* Terminate */
|
|
||||||
:: goto end;
|
|
||||||
od
|
|
||||||
LISTEN:
|
|
||||||
state[i] = ListenState;
|
|
||||||
do
|
|
||||||
:: rcv ? SYN ->
|
|
||||||
atomic {
|
|
||||||
snd ! SYN;
|
|
||||||
snd ! ACK;
|
|
||||||
goto SYN_RECEIVED;
|
|
||||||
}
|
|
||||||
/* Simultaneous LISTEN */
|
|
||||||
:: rcv ? _ -> skip;
|
|
||||||
:: timeout -> goto CLOSED;
|
|
||||||
od
|
|
||||||
SYN_SENT:
|
|
||||||
state[i] = SynSentState;
|
|
||||||
do
|
|
||||||
:: rcv ? SYN;
|
|
||||||
if
|
|
||||||
/* Standard behavior */
|
|
||||||
:: rcv ? ACK -> snd ! ACK; goto ESTABLISHED;
|
|
||||||
/* Simultaneous open */
|
|
||||||
:: snd ! ACK; goto SYN_RECEIVED;
|
|
||||||
fi
|
|
||||||
:: rcv ? ACK;
|
|
||||||
do
|
|
||||||
:: rcv ? SYN ->
|
|
||||||
snd ! ACK;
|
|
||||||
goto ESTABLISHED;
|
|
||||||
:: rcv ? _ -> skip;
|
|
||||||
od
|
|
||||||
:: rcv ? _ -> skip;
|
|
||||||
:: timeout -> goto CLOSED; /* Timeout */
|
|
||||||
od
|
|
||||||
SYN_RECEIVED:
|
|
||||||
state[i] = SynRecState;
|
|
||||||
do
|
|
||||||
:: rcv ? ACK -> goto ESTABLISHED;
|
|
||||||
:: rcv ? _ -> skip;
|
|
||||||
od
|
|
||||||
/* We may want to consider putting a timeout -> CLOSED here. */
|
|
||||||
ESTABLISHED:
|
|
||||||
state[i] = EstState;
|
|
||||||
do
|
|
||||||
/* Close - initiator sequence */
|
|
||||||
:: snd ! FIN; goto FIN_WAIT_1;
|
|
||||||
/* Close - responder sequence */
|
|
||||||
:: rcv ? FIN ->
|
|
||||||
snd ! ACK;
|
|
||||||
goto CLOSE_WAIT;
|
|
||||||
:: rcv ? _ -> skip;
|
|
||||||
od
|
|
||||||
FIN_WAIT_1:
|
|
||||||
state[i] = FinW1State;
|
|
||||||
do
|
|
||||||
/* Simultaneous close */
|
|
||||||
:: rcv ? FIN ->
|
|
||||||
snd ! ACK;
|
|
||||||
goto CLOSING;
|
|
||||||
/* Standard close */
|
|
||||||
:: rcv ? ACK -> goto FIN_WAIT_2;
|
|
||||||
:: rcv ? _ -> skip;
|
|
||||||
od
|
|
||||||
CLOSE_WAIT:
|
|
||||||
state[i] = CloseWaitState;
|
|
||||||
do
|
|
||||||
:: snd ! FIN; goto LAST_ACK;
|
|
||||||
:: rcv ? _ -> skip;
|
|
||||||
od
|
|
||||||
FIN_WAIT_2:
|
|
||||||
state[i] = FinW2State;
|
|
||||||
do
|
|
||||||
:: rcv ? FIN ->
|
|
||||||
snd ! ACK;
|
|
||||||
goto TIME_WAIT;
|
|
||||||
:: rcv ? _ -> skip;
|
|
||||||
od
|
|
||||||
CLOSING:
|
|
||||||
state[i] = ClosingState;
|
|
||||||
do
|
|
||||||
:: rcv ? ACK -> goto TIME_WAIT;
|
|
||||||
:: rcv ? _ -> skip;
|
|
||||||
od
|
|
||||||
LAST_ACK:
|
|
||||||
state[i] = LastAckState;
|
|
||||||
do
|
|
||||||
:: rcv ? ACK -> goto CLOSED;
|
|
||||||
:: rcv ? _ -> skip;
|
|
||||||
od
|
|
||||||
TIME_WAIT:
|
|
||||||
state[i] = TimeWaitState;
|
|
||||||
goto CLOSED;
|
|
||||||
end:
|
|
||||||
state[i] = EndState;
|
|
||||||
}
|
|
||||||
|
|
||||||
init {
|
|
||||||
state[0] = ClosedState;
|
|
||||||
state[1] = ClosedState;
|
|
||||||
run TCP(AtoN, NtoA, 0);
|
|
||||||
run TCP(BtoN, NtoB, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* liveness: SYN_RECEIVED resolution*/
|
|
||||||
ltl phi5 {
|
|
||||||
always (
|
|
||||||
(state[0] == SynRecState)
|
|
||||||
implies (
|
|
||||||
eventually (
|
|
||||||
(state[0] == EstState ||
|
|
||||||
state[0] == FinW1State ||
|
|
||||||
state[0] == ClosedState)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@@ -1,154 +0,0 @@
|
|||||||
// models: phi1, phi2, phi3, phi5
|
|
||||||
// does not model: phi4, phi7
|
|
||||||
// not yet implemented: phi6
|
|
||||||
mtype = { SYN, FIN, ACK, ABORT, CLOSE, RST, OPEN }
|
|
||||||
|
|
||||||
chan AtoN = [2] of { mtype };
|
|
||||||
chan NtoA = [2] of { mtype };
|
|
||||||
chan BtoN = [2] of { mtype };
|
|
||||||
chan NtoB = [2] of { mtype };
|
|
||||||
|
|
||||||
int state[2];
|
|
||||||
int pids[2];
|
|
||||||
|
|
||||||
#define ClosedState 0
|
|
||||||
#define ListenState 1
|
|
||||||
#define SynSentState 2
|
|
||||||
#define SynRecState 3
|
|
||||||
#define EstState 4
|
|
||||||
#define FinW1State 5
|
|
||||||
#define CloseWaitState 6
|
|
||||||
#define FinW2State 7
|
|
||||||
#define ClosingState 8
|
|
||||||
#define LastAckState 9
|
|
||||||
#define TimeWaitState 10
|
|
||||||
#define EndState -1
|
|
||||||
|
|
||||||
#define leftConnecting (state[0] == ListenState && state[1] == SynSentState)
|
|
||||||
#define leftEstablished (state[0] == EstState)
|
|
||||||
#define rightEstablished (state[1] == EstState)
|
|
||||||
#define leftClosed (state[0] == ClosedState)
|
|
||||||
|
|
||||||
proctype TCP(chan snd, rcv; int i) {
|
|
||||||
pids[i] = _pid;
|
|
||||||
CLOSED:
|
|
||||||
state[i] = ClosedState;
|
|
||||||
do
|
|
||||||
/* Passive open */
|
|
||||||
:: goto LISTEN;
|
|
||||||
/* Active open */
|
|
||||||
:: snd ! SYN; goto SYN_SENT;
|
|
||||||
/* Terminate */
|
|
||||||
:: goto end;
|
|
||||||
od
|
|
||||||
LISTEN:
|
|
||||||
state[i] = ListenState;
|
|
||||||
do
|
|
||||||
:: rcv ? SYN ->
|
|
||||||
atomic {
|
|
||||||
snd ! SYN;
|
|
||||||
snd ! ACK;
|
|
||||||
goto SYN_RECEIVED;
|
|
||||||
}
|
|
||||||
/* Simultaneous LISTEN */
|
|
||||||
:: rcv ? _ -> skip;
|
|
||||||
:: timeout -> goto CLOSED;
|
|
||||||
od
|
|
||||||
SYN_SENT:
|
|
||||||
state[i] = SynSentState;
|
|
||||||
do
|
|
||||||
:: rcv ? SYN;
|
|
||||||
if
|
|
||||||
/* Standard behavior */
|
|
||||||
:: rcv ? ACK -> snd ! ACK; goto ESTABLISHED;
|
|
||||||
/* Simultaneous open */
|
|
||||||
:: snd ! ACK; goto SYN_RECEIVED;
|
|
||||||
fi
|
|
||||||
:: rcv ? ACK;
|
|
||||||
do
|
|
||||||
:: rcv ? SYN ->
|
|
||||||
snd ! ACK;
|
|
||||||
goto ESTABLISHED;
|
|
||||||
:: rcv ? _ -> skip;
|
|
||||||
od
|
|
||||||
:: rcv ? _ -> skip;
|
|
||||||
:: timeout -> goto CLOSED; /* Timeout */
|
|
||||||
od
|
|
||||||
SYN_RECEIVED:
|
|
||||||
state[i] = SynRecState;
|
|
||||||
do
|
|
||||||
:: rcv ? ACK -> goto ESTABLISHED;
|
|
||||||
:: rcv ? _ -> skip;
|
|
||||||
od
|
|
||||||
/* We may want to consider putting a timeout -> CLOSED here. */
|
|
||||||
ESTABLISHED:
|
|
||||||
state[i] = EstState;
|
|
||||||
do
|
|
||||||
/* Close - initiator sequence */
|
|
||||||
:: snd ! FIN; goto FIN_WAIT_1;
|
|
||||||
/* Close - responder sequence */
|
|
||||||
:: rcv ? FIN ->
|
|
||||||
snd ! ACK;
|
|
||||||
goto CLOSE_WAIT;
|
|
||||||
:: rcv ? _ -> skip;
|
|
||||||
od
|
|
||||||
FIN_WAIT_1:
|
|
||||||
state[i] = FinW1State;
|
|
||||||
do
|
|
||||||
/* Simultaneous close */
|
|
||||||
:: rcv ? FIN ->
|
|
||||||
snd ! ACK;
|
|
||||||
goto CLOSING;
|
|
||||||
/* Standard close */
|
|
||||||
:: rcv ? ACK -> goto FIN_WAIT_2;
|
|
||||||
:: rcv ? _ -> skip;
|
|
||||||
od
|
|
||||||
CLOSE_WAIT:
|
|
||||||
state[i] = CloseWaitState;
|
|
||||||
do
|
|
||||||
:: snd ! FIN; goto LAST_ACK;
|
|
||||||
:: rcv ? _ -> skip;
|
|
||||||
od
|
|
||||||
FIN_WAIT_2:
|
|
||||||
state[i] = FinW2State;
|
|
||||||
do
|
|
||||||
:: rcv ? FIN ->
|
|
||||||
snd ! ACK;
|
|
||||||
goto TIME_WAIT;
|
|
||||||
:: rcv ? _ -> skip;
|
|
||||||
od
|
|
||||||
CLOSING:
|
|
||||||
state[i] = ClosingState;
|
|
||||||
do
|
|
||||||
:: rcv ? ACK -> goto TIME_WAIT;
|
|
||||||
:: rcv ? _ -> skip;
|
|
||||||
od
|
|
||||||
LAST_ACK:
|
|
||||||
state[i] = LastAckState;
|
|
||||||
do
|
|
||||||
:: rcv ? ACK -> goto CLOSED;
|
|
||||||
:: rcv ? _ -> skip;
|
|
||||||
od
|
|
||||||
TIME_WAIT:
|
|
||||||
state[i] = TimeWaitState;
|
|
||||||
goto CLOSED;
|
|
||||||
end:
|
|
||||||
state[i] = EndState;
|
|
||||||
}
|
|
||||||
|
|
||||||
init {
|
|
||||||
state[0] = ClosedState;
|
|
||||||
state[1] = ClosedState;
|
|
||||||
run TCP(AtoN, NtoA, 0);
|
|
||||||
run TCP(BtoN, NtoB, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* safety: strict closing transitions */
|
|
||||||
ltl phi6 {
|
|
||||||
always (
|
|
||||||
(state[0] == ClosingState)
|
|
||||||
implies
|
|
||||||
(next (state[0] == ClosingState ||
|
|
||||||
state[0] == ClosedState))
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@@ -1,144 +0,0 @@
|
|||||||
// models: phi1, phi2, phi3, phi5
|
|
||||||
// does not model: phi4, phi7
|
|
||||||
// not yet implemented: phi6
|
|
||||||
mtype = { SYN, FIN, ACK, ABORT, CLOSE, RST, OPEN }
|
|
||||||
|
|
||||||
chan AtoN = [2] of { mtype };
|
|
||||||
chan NtoA = [2] of { mtype };
|
|
||||||
chan BtoN = [2] of { mtype };
|
|
||||||
chan NtoB = [2] of { mtype };
|
|
||||||
|
|
||||||
int state[2];
|
|
||||||
int pids[2];
|
|
||||||
|
|
||||||
#define ClosedState 0
|
|
||||||
#define ListenState 1
|
|
||||||
#define SynSentState 2
|
|
||||||
#define SynRecState 3
|
|
||||||
#define EstState 4
|
|
||||||
#define FinW1State 5
|
|
||||||
#define CloseWaitState 6
|
|
||||||
#define FinW2State 7
|
|
||||||
#define ClosingState 8
|
|
||||||
#define LastAckState 9
|
|
||||||
#define TimeWaitState 10
|
|
||||||
#define EndState -1
|
|
||||||
|
|
||||||
#define leftConnecting (state[0] == ListenState && state[1] == SynSentState)
|
|
||||||
#define leftEstablished (state[0] == EstState)
|
|
||||||
#define rightEstablished (state[1] == EstState)
|
|
||||||
#define leftClosed (state[0] == ClosedState)
|
|
||||||
|
|
||||||
proctype TCP(chan snd, rcv; int i) {
|
|
||||||
pids[i] = _pid;
|
|
||||||
CLOSED:
|
|
||||||
state[i] = ClosedState;
|
|
||||||
do
|
|
||||||
/* Passive open */
|
|
||||||
:: goto LISTEN;
|
|
||||||
/* Active open */
|
|
||||||
:: snd ! SYN; goto SYN_SENT;
|
|
||||||
/* Terminate */
|
|
||||||
:: goto end;
|
|
||||||
od
|
|
||||||
LISTEN:
|
|
||||||
state[i] = ListenState;
|
|
||||||
do
|
|
||||||
:: rcv ? SYN ->
|
|
||||||
atomic {
|
|
||||||
snd ! SYN;
|
|
||||||
snd ! ACK;
|
|
||||||
goto SYN_RECEIVED;
|
|
||||||
}
|
|
||||||
/* Simultaneous LISTEN */
|
|
||||||
:: rcv ? _ -> skip;
|
|
||||||
:: timeout -> goto CLOSED;
|
|
||||||
od
|
|
||||||
SYN_SENT:
|
|
||||||
state[i] = SynSentState;
|
|
||||||
do
|
|
||||||
:: rcv ? SYN;
|
|
||||||
if
|
|
||||||
/* Standard behavior */
|
|
||||||
:: rcv ? ACK -> snd ! ACK; goto ESTABLISHED;
|
|
||||||
/* Simultaneous open */
|
|
||||||
:: snd ! ACK; goto SYN_RECEIVED;
|
|
||||||
fi
|
|
||||||
:: rcv ? ACK;
|
|
||||||
do
|
|
||||||
:: rcv ? SYN ->
|
|
||||||
snd ! ACK;
|
|
||||||
goto ESTABLISHED;
|
|
||||||
:: rcv ? _ -> skip;
|
|
||||||
od
|
|
||||||
:: rcv ? _ -> skip;
|
|
||||||
:: timeout -> goto CLOSED; /* Timeout */
|
|
||||||
od
|
|
||||||
SYN_RECEIVED:
|
|
||||||
state[i] = SynRecState;
|
|
||||||
do
|
|
||||||
:: rcv ? ACK -> goto ESTABLISHED;
|
|
||||||
:: rcv ? _ -> skip;
|
|
||||||
od
|
|
||||||
/* We may want to consider putting a timeout -> CLOSED here. */
|
|
||||||
ESTABLISHED:
|
|
||||||
state[i] = EstState;
|
|
||||||
do
|
|
||||||
/* Close - initiator sequence */
|
|
||||||
:: snd ! FIN; goto FIN_WAIT_1;
|
|
||||||
/* Close - responder sequence */
|
|
||||||
:: rcv ? FIN ->
|
|
||||||
snd ! ACK;
|
|
||||||
goto CLOSE_WAIT;
|
|
||||||
:: rcv ? _ -> skip;
|
|
||||||
od
|
|
||||||
FIN_WAIT_1:
|
|
||||||
state[i] = FinW1State;
|
|
||||||
do
|
|
||||||
/* Simultaneous close */
|
|
||||||
:: rcv ? FIN ->
|
|
||||||
snd ! ACK;
|
|
||||||
goto CLOSING;
|
|
||||||
/* Standard close */
|
|
||||||
:: rcv ? ACK -> goto FIN_WAIT_2;
|
|
||||||
:: rcv ? _ -> skip;
|
|
||||||
od
|
|
||||||
CLOSE_WAIT:
|
|
||||||
state[i] = CloseWaitState;
|
|
||||||
do
|
|
||||||
:: snd ! FIN; goto LAST_ACK;
|
|
||||||
:: rcv ? _ -> skip;
|
|
||||||
od
|
|
||||||
FIN_WAIT_2:
|
|
||||||
state[i] = FinW2State;
|
|
||||||
do
|
|
||||||
:: rcv ? FIN ->
|
|
||||||
snd ! ACK;
|
|
||||||
goto TIME_WAIT;
|
|
||||||
:: rcv ? _ -> skip;
|
|
||||||
od
|
|
||||||
CLOSING:
|
|
||||||
state[i] = ClosingState;
|
|
||||||
do
|
|
||||||
:: rcv ? ACK -> goto TIME_WAIT;
|
|
||||||
:: rcv ? _ -> skip;
|
|
||||||
od
|
|
||||||
LAST_ACK:
|
|
||||||
state[i] = LastAckState;
|
|
||||||
do
|
|
||||||
:: rcv ? ACK -> goto CLOSED;
|
|
||||||
:: rcv ? _ -> skip;
|
|
||||||
od
|
|
||||||
TIME_WAIT:
|
|
||||||
state[i] = TimeWaitState;
|
|
||||||
goto CLOSED;
|
|
||||||
end:
|
|
||||||
state[i] = EndState;
|
|
||||||
}
|
|
||||||
|
|
||||||
init {
|
|
||||||
state[0] = ClosedState;
|
|
||||||
state[1] = ClosedState;
|
|
||||||
run TCP(AtoN, NtoA, 0);
|
|
||||||
run TCP(BtoN, NtoB, 1);
|
|
||||||
}
|
|
||||||
Binary file not shown.
@@ -1,192 +0,0 @@
|
|||||||
-2:2:-2
|
|
||||||
-4:-4:-4
|
|
||||||
1:0:139
|
|
||||||
2:1:130
|
|
||||||
3:0:139
|
|
||||||
4:1:131
|
|
||||||
5:0:139
|
|
||||||
6:1:132
|
|
||||||
7:1:133
|
|
||||||
8:0:139
|
|
||||||
9:3:0
|
|
||||||
10:0:139
|
|
||||||
11:3:1
|
|
||||||
12:0:139
|
|
||||||
13:3:6
|
|
||||||
14:0:139
|
|
||||||
15:2:0
|
|
||||||
16:0:139
|
|
||||||
17:2:1
|
|
||||||
18:0:139
|
|
||||||
19:2:6
|
|
||||||
20:0:139
|
|
||||||
21:3:16
|
|
||||||
22:0:139
|
|
||||||
23:3:0
|
|
||||||
24:0:139
|
|
||||||
25:3:2
|
|
||||||
26:0:139
|
|
||||||
27:3:21
|
|
||||||
28:0:139
|
|
||||||
29:2:7
|
|
||||||
30:0:139
|
|
||||||
31:2:8
|
|
||||||
32:0:139
|
|
||||||
33:2:9
|
|
||||||
34:0:139
|
|
||||||
35:3:22
|
|
||||||
36:0:139
|
|
||||||
37:3:23
|
|
||||||
38:0:139
|
|
||||||
39:3:24
|
|
||||||
40:0:139
|
|
||||||
41:3:49
|
|
||||||
42:0:139
|
|
||||||
43:2:10
|
|
||||||
44:0:139
|
|
||||||
45:3:50
|
|
||||||
46:0:139
|
|
||||||
47:3:51
|
|
||||||
48:0:139
|
|
||||||
49:3:62
|
|
||||||
50:0:139
|
|
||||||
51:3:63
|
|
||||||
52:0:139
|
|
||||||
53:3:76
|
|
||||||
54:0:139
|
|
||||||
55:2:49
|
|
||||||
56:0:139
|
|
||||||
57:2:50
|
|
||||||
58:0:139
|
|
||||||
59:2:51
|
|
||||||
60:0:139
|
|
||||||
61:2:62
|
|
||||||
62:0:139
|
|
||||||
63:2:63
|
|
||||||
64:0:139
|
|
||||||
65:3:77
|
|
||||||
66:0:139
|
|
||||||
67:3:78
|
|
||||||
68:0:139
|
|
||||||
69:3:79
|
|
||||||
70:0:139
|
|
||||||
71:3:102
|
|
||||||
72:0:139
|
|
||||||
73:2:76
|
|
||||||
74:0:139
|
|
||||||
75:2:77
|
|
||||||
76:0:139
|
|
||||||
77:2:78
|
|
||||||
78:0:139
|
|
||||||
79:2:79
|
|
||||||
80:0:139
|
|
||||||
81:3:103
|
|
||||||
82:0:139
|
|
||||||
83:3:104
|
|
||||||
84:0:139
|
|
||||||
85:3:127
|
|
||||||
86:0:139
|
|
||||||
87:3:0
|
|
||||||
88:0:139
|
|
||||||
89:3:1
|
|
||||||
90:0:139
|
|
||||||
91:2:102
|
|
||||||
92:0:139
|
|
||||||
93:2:103
|
|
||||||
94:0:139
|
|
||||||
95:2:104
|
|
||||||
96:0:139
|
|
||||||
97:2:127
|
|
||||||
98:0:139
|
|
||||||
99:2:0
|
|
||||||
100:0:139
|
|
||||||
101:2:2
|
|
||||||
102:0:139
|
|
||||||
103:3:6
|
|
||||||
104:0:139
|
|
||||||
105:3:7
|
|
||||||
106:0:139
|
|
||||||
107:3:8
|
|
||||||
108:0:139
|
|
||||||
109:3:9
|
|
||||||
110:0:139
|
|
||||||
111:3:10
|
|
||||||
112:0:139
|
|
||||||
113:3:49
|
|
||||||
114:0:139
|
|
||||||
115:2:21
|
|
||||||
116:0:139
|
|
||||||
117:2:22
|
|
||||||
118:0:139
|
|
||||||
119:2:23
|
|
||||||
120:0:139
|
|
||||||
121:2:24
|
|
||||||
122:0:139
|
|
||||||
123:3:50
|
|
||||||
124:0:139
|
|
||||||
125:3:51
|
|
||||||
126:0:139
|
|
||||||
127:3:62
|
|
||||||
128:0:139
|
|
||||||
129:3:63
|
|
||||||
130:0:139
|
|
||||||
131:2:49
|
|
||||||
132:0:139
|
|
||||||
133:2:50
|
|
||||||
134:0:139
|
|
||||||
135:2:51
|
|
||||||
136:0:139
|
|
||||||
137:2:62
|
|
||||||
138:0:139
|
|
||||||
139:2:63
|
|
||||||
140:0:139
|
|
||||||
141:2:76
|
|
||||||
142:0:139
|
|
||||||
143:3:76
|
|
||||||
144:0:139
|
|
||||||
145:3:77
|
|
||||||
146:0:139
|
|
||||||
147:3:78
|
|
||||||
148:0:139
|
|
||||||
149:3:79
|
|
||||||
150:0:139
|
|
||||||
151:2:77
|
|
||||||
152:0:139
|
|
||||||
153:2:78
|
|
||||||
154:0:139
|
|
||||||
155:2:79
|
|
||||||
156:0:139
|
|
||||||
157:2:102
|
|
||||||
158:0:139
|
|
||||||
159:3:102
|
|
||||||
160:0:139
|
|
||||||
161:3:103
|
|
||||||
162:0:139
|
|
||||||
163:3:104
|
|
||||||
164:0:139
|
|
||||||
165:3:127
|
|
||||||
166:0:139
|
|
||||||
167:3:0
|
|
||||||
168:0:139
|
|
||||||
169:3:2
|
|
||||||
170:0:139
|
|
||||||
171:3:21
|
|
||||||
172:0:139
|
|
||||||
173:2:103
|
|
||||||
174:0:139
|
|
||||||
175:2:104
|
|
||||||
176:0:139
|
|
||||||
177:2:127
|
|
||||||
178:0:139
|
|
||||||
179:2:0
|
|
||||||
180:0:139
|
|
||||||
181:2:2
|
|
||||||
182:0:139
|
|
||||||
183:3:22
|
|
||||||
184:0:139
|
|
||||||
185:3:23
|
|
||||||
186:0:139
|
|
||||||
187:3:24
|
|
||||||
188:0:139
|
|
||||||
189:2:21
|
|
||||||
190:0:136
|
|
||||||
@@ -1,102 +0,0 @@
|
|||||||
-2:2:-2
|
|
||||||
-4:-4:-4
|
|
||||||
1:0:138
|
|
||||||
2:1:130
|
|
||||||
3:0:138
|
|
||||||
4:1:131
|
|
||||||
5:0:138
|
|
||||||
6:1:132
|
|
||||||
7:1:133
|
|
||||||
8:0:138
|
|
||||||
9:3:0
|
|
||||||
10:0:138
|
|
||||||
11:3:1
|
|
||||||
12:0:138
|
|
||||||
13:3:6
|
|
||||||
14:0:138
|
|
||||||
15:2:0
|
|
||||||
16:0:138
|
|
||||||
17:2:1
|
|
||||||
18:0:138
|
|
||||||
19:2:6
|
|
||||||
20:0:138
|
|
||||||
21:3:16
|
|
||||||
22:0:138
|
|
||||||
23:3:0
|
|
||||||
24:0:138
|
|
||||||
25:3:2
|
|
||||||
26:0:138
|
|
||||||
27:3:21
|
|
||||||
28:0:138
|
|
||||||
29:2:7
|
|
||||||
30:0:138
|
|
||||||
31:2:8
|
|
||||||
32:0:138
|
|
||||||
33:2:9
|
|
||||||
34:0:138
|
|
||||||
35:3:22
|
|
||||||
36:0:138
|
|
||||||
37:3:23
|
|
||||||
38:0:138
|
|
||||||
39:3:24
|
|
||||||
40:0:138
|
|
||||||
41:3:49
|
|
||||||
42:0:138
|
|
||||||
43:2:10
|
|
||||||
44:0:138
|
|
||||||
45:3:50
|
|
||||||
46:0:138
|
|
||||||
47:3:51
|
|
||||||
48:0:138
|
|
||||||
49:3:62
|
|
||||||
50:0:138
|
|
||||||
51:3:63
|
|
||||||
52:0:138
|
|
||||||
53:3:76
|
|
||||||
54:0:138
|
|
||||||
55:2:49
|
|
||||||
56:0:138
|
|
||||||
57:2:50
|
|
||||||
58:0:138
|
|
||||||
59:2:51
|
|
||||||
60:0:138
|
|
||||||
61:2:62
|
|
||||||
62:0:138
|
|
||||||
63:2:63
|
|
||||||
64:0:138
|
|
||||||
65:3:77
|
|
||||||
66:0:138
|
|
||||||
67:3:78
|
|
||||||
68:0:138
|
|
||||||
69:3:79
|
|
||||||
70:0:138
|
|
||||||
71:3:102
|
|
||||||
72:0:138
|
|
||||||
73:2:76
|
|
||||||
74:0:138
|
|
||||||
75:2:77
|
|
||||||
76:0:138
|
|
||||||
77:2:78
|
|
||||||
78:0:138
|
|
||||||
79:2:79
|
|
||||||
80:0:138
|
|
||||||
81:3:103
|
|
||||||
82:0:138
|
|
||||||
83:3:104
|
|
||||||
84:0:138
|
|
||||||
85:3:127
|
|
||||||
86:0:138
|
|
||||||
87:3:0
|
|
||||||
88:0:138
|
|
||||||
89:3:1
|
|
||||||
90:0:138
|
|
||||||
91:3:6
|
|
||||||
92:0:138
|
|
||||||
93:2:102
|
|
||||||
94:0:138
|
|
||||||
95:2:103
|
|
||||||
96:0:138
|
|
||||||
97:2:104
|
|
||||||
98:0:136
|
|
||||||
99:2:127
|
|
||||||
100:0:143
|
|
||||||
Reference in New Issue
Block a user