1# -*- test-case-name: vertex.test.test_ptcp -*-
2# Copyright 2005 Divmod, Inc.  See LICENSE file for details
3
4from vertex.statemachine import StateMachine, NOTHING
5
6# States
7
8CLOSED = 'CLOSED'
9LISTEN = 'LISTEN'
10SYN_RCVD = 'SYN_RCVD'
11SYN_SENT = 'SYN_SENT'
12ESTABLISHED = 'ESTABLISHED'
13CLOSE_WAIT = 'CLOSE_WAIT'
14LAST_ACK = 'LAST_ACK'
15CLOSING = 'CLOSING'
16FIN_WAIT_1 = 'FIN_WAIT_1'
17FIN_WAIT_2 = 'FIN_WAIT_2'
18TIME_WAIT = 'TIME_WAIT'
19
20# Network vocabulary
21SYN = 'SYN'
22ACK = 'ACK'
23SYN_ACK = 'SYN_ACK'
24FIN = 'FIN'
25RST = 'RST'
26
27# Application vocabulary
28APP_PASSIVE_OPEN = 'PASSIVE_OPEN'
29APP_ACTIVE_OPEN = 'ACTIVE_OPEN'
30APP_SEND_DATA = 'APP_SEND'
31TIMEOUT = 'TIMEOUT'
32APP_CLOSE = 'APP_CLOSE'
33
34# This isn't detailed by the spec in the diagram, so we use a different
35# identifier, but in various places it does make references to going straight
36# to the 'closed' state.
37BROKEN = 'CLOSED'
38
39
40class TCP(StateMachine):
41    # dict, mapping state to dict of input: (output, new-state)
42
43    states = {
44        CLOSED: {
45            APP_PASSIVE_OPEN: (NOTHING, LISTEN),
46            APP_ACTIVE_OPEN: (SYN, SYN_SENT),
47            },
48        SYN_SENT: {
49            TIMEOUT: (NOTHING, CLOSED),
50            APP_CLOSE: (NOTHING, CLOSED),
51            SYN_ACK: (ACK, ESTABLISHED),
52            # SYN: (SYN_ACK, SYN_RCVD),
53            },
54        SYN_RCVD: {
55            ACK: (NOTHING, ESTABLISHED),
56            APP_CLOSE: (FIN, FIN_WAIT_1),
57            TIMEOUT: (RST, CLOSED),
58            RST: (NOTHING, LISTEN),
59            },
60        LISTEN: {
61            APP_SEND_DATA: (SYN, SYN_SENT),
62            SYN: (SYN_ACK, SYN_RCVD),
63            },
64        ESTABLISHED: {
65            APP_CLOSE: (FIN, FIN_WAIT_1),
66            FIN: (ACK, CLOSE_WAIT),
67            TIMEOUT: (NOTHING, BROKEN),
68            },
69        CLOSE_WAIT: {
70            APP_CLOSE: (FIN, LAST_ACK),
71            TIMEOUT: (NOTHING, BROKEN),
72            },
73        LAST_ACK:  {
74            ACK: (NOTHING, CLOSED),
75            TIMEOUT: (NOTHING, BROKEN),
76            },
77        FIN_WAIT_1: {
78            ACK: (NOTHING, FIN_WAIT_2),
79            FIN: (ACK, CLOSING),
80            # FIN_ACK: (ACK, TIME_WAIT),
81            TIMEOUT: (NOTHING, BROKEN),
82            },
83        FIN_WAIT_2: {
84            TIMEOUT: (NOTHING, BROKEN),
85            FIN: (ACK, TIME_WAIT),
86            },
87        CLOSING: {
88            TIMEOUT: (NOTHING, BROKEN),
89            ACK: (NOTHING, TIME_WAIT),
90            },
91        TIME_WAIT: {
92            TIMEOUT: (NOTHING, CLOSED),
93            },
94        }
95
96    initialState = CLOSED
97