3 # Message.py -- Switzerland protocol messages.
9 Message: represents each message that can be sent by Alice or Switzerland
10 or both. We don't instantiate this class for every message on the wire;
11 these objects are just used to fill static dicts that the *Link classes
12 use to look up message properties.
15 def __init__(self
, name
, arguments
, expects_ack
, expects_reply
, is_reply
):
16 assert isinstance(name
, types
.StringType
)
17 assert isinstance(arguments
, types
.ListType
)
20 self
.length
= len(arguments
) + 1
21 self
.expects_ack
= expects_ack
22 self
.expects_reply
= expects_reply
23 self
.is_reply
= is_reply
25 if expects_ack
or expects_reply
:
26 self
.length
+= 1 # for a sequence number
29 self
.length
+= 1 # for a reply sequence number
31 alice_in_messages
= {}
32 alice_out_messages
= {}
33 switzerland_in_messages
= {}
34 switzerland_out_messages
= {}
36 # Some syntactic sugar -- concisely construct each message and place it in
37 # the correct categories.
38 def _cmsg(name
, num_args
, expects_ack
=False, expects_reply
=False,
40 """These go in either direction."""
42 msg
= Message(name
, num_args
, expects_ack
, expects_reply
, is_reply
)
43 alice_in_messages
[name
] = switzerland_out_messages
[name
] = msg
44 alice_out_messages
[name
] = switzerland_in_messages
[name
] = msg
46 def _amsg(name
, num_args
, expects_ack
=False, expects_reply
=False,
48 """Alice sends these to Switzerland."""
50 msg
= Message(name
, num_args
, expects_ack
, expects_reply
, is_reply
)
51 alice_out_messages
[name
] = msg
52 switzerland_in_messages
[name
] = msg
54 def _smsg(name
, num_args
, expects_ack
=False, expects_reply
=False,
55 is_reply
=None, assert_len
=None):
56 """Switzerland sends these to alice."""
58 msg
= Message(name
, num_args
, expects_ack
, expects_reply
, is_reply
)
59 alice_in_messages
[name
] = msg
60 switzerland_out_messages
[name
] = msg
62 # The contents of the arguments below are purely for documentation
64 # Messages that can be sent in either direction.
66 _cmsg("ping", [], expects_ack
=True)
67 _cmsg("error-bye", ["details"])
68 _cmsg("error-cont", ["details"], expects_ack
=True)
70 _cmsg("ack", ["seq_no"], ) # sort of a special case for not having an is_ack
71 _cmsg("test", ["alpha", "beta", "gamma"])
73 # Alice -> Switzerland
76 [{"clock dispersion" : 0.085, "will send actual packets": False}])
77 _amsg("my-ip", [["my private ip", "my public ip"]], expects_reply
=True)
78 _amsg("active_flows", [["new flows"], ["deleted flows"]])
79 _amsg("flow_stats", [("flow", {"stat": "value"})])
80 _amsg("sent", ["flow id", "timestamp", "concatenated hashes"])
81 _amsg("recd", ["flow id", "timestamp", "concatenated hashes"])
82 _amsg("fi-context", [{"hash": [("timestamp", "hash", "data")]}], is_reply
=True, expects_reply
=True)
83 _amsg("fo-context", [{"hash": [("timestamp", "data")]}, {"hash": ["diff1","diff2"]}], is_reply
=True)
84 _amsg("rst-radar", [[("list", "of"), ("packet", "pairs")]])
85 _amsg("traceroute", ["destination", "type", "results"])
87 # Switzerland -> Alice
89 _smsg("debug-ipid", ["ipid"])
90 _smsg("public-ip", ["your public ip"], is_reply
=True)
91 _smsg("new-members", [[("ip1", "firewalled", "key"), ("ip2", "firewalled", "key")]], expects_ack
=True)
93 # Other client hangs up.
94 _smsg("farewell", ["ip"], expects_ack
=True)
95 # Other clients go missing.
96 _smsg("igcognito", [["list", "of", "ips"]], expects_ack
=True)
98 _smsg("forged-in", ["flow id", [("timestamp", "hash")]], expects_reply
=True)
99 _smsg("forged-out", ["flow id", [["context"]]], expects_reply
=True, assert_len
=2)
100 _smsg("forged-details", ["flow id", [("timestamp", "context", "report")]], is_reply
=True)
102 # The other side isn't reporting this flow in a way that allows us to match
104 _smsg("dangling-flow", ["flow id", "opening hash"])
106 # The other side isn't reporting this flow in a way that allows us to match
108 _smsg("flow-status", ["string"])