--- /dev/null
+<svg id="mermaid-1557425697940" width="100%" xmlns="http://www.w3.org/2000/svg" height="100%" style="max-width:450px;" viewBox="-50 -10 450 301"><style>
+
+
+#mermaid-1557425697940 .label {
+ font-family: 'trebuchet ms', verdana, arial;
+ color: #333; }
+
+#mermaid-1557425697940 .node rect,
+#mermaid-1557425697940 .node circle,
+#mermaid-1557425697940 .node ellipse,
+#mermaid-1557425697940 .node polygon {
+ fill: #ECECFF;
+ stroke: #9370DB;
+ stroke-width: 1px; }
+
+#mermaid-1557425697940 .node.clickable {
+ cursor: pointer; }
+
+#mermaid-1557425697940 .arrowheadPath {
+ fill: #333333; }
+
+#mermaid-1557425697940 .edgePath .path {
+ stroke: #333333;
+ stroke-width: 1.5px; }
+
+#mermaid-1557425697940 .edgeLabel {
+ background-color: #e8e8e8; }
+
+#mermaid-1557425697940 .cluster rect {
+ fill: #ffffde !important;
+ stroke: #aaaa33 !important;
+ stroke-width: 1px !important; }
+
+#mermaid-1557425697940 .cluster text {
+ fill: #333; }
+
+#mermaid-1557425697940 div.mermaidTooltip {
+ position: absolute;
+ text-align: center;
+ max-width: 200px;
+ padding: 2px;
+ font-family: 'trebuchet ms', verdana, arial;
+ font-size: 12px;
+ background: #ffffde;
+ border: 1px solid #aaaa33;
+ border-radius: 2px;
+ pointer-events: none;
+ z-index: 100; }
+
+#mermaid-1557425697940 .actor {
+ stroke: #CCCCFF;
+ fill: #ECECFF; }
+
+#mermaid-1557425697940 text.actor {
+ fill: black;
+ stroke: none; }
+
+#mermaid-1557425697940 .actor-line {
+ stroke: grey; }
+
+#mermaid-1557425697940 .messageLine0 {
+ stroke-width: 1.5;
+ stroke-dasharray: '2 2';
+ stroke: #333; }
+
+#mermaid-1557425697940 .messageLine1 {
+ stroke-width: 1.5;
+ stroke-dasharray: '2 2';
+ stroke: #333; }
+
+#mermaid-1557425697940 #arrowhead {
+ fill: #333; }
+
+#mermaid-1557425697940 #crosshead path {
+ fill: #333 !important;
+ stroke: #333 !important; }
+
+#mermaid-1557425697940 .messageText {
+ fill: #333;
+ stroke: none; }
+
+#mermaid-1557425697940 .labelBox {
+ stroke: #CCCCFF;
+ fill: #ECECFF; }
+
+#mermaid-1557425697940 .labelText {
+ fill: black;
+ stroke: none; }
+
+#mermaid-1557425697940 .loopText {
+ fill: black;
+ stroke: none; }
+
+#mermaid-1557425697940 .loopLine {
+ stroke-width: 2;
+ stroke-dasharray: '2 2';
+ stroke: #CCCCFF; }
+
+#mermaid-1557425697940 .note {
+ stroke: #aaaa33;
+ fill: #fff5ad; }
+
+#mermaid-1557425697940 .noteText {
+ fill: black;
+ stroke: none;
+ font-family: 'trebuchet ms', verdana, arial;
+ font-size: 14px; }
+
+#mermaid-1557425697940 .activation0 {
+ fill: #f4f4f4;
+ stroke: #666; }
+
+#mermaid-1557425697940 .activation1 {
+ fill: #f4f4f4;
+ stroke: #666; }
+
+#mermaid-1557425697940 .activation2 {
+ fill: #f4f4f4;
+ stroke: #666; }
+
+
+#mermaid-1557425697940 .section {
+ stroke: none;
+ opacity: 0.2; }
+
+#mermaid-1557425697940 .section0 {
+ fill: rgba(102, 102, 255, 0.49); }
+
+#mermaid-1557425697940 .section2 {
+ fill: #fff400; }
+
+#mermaid-1557425697940 .section1,
+#mermaid-1557425697940 .section3 {
+ fill: white;
+ opacity: 0.2; }
+
+#mermaid-1557425697940 .sectionTitle0 {
+ fill: #333; }
+
+#mermaid-1557425697940 .sectionTitle1 {
+ fill: #333; }
+
+#mermaid-1557425697940 .sectionTitle2 {
+ fill: #333; }
+
+#mermaid-1557425697940 .sectionTitle3 {
+ fill: #333; }
+
+#mermaid-1557425697940 .sectionTitle {
+ text-anchor: start;
+ font-size: 11px;
+ text-height: 14px; }
+
+
+#mermaid-1557425697940 .grid .tick {
+ stroke: lightgrey;
+ opacity: 0.3;
+ shape-rendering: crispEdges; }
+
+#mermaid-1557425697940 .grid path {
+ stroke-width: 0; }
+
+
+#mermaid-1557425697940 .today {
+ fill: none;
+ stroke: red;
+ stroke-width: 2px; }
+
+
+
+#mermaid-1557425697940 .task {
+ stroke-width: 2; }
+
+#mermaid-1557425697940 .taskText {
+ text-anchor: middle;
+ font-size: 11px; }
+
+#mermaid-1557425697940 .taskTextOutsideRight {
+ fill: black;
+ text-anchor: start;
+ font-size: 11px; }
+
+#mermaid-1557425697940 .taskTextOutsideLeft {
+ fill: black;
+ text-anchor: end;
+ font-size: 11px; }
+
+
+#mermaid-1557425697940 .taskText0,
+#mermaid-1557425697940 .taskText1,
+#mermaid-1557425697940 .taskText2,
+#mermaid-1557425697940 .taskText3 {
+ fill: white; }
+
+#mermaid-1557425697940 .task0,
+#mermaid-1557425697940 .task1,
+#mermaid-1557425697940 .task2,
+#mermaid-1557425697940 .task3 {
+ fill: #8a90dd;
+ stroke: #534fbc; }
+
+#mermaid-1557425697940 .taskTextOutside0,
+#mermaid-1557425697940 .taskTextOutside2 {
+ fill: black; }
+
+#mermaid-1557425697940 .taskTextOutside1,
+#mermaid-1557425697940 .taskTextOutside3 {
+ fill: black; }
+
+
+#mermaid-1557425697940 .active0,
+#mermaid-1557425697940 .active1,
+#mermaid-1557425697940 .active2,
+#mermaid-1557425697940 .active3 {
+ fill: #bfc7ff;
+ stroke: #534fbc; }
+
+#mermaid-1557425697940 .activeText0,
+#mermaid-1557425697940 .activeText1,
+#mermaid-1557425697940 .activeText2,
+#mermaid-1557425697940 .activeText3 {
+ fill: black !important; }
+
+
+#mermaid-1557425697940 .done0,
+#mermaid-1557425697940 .done1,
+#mermaid-1557425697940 .done2,
+#mermaid-1557425697940 .done3 {
+ stroke: grey;
+ fill: lightgrey;
+ stroke-width: 2; }
+
+#mermaid-1557425697940 .doneText0,
+#mermaid-1557425697940 .doneText1,
+#mermaid-1557425697940 .doneText2,
+#mermaid-1557425697940 .doneText3 {
+ fill: black !important; }
+
+
+#mermaid-1557425697940 .crit0,
+#mermaid-1557425697940 .crit1,
+#mermaid-1557425697940 .crit2,
+#mermaid-1557425697940 .crit3 {
+ stroke: #ff8888;
+ fill: red;
+ stroke-width: 2; }
+
+#mermaid-1557425697940 .activeCrit0,
+#mermaid-1557425697940 .activeCrit1,
+#mermaid-1557425697940 .activeCrit2,
+#mermaid-1557425697940 .activeCrit3 {
+ stroke: #ff8888;
+ fill: #bfc7ff;
+ stroke-width: 2; }
+
+#mermaid-1557425697940 .doneCrit0,
+#mermaid-1557425697940 .doneCrit1,
+#mermaid-1557425697940 .doneCrit2,
+#mermaid-1557425697940 .doneCrit3 {
+ stroke: #ff8888;
+ fill: lightgrey;
+ stroke-width: 2;
+ cursor: pointer;
+ shape-rendering: crispEdges; }
+
+#mermaid-1557425697940 .doneCritText0,
+#mermaid-1557425697940 .doneCritText1,
+#mermaid-1557425697940 .doneCritText2,
+#mermaid-1557425697940 .doneCritText3 {
+ fill: black !important; }
+
+#mermaid-1557425697940 .activeCritText0,
+#mermaid-1557425697940 .activeCritText1,
+#mermaid-1557425697940 .activeCritText2,
+#mermaid-1557425697940 .activeCritText3 {
+ fill: black !important; }
+
+#mermaid-1557425697940 .titleText {
+ text-anchor: middle;
+ font-size: 18px;
+ fill: black; }
+
+#mermaid-1557425697940 g.classGroup text {
+ fill: #9370DB;
+ stroke: none;
+ font-family: 'trebuchet ms', verdana, arial;
+ font-size: 10px; }
+
+#mermaid-1557425697940 g.classGroup rect {
+ fill: #ECECFF;
+ stroke: #9370DB; }
+
+#mermaid-1557425697940 g.classGroup line {
+ stroke: #9370DB;
+ stroke-width: 1; }
+
+#mermaid-1557425697940 .classLabel .box {
+ stroke: none;
+ stroke-width: 0;
+ fill: #ECECFF;
+ opacity: 0.5; }
+
+#mermaid-1557425697940 .classLabel .label {
+ fill: #9370DB;
+ font-size: 10px; }
+
+#mermaid-1557425697940 .relation {
+ stroke: #9370DB;
+ stroke-width: 1;
+ fill: none; }
+
+#mermaid-1557425697940 #compositionStart {
+ fill: #9370DB;
+ stroke: #9370DB;
+ stroke-width: 1; }
+
+#mermaid-1557425697940 #compositionEnd {
+ fill: #9370DB;
+ stroke: #9370DB;
+ stroke-width: 1; }
+
+#mermaid-1557425697940 #aggregationStart {
+ fill: #ECECFF;
+ stroke: #9370DB;
+ stroke-width: 1; }
+
+#mermaid-1557425697940 #aggregationEnd {
+ fill: #ECECFF;
+ stroke: #9370DB;
+ stroke-width: 1; }
+
+#mermaid-1557425697940 #dependencyStart {
+ fill: #9370DB;
+ stroke: #9370DB;
+ stroke-width: 1; }
+
+#mermaid-1557425697940 #dependencyEnd {
+ fill: #9370DB;
+ stroke: #9370DB;
+ stroke-width: 1; }
+
+#mermaid-1557425697940 #extensionStart {
+ fill: #9370DB;
+ stroke: #9370DB;
+ stroke-width: 1; }
+
+#mermaid-1557425697940 #extensionEnd {
+ fill: #9370DB;
+ stroke: #9370DB;
+ stroke-width: 1; }
+
+#mermaid-1557425697940 .commit-id,
+#mermaid-1557425697940 .commit-msg,
+#mermaid-1557425697940 .branch-label {
+ fill: lightgrey;
+ color: lightgrey; }
+</style><style>#mermaid-1557425697940 {
+ color: rgba(0, 0, 0, 0.65);
+ font: ;
+ }</style><g></g><g><line id="actor1158" x1="75" y1="5" x2="75" y2="290" class="actor-line" stroke-width="0.5px" stroke="#999"></line><rect x="0" y="0" fill="#eaeaea" stroke="#666" width="150" height="65" rx="3" ry="3" class="actor"></rect><text x="75" y="32.5" dominant-baseline="central" alignment-baseline="central" class="actor" style="text-anchor: middle; font-size: 14px; font-family: Open-Sans, sans-serif;"><tspan x="75" dy="0">Runtime</tspan></text></g><g><line id="actor1159" x1="275" y1="5" x2="275" y2="290" class="actor-line" stroke-width="0.5px" stroke="#999"></line><rect x="200" y="0" fill="#eaeaea" stroke="#666" width="150" height="65" rx="3" ry="3" class="actor"></rect><text x="275" y="32.5" dominant-baseline="central" alignment-baseline="central" class="actor" style="text-anchor: middle; font-size: 14px; font-family: Open-Sans, sans-serif;"><tspan x="275" dy="0">Client</tspan></text></g><defs><marker id="arrowhead" refX="5" refY="2" markerWidth="6" markerHeight="4" orient="auto"><path d="M 0,0 V 4 L6,2 Z"></path></marker></defs><defs><marker id="crosshead" markerWidth="15" markerHeight="8" orient="auto" refX="16" refY="4"><path fill="black" stroke="#000000" stroke-width="1px" d="M 9,2 V 6 L16,4 Z" style="stroke-dasharray: 0, 0;"></path><path fill="none" stroke="#000000" stroke-width="1px" d="M 0,1 L 6,7 M 6,1 L 0,7" style="stroke-dasharray: 0, 0;"></path></marker></defs><g><text x="175" y="93" class="messageText" style="text-anchor: middle;">Diagnostic IPC Message</text><line x1="275" y1="100" x2="75" y2="100" class="messageLine0" stroke-width="2" stroke="black" marker-end="url(#arrowhead)" style="fill: none;"></line></g><g><text x="175" y="128" class="messageText" style="text-anchor: middle;">Diagnostic IPC Message</text><line x1="75" y1="135" x2="275" y2="135" class="messageLine1" stroke-width="2" stroke="black" marker-end="url(#arrowhead)" style="stroke-dasharray: 3, 3; fill: none;"></line></g><g><text x="175" y="188" class="messageText" style="text-anchor: middle;">Command Specific Communication</text><line x1="75" y1="195" x2="275" y2="195" class="messageLine0" stroke-width="2" stroke="black" style="fill: none;"></line></g><g><line x1="65" y1="145" x2="285" y2="145" class="loopLine"></line><line x1="285" y1="145" x2="285" y2="205" class="loopLine"></line><line x1="65" y1="205" x2="285" y2="205" class="loopLine"></line><line x1="65" y1="145" x2="65" y2="205" class="loopLine"></line><polygon points="65,145 115,145 115,158 106.6,165 65,165" class="labelBox"></polygon><text x="72.5" y="160" fill="black" class="labelText"><tspan x="72.5" fill="black">opt</tspan></text><text x="175" y="160" fill="black" class="loopText" style="text-anchor: middle;"><tspan x="175" fill="black">[ Optional Continuation ]</tspan></text></g><g><rect x="0" y="225" fill="#eaeaea" stroke="#666" width="150" height="65" rx="3" ry="3" class="actor"></rect><text x="75" y="257.5" dominant-baseline="central" alignment-baseline="central" class="actor" style="text-anchor: middle; font-size: 14px; font-family: Open-Sans, sans-serif;"><tspan x="75" dy="0">Runtime</tspan></text></g><g><rect x="200" y="225" fill="#eaeaea" stroke="#666" width="150" height="65" rx="3" ry="3" class="actor"></rect><text x="275" y="257.5" dominant-baseline="central" alignment-baseline="central" class="actor" style="text-anchor: middle; font-size: 14px; font-family: Open-Sans, sans-serif;"><tspan x="275" dy="0">Client</tspan></text></g></svg>
\ No newline at end of file
--- /dev/null
+# Diagnostic IPC Protocol
+
+## Overview
+
+This spec describes the IPC Protocol to be used for communicating with the dotnet core runtime's Diagnostics Server from an external client over a platform-specific transport, e.g., Unix Domain Sockets.
+
+
+### Terminology
+
+The protocol will use the following names for various constructs and behaviors defined in this spec:
+* *Diagnostic IPC Protocol*: The protocol defined in this spec
+* *Diagnostic Server*: The server in the runtime that receives/sends Diagnostic IPC Procotol communication.
+* *Commands*: The functionality being invoked in the runtime that communicates over the Diagnostic IPC Protocol, e.g., "Start an EventPipe stream". These are encoded as a `command_set` and a `command_id`.
+* *Flow*: A sequence of interactions making up communication with the Diagnostics Server
+* *Pipe*: The duplex communication construct this protocol is communicated over. This is a Unix Domain Socket on *nix systems and a Named Pipe on Windows.
+* *IPC Message*: The base unit of communication over the Diagnostic IPC Protocol. Is made up of a Header and a Payload.
+* *Header*: A struct containing a magic version, the size, a command, and metadata.
+* *Payload*: An opaque chunk of data that is Command specific.
+* *Optional Continuation*: The reuse of the pipe for application specific communication. This communication does not need to adhere to any requirements listed in this spec, e.g., this could be a stream of custom encoded data that is Command specific.
+
+## General Flow
+
+All communication with the Diagnostic Server will begin with a Diagnostic IPC Message sent from the client to the server. The server will respond with a Diagnostic IPC Message. After this, the client and runtime _may_ reuse the Pipe for any Command specific communication which is referred to as an Optional Continuation.
+
+
+
+```
+runtime <- client : [ Header ][ Payload ]
+runtime -> client : [ Header ][ Payload ]
+optional:
+ runtime <-> client : [ Optional Continuation ]
+connection closed
+```
+
+Example flow for EventPipe:
+```
+runtime <- client : [ magic; size; EventPipe CollectTracing ][ stream config struct ] <- Diagnostic IPC Message
+runtime -> client : [ magic; size; Server OK ][ sessionId ] <- Diagnostic IPC Message
+runtime -> client : [ stream of netperf data ] <- Optional Continuation
+
+// stop message is sent on another connection
+
+connection closed
+```
+
+## Transport
+
+The protocol will be communicated over a platform-specific transport. On Unix/Linux based platforms, a Unix Domain Socket will be used, and on Windows, a Named Pipe will be used.
+
+#### Naming and Location Conventions
+
+Unix Domain Sockets (MacOS and *nix):
+
+The socket is placed in one of two places:
+1. The directory specified in `$TMPDIR`
+2. `/tmp` if `$TMPDIR` is undefined/empty
+
+In order to ensure filename uniqueness, a `disambiguation key` is generated. On Mac and NetBSD, this is the process start time encoded as the number of seconds since UNIX epoch time. If `/proc/$PID/stat` is available (all other *nix platforms), then the process start time encoded as jiffies since boot time is used.
+
+> NOTE: If the target application is running inside an application sandbox on MacOS, the transport will be placed in the Application Group container directory. This is a convention for all sandboxed applications on MacOS.
+
+socket name:
+```c
+dotnetcore-diagnostic-{%d:PID}-{%llu:disambiguation key}-socket
+```
+
+Named Pipes (Windows):
+```
+\\.\pipe\dotnetcore-diagnostic-{%d:PID}
+```
+
+## Messages
+
+Diagnostic IPC Messages are the base unit of communication with the Diagnostic Server. A Diagnostic IPC Message contains a Header and Payload (described in following sections).
+
+<table>
+ <tr>
+ <th>1</th>
+ <th>2</th>
+ <th>3</th>
+ <th>4</th>
+ <th>5</th>
+ <th>6</th>
+ <th>7</th>
+ <th>8</th>
+ <th>9</th>
+ <th>10</th>
+ <th>11</th>
+ <th>12</th>
+ <th>13</th>
+ <th>14</th>
+ <th>15</th>
+ <th>16</th>
+ <th>17</th>
+ <th>18</th>
+ <th>19</th>
+ <th>20</th>
+ <th>21</th>
+ <th>22</th>
+ <th>23</th>
+ <th>24</th>
+ <th>...</th>
+ <th>size - 1 </th>
+ <th>size</th>
+ </tr>
+ <tr>
+ <td colspan="20">header</td>
+ <td colspan="7">payload</td>
+ </tr>
+ <tr>
+ <td colspan="14">magic</td>
+ <td colspan="2">size</td>
+ <td colspan="1">command_set</td>
+ <td colspan="1">command_id</td>
+ <td colspan="2">reserved</td>
+ <td colspan="7">payload</td>
+ </tr>
+</table>
+
+The simplest Diagnostic IPC Message will contain a Header and an empty Payload and therefore only be 20 bytes long.
+
+For example, this IPC Message is the generic OK message which has an empty Payload:
+<table>
+ <tr>
+ <th>1</th>
+ <th>2</th>
+ <th>3</th>
+ <th>4</th>
+ <th>5</th>
+ <th>6</th>
+ <th>7</th>
+ <th>8</th>
+ <th>9</th>
+ <th>10</th>
+ <th>11</th>
+ <th>12</th>
+ <th>13</th>
+ <th>14</th>
+ <th>15</th>
+ <th>16</th>
+ <th>17</th>
+ <th>18</th>
+ <th>19</th>
+ <th>20</th>
+ </tr>
+ <tr>
+ <tr>
+ <td colspan="14">magic</td>
+ <td colspan="2">size</td>
+ <td colspan="2">command</td>
+ <td colspan="2">reserved</td>
+ </tr>
+ <tr>
+ <td colspan="14">"DOTNET_IPC_V1"</td>
+ <td colspan="2">20</td>
+ <td colspan="1">0xFF</td>
+ <td colspan="1">0x00</td>
+ <td colspan="2">0x0000</td>
+ </tr>
+</table>
+
+### Headers
+
+Every Diagnostic IPC Message will start with a header and every header will:
+* start with a magic version number and a size
+* `sizeof(IpcHeader) == 20`
+* encode numbers little-endian
+* account for the size of the payload in the `size` value, i.e., `IpcHeader.size == sizeof(IpcHeader) + PayloadStruct.GetSize()`
+
+```c
+// size = 14 + 2 + 1 + 1 + 2 = 20 bytes
+struct IpcHeader
+{
+ uint8_t[14] magic = "DOTNET_IPC_V1";
+ uint16_t size; // size of packet = size of header + payload
+ uint8_t command_set; // combined with command_id is the Command to invoke
+ uint8_t command_id; // combined with command_set is the Command to invoke
+ uint16_t reserved; // for potential future use
+};
+```
+
+The `reserved` field is reserved for future use. It is unused in `DOTNET_IPC_V1` and must be 0x0000.
+
+
+### Payloads
+
+Payloads are Command specific data encoded into a Diagnostic IPC Message. The size of the payload is implicitly encoded in the Header's `size` field as `PayloadSize = header.size - sizeof(struct IpcHeader)`. A Payload _may_ be 0 bytes long if it empty. The encoding of data in the Payload is Command specific.
+
+Payloads are either encoded as fixed size structures that can be `memcpy`'ed , _or_:
+
+* `X, Y, Z` means encode bytes for `X` followed by bytes for `Y` followed by bytes for `Z`
+* `uint` = 4 little endian bytes
+* `ulong` = 8 little endian bytes
+* `wchar` = 2 little endian bytes, UTF16 encoding
+* `array<T>` = uint length, length # of `T`s
+* `string` = (`array<wchar>` where the last `wchar` must = `0`) or (length = `0`)
+
+As an example, the CollectTracing command to EventPipe (explained below) encodes its Payload as:
+
+<table>
+ <tr>
+ <th>1</th>
+ <th>2</th>
+ <th>3</th>
+ <th>4</th>
+ <th>5</th>
+ <th>6</th>
+ <th>7</th>
+ <th>8</th>
+ <th>9</th>
+ <th>10</th>
+ <th>11</th>
+ <th>12</th>
+ <th>13</th>
+ <th>14</th>
+ <th>15</th>
+ <th>16</th>
+ <th>17</th>
+ <th>18</th>
+ <th>19</th>
+ <th>20</th>
+ <th>21</th>
+ <th>22</th>
+ <th>23</th>
+ <th>24</th>
+ <th>25</th>
+ <th>26</th>
+ <th>27</th>
+ <th>28</th>
+ <th>29</th>
+ <th>30</th>
+ <th>31</th>
+ <th>32</th>
+ <th>33</th>
+ <th>34</th>
+ <th>35</th>
+ <th>36</th>
+ <th>37</th>
+ <th>38</th>
+ <th>39</th>
+ <th>40</th>
+ <th>41</th>
+ <th>42</th>
+ <th>43</th>
+ <th>44</th>
+ <th>45</th>
+ <th>46</th>
+ <th>47</th>
+ <th>48</th>
+ <th>49</th>
+ <th>50</th>
+ <th>51</th>
+ <th>52</th>
+ <th>53</th>
+ <th>54</th>
+ <th>55</th>
+ <th>56</th>
+ <th>57</th>
+ <th>58</th>
+ <th>59</th>
+ <th>60</th>
+ <th>61</th>
+ <th>62</th>
+ <th>63</th>
+ <th>64</th>
+ <th>65</th>
+ <th>66</th>
+ <th>67</th>
+ <th>68</th>
+ <th>69</th>
+ <th>70</th>
+ <th>71</th>
+ <th>72</th>
+ <th>73</th>
+ <th>74</th>
+ <th>75</th>
+ <th>76</th>
+ <th>77</th>
+ <th>78</th>
+ </tr>
+ <tr>
+ <td colspan="20">Header</td>
+ <td colspan="58">Payload</td>
+ </tr>
+ <tr>
+ <td colspan="14">magic</td>
+ <td colspan="2">size</td>
+ <td colspan="2">command</td>
+ <td colspan="2">reserved</td>
+ <td colspan="4">circularBufferMB</td>
+ <td colspan="4">outputPath Length</td>
+ <td colspan="16">outputPath String</td>
+ <td colspan="4">n Providers</td>
+ <td colspan="8">Keywords</td>
+ <td colspan="4">logLevel</td>
+ <td colspan="4">provider_name length</td>
+ <td colspan="14">provider_name string</td>
+ </tr>
+ <tr>
+ <td colspan="14">"DOTNET_IPC_V1"</td>
+ <td colspan="2">78</td>
+ <td colspan="2">0x0202</td>
+ <td colspan="2">0x0000</td>
+ <td colspan="4">250</td>
+ <td colspan="4">16</td>
+ <td colspan="16">"/tmp/foo.netperf"</td>
+ <td colspan="4">1</td>
+ <td colspan="8">100</td>
+ <td colspan="4">2</td>
+ <td colspan="4">14</td>
+ <td colspan="14">"MyEventSource"</td>
+ </tr>
+</table>
+
+Where `0x0202` is the Command to start streaming with EventPipe.
+
+### Commands
+
+Commands are a `command_set` and a `command_id`. A `command_set` is analogous to a namespace for `command_id`s. The typical grouping is by service running on the Diagnostic Server, e.g., there is a `command_set` for EventPipe. This allows multiple services to have the same `command_id`s without clashing. The combination of a `command_set` and a `command_id` encodes the Command being invoked on the Diagnostic Server.
+
+The current set of `command_set`s and `command_id`s are listed below:
+
+```c
+enum class CommandSet : uint8_t
+{
+ // reserved = 0x00,
+ Miscellaneous = 0x01,
+ EventPipe = 0x02,
+ // future
+
+ Server = 0xFF,
+};
+```
+
+```c
+enum class ServerCommandId : uint8_t
+{
+ OK = 0x00,
+ Error = 0xFF,
+};
+```
+
+```c
+enum class EventPipeCommandId : uint8_t
+{
+ // reserved = 0x00,
+ StopTracing = 0x01, // stop a given session
+ CollectTracing = 0x02, // create/start a given session
+}
+```
+
+Commands may use the generic `{ magic="DOTNET_IPC_V1"; size=20; command_set=0xFF (Server); command_id=0x00 (OK); reserved = 0x0000; }` to indicate success rather than having a command specific success `command_id`.
+
+For example, the Command to start a stream session with EventPipe would be `0x0202` made up of `0x02` (the `command_set` for EventPipe) and `0x02` (the `command_id` for CollectTracing).
+
+## EventPipe Commands
+
+```c
+enum class EventPipeCommandId : uint8_t
+{
+ // reserved = 0x00,
+ StopTracing = 0x01, // stop a given session
+ CollectTracing = 0x02, // create/start a given session
+}
+```
+EventPipe Payloads are encoded with the following rules:
+
+* `X, Y, Z` means encode bytes for `X` followed by bytes for `Y` followed by bytes for `Z`
+* `uint` = 4 little endian bytes
+* `ulong` = 8 little endian bytes
+* `wchar` = 2 little endian bytes, UTF16 encoding
+* `array<T>` = uint length, length # of `T`s
+* `string` = (`array<wchar>` where the last `wchar` must = `0`) or (length = `0`)
+
+### `CollectTracing`
+
+Command Code: `0x0202`
+
+The `CollectTracing` Command is used to start a streaming session of event data. The runtime will attempt to start a session and respond with a success message with a payload of the `sessionId`. The event data is streamed in the `netperf` format. The stream begins after the response Message from the runtime to the client. The client is expected to continue to listen on the transport until the connection is closed.
+
+In the event there is an [error](#Errors), the runtime will attempt to send an error message and subsequently close the connection.
+
+The client is expected to send a [`StopTracing`](#StopTracing) command to the runtime in order to stop the stream, as there is a "run down" at the end of a stream session that transmits additional metadata.
+
+If the stream is stopped prematurely due to a client or server error, the `netperf` file generated will be incomplete and should be considered corrupted.
+
+#### Inputs:
+
+Header: `{ Magic; Size; 0x0202; 0x0000 }`
+
+* `uint circularBufferMB`: The size of the circular buffer used for buffering event data while streaming
+* `string outputPath`: currently unused, and should be 0 length
+* `array<provider_config> providers`: The providers to turn on for the streaming session
+
+A `provider_config` is composed of the following data:
+* `ulong keywords`: The keywords to turn on with this providers
+* `uint logLevel`: The level of information to turn on
+* `string provider_name`: The name of the provider
+* `string filter_data` (optional): Filter information
+
+> see ETW documentation for a more detailed explanation of Keywords, Filters, and Log Level.
+
+#### Returns (as an IPC Message Payload):
+
+Header: `{ Magic; 28; 0xFF00; 0x0000; }`
+
+`CollectTracing` returns:
+* `ulong sessionId`: the ID for the stream session starting on the current connection
+
+##### Details:
+
+Input:
+```
+Payload
+{
+ uint circularBufferMB,
+ string outputPath,
+ array<provider_config> providers
+}
+
+provider_config
+{
+ ulong keywords,
+ uint logLevel,
+ string provider_name,
+ string filter_data (optional)
+}
+```
+
+Returns:
+```c
+Payload
+{
+ ulong sessionId
+}
+```
+Followed by an Optional Continuation of a `netperf` format stream of events.
+
+### `StopTracing`
+
+Command Code: `0x0201`
+
+The `StopTracing` command is used to stop a specific streaming session. Clients are expected to use this command to stop streaming sessions started with [`CollectStreaming`](#CollectStreaming).
+
+#### Inputs:
+
+Header: `{ Magic; 28; 0x0201; 0x0000 }`
+
+* `ulong sessionId`: The ID for the streaming session to stop
+
+#### Returns:
+
+Header: `{ Magic; 28; 0xFF00; 0x0000 }`
+
+* `ulong sessionId`: the ID for the streaming session that was stopped
+
+
+##### Details:
+
+Inputs:
+```c
+Payload
+{
+ ulong sessionId
+}
+```
+
+Returns:
+```c
+Payload
+{
+ ulong sessionId
+}
+```
+
+### Errors
+
+In the event an error occurs in the handling of an Ipc Message, the Diagnostic Server will attempt to send an Ipc Message encoding the error and subsequently close the connection. The connection will be closed **regardless** of the success of sending the error message. The Client is expected to be resilient in the event of a connection being abruptly closed.
+
+```c++
+enum class DiagnosticServerErrorCode : uint32_t
+{
+ OK = 0x00000000,
+ BadEncoding = 0x00000001,
+ UnknownCommand = 0x00000002,
+ UnknownMagic = 0x00000003,
+ BadInput = 0x00000004,
+ // future
+
+ UnknownError = 0xFFFFFFFF,
+};
+```
+
+Diagnostic Server errors are sent as a Diagnostic IPC Message with:
+* a `command_set` of `0xFF`
+* a `command_id` of `0xFF`
+* a Payload consisting of a `uint32_t` representing the error encountered (described above)
+
+All errors will result in the Server closing the connection.
+
+Error response Messages will be sent when:
+* the client sends an improperly encoded Diagnostic IPC Message
+* the client uses an unknown `command`
+* the client uses an unknown `magic` version string
+* the server encounters an unrecoverable error, e.g., OOM, transport error, etc.
+
+The client is expected to be resilient in the event that the Diagnostic Server fails to respond in a reasonable amount of time (this may be Command specific).
+
+For example, if the Diagnostic Server finds incorrectly encoded data while parsing a Message, it would send the following Message in response:
+
+<table>
+ <tr>
+ <th>1</th>
+ <th>2</th>
+ <th>3</th>
+ <th>4</th>
+ <th>5</th>
+ <th>6</th>
+ <th>7</th>
+ <th>8</th>
+ <th>9</th>
+ <th>10</th>
+ <th>11</th>
+ <th>12</th>
+ <th>13</th>
+ <th>14</th>
+ <th>15</th>
+ <th>16</th>
+ <th>17</th>
+ <th>18</th>
+ <th>19</th>
+ <th>20</th>
+ <th>21</th>
+ <th>22</th>
+ <th>23</th>
+ <th>24</th>
+ <th>25</th>
+ <th>26</th>
+ <th>27</th>
+ <th>28</th>
+ </tr>
+ <tr>
+ <td colspan="20">Header</td>
+ <td colspan="8">Payload</td>
+ </tr>
+ <tr>
+ <td colspan="14">magic</td>
+ <td colspan="2">size</td>
+ <td colspan="1">command_set</td>
+ <td colspan="1">command_id</td>
+ <td colspan="2">reserved</td>
+ <td colspan="8">Error Code</td>
+ </tr>
+ <tr>
+ <td colspan="14">"DOTNET_IPC_V1"</td>
+ <td colspan="2">28</td>
+ <td colspan="1">0xFF</td>
+ <td colspan="1">0xFF</td>
+ <td colspan="2">0x0000</td>
+ <td colspan="8">0x00000001</td>
+ </tr>
+</table>
+
+-----
+### Current Implementation (OLD)
+
+Single-purpose IPC protocol used exclusively for EventPipe functionality. "Packets" in the current implementation are simply the `netperf` payloads and command/control is handled via `uint32` enum values sent one way with hard coded responses expected.
+
+```c++
+enum class DiagnosticMessageType : uint32_t
+{
+ // EventPipe
+ StartEventPipeTracing = 1024, // To file
+ StopEventPipeTracing,
+ CollectEventPipeTracing, // To IPC
+};
+
+struct MessageHeader
+{
+ DiagnosticMessageType RequestType;
+ uint32_t Pid;
+};
+```
+
+```
+runtime <- client : MessageHeader { CollectEventPipeTracing }
+ error? -> 0 then session close
+runtime -> client : session ID
+runtime -> client : event stream
+
+...
+
+runtime <- client : stop command
+runtime -> client : session id and stops
+```
\ No newline at end of file