Skip to content

Commit 42e5961

Browse files
committed
More RFC alignment work
1 parent 98429d2 commit 42e5961

14 files changed

Lines changed: 1205 additions & 132 deletions

docs/source/api.rst

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,15 @@ Now the application can get the event loop, call the listen the coroutine and th
117117
loop.create_task(preconnection.listen())
118118
loop.run_forever()
119119

120+
Rendezvous
121+
----------
122+
123+
To simultaneously listen and initiate from the same preconnection template, call ``rendezvous()``. The returned ``RendezvousResult`` gives access to both the actively initiated connection and the passive listener::
124+
125+
result = await preconnection.rendezvous(timeout=5)
126+
connection = result.connection
127+
listener = result.listener
128+
120129
Sending data
121130
------------
122131

docs/source/reference.rst

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@ Security Parameters
3939

4040
.. automethod:: add_identity
4141
.. automethod:: add_trust_ca
42+
.. automethod:: add_allowed_security_protocol
43+
.. automethod:: add_pinned_server_certificate
4244
.. automethod:: add_alpn_protocol
4345
.. automethod:: with_server_name
4446
.. automethod:: disable_peer_authentication
@@ -49,14 +51,26 @@ Preconnection
4951
.. autoclass:: Preconnection
5052

5153
.. automethod:: initiate
54+
.. automethod:: initiate_with_send
5255
.. automethod:: listen
56+
.. automethod:: rendezvous
5357
.. automethod:: resolve
5458
.. automethod:: add_framer
5559
.. automethod:: on_ready
5660
.. automethod:: on_initiate_error
61+
.. automethod:: on_establishment_error
5762
.. automethod:: on_connection_received
5863
.. automethod:: on_listen_error
5964
.. automethod:: on_stopped
65+
.. automethod:: on_rendezvous_done
66+
67+
Rendezvous Result
68+
-----------------
69+
.. autoclass:: RendezvousResult
70+
71+
.. automethod:: wait_ready
72+
.. automethod:: wait_listening
73+
.. automethod:: close
6074

6175
Connection
6276
----------
@@ -73,18 +87,39 @@ Connection
7387
.. automethod:: receive_message
7488
.. automethod:: wait_ready
7589
.. automethod:: wait_closed
90+
.. automethod:: note_path_change
7691
.. automethod:: close
7792
.. automethod:: on_ready
7893
.. automethod:: on_initiate_error
94+
.. automethod:: on_establishment_error
95+
.. automethod:: on_rendezvous_done
7996
.. automethod:: on_sent
8097
.. automethod:: on_send_error
8198
.. automethod:: on_expired
8299
.. automethod:: on_received
83100
.. automethod:: on_received_partial
84101
.. automethod:: on_receive_error
102+
.. automethod:: on_soft_error
103+
.. automethod:: on_path_change
85104
.. automethod:: on_connection_error
86105
.. automethod:: on_closed
87106

107+
Listener
108+
--------
109+
.. autoclass:: Listener
110+
111+
.. automethod:: wait_listening
112+
.. automethod:: accept
113+
.. automethod:: wait_stopped
114+
.. automethod:: stop
115+
116+
Connection Group
117+
----------------
118+
.. autoclass:: ConnectionGroup
119+
120+
.. automethod:: close
121+
.. automethod:: abort
122+
88123
Framer
89124
------
90125
.. autoclass:: Framer

docs/source/rfc-gap-analysis.rst

Lines changed: 129 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -9,55 +9,132 @@ work are:
99
- RFC 9622: An Abstract Application Programming Interface (API) for Transport Services
1010
- RFC 9623: Implementing Interfaces to Transport Services
1111

