moar
This commit is contained in:
@@ -1,10 +1,9 @@
|
||||
mtype = { SYN, FIN, ACK, ABORT, CLOSE, RST, OPEN }
|
||||
mtype = { SYN, FIN, ACK }
|
||||
|
||||
chan AtoB = [2] of { mtype };
|
||||
chan BtoA = [2] of { mtype };
|
||||
|
||||
int state[2];
|
||||
int pids[2];
|
||||
|
||||
#define ClosedState 0
|
||||
#define ListenState 1
|
||||
@@ -17,124 +16,126 @@ int pids[2];
|
||||
#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;
|
||||
mtype msg;
|
||||
CLOSED:
|
||||
state[i] = ClosedState;
|
||||
do
|
||||
/* Passive open */
|
||||
:: goto LISTEN;
|
||||
/* Active open */
|
||||
:: snd ! SYN; goto SYN_SENT;
|
||||
/* Terminate */
|
||||
:: goto end;
|
||||
od
|
||||
state[i] = ClosedState;
|
||||
if
|
||||
:: goto LISTEN;
|
||||
:: snd ! SYN; goto SYN_SENT;
|
||||
fi;
|
||||
|
||||
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;
|
||||
state[i] = ListenState;
|
||||
do
|
||||
:: rcv ? SYN ->
|
||||
snd ! ACK;
|
||||
goto ESTABLISHED;
|
||||
:: rcv ? _ -> skip;
|
||||
od
|
||||
:: rcv ? _ -> skip;
|
||||
:: timeout -> goto CLOSED; /* Timeout */
|
||||
od
|
||||
:: rcv ? msg ->
|
||||
if
|
||||
:: msg == SYN -> snd ! SYN; snd ! ACK; goto SYN_RECEIVED;
|
||||
:: else -> skip;
|
||||
fi
|
||||
:: timeout -> goto CLOSED;
|
||||
od;
|
||||
|
||||
SYN_SENT:
|
||||
state[i] = SynSentState;
|
||||
do
|
||||
:: rcv ? msg ->
|
||||
if
|
||||
:: msg == SYN -> snd ! ACK; goto SYN_RECEIVED;
|
||||
:: msg == ACK ->
|
||||
do
|
||||
:: rcv ? msg ->
|
||||
if
|
||||
:: msg == SYN -> snd ! ACK; goto ESTABLISHED;
|
||||
:: else -> skip;
|
||||
fi
|
||||
:: timeout -> goto CLOSED;
|
||||
od
|
||||
:: else -> skip;
|
||||
fi
|
||||
:: timeout -> goto CLOSED;
|
||||
od;
|
||||
|
||||
SYN_RECEIVED:
|
||||
state[i] = SynRecState;
|
||||
do
|
||||
:: rcv ? ACK -> goto ESTABLISHED;
|
||||
:: rcv ? _ -> skip;
|
||||
od
|
||||
state[i] = SynRecState;
|
||||
do
|
||||
:: rcv ? msg ->
|
||||
if
|
||||
:: msg == ACK -> goto ESTABLISHED;
|
||||
:: else -> skip;
|
||||
fi
|
||||
:: timeout -> goto CLOSED;
|
||||
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
|
||||
state[i] = EstState;
|
||||
do
|
||||
:: snd ! FIN; goto FIN_WAIT_1;
|
||||
:: rcv ? msg ->
|
||||
if
|
||||
:: msg == FIN -> snd ! ACK; goto CLOSE_WAIT;
|
||||
:: else -> skip;
|
||||
fi
|
||||
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
|
||||
state[i] = FinW1State;
|
||||
do
|
||||
:: rcv ? msg ->
|
||||
if
|
||||
:: msg == FIN -> snd ! ACK; goto CLOSING;
|
||||
:: msg == ACK -> goto FIN_WAIT_2;
|
||||
:: else -> skip;
|
||||
fi
|
||||
od;
|
||||
|
||||
FIN_WAIT_2:
|
||||
state[i] = FinW2State;
|
||||
do
|
||||
:: rcv ? FIN ->
|
||||
snd ! ACK;
|
||||
goto TIME_WAIT;
|
||||
:: rcv ? _ -> skip;
|
||||
od
|
||||
state[i] = FinW2State;
|
||||
do
|
||||
:: rcv ? msg ->
|
||||
if
|
||||
:: msg == FIN -> snd ! ACK; goto TIME_WAIT;
|
||||
:: else -> skip;
|
||||
fi
|
||||
od;
|
||||
|
||||
CLOSING:
|
||||
state[i] = ClosingState;
|
||||
do
|
||||
:: rcv ? ACK -> goto TIME_WAIT;
|
||||
:: rcv ? _ -> skip;
|
||||
od
|
||||
state[i] = ClosingState;
|
||||
do
|
||||
:: rcv ? msg ->
|
||||
if
|
||||
:: msg == ACK -> goto TIME_WAIT;
|
||||
:: else -> skip;
|
||||
fi
|
||||
od;
|
||||
|
||||
CLOSE_WAIT:
|
||||
state[i] = CloseWaitState;
|
||||
snd ! FIN; goto LAST_ACK;
|
||||
|
||||
LAST_ACK:
|
||||
state[i] = LastAckState;
|
||||
do
|
||||
:: rcv ? ACK -> goto CLOSED;
|
||||
:: rcv ? _ -> skip;
|
||||
od
|
||||
state[i] = LastAckState;
|
||||
do
|
||||
:: rcv ? msg ->
|
||||
if
|
||||
:: msg == ACK -> goto CLOSED;
|
||||
:: else -> skip;
|
||||
fi
|
||||
od;
|
||||
|
||||
TIME_WAIT:
|
||||
state[i] = TimeWaitState;
|
||||
goto CLOSED;
|
||||
end:
|
||||
state[i] = EndState;
|
||||
state[i] = TimeWaitState;
|
||||
goto CLOSED;
|
||||
}
|
||||
|
||||
init {
|
||||
state[0] = ClosedState;
|
||||
state[1] = ClosedState;
|
||||
run TCP(AtoB, BtoA, 0);
|
||||
run TCP(BtoA, AtoB, 1);
|
||||
state[0] = ClosedState;
|
||||
state[1] = ClosedState;
|
||||
atomic {
|
||||
run TCP(AtoB, BtoA, 0);
|
||||
run TCP(BtoA, AtoB, 1);
|
||||
}
|
||||
}
|
||||
|
||||
/* safety: strict closing transitions */
|
||||
|
||||
Reference in New Issue
Block a user