Posted to tcl by Stu at Wed Aug 22 23:32:54 GMT 2012view raw

  1. TIP:
  2. Title: Datagram I/O in Tcl
  3. Author: Alexandre Ferrieux, Colin McCormack
  4. Type: Project
  5. Tcl-Version: 8.7
  6. Created: 17-Aug-2012
  7.  
  8. ~ Abstract
  9.  
  10. This TIP adds support for Datagram I/O in Tcl (starting with UDP),
  11. with a pure event approach to packet reception (as opposed to
  12. hijacking the existing channel infrastructure).
  13.  
  14. ~ Rationale
  15.  
  16. UDP support is a long-awaited feature in Tcl. Some extensions have
  17. traditionally supported it through the channel abstraction. This is of
  18. course doable, but there is a nonnegligible cost in both complexity
  19. and performance due to the impedence mismatch between the "fluid"
  20. model behind channels and the "granular" world of packets or datagrams
  21. (where boundaries are significant). Another discrepancy is the
  22. existence of (per-packet) metadata (like the source address and port
  23. of an incoming UDP packet), which does not fit nicely in the
  24. (per-connection) options of the channel API (via fconfigure).
  25.  
  26. Once this mismatch is acknowledged, it is easy to identify a better
  27. home for packet I/O in Tcl: let it be a direct event source (for the
  28. receive side), just like Tk or Snack.
  29.  
  30. Indeed, hooking a callback for packet reception is a natural fit with
  31. Tcl's event-driven tradition, while preserving packet boundaries and
  32. easily exposing per-packet metadata.
  33.  
  34. Sending is trivially handled by a direct per-packet call (but not
  35. disguised as a [puts]). Again, this naturally allows for boundary
  36. preservation and metadata specification.
  37.  
  38. The script API put forth in this TIP is also designed for easy
  39. generalization to other kinds of packet I/O. Though only UDP is
  40. supported in the reference implementation, other protocols may be
  41. registered, and selected with the ''protocol'' paramater. Future
  42. additions may include:
  43.  
  44. - raw IP sockets
  45. - USB
  46. - Bluetooth
  47.  
  48. ~ Overall Specification
  49.  
  50. The new '''dgram''' command creates a "datagram endpoint" of the given
  51. protocol:
  52.  
  53. > '''dgram''' ''protocol'' ?''options''?
  54.  
  55. Following the traditions of Tk and Snack, it returns a Tcl command,
  56. which takes subcommands implementing the needed verbs. An endpoint is
  57. thus created by:
  58.  
  59. > set d ['''dgram''' ''protocol'' ?-''option'' ''value''? ...]
  60.  
  61. The returned command lives by default in the ::tcl::dgram namespace;
  62. however, the generic ''-name'' option allows it to take a (possibly
  63. fully qualified) user-provided name:
  64.  
  65. > dgram ''protocol'' -name foo ...
  66.  
  67. creates (and returns) the command ::foo to hold the endpoint.
  68.  
  69. Once created, its configuration can be tweaked by:
  70.  
  71. > $d configure -''option'' ''value''
  72.  
  73. and retrieved with
  74.  
  75. > set value [$d configure -''option'']
  76.  
  77. To close the endpoint, use:
  78.  
  79. > $d close
  80.  
  81. or, as in Tk, destroy the command:
  82.  
  83. > rename $d {}
  84.  
  85. or the whole namespace.
  86.  
  87. Other verbs, and the detailed list of options, are
  88. protocol-specific. From now on, the specification concentrates on the
  89. UDP case. The rationale for *not* generalizing much is the feeling
  90. that the costs of parameter variability would largely outweigh the
  91. tiny amount of code sharing.
  92.  
  93. ~ The UDP case
  94.  
  95. With UDP, addresses and ports may only be specified on creation:
  96.  
  97. > set d ['''dgram udp''' ?-localaddr ''address''? ?-localport ''port''?]
  98.  
  99. They default to INADDR_ANY and 0, respectively. In case of port 0,
  100. after creation of the endpoint the actual port chosen by the OS can be
  101. retrieved with [$d configure]:
  102.  
  103. > set d [dgram udp]
  104. > puts "Local port is: [$d configure -localport]"
  105.  
  106. One can also specify remote address and port, meaning to connect() the
  107. underlying UDP socket:
  108.  
  109. > set d ['''dgram udp''' ?-remoteaddr ''address'' -remoteport ''port''?]
  110.  
  111. These options suffer no default, and must be simultaneously present or
  112. absent. The semantics, as is well known, is to tell the kernel (a) to
  113. forbid sending to any other destination, and (b) to discard all
  114. incoming packets sent by another source.
  115.  
  116. All the other options may be specified on creation or through
  117. [configure].
  118.  
  119. Sending is done with, unsurprisingly, the 'send' verb:
  120.  
  121. > $d '''send''' ''payload'' ?''destaddr'' ''destport''?
  122.  
  123. Its blocking semantics is that of the underlying protocol: it
  124. typically returns immediately, though the hardware may buffer the data
  125. for some time, and delivery is not guaranteed.
  126.  
  127. The destination parameters can, unsurprisingly, be omitted if the
  128. endpoint has been created with the -remoteaddr/port options (connected
  129. mode).
  130.  
  131. Receiving is done with the -listener callback:
  132.  
  133. > $d '''configure -listener''' ''command_prefix''
  134.  
  135. Subsequently, when an incoming packet hits Tcl in the event loop, the
  136. ''command_prefix'' is called with the endpoint identifier, payload and
  137. metadata:
  138.  
  139. > ''command_prefix'' $d ''payload'' ''metadata_dict''
  140.  
  141. where ''payload'' is the byte array of the UDP payload, and
  142. ''metadata_dict'' is a dict containing at least three options:
  143.  
  144. > '''-remoteaddr''' ''address''
  145. > '''-remoteport''' ''port''
  146. > '''-localaddr''' ''address''
  147.  
  148. When ''command_prefix'' is the empty string, the notifier gives up
  149. interest in the underlying UDP socket; this allows to keep the port
  150. bound while letting the OS buffer any incoming packets (up to a
  151. configurable limit) without any script-level handling, while leaving
  152. the event loop active. This is similar to setting a fileevent to {}.
  153.  
  154. ~ Advanced UDP options
  155.  
  156. (TODO: multicast, ttl, buffersize ...)
  157.  
  158. ~ Copyright
  159.  
  160. This document has been placed in the public domain.
  161.