12-
Initial observations
13-
--------------------
14-
15-
- The public API is centered on ``Preconnection``, ``Connection``, and
16-
``Listener``, which is compatible with the overall TAPS architecture, but the
17-
available operations and event coverage are much smaller than the final API.
18-
- Transport properties are still modeled using an older, smaller property set
19-
and do not yet include the full RFC 9622 property catalog.
20-
- Candidate gathering and racing exist, but they currently implement a much
21-
simpler protocol ranking scheme than the branch-sorting and cache-informed
22-
candidate selection described in RFC 9623.
23-
- Optional YANG and multicast integrations are wired into the repository, but
24-
they are not yet packaged as cleanly optional features for modern installs.
25-
26-
Suggested phases
27-
----------------
28-
29-
Phase 1: Modernize the developer surface
30-
31-
- keep package importable on current Python versions
32-
- declare dependencies and optional features explicitly
33-
- make automated tests runnable in a clean environment
34-
35-
Phase 2: Define the spec delta
36-
37-
- map every RFC 9622 API object, method, callback, property, and event to
38-
current implementation status
39-
- classify each item as implemented, partial, missing, or draft-only legacy
40-
41-
Phase 3: Reconcile the core object model
42-
43-
- make Preconnection state immutable after Initiate or Listen
44-
- add a model for Connection Groups and cloned Connections
45-
- distinguish Selection Properties from Connection Properties
46-
47-
Phase 4: Rework establishment and racing
48-
49-
- gather candidate paths, endpoints, and protocol stacks separately
50-
- sort branches using prohibited, required, preferred, and avoided properties
51-
- incorporate cached state and policy hooks per RFC 9623
52-
53-
Phase 5: Expand transfer semantics
54-
55-
- extend message contexts and message properties
56-
- align send and receive events with the RFC 9622 lifecycle
57-
- support additional establishment patterns such as InitiateWithSend and Rendezvous
58-
59-
Phase 6: Grow transport and security coverage
60-
61-
- refresh TLS handling against the RFC security parameter model
62-
- assess protocol support for QUIC, SCTP, multipath, and multistreaming
63-
- add targeted conformance and interoperability tests
12+
Current status
13+
--------------
14+
15+
The repository is no longer at its original draft-era baseline. It now has a
16+
usable RFC-facing core, but it is still a partial implementation of RFC 9622.
17+
The status labels below are practical engineering labels rather than formal
18+
conformance claims:
19+
20+
- ``implemented`` means the repo has a real, tested implementation of the
21+
feature area
22+
- ``partial`` means a meaningful subset exists, but the RFC surface is broader
23+
- ``missing`` means the feature is not meaningfully present yet
24+
25+
RFC 9622 checklist
26+
------------------
27+
28+
+---------------------------------------------+-------------+--------------------------------------------------------------+
29+
| API area | Status | Notes |
30+
+=============================================+=============+==============================================================+
31+
| ``Preconnection`` object | partial | Endpoints, properties, security, YANG loading, ``initiate``, |
32+
| | | ``listen``, and ``rendezvous`` are implemented; full RFC |
33+
| | | API still broader. |
34+
+---------------------------------------------+-------------+--------------------------------------------------------------+
35+
| ``Connection`` object | partial | Send/receive/close, property access, clone support, |
36+
| | | lifecycle waiters, batching, and expiration exist. |
37+
+---------------------------------------------+-------------+--------------------------------------------------------------+
38+
| ``Listener`` object | partial | ``wait_listening()``, ``accept()``, ``stop()``, error |
39+
| | | propagation, and lifecycle state are present. |
40+
+---------------------------------------------+-------------+--------------------------------------------------------------+
41+
| ``ConnectionGroup`` | partial | Group-wide close/abort and shared connection-property |
42+
| | | propagation exist, but semantics are still lightweight. |
43+
+---------------------------------------------+-------------+--------------------------------------------------------------+
44+
| Selection Properties | partial | Clear split from connection properties with RFC-style |
45+
| | | canonical names and a stronger security property set. |
46+
+---------------------------------------------+-------------+--------------------------------------------------------------+
47+
| Connection Properties | partial | Query/update support exists, but the RFC catalog is not |
48+
| | | complete yet. |
49+
+---------------------------------------------+-------------+--------------------------------------------------------------+
50+
| Message Properties / Context | partial | ``msgPriority``, ``msgOrdered``, ``msgLifetime``, |
51+
| | | ``safelyReplayable``, ``final``, batching, and addressing |
52+
| | | metadata are implemented. |
53+
+---------------------------------------------+-------------+--------------------------------------------------------------+
54+
| ``Initiate`` | partial | Real candidate racing, failure propagation, and waiters |
55+
| | | exist, but not all RFC establishment behaviors. |
56+
+---------------------------------------------+-------------+--------------------------------------------------------------+
57+
| ``InitiateWithSend`` | implemented | Present and backed by runtime behavior, including |
58+
| | | pre-establishment expiration handling. |
59+
+---------------------------------------------+-------------+--------------------------------------------------------------+
60+
| ``Listen`` | partial | Works for TCP, UDP, and TLS listeners with explicit |
61+
| | | lifecycle state. |
62+
+---------------------------------------------+-------------+--------------------------------------------------------------+
63+
| ``Rendezvous`` | partial | Implemented with simultaneous local listen and active |
64+
| | | initiate, but still without broader rendezvous policy |
65+
| | | semantics. |
66+
+---------------------------------------------+-------------+--------------------------------------------------------------+
67+
| ``Clone`` | partial | Exists and integrates with connection groups, but semantics |
68+
| | | are not fully RFC-complete. |
69+
+---------------------------------------------+-------------+--------------------------------------------------------------+
70+
| ``Send`` | partial | Message context, expiration, batch send, queueing, |
71+
| | | and priority scheduling are implemented. |
72+
+---------------------------------------------+-------------+--------------------------------------------------------------+
73+
| ``Receive`` | partial | Awaitable and callback-driven receive paths both exist, |
74+
| | | including partial stream delivery. |
75+
+---------------------------------------------+-------------+--------------------------------------------------------------+
76+
| Close / Abort | partial | Connection and group close/abort exist with improved |
77+
| | | lifecycle handling, but not the full RFC event surface. |
78+
+---------------------------------------------+-------------+--------------------------------------------------------------+
79+
| Add/Remove Local and Remote Endpoints | partial | Implemented on ``Connection`` with basic endpoint merging |
80+
| | | and removal behavior. |
81+
+---------------------------------------------+-------------+--------------------------------------------------------------+
82+
| Property inspection and mutation | partial | Connection, preconnection, listener, and message property |
83+
| | | accessors exist, but not yet a full RFC API map. |
84+
+---------------------------------------------+-------------+--------------------------------------------------------------+
85+
| Ready / Closed / Error lifecycle events | partial | Much more explicit than the original code; still not a |
86+
| | | complete RFC event matrix. |
87+
+---------------------------------------------+-------------+--------------------------------------------------------------+
88+
| Sent / SendError / Expired events | partial | Sent and send-error callbacks exist, and expired messages |
89+
| | | now trigger real runtime behavior. |
90+
+---------------------------------------------+-------------+--------------------------------------------------------------+
91+
| Received / Partial Received events | partial | Present and now carry structured message context. |
92+
+---------------------------------------------+-------------+--------------------------------------------------------------+
93+
| Security Parameters | partial | Trust CA, identity, ALPN, SNI, cipher suites, and peer-auth |
94+
| | | control exist, but not the full RFC security surface. |
95+
+---------------------------------------------+-------------+--------------------------------------------------------------+
96+
| Framers | partial | Supported with working helper API and message-context |
97+
| | | propagation; still relatively lightweight overall. |
98+
+---------------------------------------------+-------------+--------------------------------------------------------------+
99+
| QUIC / SCTP | missing | Not implemented. |
100+
+---------------------------------------------+-------------+--------------------------------------------------------------+
101+
| Multistreaming / Multipath runtime support | missing | Property names exist in part, but real transport/runtime |
102+
| | | support is not there yet. |
103+
+---------------------------------------------+-------------+--------------------------------------------------------------+
104+
| YANG alignment | partial | Existing YANG examples still work, but the final RFC model |
105+
| | | is not fully mapped. |
106+
+---------------------------------------------+-------------+--------------------------------------------------------------+
107+
108+
Where the repository is strongest
109+
---------------------------------
110+
111+
- The core object model is now much cleaner and better structured.
112+
- The establishment path is substantially closer to RFC 9623 than the original
113+
codebase.
114+
- TLS handling is real rather than nominal, and the test PKI is current.
115+
- Message lifecycle behavior is now materially better, including receive
116+
waiters, expiration, batching, and priority-aware queue flush.
117+
- The test and lint baseline is healthy enough to support further spec work.
118+
119+
Largest remaining RFC 9622 gaps
120+
-------------------------------
121+
122+
- Complete the RFC 9622 property catalog, especially the remaining connection
123+
and message properties.
124+
- Expand the event model and advisory-error surface beyond the current subset.
125+
- Complete the remaining event and advisory-error surface around the now
126+
broader establishment API.
127+
- Decide which advanced transports are genuinely in scope for this repository,
128+
especially QUIC, SCTP, multistreaming, and multipath.
129+
- Build a more systematic conformance matrix and targeted interoperability
130+
tests.
131+
132+
Recommended next steps
133+
----------------------
134+
135+
1. Complete the property catalog section by section from RFC 9622.
136+
2. Fill out the remaining event and advisory-error semantics.
137+
3. Extend the now-present API surface with fuller RFC event and policy
138+
semantics, especially around groups and advisory errors.
139+
4. Decide whether this repository will grow into a fuller transport
140+
implementation or remain a cleaned-up reference subset.

examples/echo_example/echoClient.py

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -76,14 +76,23 @@ async def handle_ready(self, connection):
7676
taps.print_time("Connection cbs set.", color)
7777

7878
# Send messages
79-
await self.connection.send("Hello\n")
80-
await self.connection.send("There")
81-
await self.connection.send("Friend")
82-
await self.connection.send("How")
83-
await self.connection.send("Are")
84-
await self.connection.send("You\n")
85-
await self.connection.send("Today?\n")
86-
await self.connection.send("343536")
79+
async def send_message(data):
80+
send_context = None
81+
if self.connection.protocol == "udp":
82+
send_context = self.connection.new_message_context(
83+
safelyReplayable=True,
84+
final=False,
85+
)
86+
await self.connection.send(data, send_context)
87+
88+
await send_message("Hello\n")
89+
await send_message("There")
90+
await send_message("Friend")
91+
await send_message("How")
92+
await send_message("Are")
93+
await send_message("You\n")
94+
await send_message("Today?\n")
95+
await send_message("343536")
8796
taps.print_time("send called.", color)
8897

8998
async def main(self, args):

examples/echo_example/echoServer.py

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,14 +44,26 @@ async def handle_received_partial(self, data, context, end_of_message,
4444
self.loop.create_task(
4545
self.connection.receive(min_incomplete_length=1, max_length=5)
4646
)
47-
await self.connection.send(data)
47+
reply_context = None
48+
if self.connection.protocol == "udp":
49+
reply_context = self.connection.new_message_context(
50+
safelyReplayable=True,
51+
final=False,
52+
)
53+
await self.connection.send(data, reply_context)
4854

4955
async def handle_received(self, data, context, connection):
5056
logger.info("Received message %s from %s.", data, context.addr)
5157
self.loop.create_task(
5258
self.connection.receive(min_incomplete_length=1, max_length=5)
5359
)
54-
await self.connection.send(data)
60+
reply_context = None
61+
if self.connection.protocol == "udp":
62+
reply_context = self.connection.new_message_context(
63+
safelyReplayable=True,
64+
final=False,
65+
)
66+
await self.connection.send(data, reply_context)
5567

5668
async def handle_listen_error(self):
5769
logger.warning("Listen Error occured.")

pytaps/__init__.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
from .listener import Listener as Listener
66
from .message import MessageContext as MessageContext, ReceivedMessage as ReceivedMessage
77
from .multicast import do_join as do_join
8-
from .preconnection import Preconnection as Preconnection
8+
from .preconnection import Preconnection as Preconnection, RendezvousResult as RendezvousResult
99
from .securityParameters import SecurityParameters as SecurityParameters
1010
from .transportProperties import (
1111
PreferenceLevel as PreferenceLevel,
@@ -30,6 +30,7 @@
3030
"Preconnection",
3131
"ReceivedMessage",
3232
"RemoteEndpoint",
33+
"RendezvousResult",
3334
"SecurityParameters",
3435
"TransportProperties",
3536
"do_join",

0 commit comments

Comments
 (0)